Skip to content

Commit 8b6653d

Browse files
committed
refactor: remove redudant function calls
1 parent 1cc2935 commit 8b6653d

File tree

3 files changed

+122
-117
lines changed

3 files changed

+122
-117
lines changed

site/src/pages/TemplatePage/TemplatePageHeader.tsx

Lines changed: 116 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -35,77 +35,142 @@ import CopyIcon from "@mui/icons-material/FileCopyOutlined";
3535
type TemplateMenuProps = {
3636
templateName: string;
3737
templateVersion: string;
38+
templateId: string;
3839
onDelete: () => void;
3940
};
4041

4142
const TemplateMenu: FC<TemplateMenuProps> = ({
4243
templateName,
4344
templateVersion,
45+
templateId,
4446
onDelete,
4547
}) => {
48+
const dialogState = useDeletionDialogState(templateId, onDelete);
4649
const menuTriggerRef = useRef<HTMLButtonElement>(null);
4750
const [isMenuOpen, setIsMenuOpen] = useState(false);
4851
const navigate = useNavigate();
4952

53+
const queryText = `template:${templateName}`;
54+
const workspaceCountQuery = useQuery({
55+
...workspacesByQuery(queryText),
56+
select: (res) => res.count,
57+
});
58+
5059
// Returns a function that will execute the action and close the menu
5160
const onMenuItemClick = (actionFn: () => void) => () => {
5261
setIsMenuOpen(false);
5362
actionFn();
5463
};
5564

65+
const safeToDeleteTemplate =
66+
workspaceCountQuery.status === "success" && workspaceCountQuery.data === 0;
67+
5668
return (
57-
<div>
58-
<IconButton
59-
aria-controls="template-options"
60-
aria-haspopup="true"
61-
onClick={() => setIsMenuOpen(true)}
62-
ref={menuTriggerRef}
63-
arial-label="More options"
64-
>
65-
<MoreVertOutlined />
66-
</IconButton>
67-
68-
<Menu
69-
id="template-options"
70-
anchorEl={menuTriggerRef.current}
71-
open={isMenuOpen}
72-
onClose={() => setIsMenuOpen(false)}
73-
>
74-
<MenuItem
75-
onClick={onMenuItemClick(() =>
76-
navigate(`/templates/${templateName}/settings`),
77-
)}
69+
<>
70+
<div>
71+
<IconButton
72+
aria-controls="template-options"
73+
aria-haspopup="true"
74+
onClick={() => setIsMenuOpen(true)}
75+
ref={menuTriggerRef}
76+
arial-label="More options"
7877
>
79-
<SettingsIcon />
80-
Settings
81-
</MenuItem>
82-
83-
<MenuItem
84-
onClick={onMenuItemClick(() =>
85-
navigate(
86-
`/templates/${templateName}/versions/${templateVersion}/edit`,
87-
),
88-
)}
78+
<MoreVertOutlined />
79+
</IconButton>
80+
81+
<Menu
82+
id="template-options"
83+
anchorEl={menuTriggerRef.current}
84+
open={isMenuOpen}
85+
onClose={() => setIsMenuOpen(false)}
8986
>
90-
<EditIcon />
91-
Edit files
92-
</MenuItem>
87+
<MenuItem
88+
onClick={onMenuItemClick(() =>
89+
navigate(`/templates/${templateName}/settings`),
90+
)}
91+
>
92+
<SettingsIcon />
93+
Settings
94+
</MenuItem>
95+
96+
<MenuItem
97+
onClick={onMenuItemClick(() =>
98+
navigate(
99+
`/templates/${templateName}/versions/${templateVersion}/edit`,
100+
),
101+
)}
102+
>
103+
<EditIcon />
104+
Edit files
105+
</MenuItem>
106+
107+
<MenuItem
108+
onClick={onMenuItemClick(() =>
109+
navigate(`/templates/new?fromTemplate=${templateName}`),
110+
)}
111+
>
112+
<CopyIcon />
113+
Duplicate&hellip;
114+
</MenuItem>
115+
116+
<MenuItem
117+
onClick={onMenuItemClick(dialogState.openDeleteConfirmation)}
118+
>
119+
<DeleteIcon />
120+
Delete&hellip;
121+
</MenuItem>
122+
</Menu>
123+
</div>
93124

94-
<MenuItem
95-
onClick={onMenuItemClick(() =>
96-
navigate(`/templates/new?fromTemplate=${templateName}`),
97-
)}
98-
>
99-
<CopyIcon />
100-
Duplicate&hellip;
101-
</MenuItem>
102-
103-
<MenuItem onClick={onMenuItemClick(onDelete)}>
104-
<DeleteIcon />
105-
Delete&hellip;
106-
</MenuItem>
107-
</Menu>
108-
</div>
125+
{safeToDeleteTemplate ? (
126+
<DeleteDialog
127+
isOpen={dialogState.isDeleteDialogOpen}
128+
onConfirm={dialogState.confirmDelete}
129+
onCancel={dialogState.cancelDeleteConfirmation}
130+
entity="template"
131+
name={templateName}
132+
/>
133+
) : (
134+
<ConfirmDialog
135+
type="info"
136+
title="Unable to delete"
137+
hideCancel={false}
138+
open={dialogState.isDeleteDialogOpen}
139+
onClose={dialogState.cancelDeleteConfirmation}
140+
confirmText="See workspaces"
141+
confirmLoading={workspaceCountQuery.status !== "success"}
142+
onConfirm={() => {
143+
navigate({
144+
pathname: "/workspaces",
145+
search: new URLSearchParams({ filter: queryText }).toString(),
146+
});
147+
}}
148+
description={
149+
<>
150+
{workspaceCountQuery.isSuccess && (
151+
<>
152+
This template is used by{" "}
153+
<strong>
154+
{workspaceCountQuery.data} workspace
155+
{workspaceCountQuery.data === 1 ? "" : "s"}
156+
</strong>
157+
. Please delete all related workspaces before deleting this
158+
template.
159+
</>
160+
)}
161+
162+
{workspaceCountQuery.isLoading && (
163+
<>Loading information about workspaces used by this template.</>
164+
)}
165+
166+
{workspaceCountQuery.isError && (
167+
<>Unable to determine workspaces used by this template.</>
168+
)}
169+
</>
170+
}
171+
/>
172+
)}
173+
</>
109174
);
110175
};
111176

