@@ -3,7 +3,7 @@ import { ProvisionerJobLog } from "api/typesGenerated"
33import { useDashboard } from "components/Dashboard/DashboardProvider"
44import dayjs from "dayjs"
55import { useFeatureVisibility } from "hooks/useFeatureVisibility"
6- import { useEffect , useState } from "react"
6+ import { FC , useEffect , useState } from "react"
77import { Helmet } from "react-helmet-async"
88import { useTranslation } from "react-i18next"
99import { useNavigate } from "react-router-dom"
@@ -31,7 +31,13 @@ import { ChangeVersionDialog } from "./ChangeVersionDialog"
3131import { useQuery } from "@tanstack/react-query"
3232import { getTemplateVersions } from "api/api"
3333import { 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"
3541
3642interface WorkspaceReadyPageProps {
3743 workspaceState : StateFrom < typeof workspaceMachine >
@@ -79,6 +85,9 @@ export const WorkspaceReadyPage = ({
7985 enabled : changeVersionDialogOpen ,
8086 } )
8187 const [ isConfirmingUpdate , setIsConfirmingUpdate ] = useState ( false )
88+ const [ isConfirmingRestart , setIsConfirmingRestart ] = useState ( false )
89+ const user = useMe ( )
90+ const { isWarningIgnored, ignoreWarning } = useIgnoreWarnings ( user . id )
8291
8392 const {
8493 mutate : restartWorkspace ,
@@ -133,9 +142,21 @@ export const WorkspaceReadyPage = ({
133142 workspace = { workspace }
134143 handleStart = { ( ) => workspaceSend ( { type : "START" } ) }
135144 handleStop = { ( ) => workspaceSend ( { type : "STOP" } ) }
136- handleRestart = { ( ) => restartWorkspace ( workspace ) }
137145 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+ } }
139160 handleCancel = { ( ) => workspaceSend ( { type : "CANCEL" } ) }
140161 handleSettings = { ( ) => navigate ( "settings" ) }
141162 handleBuildRetry = { ( ) => workspaceSend ( { type : "RETRY_BUILD" } ) }
@@ -202,11 +223,12 @@ export const WorkspaceReadyPage = ({
202223 } )
203224 } }
204225 />
205- < ConfirmDialog
206- type = "info"
207- hideCancel = { false }
226+ < WarningDialog
208227 open = { isConfirmingUpdate }
209- onConfirm = { ( ) => {
228+ onConfirm = { ( shouldIgnore ) => {
229+ if ( shouldIgnore ) {
230+ ignoreWarning ( "update" )
231+ }
210232 workspaceSend ( { type : "UPDATE" } )
211233 setIsConfirmingUpdate ( false )
212234 } }
@@ -215,6 +237,93 @@ export const WorkspaceReadyPage = ({
215237 confirmText = "Update"
216238 description = "Are you sure you want to update your workspace? Updating your workspace will stop all running processes and delete non-persistent data."
217239 />
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+ />
218255 </ >
219256 )
220257}
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