Skip to content

Commit 9db6ec6

Browse files
committed
Move suspend to react-query
1 parent 9b3adea commit 9db6ec6

File tree

4 files changed

+40
-110
lines changed

4 files changed

+40
-110
lines changed

site/src/api/queries/users.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { QueryClient } from "@tanstack/react-query";
12
import * as API from "api/api";
23
import { UpdateUserPasswordRequest, UsersRequest } from "api/typesGenerated";
34

@@ -29,3 +30,12 @@ export const createFirstUser = () => {
2930
mutationFn: API.createFirstUser,
3031
};
3132
};
33+
34+
export const suspendUser = (queryClient: QueryClient) => {
35+
return {
36+
mutationFn: API.suspendUser,
37+
onSuccess: async () => {
38+
await queryClient.invalidateQueries(["users"]);
39+
},
40+
};
41+
};

site/src/pages/UsersPage/UsersPage.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ describe("UsersPage", () => {
176176
});
177177

178178
// Check if the success message is displayed
179-
await screen.findByText(usersXServiceLanguage.suspendUserSuccess);
179+
await screen.findByText("User suspended");
180180

181181
// Check if the API was called correctly
182182
expect(API.suspendUser).toBeCalledTimes(1);
@@ -195,7 +195,7 @@ describe("UsersPage", () => {
195195
});
196196

197197
// Check if the error message is displayed
198-
await screen.findByText(usersXServiceLanguage.suspendUserError);
198+
await screen.findByText("Error suspending user");
199199

200200
// Check if the API was called correctly
201201
expect(API.suspendUser).toBeCalledTimes(1);

site/src/pages/UsersPage/UsersPage.tsx

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog";
44
import { nonInitialPage } from "components/PaginationWidget/utils";
55
import { useMe } from "hooks/useMe";
66
import { usePermissions } from "hooks/usePermissions";
7-
import { FC, ReactNode } from "react";
7+
import { FC, ReactNode, useState } from "react";
88
import { Helmet } from "react-helmet-async";
99
import { useSearchParams, useNavigate } from "react-router-dom";
1010
import { usersMachine } from "xServices/users/usersXService";
@@ -15,13 +15,15 @@ import { UsersPageView } from "./UsersPageView";
1515
import { useStatusFilterMenu } from "./UsersFilter";
1616
import { useFilter } from "components/Filter/filter";
1717
import { useDashboard } from "components/Dashboard/DashboardProvider";
18-
import { useQuery } from "@tanstack/react-query";
18+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
1919
import { getAuthMethods } from "api/api";
2020
import { roles } from "api/queries/roles";
2121
import { deploymentConfig } from "api/queries/deployment";
2222
import { prepareQuery } from "utils/filters";
2323
import { usePagination } from "hooks";
24-
import * as UsersQuery from "api/queries/users";
24+
import { users, suspendUser } from "api/queries/users";
25+
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
26+
import { getErrorMessage } from "api/errors";
2527