@@ -122,18 +187,7 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
122187
permissions,
123188
onDeleteTemplate,
124189
}) => {
125-
const navigate = useNavigate();
126-
const dialogState = useDeletionDialogState(template, onDeleteTemplate);
127-
128-
const queryText = `template:${template.name}`;
129-
const workspaceCountQuery = useQuery({
130-
...workspacesByQuery(queryText),
131-
select: (res) => res.count,
132-
});
133-
134190
const hasIcon = template.icon && template.icon !== "";
135-
const safeToDeleteTemplate =
136-
workspaceCountQuery.status === "success" && workspaceCountQuery.data === 0;
137191

138192
return (
139193
<Margins>
@@ -153,7 +207,8 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
153207
<TemplateMenu
154208
templateVersion={activeVersion.name}
155209
templateName={template.name}
156-
onDelete={dialogState.openDeleteConfirmation}
210+
templateId={template.id}
211+
onDelete={onDeleteTemplate}
157212
/>
158213
)}
159214
</>
@@ -181,55 +236,6 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
181236
</div>
182237
</Stack>
183238
</PageHeader>
184-
185-
{safeToDeleteTemplate ? (
186-
<DeleteDialog
187-
isOpen={dialogState.isDeleteDialogOpen}
188-
onConfirm={dialogState.confirmDelete}
189-
onCancel={dialogState.cancelDeleteConfirmation}
190-
entity="template"
191-
name={template.name}
192-
/>
193-
) : (
194-
<ConfirmDialog
195-
type="info"
196-
title="Unable to delete"
197-
hideCancel={false}
198-
open={dialogState.isDeleteDialogOpen}
199-
onClose={dialogState.cancelDeleteConfirmation}
200-
confirmText="See workspaces"
201-
confirmLoading={workspaceCountQuery.status !== "success"}
202-
onConfirm={() => {
203-
navigate({
204-
pathname: "/workspaces",
205-
search: new URLSearchParams({ filter: queryText }).toString(),
206-
});
207-
}}
208-
description={
209-
<>
210-
{workspaceCountQuery.isSuccess && (
211-
<>
212-
This template is used by{" "}
213-
<strong>
214-
{workspaceCountQuery.data} workspace
215-
{workspaceCountQuery.data === 1 ? "" : "s"}
216-
</strong>
217-
. Please delete all related workspaces before deleting this
218-
template.
219-
</>
220-
)}
221-
222-
{workspaceCountQuery.isLoading && (
223-
<>Loading information about workspaces used by this template.</>
224-
)}
225-
226-
{workspaceCountQuery.isError && (
227-
<>Unable to determine workspaces used by this template.</>
228-
)}
229-
</>
230-
}
231-
/>
232-
)}
233239
</Margins>
234240
);
235241
};

site/src/pages/TemplatePage/useDeletionDialogState.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import * as API from "api/api";
55

66
test("delete dialog starts closed", () => {
77
const { result } = renderHook(() =>
8-
useDeletionDialogState(MockTemplate, jest.fn()),
8+
useDeletionDialogState(MockTemplate.id, jest.fn()),
99
);
1010
expect(result.current.isDeleteDialogOpen).toBeFalsy();
1111
});
1212

1313
test("confirm template deletion", async () => {
1414
const onDeleteTemplate = jest.fn();
1515
const { result } = renderHook(() =>
16-
useDeletionDialogState(MockTemplate, onDeleteTemplate),
16+
useDeletionDialogState(MockTemplate.id, onDeleteTemplate),
1717
);
1818

1919
//Open delete confirmation
@@ -31,7 +31,7 @@ test("confirm template deletion", async () => {
3131

3232
test("cancel template deletion", () => {
3333
const { result } = renderHook(() =>
34-
useDeletionDialogState(MockTemplate, jest.fn()),
34+
useDeletionDialogState(MockTemplate.id, jest.fn()),
3535
);
3636

3737
//Open delete confirmation

site/src/pages/TemplatePage/useDeletionDialogState.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1+
import { useState } from "react";
12
import { deleteTemplate } from "api/api";
23
import { getErrorMessage } from "api/errors";
3-
import { Template } from "api/typesGenerated";
44
import { displayError } from "components/GlobalSnackbar/utils";
5-
import { useState } from "react";
65

76
type DeleteTemplateState =
87
| { status: "idle" }
98
| { status: "confirming" }
109
| { status: "deleting" };
1110

1211
export const useDeletionDialogState = (
13-
template: Template,
12+
templateId: string,
1413
onDelete: () => void,
1514
) => {
1615
const [state, setState] = useState<DeleteTemplateState>({ status: "idle" });
@@ -28,7 +27,7 @@ export const useDeletionDialogState = (
2827
const confirmDelete = async () => {
2928
try {
3029
setState({ status: "deleting" });
31-
await deleteTemplate(template.id);
30+
await deleteTemplate(templateId);
3231
onDelete();
3332
} catch (e) {
3433
setState({ status: "confirming" });

0 commit comments

Comments
 (0)