diff --git a/site/src/components/WarningAlert/WarningAlert.stories.tsx b/site/src/components/WarningAlert/WarningAlert.stories.tsx index 57ffdebb65158..774f995010604 100644 --- a/site/src/components/WarningAlert/WarningAlert.stories.tsx +++ b/site/src/components/WarningAlert/WarningAlert.stories.tsx @@ -1,18 +1,21 @@ -import { Story } from "@storybook/react" -import { WarningAlert, WarningAlertProps } from "./WarningAlert" +import { Meta, StoryObj } from "@storybook/react" +import { WarningAlert } from "./WarningAlert" import Button from "@mui/material/Button" -export default { +const meta: Meta = { title: "components/WarningAlert", component: WarningAlert, } -const Template: Story = (args) => +export default meta -export const ExampleWithDismiss = Template.bind({}) -ExampleWithDismiss.args = { - text: "This is a warning", - dismissible: true, +type Story = StoryObj + +export const ExampleWithDismiss: Story = { + args: { + text: "This is a warning", + dismissible: true, + }, } const ExampleAction = ( @@ -21,15 +24,17 @@ const ExampleAction = ( ) -export const ExampleWithAction = Template.bind({}) -ExampleWithAction.args = { - text: "This is a warning", - actions: [ExampleAction], +export const ExampleWithAction = { + args: { + text: "This is a warning", + actions: [ExampleAction], + }, } -export const ExampleWithActionAndDismiss = Template.bind({}) -ExampleWithActionAndDismiss.args = { - text: "This is a warning", - actions: [ExampleAction], - dismissible: true, +export const ExampleWithActionAndDismiss = { + args: { + text: "This is a warning", + actions: [ExampleAction], + dismissible: true, + }, } diff --git a/site/src/pages/TerminalPage/TerminalPage.tsx b/site/src/pages/TerminalPage/TerminalPage.tsx index d49709aa3c710..ccf035d55e7b9 100644 --- a/site/src/pages/TerminalPage/TerminalPage.tsx +++ b/site/src/pages/TerminalPage/TerminalPage.tsx @@ -1,7 +1,4 @@ -import Button from "@mui/material/Button" import { makeStyles, useTheme } from "@mui/styles" -import WarningIcon from "@mui/icons-material/ErrorOutlineRounded" -import RefreshOutlined from "@mui/icons-material/RefreshOutlined" import { useMachine } from "@xstate/react" import { portForwardURL } from "components/PortForwardButton/PortForwardButton" import { Stack } from "components/Stack/Stack" @@ -18,13 +15,13 @@ import { MONOSPACE_FONT_FAMILY } from "../../theme/constants" import { pageTitle } from "../../utils/page" import { terminalMachine } from "../../xServices/terminal/terminalXService" import { useProxy } from "contexts/ProxyContext" -import { combineClasses } from "utils/combineClasses" import Box from "@mui/material/Box" import { useDashboard } from "components/Dashboard/DashboardProvider" import { Region } from "api/typesGenerated" import { getLatencyColor } from "utils/latency" import Popover from "@mui/material/Popover" import { ProxyStatusLatency } from "components/ProxyStatusLatency/ProxyStatusLatency" +import TerminalPageAlert, { TerminalPageAlertType } from "./TerminalPageAlert" export const Language = { workspaceErrorMessagePrefix: "Unable to fetch workspace: ", @@ -80,12 +77,26 @@ const TerminalPage: FC = () => { websocketError, } = terminalState.context const reloading = useReloading(isDisconnected) - const shouldDisplayStartupWarning = workspaceAgent - ? ["starting", "starting_timeout"].includes(workspaceAgent.lifecycle_state) - : false - const shouldDisplayStartupError = workspaceAgent - ? workspaceAgent.lifecycle_state === "start_error" - : false + const lifecycleState = workspaceAgent?.lifecycle_state + const [startupWarning, setStartupWarning] = useState< + TerminalPageAlertType | undefined + >(undefined) + + useEffect(() => { + if (lifecycleState === "start_error") { + setStartupWarning("error") + } else if (lifecycleState === "starting") { + setStartupWarning("starting") + } else { + setStartupWarning((prev) => { + if (prev === "starting") { + return "success" + } + return undefined + }) + } + }, [lifecycleState]) + const dashboard = useDashboard() const proxyContext = useProxy() const selectedProxy = proxyContext.proxy.proxy @@ -305,49 +316,8 @@ const TerminalPage: FC = () => { )} - {shouldDisplayStartupError && ( -
- -
-
Startup script failed
-
- You can continue using this terminal, but something may be missing - or not fully set up. -
-
-
- )} - {shouldDisplayStartupWarning && ( -
- -
-
- Startup script is still running -
-
- You can continue using this terminal, but something may be - missing or not fully set up. -
-
-
- -
-
- )} + {startupWarning && }
= { + component: TerminalPageAlert, + title: "components/TerminalPageAlert", + argTypes: { + alertType: { + control: { + type: "radio", + }, + options: ["error", "starting", "success"], + }, + }, +} +type Story = StoryObj + +export const Error: Story = { + args: { + alertType: "error", + }, +} + +export const Starting: Story = { + args: { + alertType: "starting", + }, +} + +export const Success: Story = { + args: { + alertType: "success", + }, +} + +export default meta diff --git a/site/src/pages/TerminalPage/TerminalPageAlert.tsx b/site/src/pages/TerminalPage/TerminalPageAlert.tsx new file mode 100644 index 0000000000000..3816ff60a92ae --- /dev/null +++ b/site/src/pages/TerminalPage/TerminalPageAlert.tsx @@ -0,0 +1,113 @@ +import { AlertColor } from "@mui/material/Alert/Alert" +import Button from "@mui/material/Button" +import Link from "@mui/material/Link" +import { Alert } from "components/Alert/Alert" +import { ReactNode } from "react" + +export type TerminalPageAlertType = "error" | "starting" | "success" + +type MapAlertTypeToComponent = { + [key in TerminalPageAlertType]: { + severity: AlertColor + children: ReactNode | undefined + } +} + +const mapAlertTypeToText: MapAlertTypeToComponent = { + error: { + severity: "warning", + children: ( + <> + The workspace{" "} + + startup script has exited with an error + + , we recommend reloading this session and{" "} + + debugging the startup script + {" "} + because{" "} + + your workspace may be incomplete. + {" "} + + ), + }, + starting: { + severity: "info", + children: ( + <> + Startup script is still running. You can continue using this terminal, + but{" "} + + {" "} + your workspace may be incomplete. + + + ), + }, + success: { + severity: "success", + children: ( + <> + Startup script has completed successfully. The workspace is ready but + this{" "} + + session was started before the startup script finished. + {" "} + To ensure your shell environment is up-to-date, we recommend reloading + this session. + + ), + }, +} + +export default ({ alertType }: { alertType: TerminalPageAlertType }) => { + return ( + { + // By redirecting the user without the session in the URL we + // create a new one + window.location.href = window.location.pathname + }} + > + Refresh session + , + ]} + > + {mapAlertTypeToText[alertType].children} + + ) +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy