Skip to content

Commit cda4b4f

Browse files
committed
Move users loading to react-query
1 parent 9e84521 commit cda4b4f

File tree

7 files changed

+74
-156
lines changed

7 files changed

+74
-156
lines changed

site/src/api/queries/users.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import * as API from "api/api";
2-
import { UpdateUserPasswordRequest } from "api/typesGenerated";
2+
import { UpdateUserPasswordRequest, UsersRequest } from "api/typesGenerated";
3+
4+
export const users = (req: UsersRequest) => {
5+
return {
6+
queryKey: ["users", req],
7+
queryFn: () => API.getUsers(req),
8+
};
9+
};
310

411
export const updatePassword = () => {
512
return {

site/src/hooks/usePagination.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const usePagination = ({
99
const [searchParams, setSearchParams] = searchParamsResult;
1010
const page = searchParams.get("page") ? Number(searchParams.get("page")) : 1;
1111
const limit = DEFAULT_RECORDS_PER_PAGE;
12+
const offset = page <= 0 ? 0 : (page - 1) * limit;
1213

1314
const goToPage = (page: number) => {
1415
searchParams.set("page", page.toString());
@@ -19,5 +20,6 @@ export const usePagination = ({
1920
page,
2021
limit,
2122
goToPage,
23+
offset,
2224
};
2325
};

site/src/pages/UsersPage/UsersPage.tsx

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import { useMachine } from "@xstate/react";
22
import { User } from "api/typesGenerated";
33
import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
4-
import {
5-
getPaginationContext,
6-
nonInitialPage,
7-
} from "components/PaginationWidget/utils";
4+
import { nonInitialPage } from "components/PaginationWidget/utils";
85
import { useMe } from "hooks/useMe";
96
import { usePermissions } from "hooks/usePermissions";
10-
import { FC, ReactNode, useEffect } from "react";
7+
import { FC, ReactNode } from "react";
118
import { Helmet } from "react-helmet-async";
129
import { useSearchParams, useNavigate } from "react-router-dom";
1310
import { usersMachine } from "xServices/users/usersXService";
@@ -22,6 +19,9 @@ import { useQuery } from "@tanstack/react-query";
2219
import { getAuthMethods } from "api/api";
2320
import { roles } from "api/queries/roles";
2421
import { deploymentConfig } from "api/queries/deployment";
22+
import { prepareQuery } from "utils/filters";
23+
import { usePagination } from "hooks";
24+
import * as UsersQuery from "api/queries/users";
2525

2626
export const Language = {
2727
suspendDialogTitle: "Suspend user",
@@ -39,28 +39,27 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
3939
const navigate = useNavigate();
4040
const searchParamsResult = useSearchParams();
4141
const { entitlements } = useDashboard();
42-
const [searchParams, setSearchParams] = searchParamsResult;
42+
const [searchParams] = searchParamsResult;
4343
const filter = searchParams.get("filter") ?? "";
44-
const [usersState, usersSend] = useMachine(usersMachine, {
45-
context: {
46-
filter,
47-
paginationContext: getPaginationContext(searchParams),
48-
},
49-
actions: {
50-
updateURL: (context, event) =>
51-
setSearchParams({ page: event.page, filter: context.filter }),
52-
},
44+
const [usersState, usersSend] = useMachine(usersMachine);
45+
const pagination = usePagination({
46+
searchParamsResult,
5347
});
48+
const usersQuery = useQuery(
49+
UsersQuery.users({
50+
q: prepareQuery(filter),
51+
limit: pagination.limit,
52+
offset: pagination.offset,
53+
}),
54+
);
55+
const users = usersQuery.data?.users;
56+
const count = usersQuery.data?.count;
5457
const {
55-
users,
56-
getUsersError,
5758
usernameToDelete,
5859
usernameToSuspend,
5960
usernameToActivate,
6061
userIdToResetPassword,
6162
newUserPassword,
62-
paginationRef,
63-
count,
6463
} = usersState.context;
6564
const { updateUsers: canEditUsers, viewDeploymentValues } = usePermissions();
6665
const rolesQuery = useQuery({ ...roles(), enabled: canEditUsers });
@@ -77,12 +76,9 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
7776
const useFilterResult = useFilter({
7877
searchParamsResult,
7978
onUpdate: () => {
80-
usersSend({ type: "UPDATE_PAGE", page: "1" });
79+
pagination.goToPage(1);
8180
},
8281
});
83-
useEffect(() => {
84-
usersSend({ type: "UPDATE_FILTER", query: useFilterResult.query });
85-
}, [useFilterResult.query, usersSend]);
8682
const statusMenu = useStatusFilterMenu({
8783
value: useFilterResult.values.status,
8884
onChange: (option) =>
@@ -97,13 +93,8 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
9793
return getAuthMethods();
9894
},
9995
});
100-
// Is loading if
101-
// - users are loading or
102-
// - the user can edit the users but the roles are loading
10396
const isLoading =
104-
usersState.matches("gettingUsers") ||
105-
rolesQuery.isLoading ||
106-
authMethods.isLoading;
97+
usersQuery.isLoading || rolesQuery.isLoading || authMethods.isLoading;
10798

10899
return (
109100
<>
@@ -115,7 +106,6 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
115106
roles={rolesQuery.data}
116107
users={users}
117108
authMethods={authMethods.data}
118-
count={count}
119109
onListWorkspaces={(user) => {
120110
navigate(
121111
"/workspaces?filter=" +
@@ -162,16 +152,19 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
162152
isLoading={isLoading}
163153
canEditUsers={canEditUsers}
164154
canViewActivity={entitlements.features.audit_log.enabled}
165-
paginationRef={paginationRef}
166155
isNonInitialPage={nonInitialPage(searchParams)}
167156
actorID={me.id}
168157
filterProps={{
169158
filter: useFilterResult,
170-
error: getUsersError,
159+
error: usersQuery.error,
171160
menus: {
172161
status: statusMenu,
173162
},
174163
}}
164+
count={count}
165+
page={pagination.page}
166+
limit={pagination.limit}
167+
onPageChange={pagination.goToPage}
175168
/>
176169

177170
<DeleteDialog

site/src/pages/UsersPage/UsersPageView.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Meta, StoryObj } from "@storybook/react";
2-
import { createPaginationRef } from "components/PaginationWidget/utils";
32
import {
43
MockUser,
54
MockUser2,
@@ -30,7 +29,8 @@ const meta: Meta<typeof UsersPageView> = {
3029
title: "pages/UsersPageView",
3130
component: UsersPageView,
3231
args: {
33-
paginationRef: createPaginationRef({ page: 1, limit: 25 }),
32+
page: 1,
33+
limit: 25,
3434
isNonInitialPage: false,
3535
users: [MockUser, MockUser2],
3636
roles: MockAssignableSiteRoles,

site/src/pages/UsersPage/UsersPageView.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import { PaginationWidget } from "components/PaginationWidget/PaginationWidget";
21
import { ComponentProps, FC } from "react";
3-
import { PaginationMachineRef } from "xServices/pagination/paginationXService";
42
import * as TypesGen from "api/typesGenerated";
53
import { UsersTable } from "./UsersTable/UsersTable";
64
import { UsersFilter } from "./UsersFilter";
75
import {
86
PaginationStatus,
97
TableToolbar,
108
} from "components/TableToolbar/TableToolbar";
9+
import { PaginationWidgetBase } from "components/PaginationWidget/PaginationWidgetBase";
1110

1211
export interface UsersPageViewProps {
1312
users?: TypesGen.User[];
14-
count?: number;
1513
roles?: TypesGen.AssignableRoles[];
1614
isUpdatingUserRoles?: boolean;
1715
canEditUsers?: boolean;
@@ -30,14 +28,17 @@ export interface UsersPageViewProps {
3028
roles: TypesGen.Role["name"][],
3129
) => void;
3230
filterProps: ComponentProps<typeof UsersFilter>;
33-
paginationRef: PaginationMachineRef;
3431
isNonInitialPage: boolean;
3532
actorID: string;
33+
// Pagination
34+
count?: number;
35+
page: number;
36+
limit: number;
37+
onPageChange: (page: number) => void;
3638
}
3739

3840
export const UsersPageView: FC<React.PropsWithChildren<UsersPageViewProps>> = ({
3941
users,
40-
count,
4142
roles,
4243
onSuspendUser,
4344
onDeleteUser,
@@ -52,10 +53,13 @@ export const UsersPageView: FC<React.PropsWithChildren<UsersPageViewProps>> = ({
5253
canViewActivity,
5354
isLoading,
5455
filterProps,
55-
paginationRef,
5656
isNonInitialPage,
5757
actorID,
5858
authMethods,
59+
count,
60+
limit,
61+
onPageChange,
62+
page,
5963
}) => {
6064
return (
6165
<>
@@ -90,7 +94,14 @@ export const UsersPageView: FC<React.PropsWithChildren<UsersPageViewProps>> = ({
9094
authMethods={authMethods}
9195
/>
9296

93-
<PaginationWidget numRecords={count} paginationRef={paginationRef} />
97+
{count !== undefined && (
98+
<PaginationWidgetBase
99+
count={count}
100+
limit={limit}
101+
onChange={onPageChange}
102+
page={page}
103+
/>
104+
)}
94105
</>
95106
);
96107
};

site/src/utils/filters.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import * as TypesGen from "api/typesGenerated";
33
export const queryToFilter = (
44
query?: string,
55
): TypesGen.WorkspaceFilter | TypesGen.UsersRequest => {
6-
const preparedQuery = query?.trim().replace(/ +/g, " ");
76
return {
8-
q: preparedQuery,
7+
q: prepareQuery(query),
98
};
109
};
1110

11+
export const prepareQuery = (query?: string) => {
12+
return query?.trim().replace(/ +/g, " ");
13+
};
14+
1215
export const workspaceFilterQuery = {
1316
me: "owner:me",
1417
all: "",

0 commit comments

Comments
 (0)