@@ -3,7 +3,7 @@ import { ProvisionerJobLog } from "api/typesGenerated"
3
3
import { useDashboard } from "components/Dashboard/DashboardProvider"
4
4
import dayjs from "dayjs"
5
5
import { useFeatureVisibility } from "hooks/useFeatureVisibility"
6
- import { useEffect , useState } from "react"
6
+ import { FC , useEffect , useState } from "react"
7
7
import { Helmet } from "react-helmet-async"
8
8
import { useTranslation } from "react-i18next"
9
9
import { useNavigate } from "react-router-dom"
@@ -31,7 +31,13 @@ import { ChangeVersionDialog } from "./ChangeVersionDialog"
31
31
import { useQuery } from "@tanstack/react-query"
32
32
import { getTemplateVersions } from "api/api"
33
33
import { useRestartWorkspace } from "./hooks"
34
- import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"
34
+ import {
35
+ ConfirmDialog ,
36
+ ConfirmDialogProps ,
37
+ } from "components/Dialogs/ConfirmDialog/ConfirmDialog"
38
+ import { useMe } from "hooks/useMe"
39
+ import Checkbox from "@mui/material/Checkbox"
40
+ import FormControlLabel from "@mui/material/FormControlLabel"
35
41
36
42
interface WorkspaceReadyPageProps {
37
43
workspaceState : StateFrom < typeof workspaceMachine >
@@ -79,6 +85,9 @@ export const WorkspaceReadyPage = ({
79
85
enabled : changeVersionDialogOpen ,
80
86
} )
81
87
const [ isConfirmingUpdate , setIsConfirmingUpdate ] = useState ( false )
88
+ const [ isConfirmingRestart , setIsConfirmingRestart ] = useState ( false )
89
+ const user = useMe ( )
90
+ const { isWarningIgnored, ignoreWarning } = useIgnoreWarnings ( user . id )
82
91
83
92
const {
84
93
mutate : restartWorkspace ,
@@ -133,9 +142,21 @@ export const WorkspaceReadyPage = ({
133
142
workspace = { workspace }
134
143
handleStart = { ( ) => workspaceSend ( { type : "START" } ) }
135
144
handleStop = { ( ) => workspaceSend ( { type : "STOP" } ) }
136
- handleRestart = { ( ) => restartWorkspace ( workspace ) }
137
145
handleDelete = { ( ) => workspaceSend ( { type : "ASK_DELETE" } ) }
138
- handleUpdate = { ( ) => setIsConfirmingUpdate ( true ) }
146
+ handleRestart = { ( ) => {
147
+ if ( isWarningIgnored ( "restart" ) ) {
148
+ restartWorkspace ( workspace )
149
+ } else {
150
+ setIsConfirmingRestart ( true )
151
+ }
152
+ } }
153
+ handleUpdate = { ( ) => {
154
+ if ( isWarningIgnored ( "update" ) ) {
155
+ workspaceSend ( { type : "UPDATE" } )
156
+ } else {
157
+ setIsConfirmingUpdate ( true )
158
+ }
159
+ } }
139
160
handleCancel = { ( ) => workspaceSend ( { type : "CANCEL" } ) }
140
161
handleSettings = { ( ) => navigate ( "settings" ) }
141
162
handleBuildRetry = { ( ) => workspaceSend ( { type : "RETRY_BUILD" } ) }
@@ -202,11 +223,12 @@ export const WorkspaceReadyPage = ({
202
223
} )
203
224
} }
204
225
/>
205
- < ConfirmDialog
206
- type = "info"
207
- hideCancel = { false }
226
+ < WarningDialog
208
227
open = { isConfirmingUpdate }
209
- onConfirm = { ( ) => {
228
+ onConfirm = { ( shouldIgnore ) => {
229
+ if ( shouldIgnore ) {
230
+ ignoreWarning ( "update" )
231
+ }
210
232
workspaceSend ( { type : "UPDATE" } )
211
233
setIsConfirmingUpdate ( false )
212
234
} }
@@ -215,6 +237,93 @@ export const WorkspaceReadyPage = ({
215
237
confirmText = "Update"
216
238
description = "Are you sure you want to update your workspace? Updating your workspace will stop all running processes and delete non-persistent data."
217
239
/>
240
+
241
+ < WarningDialog
242
+ open = { isConfirmingRestart }
243
+ onConfirm = { ( shouldIgnore ) => {
244
+ if ( shouldIgnore ) {
245
+ ignoreWarning ( "restart" )
246
+ }
247
+ restartWorkspace ( workspace )
248
+ setIsConfirmingRestart ( false )
249
+ } }
250
+ onClose = { ( ) => setIsConfirmingRestart ( false ) }
251
+ title = "Confirm restart"
252
+ confirmText = "Restart"
253
+ description = "Are you sure you want to restart your workspace? Updating your workspace will stop all running processes and delete non-persistent data."
254
+ />
218
255
</ >
219
256
)
220
257
}
258
+
259
+ type IgnoredWarnings = Record < string , string >
260
+
261
+ const useIgnoreWarnings = ( prefix : string ) => {
262
+ const ignoredWarningsJSON = localStorage . getItem ( `${ prefix } _ignoredWarnings` )
263
+ let ignoredWarnings : IgnoredWarnings | undefined
264
+ if ( ignoredWarningsJSON ) {
265
+ ignoredWarnings = JSON . parse ( ignoredWarningsJSON )
266
+ }
267
+
268
+ const isWarningIgnored = ( warningId : string ) => {
269
+ return Boolean ( ignoredWarnings ?. [ warningId ] )
270
+ }
271
+
272
+ const ignoreWarning = ( warningId : string ) => {
273
+ if ( ! ignoredWarnings ) {
274
+ ignoredWarnings = { }
275
+ }
276
+ ignoredWarnings [ warningId ] = new Date ( ) . toISOString ( )
277
+ localStorage . setItem (
278
+ `${ prefix } _ignoredWarnings` ,
279
+ JSON . stringify ( ignoredWarnings ) ,
280
+ )
281
+ }
282
+
283
+ return {
284
+ isWarningIgnored,
285
+ ignoreWarning,
286
+ }
287
+ }
288
+
289
+ const WarningDialog : FC <
290
+ Pick <
291
+ ConfirmDialogProps ,
292
+ "open" | "onClose" | "title" | "confirmText" | "description"
293
+ > & { onConfirm : ( shouldIgnore : boolean ) => void }
294
+ > = ( { open, onConfirm, onClose, title, confirmText, description } ) => {
295
+ const [ shouldIgnore , setShouldIgnore ] = useState ( false )
296
+
297
+ return (
298
+ < ConfirmDialog
299
+ type = "info"
300
+ hideCancel = { false }
301
+ open = { open }
302
+ onConfirm = { ( ) => {
303
+ onConfirm ( shouldIgnore )
304
+ } }
305
+ onClose = { onClose }
306
+ title = { title }
307
+ confirmText = { confirmText }
308
+ description = {
309
+ < >
310
+ < div > { description } </ div >
311
+ < FormControlLabel
312
+ sx = { {
313
+ marginTop : 2 ,
314
+ } }
315
+ control = {
316
+ < Checkbox
317
+ size = "small"
318
+ onChange = { ( e ) => {
319
+ setShouldIgnore ( e . target . checked )
320
+ } }
321
+ />
322
+ }
323
+ label = "Don't show me this message again"
324
+ />
325
+ </ >
326
+ }
327
+ />
328
+ )
329
+ }
0 commit comments