From 7da8608e080c8550bad4a378a284eb7d733cde32 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Tue, 4 Oct 2022 19:17:45 +0000 Subject: [PATCH 01/13] added a warning summary component --- .../WarningSummary/WarningSummary.stories.tsx | 14 ++++ .../WarningSummary/WarningSummary.tsx | 64 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 site/src/components/WarningSummary/WarningSummary.stories.tsx create mode 100644 site/src/components/WarningSummary/WarningSummary.tsx diff --git a/site/src/components/WarningSummary/WarningSummary.stories.tsx b/site/src/components/WarningSummary/WarningSummary.stories.tsx new file mode 100644 index 0000000000000..01277ae5d7781 --- /dev/null +++ b/site/src/components/WarningSummary/WarningSummary.stories.tsx @@ -0,0 +1,14 @@ +import { Story } from "@storybook/react" +import { WarningSummary, WarningSummaryProps } from "./WarningSummary" + +export default { + title: "components/WarningSummary", + component: WarningSummary, +} + +const Template: Story = (args) => + +export const Example = Template.bind({}) +Example.args = { + warningString: "This is a warning", +} diff --git a/site/src/components/WarningSummary/WarningSummary.tsx b/site/src/components/WarningSummary/WarningSummary.tsx new file mode 100644 index 0000000000000..5a3c946cead48 --- /dev/null +++ b/site/src/components/WarningSummary/WarningSummary.tsx @@ -0,0 +1,64 @@ +import { FC, useState } from "react" +import { Stack } from "components/Stack/Stack" +import { makeStyles, Theme } from "@material-ui/core/styles" +import CloseIcon from "@material-ui/icons/Close" +import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined" +import IconButton from "@material-ui/core/IconButton" +import { colors } from "theme/colors" + +export interface WarningSummaryProps { + warningString: string +} + +export const WarningSummary: FC = ({ warningString }) => { + const styles = useStyles() + const [isOpen, setOpen] = useState(true) + + const closeWarning = () => { + setOpen(false) + } + + if (!isOpen) { + return null + } + + return ( + + + + {warningString} + + + + + + + ) +} +const useStyles = makeStyles((theme) => ({ + root: { + border: `2px solid ${colors.orange[7]}`, + padding: `8px`, + borderRadius: theme.shape.borderRadius, + gap: 0, + color: `${colors.orange[7]}`, // icon inherits color from parent + }, + errorMessage: { + marginRight: `${theme.spacing(1)}px`, + marginLeft: "10px", + color: `${colors.orange[4]}`, + }, + iconButton: { + padding: 0, + }, + closeIcon: { + width: 25, + height: 25, + color: `${colors.orange[7]}`, + }, +})) From a15a59fc4d9d69e5943ad0527f5a0f56c782fe9e Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Tue, 4 Oct 2022 19:46:33 +0000 Subject: [PATCH 02/13] added warning to workspace page --- .../WarningSummary/WarningSummary.tsx | 2 +- site/src/components/Workspace/Workspace.tsx | 17 +++++++++++------ site/src/i18n/en/workspacePage.json | 3 +++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/site/src/components/WarningSummary/WarningSummary.tsx b/site/src/components/WarningSummary/WarningSummary.tsx index 5a3c946cead48..3b7a86eb22718 100644 --- a/site/src/components/WarningSummary/WarningSummary.tsx +++ b/site/src/components/WarningSummary/WarningSummary.tsx @@ -43,7 +43,7 @@ export const WarningSummary: FC = ({ warningString }) => { const useStyles = makeStyles((theme) => ({ root: { border: `2px solid ${colors.orange[7]}`, - padding: `8px`, + padding: `${theme.spacing(1)}px`, borderRadius: theme.shape.borderRadius, gap: 0, color: `${colors.orange[7]}`, // icon inherits color from parent diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index e8c1a82a41b76..a7d000f7c5215 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -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 { WarningSummary } from "../WarningSummary/WarningSummary" +import { useTranslation } from "react-i18next" export enum WorkspaceErrors { GET_RESOURCES_ERROR = "getResourcesError", @@ -71,19 +73,21 @@ export const Workspace: FC> = ({ 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]) && ( - ) : ( - <> ) - const cancellationError = workspaceErrors[WorkspaceErrors.CANCELLATION_ERROR] ? ( + + const cancellationError = Boolean(workspaceErrors[WorkspaceErrors.CANCELLATION_ERROR]) && ( - ) : ( - <> + ) + + const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && ( + ) return ( @@ -126,6 +130,7 @@ export const Workspace: FC> = ({ {buildError} {cancellationError} + {workspaceRefreshWarning} Date: Wed, 5 Oct 2022 14:53:32 +0000 Subject: [PATCH 03/13] consolidated warnings --- .../WarningAlert/WarningAlert.stories.tsx | 27 ++++++++ .../components/WarningAlert/WarningAlert.tsx | 43 +++++++++++++ .../WarningSummary/WarningSummary.stories.tsx | 14 ---- .../WarningSummary/WarningSummary.tsx | 64 ------------------- site/src/components/Workspace/Workspace.tsx | 4 +- .../WorkspaceDeletedBanner.tsx | 44 ++++--------- .../WorkspaceScheduleBanner.tsx | 44 +++++-------- site/src/i18n/en/workspacePage.json | 11 +++- 8 files changed, 110 insertions(+), 141 deletions(-) create mode 100644 site/src/components/WarningAlert/WarningAlert.stories.tsx create mode 100644 site/src/components/WarningAlert/WarningAlert.tsx delete mode 100644 site/src/components/WarningSummary/WarningSummary.stories.tsx delete mode 100644 site/src/components/WarningSummary/WarningSummary.tsx diff --git a/site/src/components/WarningAlert/WarningAlert.stories.tsx b/site/src/components/WarningAlert/WarningAlert.stories.tsx new file mode 100644 index 0000000000000..166a754b76031 --- /dev/null +++ b/site/src/components/WarningAlert/WarningAlert.stories.tsx @@ -0,0 +1,27 @@ +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 = (args) => + +export const ExampleWithClose = Template.bind({}) +ExampleWithClose.args = { + text: "This is a warning", +} + +const ExampleAction = ( + +) + +export const ExampleWithAction = Template.bind({}) +ExampleWithAction.args = { + text: "This is a warning", + action: ExampleAction, +} diff --git a/site/src/components/WarningAlert/WarningAlert.tsx b/site/src/components/WarningAlert/WarningAlert.tsx new file mode 100644 index 0000000000000..189b2f9e498f7 --- /dev/null +++ b/site/src/components/WarningAlert/WarningAlert.tsx @@ -0,0 +1,43 @@ +import { useState, FC, ReactElement } from "react" +import Alert from "@material-ui/lab/Alert" +import IconButton from "@material-ui/core/IconButton" +import Collapse from "@material-ui/core/Collapse" +import { Stack } from "components/Stack/Stack" +import CloseIcon from "@material-ui/icons/Close" + +export interface WarningAlertProps { + text: string + action?: ReactElement +} + +export const WarningAlert: FC = ({ text, action }) => { + const [open, setOpen] = useState(true) + + return ( + + + { + setOpen(false) + }} + > + + + ) + } + > + {text} + + + + ) +} diff --git a/site/src/components/WarningSummary/WarningSummary.stories.tsx b/site/src/components/WarningSummary/WarningSummary.stories.tsx deleted file mode 100644 index 01277ae5d7781..0000000000000 --- a/site/src/components/WarningSummary/WarningSummary.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { Story } from "@storybook/react" -import { WarningSummary, WarningSummaryProps } from "./WarningSummary" - -export default { - title: "components/WarningSummary", - component: WarningSummary, -} - -const Template: Story = (args) => - -export const Example = Template.bind({}) -Example.args = { - warningString: "This is a warning", -} diff --git a/site/src/components/WarningSummary/WarningSummary.tsx b/site/src/components/WarningSummary/WarningSummary.tsx deleted file mode 100644 index 3b7a86eb22718..0000000000000 --- a/site/src/components/WarningSummary/WarningSummary.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { FC, useState } from "react" -import { Stack } from "components/Stack/Stack" -import { makeStyles, Theme } from "@material-ui/core/styles" -import CloseIcon from "@material-ui/icons/Close" -import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined" -import IconButton from "@material-ui/core/IconButton" -import { colors } from "theme/colors" - -export interface WarningSummaryProps { - warningString: string -} - -export const WarningSummary: FC = ({ warningString }) => { - const styles = useStyles() - const [isOpen, setOpen] = useState(true) - - const closeWarning = () => { - setOpen(false) - } - - if (!isOpen) { - return null - } - - return ( - - - - {warningString} - - - - - - - ) -} -const useStyles = makeStyles((theme) => ({ - root: { - border: `2px solid ${colors.orange[7]}`, - padding: `${theme.spacing(1)}px`, - borderRadius: theme.shape.borderRadius, - gap: 0, - color: `${colors.orange[7]}`, // icon inherits color from parent - }, - errorMessage: { - marginRight: `${theme.spacing(1)}px`, - marginLeft: "10px", - color: `${colors.orange[4]}`, - }, - iconButton: { - padding: 0, - }, - closeIcon: { - width: 25, - height: 25, - color: `${colors.orange[7]}`, - }, -})) diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index a7d000f7c5215..9f5e2ea684c0d 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -15,7 +15,7 @@ import { WorkspaceScheduleBanner } from "../WorkspaceScheduleBanner/WorkspaceSch import { WorkspaceScheduleButton } from "../WorkspaceScheduleButton/WorkspaceScheduleButton" import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection" import { WorkspaceStats } from "../WorkspaceStats/WorkspaceStats" -import { WarningSummary } from "../WarningSummary/WarningSummary" +import { WarningAlert } from "../WarningAlert/WarningAlert" import { useTranslation } from "react-i18next" export enum WorkspaceErrors { @@ -87,7 +87,7 @@ export const Workspace: FC> = ({ ) const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && ( - + ) return ( diff --git a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx index 604de7a6d19de..cb41bf9e2150d 100644 --- a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx +++ b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx @@ -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 { FC } from "react" import * as TypesGen from "../../api/typesGenerated" import { isWorkspaceDeleted } from "../../util/workspace" - -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" export interface WorkspaceDeletedBannerProps { workspace: TypesGen.Workspace @@ -20,34 +14,22 @@ export const WorkspaceDeletedBanner: FC { - const styles = useStyles() + const { t } = useTranslation("workspacePage") if (!isWorkspaceDeleted(workspace)) { return null } + const NewWorkspaceButton = ( + + ) + return ( - - {Language.createWorkspaceCta} - - } - severity="warning" - > - {Language.bannerTitle} - + ) } - -export const useStyles = makeStyles(() => { - return { - root: { - alignItems: "center", - "& .MuiAlertTitle-root": { - marginBottom: "0px", - }, - }, - } -}) diff --git a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx index 81538af5352df..e6cd565e7f969 100644 --- a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx +++ b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx @@ -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 @@ -36,26 +31,19 @@ export const WorkspaceScheduleBanner: FC { + const { t } = useTranslation("workspacePage") + if (!shouldDisplay(workspace)) { return null - } else { - return ( - - {Language.bannerAction} - - } - severity="warning" - > - {Language.bannerTitle} - - ) } + + const ScheduleButton = ( + + ) + + return ( + + ) } diff --git a/site/src/i18n/en/workspacePage.json b/site/src/i18n/en/workspacePage.json index f4b1ab6eb9762..bbc199734661a 100644 --- a/site/src/i18n/en/workspacePage.json +++ b/site/src/i18n/en/workspacePage.json @@ -6,8 +6,15 @@ "schedule": "Schedule", "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." + "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." } } From 5db509bab209bdb0e8aa564ad9055f11ec972880 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Wed, 5 Oct 2022 15:08:59 +0000 Subject: [PATCH 04/13] prettier --- site/src/i18n/en/workspacePage.json | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/i18n/en/workspacePage.json b/site/src/i18n/en/workspacePage.json index bbc199734661a..2d98f12d4da56 100644 --- a/site/src/i18n/en/workspacePage.json +++ b/site/src/i18n/en/workspacePage.json @@ -10,7 +10,6 @@ "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.", From 5aeb6e2bc0af8f9d672c99acd9d972ed20fb294d Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Wed, 5 Oct 2022 20:05:24 +0000 Subject: [PATCH 05/13] updated design --- .../WarningAlert/WarningAlert.stories.tsx | 16 +++- .../components/WarningAlert/WarningAlert.tsx | 76 ++++++++++++------- site/src/components/Workspace/Workspace.tsx | 2 +- .../WorkspaceDeletedBanner.tsx | 4 +- .../WorkspaceScheduleBanner.tsx | 7 +- site/src/i18n/en/common.json | 3 + 6 files changed, 70 insertions(+), 38 deletions(-) diff --git a/site/src/components/WarningAlert/WarningAlert.stories.tsx b/site/src/components/WarningAlert/WarningAlert.stories.tsx index 166a754b76031..dc8eed293441e 100644 --- a/site/src/components/WarningAlert/WarningAlert.stories.tsx +++ b/site/src/components/WarningAlert/WarningAlert.stories.tsx @@ -9,13 +9,14 @@ export default { const Template: Story = (args) => -export const ExampleWithClose = Template.bind({}) -ExampleWithClose.args = { +export const ExampleWithDismiss = Template.bind({}) +ExampleWithDismiss.args = { text: "This is a warning", + dismissible: true, } const ExampleAction = ( - ) @@ -23,5 +24,12 @@ const ExampleAction = ( export const ExampleWithAction = Template.bind({}) ExampleWithAction.args = { text: "This is a warning", - action: ExampleAction, + actions: [ExampleAction], +} + +export const ExampleWithActionAndDismiss = Template.bind({}) +ExampleWithActionAndDismiss.args = { + text: "This is a warning", + actions: [ExampleAction], + dismissible: true, } diff --git a/site/src/components/WarningAlert/WarningAlert.tsx b/site/src/components/WarningAlert/WarningAlert.tsx index 189b2f9e498f7..7b0a024927913 100644 --- a/site/src/components/WarningAlert/WarningAlert.tsx +++ b/site/src/components/WarningAlert/WarningAlert.tsx @@ -1,43 +1,61 @@ import { useState, FC, ReactElement } from "react" -import Alert from "@material-ui/lab/Alert" -import IconButton from "@material-ui/core/IconButton" import Collapse from "@material-ui/core/Collapse" import { Stack } from "components/Stack/Stack" -import CloseIcon from "@material-ui/icons/Close" +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 - action?: ReactElement + dismissible?: boolean + actions?: ReactElement[] } -export const WarningAlert: FC = ({ text, action }) => { +export const WarningAlert: FC = ({ + text, + dismissible = false, + actions = [], +}) => { + const { t } = useTranslation("common") const [open, setOpen] = useState(true) + const classes = useStyles() return ( - - - { - setOpen(false) - }} - > - - - ) - } - > + + + + {text} - - - + + + {actions.length > 0 && actions.map((action) =>
{action}
)} + {dismissible && ( + + )} +
+ + ) } + +const useStyles = makeStyles((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]}`, + }, +})) diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 9f5e2ea684c0d..945258a836467 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -87,7 +87,7 @@ export const Workspace: FC> = ({ ) const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && ( - + ) return ( diff --git a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx index cb41bf9e2150d..c398047ee96fc 100644 --- a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx +++ b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx @@ -21,7 +21,7 @@ export const WorkspaceDeletedBanner: FC + ) @@ -29,7 +29,7 @@ export const WorkspaceDeletedBanner: FC ) } diff --git a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx index e6cd565e7f969..2ff5ca57096e1 100644 --- a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx +++ b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx @@ -38,12 +38,15 @@ export const WorkspaceScheduleBanner: FC + ) return ( - + ) } diff --git a/site/src/i18n/en/common.json b/site/src/i18n/en/common.json index 514205e9da8c2..99dda7c9e541d 100644 --- a/site/src/i18n/en/common.json +++ b/site/src/i18n/en/common.json @@ -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" } } From 5c517d2795e49da948f55d2860595f5e31bae6ef Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 14:04:32 +0000 Subject: [PATCH 06/13] added color scheme --- .../WarningAlert/WarningAlert.stories.tsx | 3 ++ .../components/WarningAlert/WarningAlert.tsx | 34 ++++++++++++++----- site/src/components/Workspace/Workspace.tsx | 6 +++- .../WorkspaceDeletedBanner.tsx | 9 +++++ .../WorkspaceScheduleBanner.tsx | 1 + 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/site/src/components/WarningAlert/WarningAlert.stories.tsx b/site/src/components/WarningAlert/WarningAlert.stories.tsx index dc8eed293441e..dbd7efa152de3 100644 --- a/site/src/components/WarningAlert/WarningAlert.stories.tsx +++ b/site/src/components/WarningAlert/WarningAlert.stories.tsx @@ -13,6 +13,7 @@ export const ExampleWithDismiss = Template.bind({}) ExampleWithDismiss.args = { text: "This is a warning", dismissible: true, + severity: "warning", } const ExampleAction = ( @@ -25,6 +26,7 @@ export const ExampleWithAction = Template.bind({}) ExampleWithAction.args = { text: "This is a warning", actions: [ExampleAction], + severity: "warning", } export const ExampleWithActionAndDismiss = Template.bind({}) @@ -32,4 +34,5 @@ ExampleWithActionAndDismiss.args = { text: "This is a warning", actions: [ExampleAction], dismissible: true, + severity: "warning", } diff --git a/site/src/components/WarningAlert/WarningAlert.tsx b/site/src/components/WarningAlert/WarningAlert.tsx index 7b0a024927913..ac01998f33b68 100644 --- a/site/src/components/WarningAlert/WarningAlert.tsx +++ b/site/src/components/WarningAlert/WarningAlert.tsx @@ -6,21 +6,37 @@ import { colors } from "theme/colors" import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined" import Button from "@material-ui/core/Button" import { useTranslation } from "react-i18next" +import ErrorOutlineOutlinedIcon from "@material-ui/icons/ErrorOutlineOutlined" + +type Severity = "warning" | "error" export interface WarningAlertProps { text: string + severity: Severity dismissible?: boolean actions?: ReactElement[] } +const severityConstants: Record = { + warning: { + color: colors.orange[7], + icon: , + }, + error: { + color: colors.red[7], + icon: , + }, +} + export const WarningAlert: FC = ({ text, + severity, dismissible = false, actions = [], }) => { const { t } = useTranslation("common") const [open, setOpen] = useState(true) - const classes = useStyles() + const classes = useStyles({ severity }) return ( @@ -32,7 +48,7 @@ export const WarningAlert: FC = ({ justifyContent="space-between" > - + {severityConstants[severity].icon} {text} @@ -48,14 +64,16 @@ export const WarningAlert: FC = ({ ) } -const useStyles = makeStyles((theme) => ({ - alertContainer: { +interface StyleProps { + severity: Severity +} + +const useStyles = makeStyles((theme) => ({ + alertContainer: (props) => ({ + borderColor: severityConstants[props.severity].color, 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]}`, - }, + }), })) diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 945258a836467..40e1e31579356 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -87,7 +87,11 @@ export const Workspace: FC> = ({ ) const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && ( - + ) return ( diff --git a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx index c398047ee96fc..f1f7f9f782dd0 100644 --- a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx +++ b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx @@ -26,10 +26,19 @@ export const WorkspaceDeletedBanner: FC ) + // return ( + // + // ) + return ( ) } diff --git a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx index 2ff5ca57096e1..01606dd00eb75 100644 --- a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx +++ b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx @@ -47,6 +47,7 @@ export const WorkspaceScheduleBanner: FC ) } From 06b5fbd5ddb924cd82c8a45444a37a3643acaafa Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 18:32:46 +0000 Subject: [PATCH 07/13] updated expander component --- site/src/components/Expander/Expander.tsx | 63 ++++++++++++------- .../LicenseBanner/LicenseBannerView.tsx | 20 +++--- .../components/WarningAlert/WarningAlert.tsx | 32 +++++++++- .../WorkspaceDeletedBanner.tsx | 13 ++++ site/src/i18n/en/common.json | 4 +- 5 files changed, 96 insertions(+), 36 deletions(-) diff --git a/site/src/components/Expander/Expander.tsx b/site/src/components/Expander/Expander.tsx index c11a180088382..78dfdeaa97e73 100644 --- a/site/src/components/Expander/Expander.tsx +++ b/site/src/components/Expander/Expander.tsx @@ -1,45 +1,66 @@ import Link from "@material-ui/core/Link" import makeStyles from "@material-ui/core/styles/makeStyles" import { CloseDropdown, OpenDropdown } from "components/DropdownArrows/DropdownArrows" - -const Language = { - expand: "More", - collapse: "Less", -} +import { PropsWithChildren, FC } from "react" +import Collapse from "@material-ui/core/Collapse" +import { useTranslation } from "react-i18next" +import { combineClasses } from "util/combineClasses" export interface ExpanderProps { expanded: boolean setExpanded: (val: boolean) => void } -export const Expander: React.FC = ({ expanded, setExpanded }) => { - const toggleExpanded = () => setExpanded(!expanded) +export const Expander: FC> = ({ + expanded, + setExpanded, + children, +}) => { const styles = useStyles() + const { t } = useTranslation("common") + + const toggleExpanded = () => setExpanded(!expanded) + return ( - - {expanded ? ( - - {Language.collapse} - {" "} - - ) : ( - - {Language.expand} - - + <> + {!expanded && ( + + + {t("ctas.expand")} + + + + )} + +
{children}
+
+ {expanded && ( + + + {t("ctas.collapse")} + + + )} - + ) } const useStyles = makeStyles((theme) => ({ expandLink: { cursor: "pointer", - color: theme.palette.text.primary, - display: "flex", + color: theme.palette.text.secondary, + }, + collapseLink: { + marginTop: `${theme.spacing(2)}px`, }, text: { display: "flex", alignItems: "center", + color: theme.palette.text.secondary, + fontSize: theme.typography.caption.fontSize, }, })) diff --git a/site/src/components/LicenseBanner/LicenseBannerView.tsx b/site/src/components/LicenseBanner/LicenseBannerView.tsx index 5d63d23bedb67..bb10cd2b85a0b 100644 --- a/site/src/components/LicenseBanner/LicenseBannerView.tsx +++ b/site/src/components/LicenseBanner/LicenseBannerView.tsx @@ -1,4 +1,3 @@ -import Collapse from "@material-ui/core/Collapse" import { makeStyles } from "@material-ui/core/styles" import { Expander } from "components/Expander/Expander" import { Pill } from "components/Pill/Pill" @@ -43,17 +42,16 @@ export const LicenseBannerView: React.FC = ({ warnings } {Language.upgrade} - + +
    + {warnings.map((warning) => ( +
  • + {warning} +
  • + ))} +
+
- -
    - {warnings.map((warning) => ( -
  • - {warning} -
  • - ))} -
-
) } diff --git a/site/src/components/WarningAlert/WarningAlert.tsx b/site/src/components/WarningAlert/WarningAlert.tsx index ac01998f33b68..b0981551693e4 100644 --- a/site/src/components/WarningAlert/WarningAlert.tsx +++ b/site/src/components/WarningAlert/WarningAlert.tsx @@ -7,12 +7,15 @@ import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined" import Button from "@material-ui/core/Button" import { useTranslation } from "react-i18next" import ErrorOutlineOutlinedIcon from "@material-ui/icons/ErrorOutlineOutlined" +import { ApiError, getErrorDetail, getErrorMessage } from "api/errors" +import { Expander } from "components/Expander/Expander" type Severity = "warning" | "error" export interface WarningAlertProps { text: string severity: Severity + error?: ApiError | Error | unknown dismissible?: boolean actions?: ReactElement[] } @@ -24,20 +27,35 @@ const severityConstants: Record }, error: { color: colors.red[7], - icon: , + icon: ( + + ), }, } export const WarningAlert: FC = ({ text, severity, + error, dismissible = false, actions = [], }) => { const { t } = useTranslation("common") - const [open, setOpen] = useState(true) const classes = useStyles({ severity }) + const [open, setOpen] = useState(true) + + // if an error is passed in, display that error, otherwise + // display the text passed in, e.g. warning text + const alertMessage = getErrorMessage(error, text) + + // if we have an error, check if there's detail to display + const detail = error ? getErrorDetail(error) : undefined + const [showDetails, setShowDetails] = useState(false) + return ( = ({ > {severityConstants[severity].icon} - {text} + + {alertMessage} + {detail && ( + +
{detail}
+
+ )} +
+ {actions.length > 0 && actions.map((action) =>
{action}
)} {dismissible && ( diff --git a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx index f1f7f9f782dd0..22a8725c156ce 100644 --- a/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx +++ b/site/src/components/WorkspaceDeletedBanner/WorkspaceDeletedBanner.tsx @@ -4,6 +4,7 @@ import * as TypesGen from "../../api/typesGenerated" import { isWorkspaceDeleted } from "../../util/workspace" import { WarningAlert } from "components/WarningAlert/WarningAlert" import { useTranslation } from "react-i18next" +import { makeMockApiError } from "testHelpers/entities" export interface WorkspaceDeletedBannerProps { workspace: TypesGen.Workspace @@ -34,11 +35,23 @@ export const WorkspaceDeletedBanner: FC // ) + const error = makeMockApiError({ + message: "Email or password was invalid", + detail: "you screwd up", + validations: [ + { + field: "password", + detail: "Password is invalid.", + }, + ], + }) + return ( ) } diff --git a/site/src/i18n/en/common.json b/site/src/i18n/en/common.json index 99dda7c9e541d..362168760ddc7 100644 --- a/site/src/i18n/en/common.json +++ b/site/src/i18n/en/common.json @@ -20,6 +20,8 @@ "incorrectName": "Incorrect {{entity}} name." }, "ctas": { - "dismissCta": "Dismiss" + "dismissCta": "Dismiss", + "expand": "Click here to learn more", + "collapse": "Click here to hide" } } From 44b2748fe3420f31fde1f1475dd11f37a05f794f Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 19:20:34 +0000 Subject: [PATCH 08/13] cleanup --- .../AlertBanner/AlertBanner.stories.tsx | 101 ++++++++++++++++++ .../AlertBanner.tsx} | 76 ++++++------- .../AlertBanner/AlertBannerCtas.tsx | 42 ++++++++ site/src/components/AlertBanner/alertTypes.ts | 13 +++ .../AlertBanner/severityConstants.tsx | 16 +++ .../WarningAlert/WarningAlert.stories.tsx | 38 ------- site/src/components/Workspace/Workspace.tsx | 4 +- .../WorkspaceDeletedBanner.tsx | 27 +---- .../WorkspaceScheduleBanner.tsx | 4 +- site/src/i18n/en/common.json | 6 +- 10 files changed, 215 insertions(+), 112 deletions(-) create mode 100644 site/src/components/AlertBanner/AlertBanner.stories.tsx rename site/src/components/{WarningAlert/WarningAlert.tsx => AlertBanner/AlertBanner.tsx} (53%) create mode 100644 site/src/components/AlertBanner/AlertBannerCtas.tsx create mode 100644 site/src/components/AlertBanner/alertTypes.ts create mode 100644 site/src/components/AlertBanner/severityConstants.tsx delete mode 100644 site/src/components/WarningAlert/WarningAlert.stories.tsx diff --git a/site/src/components/AlertBanner/AlertBanner.stories.tsx b/site/src/components/AlertBanner/AlertBanner.stories.tsx new file mode 100644 index 0000000000000..d426d97393cd6 --- /dev/null +++ b/site/src/components/AlertBanner/AlertBanner.stories.tsx @@ -0,0 +1,101 @@ +import { Story } from "@storybook/react" +import { AlertBanner, AlertBannerProps } from "./AlertBanner" +import Button from "@material-ui/core/Button" +import { makeMockApiError } from "testHelpers/entities" + +export default { + title: "components/AlertBanner", + component: AlertBanner, +} + +const ExampleAction = ( + +) + +const mockError = makeMockApiError({ + message: "Email or password was invalid", + detail: "Password is invalid", +}) + +const Template: Story = (args) => + +export const Warning = Template.bind({}) +Warning.args = { + text: "This is a warning", + severity: "warning", +} + +export const ErrorWithDefaultMessage = Template.bind({}) +ErrorWithDefaultMessage.args = { + text: "This is an error", + severity: "error", +} + +export const ErrorWithErrorMessage = Template.bind({}) +ErrorWithErrorMessage.args = { + error: mockError, + severity: "error", +} + +export const WarningWithDismiss = Template.bind({}) +WarningWithDismiss.args = { + text: "This is a warning", + dismissible: true, + severity: "warning", +} + +export const ErrorWithDismiss = Template.bind({}) +ErrorWithDismiss.args = { + error: mockError, + dismissible: true, + severity: "error", +} + +export const WarningWithAction = Template.bind({}) +WarningWithAction.args = { + text: "This is a warning", + actions: [ExampleAction], + severity: "warning", +} + +export const ErrorWithAction = Template.bind({}) +ErrorWithAction.args = { + error: mockError, + actions: [ExampleAction], + severity: "error", +} + +export const WarningWithActionAndDismiss = Template.bind({}) +WarningWithActionAndDismiss.args = { + text: "This is a warning", + actions: [ExampleAction], + dismissible: true, + severity: "warning", +} + +export const ErrorWithActionAndDismiss = Template.bind({}) +ErrorWithActionAndDismiss.args = { + error: mockError, + actions: [ExampleAction], + dismissible: true, + severity: "error", +} + +export const ErrorWithRetry = Template.bind({}) +ErrorWithRetry.args = { + error: mockError, + retry: () => null, + dismissible: true, + severity: "error", +} + +export const ErrorWithActionRetryAndDismiss = Template.bind({}) +ErrorWithActionRetryAndDismiss.args = { + error: mockError, + actions: [ExampleAction], + retry: () => null, + dismissible: true, + severity: "error", +} diff --git a/site/src/components/WarningAlert/WarningAlert.tsx b/site/src/components/AlertBanner/AlertBanner.tsx similarity index 53% rename from site/src/components/WarningAlert/WarningAlert.tsx rename to site/src/components/AlertBanner/AlertBanner.tsx index b0981551693e4..21a788084bcbe 100644 --- a/site/src/components/WarningAlert/WarningAlert.tsx +++ b/site/src/components/AlertBanner/AlertBanner.tsx @@ -1,59 +1,43 @@ -import { useState, FC, ReactElement } from "react" +import { useState, FC } 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" -import ErrorOutlineOutlinedIcon from "@material-ui/icons/ErrorOutlineOutlined" -import { ApiError, getErrorDetail, getErrorMessage } from "api/errors" +import { getErrorDetail, getErrorMessage } from "api/errors" import { Expander } from "components/Expander/Expander" +import { Severity, AlertBannerProps } from "./alertTypes" +import { severityConstants } from "./severityConstants" +import { AlertBannerCtas } from "./AlertBannerCtas" -type Severity = "warning" | "error" - -export interface WarningAlertProps { - text: string - severity: Severity - error?: ApiError | Error | unknown - dismissible?: boolean - actions?: ReactElement[] -} - -const severityConstants: Record = { - warning: { - color: colors.orange[7], - icon: , - }, - error: { - color: colors.red[7], - icon: ( - - ), - }, -} - -export const WarningAlert: FC = ({ - text, +/** + * severity: the level of alert severity (see ./severityTypes.ts) + * text: default text to be displayed to the user; useful for warnings or as a fallback error message + * error: should be passed in if the severity is 'Error'; warnings can use 'text' instead + * actions: an array of CTAs passed in by the consumer + * dismissible: determines whether or not the banner should have a `Dismiss` CTA + * retry: a handler to retry the action that spawned the error + */ +export const AlertBanner: FC = ({ severity, + text, error, - dismissible = false, actions = [], + retry, + dismissible = false, }) => { const { t } = useTranslation("common") - const classes = useStyles({ severity }) const [open, setOpen] = useState(true) // if an error is passed in, display that error, otherwise // display the text passed in, e.g. warning text - const alertMessage = getErrorMessage(error, text) + const alertMessage = getErrorMessage(error, text ?? t("warningsAndErrors.somethingWentWrong")) // if we have an error, check if there's detail to display const detail = error ? getErrorDetail(error) : undefined + const classes = useStyles({ severity, hasDetail: Boolean(detail) }) + const [showDetails, setShowDetails] = useState(false) return ( @@ -66,7 +50,7 @@ export const WarningAlert: FC = ({ justifyContent="space-between" > - {severityConstants[severity].icon} +
{severityConstants[severity].icon}
{alertMessage} {detail && ( @@ -77,14 +61,12 @@ export const WarningAlert: FC = ({
- - {actions.length > 0 && actions.map((action) =>
{action}
)} - {dismissible && ( - - )} -
+
) @@ -92,6 +74,7 @@ export const WarningAlert: FC = ({ interface StyleProps { severity: Severity + hasDetail: boolean } const useStyles = makeStyles((theme) => ({ @@ -102,4 +85,7 @@ const useStyles = makeStyles((theme) => ({ padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`, backgroundColor: `${colors.gray[16]}`, }), + iconContainer: (props) => ({ + marginTop: props.hasDetail ? "8px" : "unset", + }), })) diff --git a/site/src/components/AlertBanner/AlertBannerCtas.tsx b/site/src/components/AlertBanner/AlertBannerCtas.tsx new file mode 100644 index 0000000000000..4516bfac75c2f --- /dev/null +++ b/site/src/components/AlertBanner/AlertBannerCtas.tsx @@ -0,0 +1,42 @@ +import { FC } from "react" +import { AlertBannerProps } from "./alertTypes" +import { Stack } from "components/Stack/Stack" +import Button from "@material-ui/core/Button" +import RefreshIcon from "@material-ui/icons/Refresh" +import { useTranslation } from "react-i18next" + +type AlertBannerCtasProps = Pick & { + setOpen: (arg0: boolean) => void +} + +export const AlertBannerCtas: FC = ({ + actions = [], + dismissible, + retry, + setOpen, +}) => { + const { t } = useTranslation("common") + + return ( + + {/* CTAs passed in by the consumer */} + {actions.length > 0 && actions.map((action) =>
{action}
)} + + {/* retry CTA */} + {retry && ( +
+ +
+ )} + + {/* close CTA */} + {dismissible && ( + + )} +
+ ) +} diff --git a/site/src/components/AlertBanner/alertTypes.ts b/site/src/components/AlertBanner/alertTypes.ts new file mode 100644 index 0000000000000..de23548b0ba63 --- /dev/null +++ b/site/src/components/AlertBanner/alertTypes.ts @@ -0,0 +1,13 @@ +import { ApiError } from "api/errors" +import { ReactElement } from 'react' + +export type Severity = "warning" | "error" + +export interface AlertBannerProps { + severity: Severity + text?: string + error?: ApiError | Error | unknown + actions?: ReactElement[] + dismissible?: boolean + retry?: () => void +} diff --git a/site/src/components/AlertBanner/severityConstants.tsx b/site/src/components/AlertBanner/severityConstants.tsx new file mode 100644 index 0000000000000..832b851047487 --- /dev/null +++ b/site/src/components/AlertBanner/severityConstants.tsx @@ -0,0 +1,16 @@ +import ReportProblemOutlinedIcon from "@material-ui/icons/ReportProblemOutlined" +import ErrorOutlineOutlinedIcon from "@material-ui/icons/ErrorOutlineOutlined" +import { colors } from "theme/colors" +import { Severity } from "./alertTypes" +import { ReactElement } from "react" + +export const severityConstants: Record = { + warning: { + color: colors.orange[7], + icon: , + }, + error: { + color: colors.red[7], + icon: , + }, +} diff --git a/site/src/components/WarningAlert/WarningAlert.stories.tsx b/site/src/components/WarningAlert/WarningAlert.stories.tsx deleted file mode 100644 index dbd7efa152de3..0000000000000 --- a/site/src/components/WarningAlert/WarningAlert.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -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 = (args) => - -export const ExampleWithDismiss = Template.bind({}) -ExampleWithDismiss.args = { - text: "This is a warning", - dismissible: true, - severity: "warning", -} - -const ExampleAction = ( - -) - -export const ExampleWithAction = Template.bind({}) -ExampleWithAction.args = { - text: "This is a warning", - actions: [ExampleAction], - severity: "warning", -} - -export const ExampleWithActionAndDismiss = Template.bind({}) -ExampleWithActionAndDismiss.args = { - text: "This is a warning", - actions: [ExampleAction], - dismissible: true, - severity: "warning", -} diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 40e1e31579356..58489f005b1cc 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -15,7 +15,7 @@ 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 { AlertBanner } from "../AlertBanner/AlertBanner" import { useTranslation } from "react-i18next" export enum WorkspaceErrors { @@ -87,7 +87,7 @@ export const Workspace: FC> = ({ ) const workspaceRefreshWarning = Boolean(workspaceErrors[WorkspaceErrors.GET_RESOURCES_ERROR]) && ( - ) - // return ( - // - // ) - - const error = makeMockApiError({ - message: "Email or password was invalid", - detail: "you screwd up", - validations: [ - { - field: "password", - detail: "Password is invalid.", - }, - ], - }) - return ( - ) } diff --git a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx index 01606dd00eb75..f0827aa7b9f0b 100644 --- a/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx +++ b/site/src/components/WorkspaceScheduleBanner/WorkspaceScheduleBanner.tsx @@ -5,7 +5,7 @@ import utc from "dayjs/plugin/utc" import { FC } from "react" import * as TypesGen from "api/typesGenerated" import { isWorkspaceOn } from "util/workspace" -import { WarningAlert } from "components/WarningAlert/WarningAlert" +import { AlertBanner } from "components/AlertBanner/AlertBanner" import { useTranslation } from "react-i18next" dayjs.extend(utc) @@ -44,7 +44,7 @@ export const WorkspaceScheduleBanner: FC Date: Thu, 6 Oct 2022 19:33:56 +0000 Subject: [PATCH 09/13] fixed tests --- .../components/ErrorSummary/ErrorSummary.test.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/site/src/components/ErrorSummary/ErrorSummary.test.tsx b/site/src/components/ErrorSummary/ErrorSummary.test.tsx index a6d222e0e3860..1fda20d683fd9 100644 --- a/site/src/components/ErrorSummary/ErrorSummary.test.tsx +++ b/site/src/components/ErrorSummary/ErrorSummary.test.tsx @@ -1,5 +1,8 @@ import { fireEvent, render, screen } from "@testing-library/react" import { ErrorSummary } from "./ErrorSummary" +import { i18n } from "i18n" + +const { t } = i18n describe("ErrorSummary", () => { it("renders", async () => { @@ -26,7 +29,8 @@ describe("ErrorSummary", () => { render() // Then - fireEvent.click(screen.getByText("More")) + const expandText = t("ctas.expand", { ns: "common" }) + fireEvent.click(screen.getByText(expandText)) const element = await screen.findByText( "The resource you requested does not exist in the database.", { exact: false }, @@ -48,8 +52,11 @@ describe("ErrorSummary", () => { render() // Then - fireEvent.click(screen.getByText("More")) - fireEvent.click(screen.getByText("Less")) + const expandText = t("ctas.expand", { ns: "common" }) + const collapseText = t("ctas.collapse", { ns: "common" }) + + fireEvent.click(screen.getByText(expandText)) + fireEvent.click(screen.getByText(collapseText)) const element = await screen.findByText( "The resource you requested does not exist in the database.", { exact: false }, From f0175da368a9a92b7a503f9ebd4aaff87455e309 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 19:55:44 +0000 Subject: [PATCH 10/13] fixed height issue --- site/src/components/AlertBanner/AlertBanner.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site/src/components/AlertBanner/AlertBanner.tsx b/site/src/components/AlertBanner/AlertBanner.tsx index 21a788084bcbe..b777e212a747f 100644 --- a/site/src/components/AlertBanner/AlertBanner.tsx +++ b/site/src/components/AlertBanner/AlertBanner.tsx @@ -50,7 +50,7 @@ export const AlertBanner: FC = ({ justifyContent="space-between" > -
{severityConstants[severity].icon}
+ {severityConstants[severity].icon} {alertMessage} {detail && ( @@ -84,8 +84,9 @@ const useStyles = makeStyles((theme) => ({ borderRadius: theme.shape.borderRadius, padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`, backgroundColor: `${colors.gray[16]}`, - }), - iconContainer: (props) => ({ - marginTop: props.hasDetail ? "8px" : "unset", + + "& svg": { + marginTop: props.hasDetail ? "8px" : "inherit", + }, }), })) From d115771bc8bce34730f70b354fafed2a384432bd Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 20:17:01 +0000 Subject: [PATCH 11/13] prettier --- site/src/components/AlertBanner/alertTypes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/AlertBanner/alertTypes.ts b/site/src/components/AlertBanner/alertTypes.ts index de23548b0ba63..154c2c9a2cdab 100644 --- a/site/src/components/AlertBanner/alertTypes.ts +++ b/site/src/components/AlertBanner/alertTypes.ts @@ -1,5 +1,5 @@ import { ApiError } from "api/errors" -import { ReactElement } from 'react' +import { ReactElement } from "react" export type Severity = "warning" | "error" From 7da9dc6a69a13e71e43f076fa129bd35883461dc Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Thu, 6 Oct 2022 20:24:12 +0000 Subject: [PATCH 12/13] use theme constants --- site/src/components/AlertBanner/AlertBanner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/AlertBanner/AlertBanner.tsx b/site/src/components/AlertBanner/AlertBanner.tsx index b777e212a747f..3e8282d7ef1c9 100644 --- a/site/src/components/AlertBanner/AlertBanner.tsx +++ b/site/src/components/AlertBanner/AlertBanner.tsx @@ -86,7 +86,7 @@ const useStyles = makeStyles((theme) => ({ backgroundColor: `${colors.gray[16]}`, "& svg": { - marginTop: props.hasDetail ? "8px" : "inherit", + marginTop: props.hasDetail ? `${theme.spacing(1)}px` : "inherit", }, }), })) From f6356b356b19f46560dda3f22fbc919d6d9ce8c4 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Fri, 7 Oct 2022 14:21:08 +0000 Subject: [PATCH 13/13] increased icon margin --- site/src/components/AlertBanner/AlertBanner.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/site/src/components/AlertBanner/AlertBanner.tsx b/site/src/components/AlertBanner/AlertBanner.tsx index 3e8282d7ef1c9..9df5a92ae161a 100644 --- a/site/src/components/AlertBanner/AlertBanner.tsx +++ b/site/src/components/AlertBanner/AlertBanner.tsx @@ -49,7 +49,7 @@ export const AlertBanner: FC = ({ spacing={0} justifyContent="space-between" > - + {severityConstants[severity].icon} {alertMessage} @@ -87,6 +87,7 @@ const useStyles = makeStyles((theme) => ({ "& svg": { marginTop: props.hasDetail ? `${theme.spacing(1)}px` : "inherit", + marginRight: `${theme.spacing(1)}px`, }, }), }))