2628
export const Language = {
2729
suspendDialogTitle: "Suspend user",
@@ -36,6 +38,7 @@ const getSelectedUser = (id: string, users?: User[]) =>
3638
users?.find((u) => u.id === id);
3739

3840
export const UsersPage: FC<{ children?: ReactNode }> = () => {
41+
const queryClient = useQueryClient();
3942
const navigate = useNavigate();
4043
const searchParamsResult = useSearchParams();
4144
const { entitlements } = useDashboard();
@@ -46,17 +49,14 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
4649
searchParamsResult,
4750
});
4851
const usersQuery = useQuery(
49-
UsersQuery.users({
52+
users({
5053
q: prepareQuery(filter),
5154
limit: pagination.limit,
5255
offset: pagination.offset,
5356
}),
5457
);
55-
const users = usersQuery.data?.users;
56-
const count = usersQuery.data?.count;
5758
const {
5859
usernameToDelete,
59-
usernameToSuspend,
6060
usernameToActivate,
6161
userIdToResetPassword,
6262
newUserPassword,
@@ -95,6 +95,8 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
9595
});
9696
const isLoading =
9797
usersQuery.isLoading || rolesQuery.isLoading || authMethods.isLoading;
98+
const [confirmSuspendUser, setConfirmSuspendUser] = useState<User>();
99+
const suspendUserMutation = useMutation(suspendUser(queryClient));
98100

99101
return (
100102
<>
@@ -104,7 +106,7 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
104106
<UsersPageView
105107
oidcRoleSyncEnabled={oidcRoleSyncEnabled}
106108
roles={rolesQuery.data}
107-
users={users}
109+
users={usersQuery.data?.users}
108110
authMethods={authMethods.data}
109111
onListWorkspaces={(user) => {
110112
navigate(
@@ -124,13 +126,7 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
124126
username: user.username,
125127
});
126128
}}
127-
onSuspendUser={(user) => {
128-
usersSend({
129-
type: "SUSPEND_USER",
130-
userId: user.id,
131-
username: user.username,
132-
});
133-
}}
129+
onSuspendUser={setConfirmSuspendUser}
134130
onActivateUser={(user) => {
135131
usersSend({
136132
type: "ACTIVATE_USER",
@@ -161,7 +157,7 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
161157
status: statusMenu,
162158
},
163159
}}
164-
count={count}
160+
count={usersQuery.data?.count}
165161
page={pagination.page}
166162
limit={pagination.limit}
167163
onPageChange={pagination.goToPage}
@@ -187,24 +183,26 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
187183
<ConfirmDialog
188184
type="delete"
189185
hideCancel={false}
190-
open={
191-
usersState.matches("confirmUserSuspension") ||
192-
usersState.matches("suspendingUser")
193-
}
194-
confirmLoading={usersState.matches("suspendingUser")}
195-
title={Language.suspendDialogTitle}
196-
confirmText={Language.suspendDialogAction}
197-
onConfirm={() => {
198-
usersSend("CONFIRM_USER_SUSPENSION");
186+
open={confirmSuspendUser !== undefined}
187+
confirmLoading={suspendUserMutation.isLoading}
188+
title="Suspend user"
189+
confirmText="Suspend"
190+
onConfirm={async () => {
191+
try {
192+
await suspendUserMutation.mutateAsync(confirmSuspendUser!.id);
193+
setConfirmSuspendUser(undefined);
194+
displaySuccess("User suspended");
195+
} catch (e) {
196+
displayError(getErrorMessage(e, "Error suspending user"));
197+
}
199198
}}
200199
onClose={() => {
201-
usersSend("CANCEL_USER_SUSPENSION");
200+
setConfirmSuspendUser(undefined);
202201
}}
203202
description={
204203
<>
205-
{Language.suspendDialogMessagePrefix}
206-
{usernameToSuspend && " "}
207-
<strong>{usernameToSuspend ?? ""}</strong>?
204+
Do you want to suspend the user{" "}
205+
<strong>{confirmSuspendUser?.username ?? ""}</strong>?
208206
</>
209207
}
210208
/>
@@ -241,7 +239,7 @@ export const UsersPage: FC<{ children?: ReactNode }> = () => {
241239
usersState.matches("resettingUserPassword")
242240
}
243241
loading={usersState.matches("resettingUserPassword")}
244-
user={getSelectedUser(userIdToResetPassword, users)}
242+
user={getSelectedUser(userIdToResetPassword, usersQuery.data?.users)}
245243
newPassword={newUserPassword}
246244
onClose={() => {
247245
usersSend("CANCEL_USER_PASSWORD_RESET");

site/src/xServices/users/usersXService.ts

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
66
import { generateRandomString } from "utils/random";
77

88
export const Language = {
9-
getUsersError: "Error getting users.",
10-
suspendUserSuccess: "Successfully suspended the user.",
11-
suspendUserError: "Error suspending user.",
129
deleteUserSuccess: "Successfully deleted the user.",
1310
deleteUserError: "Error deleting user.",
1411
activateUserSuccess: "Successfully activated the user.",
@@ -20,10 +17,6 @@ export const Language = {
2017
};
2118

2219
export interface UsersContext {
23-
// Suspend user
24-
userIdToSuspend?: TypesGen.User["id"];
25-
usernameToSuspend?: TypesGen.User["username"];
26-
suspendUserError?: unknown;
2720
// Delete user
2821
userIdToDelete?: TypesGen.User["id"];
2922
usernameToDelete?: TypesGen.User["username"];
@@ -42,12 +35,6 @@ export interface UsersContext {
4235
}
4336

4437
export type UsersEvent =
45-
// Suspend events
46-
| {
47-
type: "SUSPEND_USER";
48-
userId: TypesGen.User["id"];
49-
username: TypesGen.User["username"];
50-
}
5138
| { type: "CONFIRM_USER_SUSPENSION" }
5239
| { type: "CANCEL_USER_SUSPENSION" }
5340
// Delete events
@@ -113,10 +100,6 @@ export const usersMachine =
113100
idle: {
114101
entry: "clearSelectedUser",
115102
on: {
116-
SUSPEND_USER: {
117-
target: "confirmUserSuspension",
118-
actions: "assignUserToSuspend",
119-
},
120103
DELETE_USER: {
121104
target: "confirmUserDeletion",
122105
actions: "assignUserToDelete",
@@ -138,16 +121,6 @@ export const usersMachine =
138121
},
139122
},
140123
},
141-
confirmUserSuspension: {
142-
on: {
143-
CONFIRM_USER_SUSPENSION: {
144-
target: "suspendingUser",
145-
},
146-
CANCEL_USER_SUSPENSION: {
147-
target: "idle",
148-
},
149-
},
150-
},
151124
confirmUserDeletion: {
152125
on: {
153126
CONFIRM_USER_DELETE: {
@@ -168,28 +141,6 @@ export const usersMachine =
168141
},
169142
},
170143
},
171-
suspendingUser: {
172-
entry: "clearSuspendUserError",
173-
invoke: {
174-
src: "suspendUser",
175-
id: "suspendUser",
176-
onDone: [
177-
{
178-
target: "idle",
179-
actions: "displaySuspendSuccess",
180-
},
181-
],
182-
onError: [
183-
{
184-
target: "idle",
185-
actions: [
186-
"assignSuspendUserError",
187-
"displaySuspendedErrorMessage",
188-
],
189-
},
190-
],
191-
},
192-
},
193144
deletingUser: {
194145
entry: "clearDeleteUserError",
195146
invoke: {
@@ -289,13 +240,6 @@ export const usersMachine =
289240
},
290241
{
291242
services: {
292-
suspendUser: (context) => {
293-
if (!context.userIdToSuspend) {
294-
throw new Error("userIdToSuspend is undefined");
295-
}
296-
297-
return API.suspendUser(context.userIdToSuspend);
298-
},
299243
deleteUser: (context) => {
300244
if (!context.userIdToDelete) {
301245
throw new Error("userIdToDelete is undefined");
@@ -334,19 +278,13 @@ export const usersMachine =
334278

335279
actions: {
336280
clearSelectedUser: assign({
337-
userIdToSuspend: (_) => undefined,
338-
usernameToSuspend: (_) => undefined,
339281
userIdToDelete: (_) => undefined,
340282
usernameToDelete: (_) => undefined,
341283
userIdToActivate: (_) => undefined,
342284
usernameToActivate: (_) => undefined,
343285
userIdToResetPassword: (_) => undefined,
344286
userIdToUpdateRoles: (_) => undefined,
345287
}),
346-
assignUserToSuspend: assign({
347-
userIdToSuspend: (_, event) => event.userId,
348-
usernameToSuspend: (_, event) => event.username,
349-
}),
350288
assignUserToDelete: assign({
351289
userIdToDelete: (_, event) => event.userId,
352290
usernameToDelete: (_, event) => event.username,
@@ -361,9 +299,6 @@ export const usersMachine =
361299
assignUserIdToUpdateRoles: assign({
362300
userIdToUpdateRoles: (_, event) => event.userId,
363301
}),
364-
assignSuspendUserError: assign({
365-
suspendUserError: (_, event) => event.data,
366-
}),
367302
assignDeleteUserError: assign({
368303
deleteUserError: (_, event) => event.data,
369304
}),
@@ -376,9 +311,6 @@ export const usersMachine =
376311
assignUpdateRolesError: assign({
377312
updateUserRolesError: (_, event) => event.data,
378313
}),
379-
clearSuspendUserError: assign({
380-
suspendUserError: (_) => undefined,
381-
}),
382314
clearDeleteUserError: assign({
383315
deleteUserError: (_) => undefined,
384316
}),
@@ -391,16 +323,6 @@ export const usersMachine =
391323
clearUpdateUserRolesError: assign({
392324
updateUserRolesError: (_) => undefined,
393325
}),
394-
displaySuspendSuccess: () => {
395-
displaySuccess(Language.suspendUserSuccess);
396-
},
397-
displaySuspendedErrorMessage: (context) => {
398-
const message = getErrorMessage(
399-
context.suspendUserError,
400-
Language.suspendUserError,
401-
);
402-
displayError(message);
403-
},
404326
displayDeleteSuccess: () => {
405327
displaySuccess(Language.deleteUserSuccess);
406328
},

0 commit comments

Comments
 (0)