From 1e9221813bdbdf2cbdc363c7942528909e875bab Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Tue, 12 Mar 2024 14:21:45 +0000 Subject: [PATCH] chore(site): refactor dormant badge and add stories --- .../WorkspaceDormantBadge.stories.tsx | 41 +++++++ .../WorkspaceDormantBadge.tsx | 58 ++++++++++ .../DormantDeletionText.tsx | 34 ------ .../WorkspaceStatusBadge.tsx | 103 ------------------ .../pages/WorkspacesPage/WorkspacesTable.tsx | 8 +- 5 files changed, 102 insertions(+), 142 deletions(-) create mode 100644 site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.stories.tsx create mode 100644 site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.tsx delete mode 100644 site/src/modules/workspaces/WorkspaceStatusBadge/DormantDeletionText.tsx diff --git a/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.stories.tsx b/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.stories.tsx new file mode 100644 index 0000000000000..27e3384a6d853 --- /dev/null +++ b/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { userEvent, within } from "@storybook/test"; +import { MockDormantWorkspace } from "testHelpers/entities"; +import { WorkspaceDormantBadge } from "./WorkspaceDormantBadge"; + +const meta: Meta = { + title: "modules/workspaces/WorkspaceDormantBadge", + component: WorkspaceDormantBadge, + args: { + workspace: MockDormantWorkspace, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Open tooltip", async () => { + await userEvent.hover(canvas.getByRole("status")); + }); + }, +}; + +export const DeletingAt: Story = { + args: { + workspace: { + ...MockDormantWorkspace, + deleting_at: "2024-03-12T14:17:12.196Z", + }, + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement); + + await step("Open tooltip", async () => { + await userEvent.hover(canvas.getByRole("status")); + }); + }, +}; diff --git a/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.tsx b/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.tsx new file mode 100644 index 0000000000000..bcaaa988e9ec7 --- /dev/null +++ b/site/src/modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge.tsx @@ -0,0 +1,58 @@ +import AutoDeleteIcon from "@mui/icons-material/AutoDelete"; +import RecyclingIcon from "@mui/icons-material/Recycling"; +import Tooltip from "@mui/material/Tooltip"; +import { formatDistanceToNow } from "date-fns"; +import type { FC } from "react"; +import type { Workspace } from "api/typesGenerated"; +import { Pill } from "components/Pill/Pill"; + +export type WorkspaceDormantBadgeProps = { + workspace: Workspace; +}; + +export const WorkspaceDormantBadge: FC = ({ + workspace, +}) => { + const formatDate = (dateStr: string): string => { + const date = new Date(dateStr); + return date.toLocaleDateString(undefined, { + month: "long", + day: "numeric", + year: "numeric", + hour: "numeric", + minute: "numeric", + }); + }; + + return workspace.deleting_at ? ( + + This workspace has not been used for{" "} + {formatDistanceToNow(Date.parse(workspace.last_used_at))} and has been + marked dormant. It is scheduled to be deleted on{" "} + {formatDate(workspace.deleting_at)}. + + } + > + } type="error"> + Deletion Pending + + + ) : ( + + This workspace has not been used for{" "} + {formatDistanceToNow(Date.parse(workspace.last_used_at))} and has been + marked dormant. It is not scheduled for auto-deletion but will become + a candidate if auto-deletion is enabled on this template. + + } + > + } type="warning"> + Dormant + + + ); +}; diff --git a/site/src/modules/workspaces/WorkspaceStatusBadge/DormantDeletionText.tsx b/site/src/modules/workspaces/WorkspaceStatusBadge/DormantDeletionText.tsx deleted file mode 100644 index 27aea1359d2df..0000000000000 --- a/site/src/modules/workspaces/WorkspaceStatusBadge/DormantDeletionText.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { FC } from "react"; -import type { Workspace } from "api/typesGenerated"; -import { useDashboard } from "modules/dashboard/useDashboard"; -import { displayDormantDeletion } from "utils/dormant"; - -interface DormantDeletionTextProps { - workspace: Workspace; -} - -export const DormantDeletionText: FC = ({ - workspace, -}) => { - const { entitlements } = useDashboard(); - const allowAdvancedScheduling = - entitlements.features["advanced_template_scheduling"].enabled; - // This check can be removed when https://github.com/coder/coder/milestone/19 - // is merged up - - if (!displayDormantDeletion(workspace, allowAdvancedScheduling)) { - return null; - } - - return ( - ({ - color: theme.palette.warning.light, - fontWeight: 600, - })} - > - Impending deletion - - ); -}; diff --git a/site/src/modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx b/site/src/modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx index 3be084e572188..80dfd9d177112 100644 --- a/site/src/modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx +++ b/site/src/modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge.tsx @@ -1,18 +1,14 @@ -import AutoDeleteIcon from "@mui/icons-material/AutoDelete"; import ErrorOutline from "@mui/icons-material/ErrorOutline"; -import RecyclingIcon from "@mui/icons-material/Recycling"; import Tooltip, { type TooltipProps, tooltipClasses, } from "@mui/material/Tooltip"; -import { formatDistanceToNow } from "date-fns"; import type { FC, ReactNode } from "react"; import type { Workspace } from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { Pill } from "components/Pill/Pill"; import { useClassName } from "hooks/useClassName"; import { getDisplayWorkspaceStatus } from "utils/workspace"; -import { DormantDeletionText } from "./DormantDeletionText"; export type WorkspaceStatusBadgeProps = { workspace: Workspace; @@ -73,105 +69,6 @@ export const WorkspaceStatusBadge: FC = ({ ); }; -export type DormantStatusBadgeProps = { - workspace: Workspace; - className?: string; -}; - -export const DormantStatusBadge: FC = ({ - workspace, - className, -}) => { - if (!workspace.dormant_at) { - return null; - } - - const formatDate = (dateStr: string): string => { - const date = new Date(dateStr); - return date.toLocaleDateString(undefined, { - month: "long", - day: "numeric", - year: "numeric", - hour: "numeric", - minute: "numeric", - }); - }; - - return workspace.deleting_at ? ( - - This workspace has not been used for{" "} - {formatDistanceToNow(Date.parse(workspace.last_used_at))} and has been - marked dormant. It is scheduled to be deleted on{" "} - {formatDate(workspace.deleting_at)}. - - } - > - } - type="error" - > - Deletion Pending - - - ) : ( - - This workspace has not been used for{" "} - {formatDistanceToNow(Date.parse(workspace.last_used_at))} and has been - marked dormant. It is not scheduled for auto-deletion but will become - a candidate if auto-deletion is enabled on this template. - - } - > - } - type="warning" - > - Dormant - - - ); -}; - -export const WorkspaceStatusText: FC = ({ - workspace, - className, -}) => { - const { text, type } = getDisplayWorkspaceStatus( - workspace.latest_build.status, - ); - - return ( - - - - - - ({ - fontWeight: 600, - color: type - ? theme.roles[type].fill.solid - : theme.experimental.l1.text, - })} - > - {text} - - - - ); -}; - const FailureTooltip: FC = ({ children, ...tooltipProps }) => { const popper = useClassName( (css, theme) => css` diff --git a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx index 66d958bd3e143..6e166dce57074 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesTable.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesTable.tsx @@ -22,11 +22,9 @@ import { TableRowSkeleton, } from "components/TableLoader/TableLoader"; import { useClickableTableRow } from "hooks/useClickableTableRow"; +import { WorkspaceDormantBadge } from "modules/workspaces/WorkspaceDormantBadge/WorkspaceDormantBadge"; import { WorkspaceOutdatedTooltip } from "modules/workspaces/WorkspaceOutdatedTooltip/WorkspaceOutdatedTooltip"; -import { - DormantStatusBadge, - WorkspaceStatusBadge, -} from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge"; +import { WorkspaceStatusBadge } from "modules/workspaces/WorkspaceStatusBadge/WorkspaceStatusBadge"; import { LastUsed } from "pages/WorkspacesPage/LastUsed"; import { getDisplayWorkspaceTemplateName } from "utils/workspace"; import { WorkspacesEmpty } from "./WorkspacesEmpty"; @@ -214,7 +212,7 @@ export const WorkspacesTable: FC = ({ /> )} {workspace.dormant_at && ( - + )}