Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions site/src/components/WarningAlert/WarningAlert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Story } from "@storybook/react"
import { WarningAlert, WarningAlertProps } from "./WarningAlert"
import Button from "@material-ui/core/Button"

export default {
title: "components/WarningAlert",
component: WarningAlert,
}

const Template: Story<WarningAlertProps> = (args) => <WarningAlert {...args} />

export const ExampleWithDismiss = Template.bind({})
ExampleWithDismiss.args = {
text: "This is a warning",
dismissible: true,
}

const ExampleAction = (
<Button onClick={() => null} size="small">
Button
</Button>
)

export const ExampleWithAction = Template.bind({})
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,
}
61 changes: 61 additions & 0 deletions site/src/components/WarningAlert/WarningAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { useState, FC, ReactElement } from "react"
import Collapse from "@material-ui/core/Collapse"
import { Stack } from "components/Stack/Stack"
import { makeStyles, Theme } from "@material-ui/core/styles"
import { colors } from "theme/colors"
import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined"
import Button from "@material-ui/core/Button"
import { useTranslation } from "react-i18next"

export interface WarningAlertProps {
text: string
dismissible?: boolean
actions?: ReactElement[]
}

export const WarningAlert: FC<WarningAlertProps> = ({
text,
dismissible = false,
actions = [],
}) => {
const { t } = useTranslation("common")
const [open, setOpen] = useState(true)
const classes = useStyles()

return (
<Collapse in={open}>
<Stack
className={classes.alertContainer}
direction="row"
alignItems="center"
spacing={0}
justifyContent="space-between"
>
<Stack direction="row" spacing={1}>
<ReportProblemOutlinedIcon fontSize="small" className={classes.alertIcon} />
{text}
</Stack>
<Stack direction="row">
{actions.length > 0 && actions.map((action) => <div key={String(action)}>{action}</div>)}
{dismissible && (
<Button size="small" onClick={() => setOpen(false)} variant="outlined">
{t("ctas.dismissCta")}
</Button>
)}
</Stack>
</Stack>
</Collapse>
)
}

const useStyles = makeStyles<Theme>((theme) => ({
alertContainer: {
border: `1px solid ${colors.orange[7]}`,
borderRadius: theme.shape.borderRadius,
padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
backgroundColor: `${colors.gray[16]}`,
},
alertIcon: {
color: `${colors.orange[7]}`,
},
}))
17 changes: 11 additions & 6 deletions site/src/components/Workspace/Workspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { WorkspaceScheduleBanner } from "../WorkspaceScheduleBanner/WorkspaceSch
import { WorkspaceScheduleButton } from "../WorkspaceScheduleButton/WorkspaceScheduleButton"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
import { WorkspaceStats } from "../WorkspaceStats/WorkspaceStats"
import { WarningAlert } from "../WarningAlert/WarningAlert"
import { useTranslation } from "react-i18next"

