Skip to content

Commit 6f9721e

Browse files
refactor: update deleteCommandgroup to use new loading pattern
1 parent dc395ba commit 6f9721e

3 files changed

Lines changed: 32 additions & 30 deletions

File tree

src/web/src/__tests__/components/WSEditorCommandGroupContent.test.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { render, screen, waitFor, within } from "@testing-library/react";
22
import userEvent from "@testing-library/user-event";
33
import { vi } from "vitest";
44
import WSEditorCommandGroupContent from "../../views/workspace/components/WSEditorCommandGroupContent/WSEditorCommandGroupContent";
5-
import * as commandApi from "../../services/commandApi";
5+
import { commandApi } from "../../services";
66

77
interface CommandGroup {
88
id: string;
@@ -15,10 +15,22 @@ interface CommandGroup {
1515
canDelete: boolean;
1616
}
1717

18-
vi.mock("../../services/commandApi");
19-
vi.mock("../../services/errorHandlerApi");
18+
vi.mock("../../services", () => ({
19+
commandApi: {
20+
deleteCommandGroup: {
21+
loadingMessage: "Deleting command group...",
22+
fn: vi.fn(),
23+
},
24+
updateCommandGroup: vi.fn(),
25+
renameCommandGroup: vi.fn(),
26+
},
27+
errorHandlerApi: {
28+
getErrorMessage: vi.fn(),
29+
},
30+
}));
2031

2132
const mockCommandApi = commandApi as any;
33+
2234
describe("WSEditorCommandGroupContent", () => {
2335
const mockWorkspaceUrl = "https://test-workspace.com/workspace/ws1";
2436

@@ -37,6 +49,7 @@ describe("WSEditorCommandGroupContent", () => {
3749

3850
beforeEach(() => {
3951
vi.clearAllMocks();
52+
mockCommandApi.deleteCommandGroup.fn.mockResolvedValue(undefined);
4053
});
4154

4255
describe("Core Rendering", () => {
@@ -270,7 +283,7 @@ describe("WSEditorCommandGroupContent", () => {
270283
await user.click(confirmDeleteButton);
271284

272285
await waitFor(() => {
273-
expect(mockCommandApi.deleteCommandGroup).toHaveBeenCalled();
286+
expect(mockCommandApi.deleteCommandGroup.fn).toHaveBeenCalled();
274287
expect(mockOnUpdateCommandGroup).toHaveBeenCalledWith(null);
275288
});
276289
});
@@ -313,7 +326,7 @@ describe("WSEditorCommandGroupContent", () => {
313326
const user = userEvent.setup();
314327
const mockError = new Error("Delete failed");
315328

316-
mockCommandApi.deleteCommandGroup.mockRejectedValue(mockError);
329+
mockCommandApi.deleteCommandGroup.fn.mockRejectedValue(mockError);
317330

318331
render(
319332
<WSEditorCommandGroupContent
@@ -335,7 +348,7 @@ describe("WSEditorCommandGroupContent", () => {
335348
await user.click(confirmDeleteButton);
336349

337350
await waitFor(() => {
338-
expect(mockCommandApi.deleteCommandGroup).toHaveBeenCalled();
351+
expect(mockCommandApi.deleteCommandGroup.fn).toHaveBeenCalled();
339352
});
340353
});
341354

src/web/src/services/commandApi.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,11 @@ export const commandApi = {
9191
await axios.post(flattenUrl);
9292
},
9393

94-
deleteCommandGroup: async (nodeUrl: string): Promise<void> => {
95-
await axios.delete(nodeUrl);
94+
deleteCommandGroup: {
95+
loadingMessage: "Deleting command group...",
96+
fn: async (nodeUrl: string): Promise<void> => {
97+
await axios.delete(nodeUrl);
98+
},
9699
},
97100

98101
updateCommandGroup: async (

src/web/src/views/workspace/components/WSEditorCommandGroupContent/CommandGroupDeleteDialog.tsx

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import {
2-
Box,
3-
Button,
4-
Dialog,
5-
DialogActions,
6-
DialogContent,
7-
DialogTitle,
8-
LinearProgress,
9-
Typography,
10-
} from "@mui/material";
1+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@mui/material";
112
import { commandApi } from "../../../../services";
3+
import { useAsyncOperation } from "../../../../services/hooks";
4+
import { AsyncOperationBanner } from "../../../../components";
125
import * as React from "react";
136
import { COMMAND_PREFIX } from "../../../../constants";
147
import type { CommandGroup } from "../../interfaces";
@@ -26,39 +19,32 @@ const CommandGroupDeleteDialog: React.FC<CommandGroupDeleteDialogProps> = ({
2619
commandGroup,
2720
onClose,
2821
}) => {
29-
const [updating, setUpdating] = React.useState<boolean>(false);
22+
const deleteCommandGroupOperation = useAsyncOperation(commandApi.deleteCommandGroup);
3023

3124
const handleClose = React.useCallback(() => {
3225
onClose(false);
3326
}, [onClose]);
3427

3528
const handleDelete = React.useCallback(async () => {
3629
const nodeUrl = `${workspaceUrl}/CommandTree/Nodes/aaz/${commandGroup.names.join("/")}`;
37-
setUpdating(true);
3830

3931
try {
40-
await commandApi.deleteCommandGroup(nodeUrl);
41-
setUpdating(false);
32+
await deleteCommandGroupOperation.execute(nodeUrl);
4233
onClose(true);
4334
} catch (err: any) {
44-
setUpdating(false);
4535
console.error(err);
4636
}
47-
}, [workspaceUrl, commandGroup.names, onClose]);
37+
}, [workspaceUrl, commandGroup.names, onClose, deleteCommandGroupOperation]);
4838

4939
return (
5040
<Dialog disableEscapeKeyDown open={open}>
5141
<DialogTitle>Delete Command Group</DialogTitle>
5242
<DialogContent dividers={true}>
43+
<AsyncOperationBanner operation={deleteCommandGroupOperation} />
5344
<Typography variant="body2">{`${COMMAND_PREFIX}${commandGroup.names.join(" ")}`}</Typography>
5445
</DialogContent>
5546
<DialogActions>
56-
{updating && (
57-
<Box sx={{ width: "100%" }}>
58-
<LinearProgress color="secondary" />
59-
</Box>
60-
)}
61-
{!updating && (
47+
{!deleteCommandGroupOperation.loading && (
6248
<React.Fragment>
6349
<Button onClick={handleClose}>Cancel</Button>
6450
<Button onClick={handleDelete}>Delete</Button>

0 commit comments

Comments
 (0)