Skip to content

Commit 730039f

Browse files
feat(site): Show warning if startup script is running (#7326)
1 parent 75ad72d commit 730039f

File tree

2 files changed

+112
-30
lines changed

2 files changed

+112
-30
lines changed

site/src/api/api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ export const getWorkspaceBuildParameters = async (
10211021
return response.data
10221022
}
10231023
type Claims = {
1024-
license_expires?: jwt.NumericDate
1024+
license_expires?: number
10251025
account_type?: string
10261026
account_id?: string
10271027
trial: boolean

site/src/pages/TerminalPage/TerminalPage.tsx

+111-29
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import Button from "@material-ui/core/Button"
12
import { makeStyles } from "@material-ui/core/styles"
3+
import WarningIcon from "@material-ui/icons/ErrorOutlineRounded"
4+
import RefreshOutlined from "@material-ui/icons/RefreshOutlined"
25
import { useMachine } from "@xstate/react"
36
import { portForwardURL } from "components/PortForwardButton/PortForwardButton"
47
import { Stack } from "components/Stack/Stack"
@@ -15,41 +18,14 @@ import { MONOSPACE_FONT_FAMILY } from "../../theme/constants"
1518
import { pageTitle } from "../../utils/page"
1619
import { terminalMachine } from "../../xServices/terminal/terminalXService"
1720
import { useProxy } from "contexts/ProxyContext"
21+
import { combineClasses } from "utils/combineClasses"
1822

1923
export const Language = {
2024
workspaceErrorMessagePrefix: "Unable to fetch workspace: ",
2125
workspaceAgentErrorMessagePrefix: "Unable to fetch workspace agent: ",
2226
websocketErrorMessagePrefix: "WebSocket failed: ",
2327
}
2428

25-
const useReloading = (isDisconnected: boolean) => {
26-
const [status, setStatus] = useState<"reloading" | "notReloading">(
27-
"notReloading",
28-
)
29-
30-
// Retry connection on key press when it is disconnected
31-
useEffect(() => {
32-
if (!isDisconnected) {
33-
return
34-
}
35-
36-
const keyDownHandler = () => {
37-
setStatus("reloading")
38-
window.location.reload()
39-
}
40-
41-
document.addEventListener("keydown", keyDownHandler)
42-
43-
return () => {
44-
document.removeEventListener("keydown", keyDownHandler)
45-
}
46-
}, [isDisconnected])
47-
48-
return {
49-
status,
50-
}
51-
}
52-
5329
const TerminalPage: FC<
5430
React.PropsWithChildren<{
5531
readonly renderer?: XTerm.RendererType
@@ -102,6 +78,12 @@ const TerminalPage: FC<
10278
websocketError,
10379
} = terminalState.context
10480
const reloading = useReloading(isDisconnected)
81+
const shouldDisplayStartupWarning = workspaceAgent
82+
? ["starting", "starting_timeout"].includes(workspaceAgent.lifecycle_state)
83+
: false
84+
const shouldDisplayStartupError = workspaceAgent
85+
? workspaceAgent.lifecycle_state === "start_error"
86+
: false
10587

10688
// handleWebLink handles opening of URLs in the terminal!
10789
const handleWebLink = useCallback(
@@ -316,12 +298,80 @@ const TerminalPage: FC<
316298
</Stack>
317299
)}
318300
</div>
301+
{shouldDisplayStartupError && (
302+
<div
303+
className={combineClasses([styles.alert, styles.alertError])}
304+
role="alert"
305+
>
306+
<WarningIcon className={styles.alertIcon} />
307+
<div>
308+
<div className={styles.alertTitle}>Startup script failed</div>
309+
<div className={styles.alertMessage}>
310+
You can continue using this terminal, but something may be missing
311+
or not fully set up.
312+
</div>
313+
</div>
314+
</div>
315+
)}
316+
{shouldDisplayStartupWarning && (
317+
<div className={styles.alert} role="alert">
318+
<WarningIcon className={styles.alertIcon} />
319+
<div>
320+
<div className={styles.alertTitle}>
321+
Startup script is still running
322+
</div>
323+
<div className={styles.alertMessage}>
324+
You can continue using this terminal, but something may be missing
325+
or not fully set up.
326+
</div>
327+
</div>
328+
<div className={styles.alertActions}>
329+
<Button
330+
startIcon={<RefreshOutlined />}
331+
size="small"
332+
onClick={() => {
333+
// By redirecting the user without the session in the URL we
334+
// create a new one
335+
window.location.href = window.location.pathname
336+
}}
337+
>
338+
Refresh session
339+
</Button>
340+
</div>
341+
</div>
342+
)}
319343
<div className={styles.terminal} ref={xtermRef} data-testid="terminal" />
320344
</>
321345
)
322346
}
323347

324-
export default TerminalPage
348+
const useReloading = (isDisconnected: boolean) => {
349+
const [status, setStatus] = useState<"reloading" | "notReloading">(
350+
"notReloading",
351+
)
352+
353+
// Retry connection on key press when it is disconnected
354+
useEffect(() => {
355+
if (!isDisconnected) {
356+
return
357+
}
358+
359+
const keyDownHandler = () => {
360+
setStatus("reloading")
361+
window.location.reload()
362+
}
363+
364+
document.addEventListener("keydown", keyDownHandler)
365+
366+
return () => {
367+
document.removeEventListener("keydown", keyDownHandler)
368+
}
369+
}, [isDisconnected])
370+
371+
return {
372+
status,
373+
}
374+
}
325375

326376
const useStyles = makeStyles((theme) => ({
327377
overlay: {
@@ -355,6 +405,8 @@ const useStyles = makeStyles((theme) => ({
355405
width: "100vw",
356406
height: "100vh",
357407
overflow: "hidden",
408+
padding: theme.spacing(1),
409+
backgroundColor: theme.palette.background.paper,
358410
// These styles attempt to mimic the VS Code scrollbar.
359411
"& .xterm": {
360412
padding: 4,
@@ -377,4 +429,34 @@ const useStyles = makeStyles((theme) => ({
377429
backgroundColor: "rgba(255, 255, 255, 0.18)",
378430
},
379431
},
432+
alert: {
433+
display: "flex",
434+
background: theme.palette.background.paperLight,
435+
alignItems: "center",
436+
padding: theme.spacing(2),
437+
gap: theme.spacing(2),
438+
borderBottom: `1px solid ${theme.palette.divider}`,
439+
},
440+
alertIcon: {
441+
color: theme.palette.warning.light,
442+
fontSize: theme.spacing(3),
443+
},
444+
alertError: {
445+
"& $alertIcon": {
446+
color: theme.palette.error.light,
447+
},
448+
},
449+
alertTitle: {
450+
fontWeight: 600,
451+
color: theme.palette.text.primary,
452+
},
453+
alertMessage: {
454+
fontSize: 14,
455+
color: theme.palette.text.secondary,
456+
},
457+
alertActions: {
458+
marginLeft: "auto",
459+
},
380460
}))
461+
462+
export default TerminalPage

0 commit comments

Comments
 (0)