export enum WorkspaceErrors {
GET_RESOURCES_ERROR = "getResourcesError",
Expand Down Expand Up @@ -71,19 +73,21 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
buildInfo,
applicationsHost,
}) => {
const { t } = useTranslation("workspacePage")
const styles = useStyles()
const navigate = useNavigate()
const hasTemplateIcon = workspace.template_icon && workspace.template_icon !== ""

const buildError = workspaceErrors[WorkspaceErrors.BUILD_ERROR] ? (
const buildError = Boolean(workspaceErrors[WorkspaceErrors.BUILD_ERROR]) && (
<ErrorSummary error={workspaceErrors[WorkspaceErrors.BUILD_ERROR]} dismissible />
) : (
<></>
)
const cancellationError = workspaceErrors[WorkspaceErrors.CANCELLATION_ERROR] ? (

const cancellationError = Boolean(workspaceErrors[WorkspaceErrors.CANCELLATION_ERROR]) && (
<ErrorSummary error={workspaceErrors[WorkspaceErrors.CANCELLATION_ERROR]} dismissible />
) : (
<></>
)

const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && (
<WarningAlert text={t("warningsAndErrors.workspaceRefreshWarning")} dismissible />
)

return (
Expand Down Expand Up @@ -127,6 +131,7 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
<Stack direction="column" className={styles.firstColumnSpacer} spacing={2.5}>
{buildError}
{cancellationError}
{workspaceRefreshWarning}

<WorkspaceScheduleBanner
isLoading={bannerProps.isLoading}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import Button from "@material-ui/core/Button"
import { makeStyles } from "@material-ui/core/styles"
import Alert from "@material-ui/lab/Alert"
import AlertTitle from "@material-ui/lab/AlertTitle"
import { Maybe } from "components/Conditionals/Maybe"
import { FC } from "react"
import * as TypesGen from "../../api/typesGenerated"

const Language = {
bannerTitle: "This workspace has been deleted and cannot be edited.",
createWorkspaceCta: "Create new workspace",
}
import { WarningAlert } from "components/WarningAlert/WarningAlert"
import { useTranslation } from "react-i18next"
import { Maybe } from "components/Conditionals/Maybe"

export interface WorkspaceDeletedBannerProps {
workspace: TypesGen.Workspace
Expand All @@ -20,32 +14,19 @@ export const WorkspaceDeletedBanner: FC<React.PropsWithChildren<WorkspaceDeleted
workspace,
handleClick,
}) => {
const styles = useStyles()
const { t } = useTranslation("workspacePage")
const NewWorkspaceButton = (
<Button onClick={handleClick} size="small">
{t("ctas.createWorkspaceCta")}
</Button>
)

return (
<Maybe condition={workspace.latest_build.status === "deleted"}>
<Alert
className={styles.root}
action={
<Button color="inherit" onClick={handleClick} size="small">
{Language.createWorkspaceCta}
</Button>
}
severity="warning"
>
<AlertTitle>{Language.bannerTitle}</AlertTitle>
</Alert>
<WarningAlert
text={t("warningsAndErrors.workspaceDeletedWarning")}
actions={[NewWorkspaceButton]}
/>
</Maybe>
)
}

export const useStyles = makeStyles(() => {
return {
root: {
alignItems: "center",
"& .MuiAlertTitle-root": {
marginBottom: "0px",
},
},
}
})
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import Button from "@material-ui/core/Button"
import Alert from "@material-ui/lab/Alert"
import AlertTitle from "@material-ui/lab/AlertTitle"
import dayjs from "dayjs"
import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
import utc from "dayjs/plugin/utc"
import { FC } from "react"
import * as TypesGen from "../../api/typesGenerated"
import { isWorkspaceOn } from "../../util/workspace"
import * as TypesGen from "api/typesGenerated"
import { isWorkspaceOn } from "util/workspace"
import { WarningAlert } from "components/WarningAlert/WarningAlert"
import { useTranslation } from "react-i18next"

dayjs.extend(utc)
dayjs.extend(isSameOrBefore)

export const Language = {
bannerAction: "Extend",
bannerTitle: "Your workspace is scheduled to automatically shut down soon.",
}

export interface WorkspaceScheduleBannerProps {
isLoading?: boolean
onExtend: () => void
Expand All @@ -36,26 +31,22 @@ export const WorkspaceScheduleBanner: FC<React.PropsWithChildren<WorkspaceSchedu
onExtend,
workspace,
}) => {
const { t } = useTranslation("workspacePage")

if (!shouldDisplay(workspace)) {
return null
} else {
return (
<Alert
action={
<Button
variant="outlined"
color="inherit"
disabled={isLoading}
onClick={onExtend}
size="small"
>
{Language.bannerAction}
</Button>
}
severity="warning"
>
<AlertTitle>{Language.bannerTitle}</AlertTitle>
</Alert>
)
}

const ScheduleButton = (
<Button variant="outlined" disabled={isLoading} onClick={onExtend} size="small">
{t("ctas.extendScheduleCta")}
</Button>
)

return (
<WarningAlert
text={t("warningsAndErrors.workspaceShutdownWarning")}
actions={[ScheduleButton]}
/>
)
}
3 changes: 3 additions & 0 deletions site/src/i18n/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
"confirm": "Are you sure you want to proceed? Type the name of this {{entity}} below to confirm.",
"confirmLabel": "Name of {{entity}} to delete",
"incorrectName": "Incorrect {{entity}} name."
},
"ctas": {
"dismissCta": "Dismiss"
}
}
9 changes: 9 additions & 0 deletions site/src/i18n/en/workspacePage.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
"editDeadlineMinus": "Subtract one hour",
"editDeadlinePlus": "Add one hour"
},
"ctas": {
"createWorkspaceCta": "Create new workspace",
"extendScheduleCta": "Extend"
},
"warningsAndErrors": {
"workspaceRefreshWarning": "We're having difficulty fetching the latest workspace state. Refresh the page to see the newest changes.",
"workspaceDeletedWarning": "This workspace has been deleted and cannot be edited.",
"workspaceShutdownWarning": "Your workspace is scheduled to automatically shut down soon."
},
"actionButton": {
"start": "Start",
"stop": "Stop",
Expand Down
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