From e7d633dcf7d0f19d48d883dde4bbf5b703c69a19 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 3 Jan 2024 19:42:26 +0000 Subject: [PATCH 01/11] WIP: Add base sidebar structure --- site/src/AppRouter.tsx | 2 +- .../src/components/FullPageLayout/Sidebar.tsx | 66 +++++++++++++ .../WorkspaceBuild/WorkspaceBuildData.tsx | 76 ++++++++++++++ .../TemplateVersionEditor.tsx | 11 +-- .../WorkspaceBuildPageView.tsx | 99 +++---------------- .../WorkspacePage/HistorySidebarContent.tsx | 44 +++++++++ .../WorkspacePage/ResourcesSidebarContent.tsx | 29 ++++++ .../pages/WorkspacePage/Workspace.stories.tsx | 2 +- site/src/pages/WorkspacePage/Workspace.tsx | 91 ++++++++++++----- .../src/pages/WorkspacePage/WorkspacePage.tsx | 22 ++--- .../WorkspacePage/WorkspaceReadyPage.tsx | 15 --- .../pages/WorkspacePage/WorkspaceTopbar.tsx | 2 +- 12 files changed, 311 insertions(+), 148 deletions(-) create mode 100644 site/src/components/FullPageLayout/Sidebar.tsx create mode 100644 site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx create mode 100644 site/src/pages/WorkspacePage/HistorySidebarContent.tsx create mode 100644 site/src/pages/WorkspacePage/ResourcesSidebarContent.tsx diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 5d19dd3b88725..d9e856484c768 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -369,7 +369,6 @@ export const AppRouter: FC = () => { {/* In order for the 404 page to work properly the routes that start with top level parameter must be fully qualified. */} - } /> } @@ -408,6 +407,7 @@ export const AppRouter: FC = () => { {/* Pages that don't have the dashboard layout */} + } /> } diff --git a/site/src/components/FullPageLayout/Sidebar.tsx b/site/src/components/FullPageLayout/Sidebar.tsx new file mode 100644 index 0000000000000..3da5718730341 --- /dev/null +++ b/site/src/components/FullPageLayout/Sidebar.tsx @@ -0,0 +1,66 @@ +import { Interpolation, Theme, useTheme } from "@mui/material/styles"; +import { HTMLAttributes } from "react"; +import { Link, LinkProps } from "react-router-dom"; + +export const Sidebar = (props: HTMLAttributes) => { + const theme = useTheme(); + return ( +
+ ); +}; + +export const SidebarLink = (props: LinkProps) => { + return ; +}; + +export const SidebarItem = (props: HTMLAttributes) => { + return
)} -
+
= ({ onRename={(file) => setRenameFileOpen(file)} activePath={activePath} /> -
+
{ return [...logs].sort( @@ -112,15 +110,20 @@ export const WorkspaceBuildPageView: FC = ({ Builds {!builds && Array.from({ length: 15 }, (_, i) => ( - + + + ))} {builds?.map((build) => ( - + to={`/@${build.workspace_owner_name}/${build.workspace_name}/builds/${build.build_number}`} + > + + + + ))} @@ -167,78 +170,6 @@ export const WorkspaceBuildPageView: FC = ({ ); }; -interface BuildSidebarItemProps { - build: WorkspaceBuild; - active: boolean; -} - -const BuildSidebarItem: FC = ({ build, active }) => { - const theme = useTheme(); - const statusType = getDisplayWorkspaceBuildStatus(theme, build).type; - - return ( - - -
- -
-
- {build.transition} by{" "} - {getDisplayWorkspaceBuildInitiatedBy(build)} -
-
- {displayWorkspaceBuildDuration(build)} -
-
-
-
- - ); -}; - -const BuildSidebarItemSkeleton: FC = () => { - return ( - -
- -
- - -
-
-
- ); -}; - const styles = { stats: (theme) => ({ padding: 0, diff --git a/site/src/pages/WorkspacePage/HistorySidebarContent.tsx b/site/src/pages/WorkspacePage/HistorySidebarContent.tsx new file mode 100644 index 0000000000000..ac1bab01a7603 --- /dev/null +++ b/site/src/pages/WorkspacePage/HistorySidebarContent.tsx @@ -0,0 +1,44 @@ +import { infiniteWorkspaceBuilds } from "api/queries/workspaceBuilds"; +import { Workspace } from "api/typesGenerated"; +import { + SidebarCaption, + SidebarItem, + SidebarLink, +} from "components/FullPageLayout/Sidebar"; +import { + WorkspaceBuildData, + WorkspaceBuildDataSkeleton, +} from "components/WorkspaceBuild/WorkspaceBuildData"; +import { useInfiniteQuery } from "react-query"; + +export const HistorySidebarContent = ({ + workspace, +}: { + workspace: Workspace; +}) => { + const buildsQuery = useInfiniteQuery({ + ...infiniteWorkspaceBuilds(workspace?.id ?? ""), + enabled: workspace !== undefined, + }); + const builds = buildsQuery.data?.pages.flat(); + + return ( + <> + History + {builds + ? builds.map((build) => ( + + + + )) + : Array.from({ length: 15 }, (_, i) => ( + + + + ))} + + ); +}; diff --git a/site/src/pages/WorkspacePage/ResourcesSidebarContent.tsx b/site/src/pages/WorkspacePage/ResourcesSidebarContent.tsx new file mode 100644 index 0000000000000..ebc43cf73dbaf --- /dev/null +++ b/site/src/pages/WorkspacePage/ResourcesSidebarContent.tsx @@ -0,0 +1,29 @@ +import { useTheme } from "@mui/material/styles"; +import { Workspace } from "api/typesGenerated"; +import { SidebarLink, SidebarCaption } from "components/FullPageLayout/Sidebar"; + +export const ResourcesSidebarContent = ({ + workspace, +}: { + workspace: Workspace; +}) => { + const theme = useTheme(); + + return ( + <> + Resources + {workspace.latest_build.resources.map((r) => ( + + {r.name} + + {r.type} + + + ))} + + ); +}; diff --git a/site/src/pages/WorkspacePage/Workspace.stories.tsx b/site/src/pages/WorkspacePage/Workspace.stories.tsx index 5a86338f6b1f4..fac23dbf60c18 100644 --- a/site/src/pages/WorkspacePage/Workspace.stories.tsx +++ b/site/src/pages/WorkspacePage/Workspace.stories.tsx @@ -75,7 +75,7 @@ export const Running: Story = { Mocks.MockWorkspaceImageResource, Mocks.MockWorkspaceContainerResource, ], - builds: [Mocks.MockWorkspaceBuild], + //builds: [Mocks.MockWorkspaceBuild], canUpdateWorkspace: true, workspaceErrors: {}, buildInfo: Mocks.MockBuildInfo, diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx index 33fe39c92aff2..b2b65c946230e 100644 --- a/site/src/pages/WorkspacePage/Workspace.tsx +++ b/site/src/pages/WorkspacePage/Workspace.tsx @@ -2,7 +2,7 @@ import { type Interpolation, type Theme } from "@emotion/react"; import Button from "@mui/material/Button"; import AlertTitle from "@mui/material/AlertTitle"; import { type FC, useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router-dom"; import dayjs from "dayjs"; import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDetail } from "components/Alert/Alert"; @@ -17,9 +17,15 @@ import { ActiveTransition, WorkspaceBuildProgress, } from "./WorkspaceBuildProgress"; -import { BuildsTable } from "./BuildsTable"; import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner"; import { WorkspaceTopbar } from "./WorkspaceTopbar"; +import { useTheme } from "@mui/material/styles"; +import MemoryOutlined from "@mui/icons-material/MemoryOutlined"; +import { TopbarIconButton } from "components/FullPageLayout/Topbar"; +import { Sidebar } from "components/FullPageLayout/Sidebar"; +import HistoryOutlined from "@mui/icons-material/HistoryOutlined"; +import { ResourcesSidebarContent } from "./ResourcesSidebarContent"; +import { HistorySidebarContent } from "./HistorySidebarContent"; export type WorkspaceError = | "getBuildsError" @@ -55,10 +61,6 @@ export interface WorkspaceProps { handleBuildRetry: () => void; handleBuildRetryDebug: () => void; buildLogs?: React.ReactNode; - builds: TypesGen.WorkspaceBuild[] | undefined; - onLoadMoreBuilds: () => void; - isLoadingMoreBuilds: boolean; - hasMoreBuilds: boolean; canAutostart: boolean; } @@ -79,7 +81,7 @@ export const Workspace: FC> = ({ isUpdating, isRestarting, resources, - builds, + canUpdateWorkspace, updateMessage, canChangeVersions, @@ -93,14 +95,15 @@ export const Workspace: FC> = ({ handleBuildRetry, handleBuildRetryDebug, buildLogs, - onLoadMoreBuilds, - isLoadingMoreBuilds, - hasMoreBuilds, canAutostart, }) => { + const theme = useTheme(); const navigate = useNavigate(); const { saveLocal, getLocal } = useLocalStorage(); + const [searchParams, setSearchParams] = useSearchParams(); + const activeSidebarOption = searchParams.get("sidebar"); + const [showAlertPendingInQueue, setShowAlertPendingInQueue] = useState(false); // 2023-11-15 - MES - This effect will be called every single render because @@ -149,7 +152,16 @@ export const Workspace: FC> = ({ template !== undefined ? ActiveTransition(template, workspace) : undefined; return ( - <> +
> = ({ canUpdateWorkspace={canUpdateWorkspace} /> +
+ { + setSearchParams((prev) => { + prev.set("sidebar", "resources"); + return prev; + }); + }} + > + + + { + setSearchParams((prev) => { + prev.set("sidebar", "history"); + return prev; + }); + }} + > + + +
+ + + {activeSidebarOption === "resources" && ( + + )} + {activeSidebarOption === "history" && ( + + )} + + {workspace.outdated && @@ -317,26 +369,17 @@ export const Workspace: FC> = ({ )} /> )} - - {workspaceErrors.getBuildsError ? ( - - ) : ( - - )} - +
); }; const styles = { content: { - marginTop: 32, + padding: 32, + gridArea: "content", + overflow: "auto", }, actions: (theme) => ({ diff --git a/site/src/pages/WorkspacePage/WorkspacePage.tsx b/site/src/pages/WorkspacePage/WorkspacePage.tsx index dfc124d2509a0..57236c6b41d3f 100644 --- a/site/src/pages/WorkspacePage/WorkspacePage.tsx +++ b/site/src/pages/WorkspacePage/WorkspacePage.tsx @@ -49,12 +49,6 @@ export const WorkspacePage: FC = () => { }); const permissions = permissionsQuery.data as WorkspacePermissions | undefined; - // Builds - const buildsQuery = useInfiniteQuery({ - ...infiniteWorkspaceBuilds(workspace?.id ?? ""), - enabled: workspace !== undefined, - }); - // Watch workspace changes const updateWorkspaceData = useEffectEvent( async (newWorkspaceData: Workspace) => { @@ -69,7 +63,7 @@ export const WorkspacePage: FC = () => { newWorkspaceData.latest_build.status !== workspace!.latest_build.status; if (hasNewBuild || lastBuildHasChanged) { - await buildsQuery.refetch(); + //await buildsQuery.refetch(); } }, ); @@ -120,13 +114,13 @@ export const WorkspacePage: FC = () => { workspace={workspace} template={template} permissions={permissions} - builds={buildsQuery.data?.pages.flat()} - buildsError={buildsQuery.error} - isLoadingMoreBuilds={buildsQuery.isFetchingNextPage} - onLoadMoreBuilds={async () => { - await buildsQuery.fetchNextPage(); - }} - hasMoreBuilds={Boolean(buildsQuery.hasNextPage)} + // builds={buildsQuery.data?.pages.flat()} + // buildsError={buildsQuery.error} + // isLoadingMoreBuilds={buildsQuery.isFetchingNextPage} + // onLoadMoreBuilds={async () => { + // await buildsQuery.fetchNextPage(); + // }} + // hasMoreBuilds={Boolean(buildsQuery.hasNextPage)} /> ); }; diff --git a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx index e917deafa2b74..eecbe295a243b 100644 --- a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx @@ -41,22 +41,12 @@ interface WorkspaceReadyPageProps { template: TypesGen.Template; workspace: TypesGen.Workspace; permissions: WorkspacePermissions; - builds: TypesGen.WorkspaceBuild[] | undefined; - buildsError: unknown; - onLoadMoreBuilds: () => void; - isLoadingMoreBuilds: boolean; - hasMoreBuilds: boolean; } export const WorkspaceReadyPage = ({ workspace, template, permissions, - builds, - buildsError, - onLoadMoreBuilds, - isLoadingMoreBuilds, - hasMoreBuilds, }: WorkspaceReadyPageProps): JSX.Element => { const navigate = useNavigate(); const queryClient = useQueryClient(); @@ -235,17 +225,12 @@ export const WorkspaceReadyPage = ({ } }} resources={workspace.latest_build.resources} - builds={builds} - onLoadMoreBuilds={onLoadMoreBuilds} - isLoadingMoreBuilds={isLoadingMoreBuilds} - hasMoreBuilds={hasMoreBuilds} canUpdateWorkspace={canUpdateWorkspace} updateMessage={latestVersion?.message} canChangeVersions={canChangeVersions} hideSSHButton={featureVisibility["browser_only"]} hideVSCodeDesktopButton={featureVisibility["browser_only"]} workspaceErrors={{ - getBuildsError: buildsError, buildError: restartBuildError ?? startWorkspaceMutation.error ?? diff --git a/site/src/pages/WorkspacePage/WorkspaceTopbar.tsx b/site/src/pages/WorkspacePage/WorkspaceTopbar.tsx index c963ebc8b683f..0a01c1bab4eaa 100644 --- a/site/src/pages/WorkspacePage/WorkspaceTopbar.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceTopbar.tsx @@ -101,7 +101,7 @@ export const WorkspaceTopbar = (props: WorkspaceProps) => { ); return ( - + From 72ed777a2545ef0701085e3559f2031ecc3f0a2e Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 12:52:15 +0000 Subject: [PATCH 02/11] Refactor to only have history sidebar --- site/src/AppRouter.tsx | 2 +- site/src/components/Resources/Resources.tsx | 8 +- ...ySidebarContent.tsx => HistorySidebar.tsx} | 11 +- site/src/pages/WorkspacePage/Workspace.tsx | 360 ++++++++---------- 4 files changed, 181 insertions(+), 200 deletions(-) rename site/src/pages/WorkspacePage/{HistorySidebarContent.tsx => HistorySidebar.tsx} (90%) diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index d9e856484c768..5d19dd3b88725 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -369,6 +369,7 @@ export const AppRouter: FC = () => { {/* In order for the 404 page to work properly the routes that start with top level parameter must be fully qualified. */} + } /> } @@ -407,7 +408,6 @@ export const AppRouter: FC = () => { {/* Pages that don't have the dashboard layout */} - } /> } diff --git a/site/src/components/Resources/Resources.tsx b/site/src/components/Resources/Resources.tsx index 5b9bf71b316ff..556133506508c 100644 --- a/site/src/components/Resources/Resources.tsx +++ b/site/src/components/Resources/Resources.tsx @@ -5,6 +5,7 @@ import type { WorkspaceAgent, WorkspaceResource } from "api/typesGenerated"; import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; import { Stack } from "../Stack/Stack"; import { ResourceCard } from "./ResourceCard"; +import { useTheme } from "@mui/material/styles"; const countAgents = (resource: WorkspaceResource) => { return resource.agents ? resource.agents.length : 0; @@ -19,6 +20,7 @@ export const Resources: FC> = ({ resources, agentRow, }) => { + const theme = useTheme(); const [shouldDisplayHideResources, setShouldDisplayHideResources] = useState(false); const displayResources = shouldDisplayHideResources @@ -30,7 +32,11 @@ export const Resources: FC> = ({ const hasHideResources = resources.some((r) => r.hide); return ( - + {displayResources.map((resource) => ( { +export const HistorySidebar = ({ workspace }: { workspace: Workspace }) => { const buildsQuery = useInfiniteQuery({ ...infiniteWorkspaceBuilds(workspace?.id ?? ""), enabled: workspace !== undefined, @@ -23,7 +20,7 @@ export const HistorySidebarContent = ({ const builds = buildsQuery.data?.pages.flat(); return ( - <> + History {builds ? builds.map((build) => ( @@ -39,6 +36,6 @@ export const HistorySidebarContent = ({ ))} - + ); }; diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx index b2b65c946230e..13bfe021113ef 100644 --- a/site/src/pages/WorkspacePage/Workspace.tsx +++ b/site/src/pages/WorkspacePage/Workspace.tsx @@ -2,11 +2,10 @@ import { type Interpolation, type Theme } from "@emotion/react"; import Button from "@mui/material/Button"; import AlertTitle from "@mui/material/AlertTitle"; import { type FC, useEffect, useState } from "react"; -import { useNavigate, useSearchParams } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; import dayjs from "dayjs"; import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDetail } from "components/Alert/Alert"; -import { Margins } from "components/Margins/Margins"; import { Resources } from "components/Resources/Resources"; import { Stack } from "components/Stack/Stack"; import { ErrorAlert } from "components/Alert/ErrorAlert"; @@ -19,13 +18,9 @@ import { } from "./WorkspaceBuildProgress"; import { WorkspaceDeletedBanner } from "./WorkspaceDeletedBanner"; import { WorkspaceTopbar } from "./WorkspaceTopbar"; -import { useTheme } from "@mui/material/styles"; -import MemoryOutlined from "@mui/icons-material/MemoryOutlined"; -import { TopbarIconButton } from "components/FullPageLayout/Topbar"; -import { Sidebar } from "components/FullPageLayout/Sidebar"; -import HistoryOutlined from "@mui/icons-material/HistoryOutlined"; -import { ResourcesSidebarContent } from "./ResourcesSidebarContent"; -import { HistorySidebarContent } from "./HistorySidebarContent"; +import { HistorySidebar } from "./HistorySidebar"; +import { dashboardContentBottomPadding, navHeight } from "theme/constants"; +import { bannerHeight } from "components/Dashboard/DeploymentBanner/DeploymentBannerView"; export type WorkspaceError = | "getBuildsError" @@ -97,13 +92,9 @@ export const Workspace: FC> = ({ buildLogs, canAutostart, }) => { - const theme = useTheme(); const navigate = useNavigate(); const { saveLocal, getLocal } = useLocalStorage(); - const [searchParams, setSearchParams] = useSearchParams(); - const activeSidebarOption = searchParams.get("sidebar"); - const [showAlertPendingInQueue, setShowAlertPendingInQueue] = useState(false); // 2023-11-15 - MES - This effect will be called every single render because @@ -154,12 +145,14 @@ export const Workspace: FC> = ({ return (
> = ({ canUpdateWorkspace={canUpdateWorkspace} /> -
- { - setSearchParams((prev) => { - prev.set("sidebar", "resources"); - return prev; - }); - }} - > - - - { - setSearchParams((prev) => { - prev.set("sidebar", "history"); - return prev; - }); - }} - > - - -
+
+
+ + {workspace.outdated && + (requiresManualUpdate ? ( + + + Autostart has been disabled for your workspace. + + + Autostart is unable to automatically update your workspace. + Manually update your workspace to reenable Autostart. + + + ) : ( + + + An update is available for your workspace + + {updateMessage && {updateMessage}} + + ))} + + {Boolean(workspaceErrors.buildError) && ( + + )} - - {activeSidebarOption === "resources" && ( - - )} - {activeSidebarOption === "history" && ( - - )} - + {Boolean(workspaceErrors.cancellationError) && ( + + )} - - - {workspace.outdated && - (requiresManualUpdate ? ( - - - Autostart has been disabled for your workspace. - + {workspace.latest_build.status === "running" && + !workspace.health.healthy && ( + { + handleRestart(); + }} + > + Restart + + ) + } + > + Workspace is unhealthy + + Your workspace is running but{" "} + {workspace.health.failing_agents.length > 1 + ? `${workspace.health.failing_agents.length} agents are unhealthy` + : `1 agent is unhealthy`} + . + + + )} + + {workspace.latest_build.status === "deleted" && ( + navigate(`/templates`)} + /> + )} + {/* determines its own visibility */} + saveLocal("dismissedWorkspace", workspace.id)} + /> + + {showAlertPendingInQueue && ( + + Workspace build is pending - Autostart is unable to automatically update your workspace. - Manually update your workspace to reenable Autostart. +
+ This workspace build job is waiting for a provisioner to + become available. If you have been waiting for an extended + period of time, please contact your administrator for + assistance. +
+
+ Position in queue:{" "} + {workspace.latest_build.job.queue_position} +
- ) : ( - - - An update is available for your workspace - - {updateMessage && {updateMessage}} - - ))} - - {Boolean(workspaceErrors.buildError) && ( - - )} - - {Boolean(workspaceErrors.cancellationError) && ( - - )} + )} - {workspace.latest_build.status === "running" && - !workspace.health.healthy && ( + {workspace.latest_build.job.error && ( { - handleRestart(); - }} - > - Restart - - ) + } > - Workspace is unhealthy - - Your workspace is running but{" "} - {workspace.health.failing_agents.length > 1 - ? `${workspace.health.failing_agents.length} agents are unhealthy` - : `1 agent is unhealthy`} - . - + Workspace build failed + {workspace.latest_build.job.error} )} - {workspace.latest_build.status === "deleted" && ( - navigate(`/templates`)} - /> - )} - {/* determines its own visibility */} - saveLocal("dismissedWorkspace", workspace.id)} - /> - - {showAlertPendingInQueue && ( - - Workspace build is pending - -
- This workspace build job is waiting for a provisioner to - become available. If you have been waiting for an extended - period of time, please contact your administrator for - assistance. -
-
- Position in queue:{" "} - {workspace.latest_build.job.queue_position} -
-
-
- )} - - {workspace.latest_build.job.error && ( - - Retry{canRetryDebugMode && " in debug mode"} - - } - > - Workspace build failed - {workspace.latest_build.job.error} - - )} + {template?.deprecated && ( + + Workspace using deprecated template + {template?.deprecation_message} + + )} - {template?.deprecated && ( - - Workspace using deprecated template - {template?.deprecation_message} - - )} + {transitionStats !== undefined && ( + + )} - {transitionStats !== undefined && ( - - )} + {buildLogs} - {buildLogs} + {typeof resources !== "undefined" && resources.length > 0 && ( + ( + + )} + /> + )} +
+
+
- {typeof resources !== "undefined" && resources.length > 0 && ( - ( - - )} - /> - )} - - +
); }; const styles = { content: { - padding: 32, + padding: 24, gridArea: "content", - overflow: "auto", + overflowY: "auto", }, + dotBackground: (theme) => ({ + padding: 24, + "--d": "1px", + background: ` + radial-gradient( + circle at + var(--d) + var(--d), + + ${theme.palette.text.secondary} calc(var(--d) - 1px), + ${theme.palette.background.default} var(--d) + ) + 0 0 / 24px 24px + `, + }), + actions: (theme) => ({ [theme.breakpoints.down("md")]: { flexDirection: "column", From e66151a9ac4fa938de2870e48542493af72fc90c Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 13:00:40 +0000 Subject: [PATCH 03/11] Minor visual adjustments --- site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx index 71d083e3d898c..97312e3e2f99e 100644 --- a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx +++ b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx @@ -71,6 +71,7 @@ const styles = { display: "flex", flexDirection: "row", alignItems: "center", - gap: 8, + gap: 12, + lineHeight: "1.4", }, } satisfies Record>; From 11109979d474edb1d34768f8e2294f111f39e183 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 13:25:59 +0000 Subject: [PATCH 04/11] Refactor timeline and group build by date --- .../src/components/FullPageLayout/Sidebar.tsx | 2 +- site/src/components/Timeline/Timeline.tsx | 9 +++- .../components/Timeline/TimelineDateRow.tsx | 6 +-- .../WorkspaceBuild/WorkspaceBuildData.tsx | 4 +- .../pages/WorkspacePage/HistorySidebar.tsx | 53 ++++++++++++++++--- 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/site/src/components/FullPageLayout/Sidebar.tsx b/site/src/components/FullPageLayout/Sidebar.tsx index 3da5718730341..d233ebf2392c8 100644 --- a/site/src/components/FullPageLayout/Sidebar.tsx +++ b/site/src/components/FullPageLayout/Sidebar.tsx @@ -49,7 +49,7 @@ export const SidebarCaption = (props: HTMLAttributes) => { const styles = { sidebarItem: (theme: Theme) => ({ - fontSize: 14, + fontSize: 13, lineHeight: 1.2, color: theme.palette.text.primary, textDecoration: "none", diff --git a/site/src/components/Timeline/Timeline.tsx b/site/src/components/Timeline/Timeline.tsx index ad7041d5e98fa..39395628cc58b 100644 --- a/site/src/components/Timeline/Timeline.tsx +++ b/site/src/components/Timeline/Timeline.tsx @@ -1,5 +1,6 @@ import { TimelineDateRow } from "components/Timeline/TimelineDateRow"; -import { Fragment } from "react"; +import { FC, Fragment } from "react"; +import { createDisplayDate } from "./utils"; type GetDateFn = (data: TData) => Date; @@ -26,12 +27,14 @@ export interface TimelineProps { items: TData[]; getDate: GetDateFn; row: (item: TData) => JSX.Element; + dateRow?: FC<{ date: Date; displayDate: string }>; } export const Timeline = ({ items, getDate, row, + dateRow: DateRow = TimelineDateRow, }: TimelineProps): JSX.Element => { const itemsByDate = groupByDate(items, getDate); @@ -39,10 +42,12 @@ export const Timeline = ({ <> {Object.keys(itemsByDate).map((dateStr) => { const items = itemsByDate[dateStr]; + const date = new Date(dateStr); + const displayDate = createDisplayDate(date); return ( - + {items.map(row)} ); diff --git a/site/src/components/Timeline/TimelineDateRow.tsx b/site/src/components/Timeline/TimelineDateRow.tsx index 331ba7e056534..ae6cdfb7109bc 100644 --- a/site/src/components/Timeline/TimelineDateRow.tsx +++ b/site/src/components/Timeline/TimelineDateRow.tsx @@ -2,13 +2,13 @@ import TableCell from "@mui/material/TableCell"; import TableRow from "@mui/material/TableRow"; import { type FC } from "react"; import { css, useTheme } from "@emotion/react"; -import { createDisplayDate } from "./utils"; export interface TimelineDateRow { date: Date; + displayDate: string; } -export const TimelineDateRow: FC = ({ date }) => { +export const TimelineDateRow: FC = ({ date, displayDate }) => { const theme = useTheme(); return ( @@ -30,7 +30,7 @@ export const TimelineDateRow: FC = ({ date }) => { }} title={date.toLocaleDateString()} > - {createDisplayDate(date)} + {displayDate} ); diff --git a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx index 97312e3e2f99e..a4086adb720d1 100644 --- a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx +++ b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx @@ -33,7 +33,9 @@ export const WorkspaceBuildData = ({ build }: { build: WorkspaceBuild }) => { }} > {build.transition} by{" "} - {getDisplayWorkspaceBuildInitiatedBy(build)} + + {getDisplayWorkspaceBuildInitiatedBy(build)} +
{ + const theme = useTheme(); const buildsQuery = useInfiniteQuery({ ...infiniteWorkspaceBuilds(workspace?.id ?? ""), enabled: workspace !== undefined, @@ -22,20 +25,54 @@ export const HistorySidebar = ({ workspace }: { workspace: Workspace }) => { return ( History - {builds - ? builds.map((build) => ( + {builds ? ( + new Date(build.created_at)} + dateRow={({ displayDate }) => ( +
+ {displayDate} +
+ )} + row={(build) => ( - )) - : Array.from({ length: 15 }, (_, i) => ( - - - - ))} + )} + /> + ) : ( + // builds.map((build) => ( + // + // + // + + // )) + Array.from({ length: 15 }, (_, i) => ( + + + + )) + )}
); }; From dcf8f32f30f045d34409b956fc85104f116fec85 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 16:28:19 +0000 Subject: [PATCH 05/11] Change workspace build data --- site/src/components/Resources/AgentRow.tsx | 7 +- .../WorkspaceBuild/WorkspaceBuildData.tsx | 3 +- .../WorkspacePage/BuildsTable.stories.tsx | 31 ------- site/src/pages/WorkspacePage/BuildsTable.tsx | 80 ------------------- .../pages/WorkspacePage/HistorySidebar.tsx | 74 +++++++---------- .../WorkspaceBuildLogsSection.tsx | 1 + .../src/pages/WorkspacePage/WorkspacePage.tsx | 25 +++--- site/src/theme/mui.ts | 4 + 8 files changed, 54 insertions(+), 171 deletions(-) delete mode 100644 site/src/pages/WorkspacePage/BuildsTable.stories.tsx delete mode 100644 site/src/pages/WorkspacePage/BuildsTable.tsx diff --git a/site/src/components/Resources/AgentRow.tsx b/site/src/components/Resources/AgentRow.tsx index 1971453bddd0e..9de6f1e6b8bbb 100644 --- a/site/src/components/Resources/AgentRow.tsx +++ b/site/src/components/Resources/AgentRow.tsx @@ -560,10 +560,11 @@ const styles = { }), agentInfo: (theme) => ({ - padding: "16px 32px", + padding: 32, display: "flex", - alignItems: "center", - gap: 48, + flexDirection: "column", + gap: 16, + alignItems: "flex-start", flexWrap: "wrap", backgroundColor: theme.palette.background.paper, diff --git a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx index a4086adb720d1..7752316c70aab 100644 --- a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx +++ b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx @@ -2,6 +2,7 @@ import { Interpolation, Theme, useTheme } from "@emotion/react"; import Skeleton from "@mui/material/Skeleton"; import { WorkspaceBuild } from "api/typesGenerated"; import { BuildIcon } from "components/BuildIcon/BuildIcon"; +import { createDayString } from "utils/createDayString"; import { getDisplayWorkspaceBuildStatus, getDisplayWorkspaceBuildInitiatedBy, @@ -44,7 +45,7 @@ export const WorkspaceBuildData = ({ build }: { build: WorkspaceBuild }) => { marginTop: 2, }} > - {displayWorkspaceBuildDuration(build)} + {createDayString(build.created_at)}
diff --git a/site/src/pages/WorkspacePage/BuildsTable.stories.tsx b/site/src/pages/WorkspacePage/BuildsTable.stories.tsx deleted file mode 100644 index 7a86c78faf970..0000000000000 --- a/site/src/pages/WorkspacePage/BuildsTable.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Meta, StoryObj } from "@storybook/react"; -import { MockBuilds } from "testHelpers/entities"; -import { BuildsTable } from "./BuildsTable"; - -const meta: Meta = { - title: "pages/WorkspacePage/BuildsTable", - component: BuildsTable, -}; - -export default meta; -type Story = StoryObj; - -export const Example: Story = { - args: { - builds: MockBuilds, - hasMoreBuilds: true, - }, -}; - -export const Empty: Story = { - args: { - builds: [], - }, -}; - -export const NoMoreBuilds: Story = { - args: { - builds: MockBuilds, - hasMoreBuilds: false, - }, -}; diff --git a/site/src/pages/WorkspacePage/BuildsTable.tsx b/site/src/pages/WorkspacePage/BuildsTable.tsx deleted file mode 100644 index 30637967911f8..0000000000000 --- a/site/src/pages/WorkspacePage/BuildsTable.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableRow from "@mui/material/TableRow"; -import LoadingButton from "@mui/lab/LoadingButton"; -import ArrowDownwardOutlined from "@mui/icons-material/ArrowDownwardOutlined"; -import { type FC, type ReactNode } from "react"; -import type * as TypesGen from "api/typesGenerated"; -import { EmptyState } from "components/EmptyState/EmptyState"; -import { TableLoader } from "components/TableLoader/TableLoader"; -import { Timeline } from "components/Timeline/Timeline"; -import { Stack } from "components/Stack/Stack"; -import { BuildRow } from "./BuildRow"; - -export const Language = { - emptyMessage: "No builds found", -}; - -export interface BuildsTableProps { - children?: ReactNode; - builds: TypesGen.WorkspaceBuild[] | undefined; - onLoadMoreBuilds: () => void; - isLoadingMoreBuilds: boolean; - hasMoreBuilds: boolean; -} - -export const BuildsTable: FC = ({ - builds, - onLoadMoreBuilds, - isLoadingMoreBuilds, - hasMoreBuilds, -}) => { - return ( - - - - - {builds ? ( - new Date(build.created_at)} - row={(build) => } - /> - ) : ( - - )} - - {builds && builds.length === 0 && ( - - -
- -
-
-
- )} -
-
-
- {hasMoreBuilds && ( - } - css={{ - display: "inline-flex", - margin: "auto", - borderRadius: "9999px", - }} - > - Load previous builds - - )} -
- ); -}; diff --git a/site/src/pages/WorkspacePage/HistorySidebar.tsx b/site/src/pages/WorkspacePage/HistorySidebar.tsx index ecdc560cc268f..27c757b3fde2a 100644 --- a/site/src/pages/WorkspacePage/HistorySidebar.tsx +++ b/site/src/pages/WorkspacePage/HistorySidebar.tsx @@ -1,4 +1,5 @@ -import { useTheme } from "@mui/material/styles"; +import ArrowDownwardOutlined from "@mui/icons-material/ArrowDownwardOutlined"; +import LoadingButton from "@mui/lab/LoadingButton"; import { infiniteWorkspaceBuilds } from "api/queries/workspaceBuilds"; import { Workspace } from "api/typesGenerated"; import { @@ -7,7 +8,6 @@ import { SidebarItem, SidebarLink, } from "components/FullPageLayout/Sidebar"; -import { Timeline } from "components/Timeline/Timeline"; import { WorkspaceBuildData, WorkspaceBuildDataSkeleton, @@ -15,7 +15,6 @@ import { import { useInfiniteQuery } from "react-query"; export const HistorySidebar = ({ workspace }: { workspace: Workspace }) => { - const theme = useTheme(); const buildsQuery = useInfiniteQuery({ ...infiniteWorkspaceBuilds(workspace?.id ?? ""), enabled: workspace !== undefined, @@ -25,53 +24,40 @@ export const HistorySidebar = ({ workspace }: { workspace: Workspace }) => { return ( History - {builds ? ( - new Date(build.created_at)} - dateRow={({ displayDate }) => ( -
- {displayDate} -
- )} - row={(build) => ( + {builds + ? builds.map((build) => ( - )} - /> - ) : ( - // builds.map((build) => ( - // - // - // - - // )) - Array.from({ length: 15 }, (_, i) => ( - - - - )) + )) + : Array.from({ length: 15 }, (_, i) => ( + + + + ))} + {buildsQuery.hasNextPage && ( +
+ buildsQuery.fetchNextPage()} + loading={buildsQuery.isFetchingNextPage} + loadingPosition="start" + variant="outlined" + color="neutral" + startIcon={} + css={{ + display: "inline-flex", + borderRadius: "9999px", + fontSize: 13, + }} + > + Show more builds + +
)}
); diff --git a/site/src/pages/WorkspacePage/WorkspaceBuildLogsSection.tsx b/site/src/pages/WorkspacePage/WorkspaceBuildLogsSection.tsx index ceb491277a00d..7460021b52bb8 100644 --- a/site/src/pages/WorkspacePage/WorkspaceBuildLogsSection.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceBuildLogsSection.tsx @@ -32,6 +32,7 @@ export const WorkspaceBuildLogsSection: FC = ({ borderRadius: 8, border: `1px solid ${theme.palette.divider}`, overflow: "hidden", + background: theme.palette.background.default, }} >
{ // Watch workspace changes const updateWorkspaceData = useEffectEvent( async (newWorkspaceData: Workspace) => { + if (!workspace) { + throw new Error( + "Applying an update for a workspace that is undefined.", + ); + } + queryClient.setQueryData( workspaceQueryOptions.queryKey, newWorkspaceData, ); const hasNewBuild = - newWorkspaceData.latest_build.id !== workspace!.latest_build.id; + newWorkspaceData.latest_build.id !== workspace.latest_build.id; const lastBuildHasChanged = - newWorkspaceData.latest_build.status !== workspace!.latest_build.status; + newWorkspaceData.latest_build.status !== workspace.latest_build.status; if (hasNewBuild || lastBuildHasChanged) { - //await buildsQuery.refetch(); + await queryClient.invalidateQueries( + workspaceBuildsKey(newWorkspaceData.id), + ); } }, ); @@ -114,13 +122,6 @@ export const WorkspacePage: FC = () => { workspace={workspace} template={template} permissions={permissions} - // builds={buildsQuery.data?.pages.flat()} - // buildsError={buildsQuery.error} - // isLoadingMoreBuilds={buildsQuery.isFetchingNextPage} - // onLoadMoreBuilds={async () => { - // await buildsQuery.fetchNextPage(); - // }} - // hasMoreBuilds={Boolean(buildsQuery.hasNextPage)} /> ); }; diff --git a/site/src/theme/mui.ts b/site/src/theme/mui.ts index c4c9a2db3e84a..96316509ebc6f 100644 --- a/site/src/theme/mui.ts +++ b/site/src/theme/mui.ts @@ -94,6 +94,10 @@ export const components = { "& .MuiLoadingButton-loadingIndicator": { width: 14, height: 14, + // Idk why but I found the loading indicator in the loading buttons + // does not align with the start icon from the regular button so this + // is a visual adjustment. + left: -6, }, "& .MuiLoadingButton-loadingIndicator .MuiCircularProgress-root": { From ec87d6b306d50de7dfb23cb6b3ba44bca82abc9d Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 16:31:23 +0000 Subject: [PATCH 06/11] Reset timeline --- site/src/components/Timeline/Timeline.tsx | 9 ++------- site/src/components/Timeline/TimelineDateRow.tsx | 6 +++--- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/site/src/components/Timeline/Timeline.tsx b/site/src/components/Timeline/Timeline.tsx index 39395628cc58b..ad7041d5e98fa 100644 --- a/site/src/components/Timeline/Timeline.tsx +++ b/site/src/components/Timeline/Timeline.tsx @@ -1,6 +1,5 @@ import { TimelineDateRow } from "components/Timeline/TimelineDateRow"; -import { FC, Fragment } from "react"; -import { createDisplayDate } from "./utils"; +import { Fragment } from "react"; type GetDateFn = (data: TData) => Date; @@ -27,14 +26,12 @@ export interface TimelineProps { items: TData[]; getDate: GetDateFn; row: (item: TData) => JSX.Element; - dateRow?: FC<{ date: Date; displayDate: string }>; } export const Timeline = ({ items, getDate, row, - dateRow: DateRow = TimelineDateRow, }: TimelineProps): JSX.Element => { const itemsByDate = groupByDate(items, getDate); @@ -42,12 +39,10 @@ export const Timeline = ({ <> {Object.keys(itemsByDate).map((dateStr) => { const items = itemsByDate[dateStr]; - const date = new Date(dateStr); - const displayDate = createDisplayDate(date); return ( - + {items.map(row)} ); diff --git a/site/src/components/Timeline/TimelineDateRow.tsx b/site/src/components/Timeline/TimelineDateRow.tsx index ae6cdfb7109bc..331ba7e056534 100644 --- a/site/src/components/Timeline/TimelineDateRow.tsx +++ b/site/src/components/Timeline/TimelineDateRow.tsx @@ -2,13 +2,13 @@ import TableCell from "@mui/material/TableCell"; import TableRow from "@mui/material/TableRow"; import { type FC } from "react"; import { css, useTheme } from "@emotion/react"; +import { createDisplayDate } from "./utils"; export interface TimelineDateRow { date: Date; - displayDate: string; } -export const TimelineDateRow: FC = ({ date, displayDate }) => { +export const TimelineDateRow: FC = ({ date }) => { const theme = useTheme(); return ( @@ -30,7 +30,7 @@ export const TimelineDateRow: FC = ({ date, displayDate }) => { }} title={date.toLocaleDateString()} > - {displayDate} + {createDisplayDate(date)} ); From 1dacdd9e934bc769a7a07694a9a8fbc671165108 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 16:52:20 +0000 Subject: [PATCH 07/11] Add left bar to the sidebar --- .../src/components/FullPageLayout/Sidebar.tsx | 32 +++++++++++++- site/src/pages/WorkspacePage/Workspace.tsx | 42 ++++++++++++++++--- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/site/src/components/FullPageLayout/Sidebar.tsx b/site/src/components/FullPageLayout/Sidebar.tsx index d233ebf2392c8..4d511cd2ffc3d 100644 --- a/site/src/components/FullPageLayout/Sidebar.tsx +++ b/site/src/components/FullPageLayout/Sidebar.tsx @@ -1,6 +1,7 @@ import { Interpolation, Theme, useTheme } from "@mui/material/styles"; -import { HTMLAttributes } from "react"; +import { ComponentProps, HTMLAttributes } from "react"; import { Link, LinkProps } from "react-router-dom"; +import { TopbarIconButton } from "./Topbar"; export const Sidebar = (props: HTMLAttributes) => { const theme = useTheme(); @@ -47,6 +48,35 @@ export const SidebarCaption = (props: HTMLAttributes) => { ); }; +export const SidebarIconButton = ( + props: { isActive: boolean } & ComponentProps, +) => { + const theme = useTheme(); + + return ( + + ); +}; + const styles = { sidebarItem: (theme: Theme) => ({ fontSize: 13, diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx index 13bfe021113ef..2bed5af9bd8d9 100644 --- a/site/src/pages/WorkspacePage/Workspace.tsx +++ b/site/src/pages/WorkspacePage/Workspace.tsx @@ -2,7 +2,7 @@ import { type Interpolation, type Theme } from "@emotion/react"; import Button from "@mui/material/Button"; import AlertTitle from "@mui/material/AlertTitle"; import { type FC, useEffect, useState } from "react"; -import { useNavigate } from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router-dom"; import dayjs from "dayjs"; import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDetail } from "components/Alert/Alert"; @@ -21,6 +21,9 @@ import { WorkspaceTopbar } from "./WorkspaceTopbar"; import { HistorySidebar } from "./HistorySidebar"; import { dashboardContentBottomPadding, navHeight } from "theme/constants"; import { bannerHeight } from "components/Dashboard/DeploymentBanner/DeploymentBannerView"; +import HistoryOutlined from "@mui/icons-material/HistoryOutlined"; +import { useTheme } from "@mui/material/styles"; +import { SidebarIconButton } from "components/FullPageLayout/Sidebar"; export type WorkspaceError = | "getBuildsError" @@ -94,6 +97,9 @@ export const Workspace: FC> = ({ }) => { const navigate = useNavigate(); const { saveLocal, getLocal } = useLocalStorage(); + const theme = useTheme(); + + const [searchParams, setSearchParams] = useSearchParams(); const [showAlertPendingInQueue, setShowAlertPendingInQueue] = useState(false); @@ -148,8 +154,8 @@ export const Workspace: FC> = ({ flex: 1, display: "grid", gridTemplate: ` - "topbar topbar" auto - "sidebar content" 1fr / auto 1fr + "topbar topbar topbar" auto + "leftbar sidebar content" 1fr / auto auto 1fr `, maxHeight: `calc(100vh - ${navHeight + bannerHeight}px)`, marginBottom: `-${dashboardContentBottomPadding}px`, @@ -175,6 +181,34 @@ export const Workspace: FC> = ({ canUpdateWorkspace={canUpdateWorkspace} /> +
+ { + const sidebarOption = searchParams.get("sidebar"); + if (sidebarOption === "history") { + searchParams.delete("sidebar"); + } else { + searchParams.set("sidebar", "history"); + } + setSearchParams(searchParams); + }} + > + + +
+ + {searchParams.get("sidebar") === "history" && ( + + )} +
@@ -331,8 +365,6 @@ export const Workspace: FC> = ({
- - ); }; From 0f56e299bed757596aaa920ab6b83b086b70047b Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 18:45:04 +0000 Subject: [PATCH 08/11] Fix tests --- site/src/pages/WorkspacePage/WorkspacePage.test.tsx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx index 393f8ab6eaf4d..3dd0e8b478d4e 100644 --- a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx +++ b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx @@ -13,7 +13,6 @@ import { MockOutdatedWorkspace, MockTemplateVersionParameter1, MockTemplateVersionParameter2, - MockBuilds, MockUser, MockDeploymentConfig, MockWorkspaceBuildDelete, @@ -317,18 +316,6 @@ describe("WorkspacePage", () => { }); }); - it("shows the timeline build", async () => { - await renderWorkspacePage(MockWorkspace); - const table = await screen.findByTestId("builds-table"); - - // Wait for the results to be loaded - await waitFor(async () => { - const rows = table.querySelectorAll("tbody > tr"); - // Added +1 because of the date row - expect(rows).toHaveLength(MockBuilds.length + 1); - }); - }); - it("restart the workspace with one time parameters when having the confirmation dialog", async () => { window.localStorage.removeItem(`${MockUser.id}_ignoredWarnings`); jest.spyOn(api, "getWorkspaceParameters").mockResolvedValue({ From 3449731dd9d4d8f6125ea2b74363660dbc83ec6a Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 4 Jan 2024 19:16:37 +0000 Subject: [PATCH 09/11] Fix lint --- site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx index 7752316c70aab..ca3a1efbee4f3 100644 --- a/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx +++ b/site/src/components/WorkspaceBuild/WorkspaceBuildData.tsx @@ -6,7 +6,6 @@ import { createDayString } from "utils/createDayString"; import { getDisplayWorkspaceBuildStatus, getDisplayWorkspaceBuildInitiatedBy, - displayWorkspaceBuildDuration, } from "utils/workspace"; export const WorkspaceBuildData = ({ build }: { build: WorkspaceBuild }) => { From df7f8b65967f70e8c4cdb0694d43e5caed822776 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 5 Jan 2024 15:00:55 +0000 Subject: [PATCH 10/11] Resolve PR comments --- site/src/components/FullPageLayout/Sidebar.tsx | 4 ++-- site/src/pages/WorkspacePage/Workspace.stories.tsx | 2 -- site/src/pages/WorkspacePage/Workspace.tsx | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/site/src/components/FullPageLayout/Sidebar.tsx b/site/src/components/FullPageLayout/Sidebar.tsx index 4d511cd2ffc3d..df75826c8c6bf 100644 --- a/site/src/components/FullPageLayout/Sidebar.tsx +++ b/site/src/components/FullPageLayout/Sidebar.tsx @@ -41,7 +41,7 @@ export const SidebarCaption = (props: HTMLAttributes) => { display: "block", textTransform: "uppercase", fontWeight: 500, - letterSpacing: 1, + letterSpacing: "0.1em", }} {...props} /> @@ -78,7 +78,7 @@ export const SidebarIconButton = ( }; const styles = { - sidebarItem: (theme: Theme) => ({ + sidebarItem: (theme) => ({ fontSize: 13, lineHeight: 1.2, color: theme.palette.text.primary, diff --git a/site/src/pages/WorkspacePage/Workspace.stories.tsx b/site/src/pages/WorkspacePage/Workspace.stories.tsx index fac23dbf60c18..12d1a39cb2b13 100644 --- a/site/src/pages/WorkspacePage/Workspace.stories.tsx +++ b/site/src/pages/WorkspacePage/Workspace.stories.tsx @@ -54,7 +54,6 @@ const meta: Meta = { withReactContext({ Context: WatchAgentMetadataContext, initialState: (_: string): EventSource => { - // Need Bruno's help here. return new EventSource(); }, }), @@ -75,7 +74,6 @@ export const Running: Story = { Mocks.MockWorkspaceImageResource, Mocks.MockWorkspaceContainerResource, ], - //builds: [Mocks.MockWorkspaceBuild], canUpdateWorkspace: true, workspaceErrors: {}, buildInfo: Mocks.MockBuildInfo, diff --git a/site/src/pages/WorkspacePage/Workspace.tsx b/site/src/pages/WorkspacePage/Workspace.tsx index 2bed5af9bd8d9..fdb5eabc95c61 100644 --- a/site/src/pages/WorkspacePage/Workspace.tsx +++ b/site/src/pages/WorkspacePage/Workspace.tsx @@ -342,7 +342,7 @@ export const Workspace: FC> = ({ {buildLogs} - {typeof resources !== "undefined" && resources.length > 0 && ( + {resources && resources.length > 0 && ( ( From 4e8fbf9ff5a012ee4469df350a701d421540f862 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 5 Jan 2024 15:08:41 +0000 Subject: [PATCH 11/11] Improve agent row --- site/src/components/Resources/AgentRow.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/site/src/components/Resources/AgentRow.tsx b/site/src/components/Resources/AgentRow.tsx index 9de6f1e6b8bbb..3a3363d907395 100644 --- a/site/src/components/Resources/AgentRow.tsx +++ b/site/src/components/Resources/AgentRow.tsx @@ -560,11 +560,11 @@ const styles = { }), agentInfo: (theme) => ({ - padding: 32, + padding: "24px 32px", display: "flex", - flexDirection: "column", gap: 16, - alignItems: "flex-start", + alignItems: "center", + justifyContent: "space-between", flexWrap: "wrap", backgroundColor: theme.palette.background.paper, @@ -587,9 +587,7 @@ const styles = { agentButtons: (theme) => ({ display: "flex", gap: 8, - justifyContent: "flex-end", flexWrap: "wrap", - flex: 1, [theme.breakpoints.down("md")]: { marginLeft: 0,