@@ -35,77 +35,142 @@ import CopyIcon from "@mui/icons-material/FileCopyOutlined";
35
35
type TemplateMenuProps = {
36
36
templateName : string ;
37
37
templateVersion : string ;
38
+ templateId : string ;
38
39
onDelete : ( ) => void ;
39
40
} ;
40
41
41
42
const TemplateMenu : FC < TemplateMenuProps > = ( {
42
43
templateName,
43
44
templateVersion,
45
+ templateId,
44
46
onDelete,
45
47
} ) => {
48
+ const dialogState = useDeletionDialogState ( templateId , onDelete ) ;
46
49
const menuTriggerRef = useRef < HTMLButtonElement > ( null ) ;
47
50
const [ isMenuOpen , setIsMenuOpen ] = useState ( false ) ;
48
51
const navigate = useNavigate ( ) ;
49
52
53
+ const queryText = `template:${ templateName } ` ;
54
+ const workspaceCountQuery = useQuery ( {
55
+ ...workspacesByQuery ( queryText ) ,
56
+ select : ( res ) => res . count ,
57
+ } ) ;
58
+
50
59
// Returns a function that will execute the action and close the menu
51
60
const onMenuItemClick = ( actionFn : ( ) => void ) => ( ) => {
52
61
setIsMenuOpen ( false ) ;
53
62
actionFn ( ) ;
54
63
} ;
55
64
65
+ const safeToDeleteTemplate =
66
+ workspaceCountQuery . status === "success" && workspaceCountQuery . data === 0 ;
67
+
56
68
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"
78
77
>
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 ) }
89
86
>
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…
114
+ </ MenuItem >
115
+
116
+ < MenuItem
117
+ onClick = { onMenuItemClick ( dialogState . openDeleteConfirmation ) }
118
+ >
119
+ < DeleteIcon />
120
+ Delete…
121
+ </ MenuItem >
122
+ </ Menu >
123
+ </ div >
93
124
94
- < MenuItem
95
- onClick = { onMenuItemClick ( ( ) =>
96
- navigate ( `/templates/new?fromTemplate=${ templateName } ` ) ,
97
- ) }
98
- >
99
- < CopyIcon />
100
- Duplicate…
101
- </ MenuItem >
102
-
103
- < MenuItem onClick = { onMenuItemClick ( onDelete ) } >
104
- < DeleteIcon />
105
- Delete…
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
+ </ >
109
174
) ;
110
175
} ;
111
176
@@ -122,18 +187,7 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
122
187
permissions,
123
188
onDeleteTemplate,
124
189
} ) => {
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
-
134
190
const hasIcon = template . icon && template . icon !== "" ;
135
- const safeToDeleteTemplate =
136
- workspaceCountQuery . status === "success" && workspaceCountQuery . data === 0 ;
137
191
138
192
return (
139
193
< Margins >
@@ -153,7 +207,8 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
153
207
< TemplateMenu
154
208
templateVersion = { activeVersion . name }
155
209
templateName = { template . name }
156
- onDelete = { dialogState . openDeleteConfirmation }
210
+ templateId = { template . id }
211
+ onDelete = { onDeleteTemplate }
157
212
/>
158
213
) }
159
214
</ >
@@ -181,55 +236,6 @@ export const TemplatePageHeader: FC<TemplatePageHeaderProps> = ({
181
236
</ div >
182
237
</ Stack >
183
238
</ 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
- ) }
233
239
</ Margins >
234
240
) ;
235
241
} ;
0 commit comments