From ddd39cec72dd23f91281f405ee8b52bdec15c923 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 5 May 2023 13:50:20 +0000 Subject: [PATCH 1/3] Fix using flex --- .../PageHeader/FullWidthPageHeader.tsx | 52 ++++ site/src/components/Stats/Stats.tsx | 25 +- site/src/components/Workspace/Workspace.tsx | 230 +++++++++--------- .../components/WorkspaceActions/Buttons.tsx | 24 +- .../WorkspaceActions/WorkspaceActions.tsx | 11 +- .../WorkspaceStats/WorkspaceStats.tsx | 30 ++- .../WorkspaceStatusBadge.tsx | 46 ++++ 7 files changed, 269 insertions(+), 149 deletions(-) create mode 100644 site/src/components/PageHeader/FullWidthPageHeader.tsx diff --git a/site/src/components/PageHeader/FullWidthPageHeader.tsx b/site/src/components/PageHeader/FullWidthPageHeader.tsx new file mode 100644 index 0000000000000..72a34fb53fb8b --- /dev/null +++ b/site/src/components/PageHeader/FullWidthPageHeader.tsx @@ -0,0 +1,52 @@ +import { makeStyles } from "@material-ui/core/styles" +import { FC, PropsWithChildren } from "react" + +export const FullWidthPageHeader: FC = ({ children }) => { + const styles = useStyles() + + return
{children}
+} + +export const PageHeaderActions: FC = ({ children }) => { + const styles = useStyles() + return
{children}
+} + +export const PageHeaderTitle: FC = ({ children }) => { + const styles = useStyles() + return

{children}

+} + +export const PageHeaderSubtitle: FC = ({ children }) => { + const styles = useStyles() + return {children} +} + +const useStyles = makeStyles((theme) => ({ + header: { + padding: theme.spacing(3), + background: theme.palette.background.paper, + borderBottom: `1px solid ${theme.palette.divider}`, + display: "flex", + alignItems: "center", + gap: theme.spacing(6), + position: "sticky", + top: 0, + zIndex: 10, + flexWrap: "wrap", + }, + actions: { + marginLeft: "auto", + }, + title: { + fontSize: 18, + fontWeight: 500, + margin: 0, + }, + subtitle: { + fontSize: 14, + color: theme.palette.text.secondary, + marginTop: theme.spacing(0.25), + display: "block", + }, +})) diff --git a/site/src/components/Stats/Stats.tsx b/site/src/components/Stats/Stats.tsx index 0b2880979876c..5b8e57da74c4b 100644 --- a/site/src/components/Stats/Stats.tsx +++ b/site/src/components/Stats/Stats.tsx @@ -1,19 +1,30 @@ import { makeStyles } from "@material-ui/core/styles" import { ComponentProps, FC, PropsWithChildren } from "react" +import { combineClasses } from "utils/combineClasses" -export const Stats: FC>> = (props) => { +export const Stats: FC> = (props) => { const styles = useStyles() - return
+ return ( +
+ ) } -export const StatsItem: FC<{ - label: string - value: string | number | JSX.Element -}> = ({ label, value }) => { +export const StatsItem: FC< + { + label: string + value: string | number | JSX.Element + } & ComponentProps<"div"> +> = ({ label, value, ...divProps }) => { const styles = useStyles() return ( -
+
{label}: {value}
diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index 69a61d29ebedc..8a1db80814baf 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -8,7 +8,6 @@ import { ActiveTransition, WorkspaceBuildProgress, } from "components/WorkspaceBuildProgress/WorkspaceBuildProgress" -import { WorkspaceStatusBadge } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge" import { FC } from "react" import { useTranslation } from "react-i18next" import { useNavigate } from "react-router-dom" @@ -16,16 +15,17 @@ import * as TypesGen from "../../api/typesGenerated" import { AlertBanner } from "../AlertBanner/AlertBanner" import { BuildsTable } from "../BuildsTable/BuildsTable" import { Margins } from "../Margins/Margins" -import { - PageHeader, - PageHeaderSubtitle, - PageHeaderTitle, -} from "../PageHeader/PageHeader" import { Resources } from "../Resources/Resources" import { Stack } from "../Stack/Stack" import { WorkspaceActions } from "../WorkspaceActions/WorkspaceActions" import { WorkspaceDeletedBanner } from "../WorkspaceDeletedBanner/WorkspaceDeletedBanner" import { WorkspaceStats } from "../WorkspaceStats/WorkspaceStats" +import { + FullWidthPageHeader, + PageHeaderActions, + PageHeaderTitle, + PageHeaderSubtitle, +} from "components/PageHeader/FullWidthPageHeader" export enum WorkspaceErrors { GET_BUILDS_ERROR = "getBuildsError", @@ -125,31 +125,11 @@ export const Workspace: FC> = ({ transitionStats = ActiveTransition(template, workspace) } return ( - - - - - } - > + <> + > = ({ {workspace.name}
- - {workspace.name} - - - - {workspace.owner_name} - + {workspace.name} + {workspace.owner_name}
-
- - - {buildError} - {cancellationError} - - navigate(`/templates`)} - /> > = ({ onDeadlinePlus={scheduleProps.onDeadlinePlus} /> - {failedBuildLogs && ( - - - - - Workspace build failed - - {workspace.latest_build.job.error} - - + + + + - {canUpdateTemplate && ( -
- -
- )} -
-
- -
- )} + + + {buildError} + {cancellationError} - {transitionStats !== undefined && ( - navigate(`/templates`)} /> - )} - {typeof resources !== "undefined" && resources.length > 0 && ( - ( - - )} - /> - )} + {failedBuildLogs && ( + + + + + Workspace build failed + + {workspace.latest_build.job.error} + + - {workspaceErrors[WorkspaceErrors.GET_BUILDS_ERROR] ? ( - - ) : ( - - )} - - + {canUpdateTemplate && ( +
+ +
+ )} +
+ + + + )} + + {transitionStats !== undefined && ( + + )} + + {typeof resources !== "undefined" && resources.length > 0 && ( + ( + + )} + /> + )} + + {workspaceErrors[WorkspaceErrors.GET_BUILDS_ERROR] ? ( + + ) : ( + + )} + +
+ ) } @@ -272,6 +264,10 @@ const spacerWidth = 300 export const useStyles = makeStyles((theme) => { return { + content: { + marginTop: theme.spacing(4), + }, + statusBadge: { marginLeft: theme.spacing(2), }, diff --git a/site/src/components/WorkspaceActions/Buttons.tsx b/site/src/components/WorkspaceActions/Buttons.tsx index 19fc2d96a0d06..d17465271a394 100644 --- a/site/src/components/WorkspaceActions/Buttons.tsx +++ b/site/src/components/WorkspaceActions/Buttons.tsx @@ -7,7 +7,6 @@ import ReplayIcon from "@material-ui/icons/Replay" import { LoadingButton } from "components/LoadingButton/LoadingButton" import { FC, PropsWithChildren } from "react" import { useTranslation } from "react-i18next" -import { makeStyles } from "@material-ui/core/styles" interface WorkspaceAction { handleAction: () => void @@ -17,15 +16,14 @@ export const UpdateButton: FC> = ({ handleAction, }) => { const { t } = useTranslation("workspacePage") - const styles = useStyles() return ( @@ -36,14 +34,12 @@ export const StartButton: FC> = ({ handleAction, }) => { const { t } = useTranslation("workspacePage") - const styles = useStyles() return ( @@ -54,14 +50,13 @@ export const StopButton: FC> = ({ handleAction, }) => { const { t } = useTranslation("workspacePage") - const styles = useStyles() return ( @@ -72,14 +67,13 @@ export const RestartButton: FC> = ({ handleAction, }) => { const { t } = useTranslation("workspacePage") - const styles = useStyles() return ( @@ -104,7 +98,7 @@ export const DisabledButton: FC> = ({ label, }) => { return ( - ) @@ -117,20 +111,12 @@ interface LoadingProps { export const ActionLoadingButton: FC> = ({ label, }) => { - const styles = useStyles() return ( ) } - -const useStyles = makeStyles((theme) => ({ - fixedWidth: { - // Make it fixed so the loading changes will not "flick" the UI - width: theme.spacing(16), - }, -})) diff --git a/site/src/components/WorkspaceActions/WorkspaceActions.tsx b/site/src/components/WorkspaceActions/WorkspaceActions.tsx index aacf1f10f085e..7f72339216244 100644 --- a/site/src/components/WorkspaceActions/WorkspaceActions.tsx +++ b/site/src/components/WorkspaceActions/WorkspaceActions.tsx @@ -1,5 +1,4 @@ import MenuItem from "@material-ui/core/MenuItem" -import Button from "@material-ui/core/Button" import Menu from "@material-ui/core/Menu" import { makeStyles } from "@material-ui/core/styles" import MoreVertOutlined from "@material-ui/icons/MoreVertOutlined" @@ -23,6 +22,7 @@ import { import SettingsOutlined from "@material-ui/icons/SettingsOutlined" import HistoryOutlined from "@material-ui/icons/HistoryOutlined" import DeleteOutlined from "@material-ui/icons/DeleteOutlined" +import IconButton from "@material-ui/core/IconButton" export interface WorkspaceActionsProps { workspaceStatus: WorkspaceStatus @@ -148,17 +148,18 @@ export const WorkspaceActions: FC = ({ ))} {canCancel && }
- + ({ actions: { display: "flex", alignItems: "center", - gap: theme.spacing(2), + gap: theme.spacing(1.5), }, })) diff --git a/site/src/components/WorkspaceStats/WorkspaceStats.tsx b/site/src/components/WorkspaceStats/WorkspaceStats.tsx index 42843891e7a0a..948f9d8c65bfa 100644 --- a/site/src/components/WorkspaceStats/WorkspaceStats.tsx +++ b/site/src/components/WorkspaceStats/WorkspaceStats.tsx @@ -19,6 +19,7 @@ import AddIcon from "@material-ui/icons/AddOutlined" import Popover from "@material-ui/core/Popover" import TextField from "@material-ui/core/TextField" import Button from "@material-ui/core/Button" +import { WorkspaceStatusText } from "components/WorkspaceStatusBadge/WorkspaceStatusBadge" const Language = { workspaceDetails: "Workspace Details", @@ -67,8 +68,14 @@ export const WorkspaceStats: FC = ({ return ( <> - + } + /> + = ({ } /> @@ -100,6 +108,7 @@ export const WorkspaceStats: FC = ({ } /> @@ -110,6 +119,7 @@ export const WorkspaceStats: FC = ({ /> {shouldDisplayScheduleLabel(workspace) && ( @@ -152,6 +162,7 @@ export const WorkspaceStats: FC = ({ )} {workspace.latest_build.daily_cost > 0 && ( { } const useStyles = makeStyles((theme) => ({ + stats: { + padding: 0, + border: 0, + gap: theme.spacing(6), + }, + + statsItem: { + flexDirection: "column", + gap: 0, + padding: 0, + + "& > span:first-child": { + fontSize: 12, + fontWeight: 500, + }, + }, + scheduleValue: { display: "flex", alignItems: "center", diff --git a/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx b/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx index 0a23ac7409bfa..a37b10a07a412 100644 --- a/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx +++ b/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx @@ -8,6 +8,8 @@ import { Pill } from "components/Pill/Pill" import i18next from "i18next" import { FC, ReactNode, PropsWithChildren } from "react" import { PaletteIndex } from "theme/palettes" +import { makeStyles } from "@material-ui/core/styles" +import { combineClasses } from "utils/combineClasses" const LoadingIcon: FC = () => { return @@ -102,3 +104,47 @@ export const WorkspaceStatusBadge: FC< const { text, icon, type } = getStatus(build.status) return } + +export const WorkspaceStatusText: FC< + PropsWithChildren +> = ({ build, className }) => { + const styles = useStyles() + const { text, type } = getStatus(build.status) + return ( + + {text} + + ) +} + +const useStyles = makeStyles((theme) => ({ + root: { fontWeight: 600 }, + "type-error": { + color: theme.palette.error.light, + }, + "type-warning": { + color: theme.palette.warning.light, + }, + "type-success": { + color: theme.palette.success.light, + }, + "type-info": { + color: theme.palette.info.light, + }, + "type-undefined": { + color: theme.palette.text.secondary, + }, + "type-primary": { + color: theme.palette.text.primary, + }, + "type-secondary": { + color: theme.palette.text.secondary, + }, +})) From dceae5f8a739d0cb487e3325786efaea4b10beb8 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 5 May 2023 14:01:59 +0000 Subject: [PATCH 2/3] Fix mobile --- .../src/components/PageHeader/FullWidthPageHeader.tsx | 11 +++++++++++ site/src/components/WorkspaceStats/WorkspaceStats.tsx | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/site/src/components/PageHeader/FullWidthPageHeader.tsx b/site/src/components/PageHeader/FullWidthPageHeader.tsx index 72a34fb53fb8b..4b00e9f0d37c1 100644 --- a/site/src/components/PageHeader/FullWidthPageHeader.tsx +++ b/site/src/components/PageHeader/FullWidthPageHeader.tsx @@ -34,9 +34,20 @@ const useStyles = makeStyles((theme) => ({ top: 0, zIndex: 10, flexWrap: "wrap", + + [theme.breakpoints.down("md")]: { + position: "unset", + alignItems: "flex-start", + }, + [theme.breakpoints.down("sm")]: { + flexDirection: "column", + }, }, actions: { marginLeft: "auto", + [theme.breakpoints.down("sm")]: { + marginLeft: "unset", + }, }, title: { fontSize: 18, diff --git a/site/src/components/WorkspaceStats/WorkspaceStats.tsx b/site/src/components/WorkspaceStats/WorkspaceStats.tsx index 948f9d8c65bfa..292fce8222d17 100644 --- a/site/src/components/WorkspaceStats/WorkspaceStats.tsx +++ b/site/src/components/WorkspaceStats/WorkspaceStats.tsx @@ -311,6 +311,15 @@ const useStyles = makeStyles((theme) => ({ padding: 0, border: 0, gap: theme.spacing(6), + rowGap: theme.spacing(3), + flex: 1, + + [theme.breakpoints.down("sm")]: { + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + gap: theme.spacing(1), + }, }, statsItem: { From 3cbf1ac3f42bba80117021eabf47dd9614bc9921 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 5 May 2023 14:11:50 +0000 Subject: [PATCH 3/3] Add header test id --- site/src/components/PageHeader/FullWidthPageHeader.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/site/src/components/PageHeader/FullWidthPageHeader.tsx b/site/src/components/PageHeader/FullWidthPageHeader.tsx index 4b00e9f0d37c1..fa940d184e2ea 100644 --- a/site/src/components/PageHeader/FullWidthPageHeader.tsx +++ b/site/src/components/PageHeader/FullWidthPageHeader.tsx @@ -4,7 +4,11 @@ import { FC, PropsWithChildren } from "react" export const FullWidthPageHeader: FC = ({ children }) => { const styles = useStyles() - return
{children}
+ return ( +
+ {children} +
+ ) } export const PageHeaderActions: FC = ({ children }) => {