From 2e1ebb3bb44367b9642253fdd766ad842a9df73d Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 6 Mar 2025 18:58:14 +0000 Subject: [PATCH 1/7] feat: add provisioner jobs --- site/src/components/Badge/Badge.tsx | 2 +- .../management/OrganizationSidebarView.tsx | 17 +- .../ProvisionersPage/ProvisionerJobsPage.tsx | 145 ++++++++++-------- .../ProvisionersPage/ProvisionersPage.tsx | 6 +- site/src/router.tsx | 10 ++ 5 files changed, 105 insertions(+), 75 deletions(-) diff --git a/site/src/components/Badge/Badge.tsx b/site/src/components/Badge/Badge.tsx index 2044db6d20614..453e852da7a37 100644 --- a/site/src/components/Badge/Badge.tsx +++ b/site/src/components/Badge/Badge.tsx @@ -12,7 +12,7 @@ export const badgeVariants = cva( variants: { variant: { default: - "border-transparent bg-surface-secondary text-content-secondary shadow hover:bg-surface-tertiary", + "border-transparent bg-surface-secondary text-content-secondary shadow", }, size: { sm: "text-2xs font-regular", diff --git a/site/src/modules/management/OrganizationSidebarView.tsx b/site/src/modules/management/OrganizationSidebarView.tsx index 71a37659ab14d..959dbec45a09e 100644 --- a/site/src/modules/management/OrganizationSidebarView.tsx +++ b/site/src/modules/management/OrganizationSidebarView.tsx @@ -186,11 +186,18 @@ const OrganizationSettingsNavigation: FC< )} {orgPermissions.viewProvisioners && orgPermissions.viewProvisionerJobs && ( - - Provisioners - + <> + + Provisioners + + + Provisioner Jobs + + )} {orgPermissions.viewIdpSyncSettings && ( { + const { organization } = useOrganizationSettings(); + + if (!organization) { + return ; + } -export const ProvisionerJobsPage: FC = ({ - orgId, -}) => { const { data: jobs, isLoadingError, refetch, - } = useQuery(provisionerJobs(orgId)); + } = useQuery(provisionerJobs(organization?.id)); return ( -
-

Provisioner jobs

-

- Provisioner Jobs are the individual tasks assigned to Provisioners when - the workspaces are being built.{" "} - View docs -

- - - - - Created - Type - Template - Tags - Status - - - - - {jobs ? ( - jobs.length > 0 ? ( - jobs.map((j) => ) + <> + + + {pageTitle( + "Provisioner Jobs", + organization.display_name || organization.name, + )} + + +
+
+
+

Provisioner Jobs

+

+ Provisioner Jobs are the individual tasks assigned to Provisioners + when the workspaces are being built.{" "} + View docs +

+
+
+ +
+ + + Created + Type + Template + Tags + Status + + + + + {jobs ? ( + jobs.length > 0 ? ( + jobs.map((j) => ) + ) : ( + + + + + + ) + ) : isLoadingError ? ( + + + refetch()}>Retry} + /> + + ) : ( - + - ) - ) : isLoadingError ? ( - - - refetch()}>Retry} - /> - - - ) : ( - - - - - - )} - -
-
+ )} + + + + ); }; @@ -133,20 +150,16 @@ const JobRow: FC = ({ job }) => { {job.type} - {job.metadata.template_name ? ( -
- - {metadata.template_display_name ?? metadata.template_name} -
- ) : ( - Not linked - )} +
+ + {metadata.template_display_name || metadata.template_name} +
@@ -213,3 +226,5 @@ const JobRow: FC = ({ job }) => { ); }; + +export default ProvisionerJobsPage; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx index 051f916c3ad99..4091b754f3be6 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx @@ -6,7 +6,7 @@ import type { FC } from "react"; import { Helmet } from "react-helmet-async"; import { pageTitle } from "utils/page"; import { ProvisionerDaemonsPage } from "./ProvisionerDaemonsPage"; -import { ProvisionerJobsPage } from "./ProvisionerJobsPage"; +import ProvisionerJobsPage from "./ProvisionerJobsPage"; const ProvisionersPage: FC = () => { const { organization, organizationPermissions } = useOrganizationSettings(); @@ -57,9 +57,7 @@ const ProvisionersPage: FC = () => {
- {tab.value === "jobs" && ( - - )} + {tab.value === "jobs" && } {tab.value === "daemons" && ( )} diff --git a/site/src/router.tsx b/site/src/router.tsx index ebb9e6763d058..898b7be234e47 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -309,6 +309,12 @@ const ChangePasswordPage = lazy( const IdpOrgSyncPage = lazy( () => import("./pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage"), ); +const ProvisionerJobsPage = lazy( + () => + import( + "./pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerJobsPage" + ), +); const RoutesWithSuspense = () => { return ( @@ -429,6 +435,10 @@ export const router = createBrowserRouter( } /> } /> + } + /> } /> } /> From d931c4a8b7dd702a4c0ec69039b033e4012a8bac Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Mon, 10 Mar 2025 17:49:30 +0000 Subject: [PATCH 2/7] Add tests and refactor location --- site/src/api/queries/organizations.ts | 7 +- .../management/OrganizationSettingsLayout.tsx | 13 +- .../CancelJobButton.stories.tsx | 4 +- .../CancelJobButton.tsx | 0 .../CancelJobConfirmationDialog.stories.tsx | 7 +- .../CancelJobConfirmationDialog.tsx | 0 .../JobRow.stories.tsx | 100 + .../JobRow.tsx} | 121 +- .../JobStatusIndicator.stories.tsx | 76 + .../JobStatusIndicator.tsx | 24 +- ...rganizationProvisionerJobsPage.stories.tsx | 1628 +++++++++++++++++ .../OrganizationProvisionerJobsPage.tsx | 120 ++ .../Tags.stories.tsx | 45 + .../Tags.tsx | 0 .../ProvisionersPage/DataGrid.tsx | 25 - .../ProvisionerDaemonsPage.tsx | 274 --- .../ProvisionersPage/ProvisionersPage.tsx | 71 - site/src/router.tsx | 2 +- site/src/utils/time.ts | 6 + 19 files changed, 2009 insertions(+), 514 deletions(-) rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/CancelJobButton.stories.tsx (90%) rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/CancelJobButton.tsx (100%) rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/CancelJobConfirmationDialog.stories.tsx (94%) rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/CancelJobConfirmationDialog.tsx (100%) create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage/ProvisionerJobsPage.tsx => OrganizationProvisionerJobsPage/JobRow.tsx} (54%) create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/JobStatusIndicator.tsx (63%) create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.stories.tsx rename site/src/pages/OrganizationSettingsPage/{ProvisionersPage => OrganizationProvisionerJobsPage}/Tags.tsx (100%) delete mode 100644 site/src/pages/OrganizationSettingsPage/ProvisionersPage/DataGrid.tsx delete mode 100644 site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerDaemonsPage.tsx delete mode 100644 site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx diff --git a/site/src/api/queries/organizations.ts b/site/src/api/queries/organizations.ts index 374f9e7eacf4e..f8d3ab40edb69 100644 --- a/site/src/api/queries/organizations.ts +++ b/site/src/api/queries/organizations.ts @@ -207,10 +207,13 @@ export const provisionerJobQueryKey = (orgId: string) => [ "provisionerjobs", ]; -export const provisionerJobs = (orgId: string) => { +export const provisionerJobs = ( + orgId: string, + fetchProvisionerJobs = API.getProvisionerJobs, +) => { return { queryKey: provisionerJobQueryKey(orgId), - queryFn: () => API.getProvisionerJobs(orgId), + queryFn: () => fetchProvisionerJobs(orgId), }; }; diff --git a/site/src/modules/management/OrganizationSettingsLayout.tsx b/site/src/modules/management/OrganizationSettingsLayout.tsx index ae1ce597641ae..8905db3563052 100644 --- a/site/src/modules/management/OrganizationSettingsLayout.tsx +++ b/site/src/modules/management/OrganizationSettingsLayout.tsx @@ -24,7 +24,7 @@ export const OrganizationSettingsContext = createContext< OrganizationSettingsValue | undefined >(undefined); -type OrganizationSettingsValue = Readonly<{ +export type OrganizationSettingsValue = Readonly<{ organizations: readonly Organization[]; organizationPermissionsByOrganizationId: Record< string, @@ -34,11 +34,14 @@ type OrganizationSettingsValue = Readonly<{ organizationPermissions?: OrganizationPermissions; }>; -export const useOrganizationSettings = (): OrganizationSettingsValue => { - const context = useContext(OrganizationSettingsContext); +export const useOrganizationSettings = ( + defaultValues?: OrganizationSettingsValue, +): OrganizationSettingsValue => { + const context = useContext(OrganizationSettingsContext) ?? defaultValues; + if (!context) { throw new Error( - "useOrganizationSettings should be used inside of OrganizationSettingsLayout", + "useOrganizationSettings should be used inside of OrganizationSettingsLayout or with the default values in case of testing.", ); } @@ -46,7 +49,7 @@ export const useOrganizationSettings = (): OrganizationSettingsValue => { }; const OrganizationSettingsLayout: FC = () => { - const { organizations, showOrganizations } = useDashboard(); + const { organizations } = useDashboard(); const { organization: orgName } = useParams() as { organization?: string; }; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobButton.stories.tsx similarity index 90% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.stories.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobButton.stories.tsx index 337149f17639c..713a7fdc299c1 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobButton.stories.tsx @@ -4,7 +4,7 @@ import { MockProvisionerJob } from "testHelpers/entities"; import { CancelJobButton } from "./CancelJobButton"; const meta: Meta = { - title: "pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton", + title: "pages/OrganizationProvisionerJobsPage/CancelJobButton", component: CancelJobButton, args: { job: { @@ -28,7 +28,7 @@ export const NotCancellable: Story = { }, }; -export const OnClick: Story = { +export const ConfirmOnClick: Story = { parameters: { chromatic: { disableSnapshot: true }, }, diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobButton.tsx similarity index 100% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobButton.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobButton.tsx diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.stories.tsx similarity index 94% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.stories.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.stories.tsx index 8d48fe6d80d1a..f0c117360d53a 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.stories.tsx @@ -6,8 +6,7 @@ import { withGlobalSnackbar } from "testHelpers/storybook"; import { CancelJobConfirmationDialog } from "./CancelJobConfirmationDialog"; const meta: Meta = { - title: - "pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog", + title: "pages/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog", component: CancelJobConfirmationDialog, args: { open: true, @@ -40,7 +39,7 @@ export const OnCancel: Story = { }, }; -export const onConfirmSuccess: Story = { +export const OnConfirmSuccess: Story = { parameters: { chromatic: { disableSnapshot: true }, }, @@ -60,7 +59,7 @@ export const onConfirmSuccess: Story = { }, }; -export const onConfirmFailure: Story = { +export const OnConfirmFailure: Story = { parameters: { chromatic: { disableSnapshot: true }, }, diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.tsx similarity index 100% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/CancelJobConfirmationDialog.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/CancelJobConfirmationDialog.tsx diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx new file mode 100644 index 0000000000000..5f455a4c74043 --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx @@ -0,0 +1,100 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { daysAgo } from "utils/time"; +import { userEvent, waitFor, within, expect } from "@storybook/test"; +import { JobRow } from "./JobRow"; +import { Table, TableBody } from "components/Table/Table"; + +const meta: Meta = { + title: "pages/OrganizationProvisionerJobsPage/JobRow", + component: JobRow, + args: { + job: { + id: "373cb47a-c33b-4e35-83bf-23c64fde0293", + created_at: daysAgo(2), + started_at: "2025-03-09T08:01:22.118677Z", + completed_at: "2025-03-09T08:01:33.310184Z", + status: "succeeded", + worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "0153584a-6cbe-4c90-8e9e-4ffb40fd1069", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", + workspace_name: "nowjosias", + }, + }, + }, + render: (args) => { + return ( + + + + +
+ ); + }, +}; + +export default meta; +type Story = StoryObj; + +export const Close: Story = {}; + +export const Open: Story = { + args: { + defaultOpen: true, + }, +}; + +export const OpenOnClick: Story = { + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement); + const showMoreButton = canvas.getByRole("button", { name: /show more/i }); + + await userEvent.click(showMoreButton); + + const jobId = canvas.getByText(args.job.id); + expect(jobId).toBeInTheDocument(); + }, + parameters: { + chromatic: { + disableSnapshot: true, + }, + }, +}; + +export const HideOnClick: Story = { + args: { + defaultOpen: true, + }, + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement); + const showMoreButton = canvas.getByRole("button", { name: /hide/i }); + + await userEvent.click(showMoreButton); + + const jobId = canvas.queryByText(args.job.id); + expect(jobId).not.toBeInTheDocument(); + }, + parameters: { + chromatic: { + disableSnapshot: true, + }, + }, +}; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerJobsPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx similarity index 54% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerJobsPage.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx index 969ce0fffd5d8..6299f725e0a1d 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerJobsPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx @@ -1,124 +1,27 @@ -import { provisionerJobs } from "api/queries/organizations"; import type { ProvisionerJob } from "api/typesGenerated"; -import { Avatar } from "components/Avatar/Avatar"; -import { Badge } from "components/Badge/Badge"; -import { Button } from "components/Button/Button"; -import { EmptyState } from "components/EmptyState/EmptyState"; -import { Link } from "components/Link/Link"; -import { Loader } from "components/Loader/Loader"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "components/Table/Table"; import { ChevronDownIcon, ChevronRightIcon, TriangleAlertIcon, } from "lucide-react"; import { type FC, useState } from "react"; -import { useQuery } from "react-query"; import { cn } from "utils/cn"; -import { docs } from "utils/docs"; import { relativeTime } from "utils/time"; import { CancelJobButton } from "./CancelJobButton"; -import { DataGrid } from "./DataGrid"; import { JobStatusIndicator } from "./JobStatusIndicator"; import { Tag, Tags, TruncateTags } from "./Tags"; -import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; -import { Helmet } from "react-helmet-async"; -import { pageTitle } from "utils/page"; - -const ProvisionerJobsPage: FC = () => { - const { organization } = useOrganizationSettings(); - - if (!organization) { - return ; - } - - const { - data: jobs, - isLoadingError, - refetch, - } = useQuery(provisionerJobs(organization?.id)); - - return ( - <> - - - {pageTitle( - "Provisioner Jobs", - organization.display_name || organization.name, - )} - - -
-
-
-

Provisioner Jobs

-

- Provisioner Jobs are the individual tasks assigned to Provisioners - when the workspaces are being built.{" "} - View docs -

-
-
- - - - - Created - Type - Template - Tags - Status - - - - - {jobs ? ( - jobs.length > 0 ? ( - jobs.map((j) => ) - ) : ( - - - - - - ) - ) : isLoadingError ? ( - - - refetch()}>Retry} - /> - - - ) : ( - - - - - - )} - -
-
- - ); -}; +import { TableCell, TableRow } from "components/Table/Table"; +import { Avatar } from "components/Avatar/Avatar"; +import { Badge } from "components/Badge/Badge"; type JobRowProps = { job: ProvisionerJob; + defaultOpen?: boolean; }; -const JobRow: FC = ({ job }) => { +export const JobRow: FC = ({ job, defaultOpen }) => { const metadata = job.metadata; - const [isOpen, setIsOpen] = useState(false); + const [isOpen, setIsOpen] = useState(defaultOpen); return ( <> @@ -186,7 +89,13 @@ const JobRow: FC = ({ job }) => { {job.error}
)} - +
Job ID:
{job.id}
@@ -219,12 +128,10 @@ const JobRow: FC = ({ job }) => { ))} - +
)} ); }; - -export default ProvisionerJobsPage; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx new file mode 100644 index 0000000000000..2c7ef63b6cf94 --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx @@ -0,0 +1,76 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { JobStatusIndicator } from "./JobStatusIndicator"; +import { MockProvisionerJob } from "testHelpers/entities"; + +const meta: Meta = { + title: "pages/OrganizationProvisionerJobsPage/JobStatusIndicator", + component: JobStatusIndicator, +}; + +export default meta; +type Story = StoryObj; + +export const Succeeded: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "succeeded", + }, + }, +}; + +export const Failed: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "failed", + }, + }, +}; + +export const Pending: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "pending", + queue_position: 1, + queue_size: 1, + }, + }, +}; + +export const Running: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "running", + }, + }, +}; + +export const Canceling: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "canceling", + }, + }, +}; + +export const Canceled: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "canceled", + }, + }, +}; + +export const Unknown: Story = { + args: { + job: { + ...MockProvisionerJob, + status: "unknown", + }, + }, +}; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/JobStatusIndicator.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.tsx similarity index 63% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/JobStatusIndicator.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.tsx index 0671a6b932d10..2111b11902129 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/JobStatusIndicator.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.tsx @@ -1,8 +1,4 @@ -import type { - ProvisionerDaemonJob, - ProvisionerJob, - ProvisionerJobStatus, -} from "api/typesGenerated"; +import type { ProvisionerJob, ProvisionerJobStatus } from "api/typesGenerated"; import { StatusIndicator, StatusIndicatorDot, @@ -40,21 +36,3 @@ export const JobStatusIndicator: FC = ({ job }) => { ); }; - -type DaemonJobStatusIndicatorProps = { - job: ProvisionerDaemonJob; -}; - -export const DaemonJobStatusIndicator: FC = ({ - job, -}) => { - return ( - - - {job.status} - {job.status === "failed" && ( - - )} - - ); -}; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx new file mode 100644 index 0000000000000..073086a45d30d --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx @@ -0,0 +1,1628 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import OrganizationProvisionerJobsPage from "./OrganizationProvisionerJobsPage"; +import { + MockOrganization, + MockOrganizationPermissions, +} from "testHelpers/entities"; +import type { ProvisionerJob } from "api/typesGenerated"; +import { daysAgo } from "utils/time"; +import { userEvent, waitFor, within, expect } from "@storybook/test"; + +const defaultOrganizationSettingsValue = { + organization: MockOrganization, + organizationPermissionsByOrganizationId: {}, + organizations: [MockOrganization], + organizationPermissions: MockOrganizationPermissions, +}; + +const meta: Meta = { + title: "pages/OrganizationProvisionerJobsPage", + component: OrganizationProvisionerJobsPage, + args: { + defaultOrganizationSettingsValue, + getProvisionerJobs: async () => MockProvisionerJobs, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const OrganizationNotFound: Story = { + args: { + defaultOrganizationSettingsValue: { + ...defaultOrganizationSettingsValue, + organization: undefined, + }, + }, +}; + +export const Loading: Story = { + args: { + getProvisionerJobs: () => + new Promise((res) => { + setTimeout(res, 100_000); + }), + }, +}; + +export const LoadingError: Story = { + args: { + getProvisionerJobs: async () => { + throw new Error("Failed to load jobs"); + }, + }, +}; + +export const RetryAfterError: Story = { + args: { + getProvisionerJobs: (() => { + let count = 0; + + return async () => { + count++; + + if (count === 1) { + throw new Error("Failed to load jobs"); + } + + return MockProvisionerJobs; + }; + })(), + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const retryButton = await canvas.findByRole("button", { name: "Retry" }); + + userEvent.click(retryButton); + + await waitFor(() => { + const rows = canvasElement.querySelectorAll("tbody > tr"); + expect(rows).toHaveLength(MockProvisionerJobs.length); + }); + }, +}; + +export const Empty: Story = { + args: { + getProvisionerJobs: async () => [], + }, +}; + +const MockProvisionerJobs: ProvisionerJob[] = [ + { + id: "f5de6c0a-953e-4b33-8589-aaea0a2b3ac1", + created_at: daysAgo(2), + started_at: "2025-03-10T16:55:38.725215Z", + completed_at: "2025-03-10T16:55:55.659245Z", + status: "succeeded", + worker_id: "9931f161-cb63-4fa2-91a4-04a0e49b530e", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "b917b683-0792-4c49-96cb-63ed544758d8", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "81b937d7-5777-4df5-b5cb-80241f30326f", + workspace_name: "pog2", + }, + }, + { + id: "f2414230-1f36-40a1-b91d-ba3d7942f5d4", + created_at: daysAgo(2), + started_at: "2025-03-10T15:56:16.747888Z", + completed_at: "2025-03-10T15:56:27.744942Z", + status: "succeeded", + worker_id: "c0c34314-de6c-4683-b31b-0f051857c6a1", + file_id: "1fc752d7-d518-444a-bfff-0613e57de6fc", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a9c10592-4c78-4243-b2eb-7048b9c33ac8", + }, + type: "workspace_build", + metadata: { + template_version_name: "546d915", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "bffd162c-f10c-4f15-856a-6af2d68d8ead", + workspace_name: "bagel", + }, + }, + { + id: "7cc08825-4c8c-45fa-8926-b6dd216b9fbb", + created_at: daysAgo(2), + started_at: "2025-03-10T15:56:11.233745Z", + completed_at: "2025-03-10T15:56:16.475245Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "1fc752d7-d518-444a-bfff-0613e57de6fc", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + template_version_id: "6efd4b22-e88a-4dec-8a6e-ffa1c97157e6", + }, + type: "template_version_dry_run", + metadata: { + template_version_name: "546d915", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + }, + }, + { + id: "6cceb4d7-5904-4ae7-ba65-b00c443a1ba2", + created_at: daysAgo(2), + started_at: "2025-03-10T15:47:44.778542Z", + completed_at: "2025-03-10T15:48:20.319366Z", + error: "terraform plan: exit status 1", + status: "failed", + worker_id: "c5df0266-1947-49c0-b422-ffea42f98295", + file_id: "89f2eafc-fffa-488b-8dba-8fefa7dbbd2f", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "c63ffdbe-79ef-4664-9575-47a25ad8d958", + }, + type: "workspace_build", + metadata: { + template_version_name: "eb72866", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "6124440f-84ee-4cb2-8080-3a285fc0380e", + workspace_name: "blah", + }, + }, + { + id: "f53cdfa6-3b8d-41fc-b03e-cfe7fb418d6a", + created_at: daysAgo(2), + started_at: "2025-03-10T15:30:44.804282Z", + completed_at: "2025-03-10T15:30:52.951307Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "bda3cc38-5d42-498d-b32b-ec76f7914f1d", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "d846be7b-7fd5-4f5b-ae2b-9d2ada5bee03", + workspace_name: "aspen", + }, + }, + { + id: "91c1b023-3ca3-4d56-a999-c5caf34462c3", + created_at: daysAgo(2), + started_at: "2025-03-10T15:28:30.311966Z", + completed_at: "2025-03-10T15:28:39.563397Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "d890b9ad-dbc3-4c14-8f21-2b266015b46a", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "7a878ab0-723b-4c93-8615-690091b617e5", + workspace_name: "another-k", + }, + }, + { + id: "17139da6-27af-4aef-8760-1e43a853811e", + created_at: daysAgo(2), + started_at: "2025-03-10T15:01:44.808341Z", + completed_at: "2025-03-10T15:01:52.539856Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "2971223b-5044-48db-8418-12c0d5d9c440", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "05998293-76d4-4ee5-afbb-5c303f675f77", + workspace_name: "dev", + }, + }, + { + id: "e6199254-3a57-4764-8b9b-7bb334e2a844", + created_at: daysAgo(2), + started_at: "2025-03-10T15:00:44.830301Z", + completed_at: "2025-03-10T15:00:53.159933Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "4a061c28-6f53-4188-a59e-a38075928aee", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "0227ff20-adca-4984-9c62-7de90bd48bff", + workspace_name: "dev", + }, + }, + { + id: "62e651c4-ca56-49c9-9437-b4317e9eab89", + created_at: daysAgo(2), + started_at: "2025-03-10T14:57:16.922776Z", + completed_at: "2025-03-10T14:57:26.825752Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "d24adfc2-557e-4e0a-988d-3d457a8e42b1", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e4cd7360-d2dd-4139-8717-0ba0fb8fba87", + workspace_name: "clawed", + }, + }, + { + id: "993c6a84-fed6-483b-939e-c29a8be479a8", + created_at: daysAgo(2), + started_at: "2025-03-10T14:47:43.194604Z", + completed_at: "2025-03-10T14:47:53.20559Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "d9a3edb5-8922-4ac7-85c1-9ed13d809057", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "cfc0a66c-316b-4d5f-af53-4757bf000ffe", + workspace_name: "peach-cricket-38", + }, + }, + { + id: "62134b38-3593-4e30-a889-4bddb1377354", + created_at: daysAgo(2), + started_at: "2025-03-10T14:44:27.34817Z", + completed_at: "2025-03-10T14:44:37.863161Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "72747879-46c4-4ec6-bcdf-38044cf00cbf", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "cfc0a66c-316b-4d5f-af53-4757bf000ffe", + workspace_name: "peach-cricket-38", + }, + }, + { + id: "a70dd91f-5254-4e77-8699-6250e2070263", + created_at: daysAgo(2), + started_at: "2025-03-10T14:43:23.121368Z", + completed_at: "2025-03-10T14:43:30.678666Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "d4c8c042-6821-44cc-b52a-70671700eae4", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + template_version_id: "8d103e49-5e35-4309-bcda-5a1b9f663647", + }, + type: "template_version_import", + metadata: { + template_version_name: "kind_bose1", + template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", + template_name: "coder-with-ai", + template_display_name: "Write Coder on Coder with AI", + template_icon: "/emojis/1f916.png", + }, + }, + { + id: "96c08785-5a50-4c8e-bd4f-0ba3fa546764", + created_at: daysAgo(2), + started_at: "2025-03-10T14:31:38.086908Z", + completed_at: "2025-03-10T14:31:46.266121Z", + status: "succeeded", + worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", + file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "532a04f1-caaf-4804-86ee-d90c7851b6c8", + }, + type: "workspace_build", + metadata: { + template_version_name: "clever_nash3", + template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", + template_name: "coder-with-ai", + template_display_name: "Write Coder on Coder with AI", + template_icon: "/emojis/1f916.png", + workspace_id: "a2d2f4f9-52dd-4c41-a3e5-8efe60481ea8", + workspace_name: "bronze-quail-81", + }, + }, + { + id: "2ab83d83-2927-4295-8e78-bc03b1cf3b8b", + created_at: daysAgo(2), + started_at: "2025-03-10T14:30:44.804225Z", + completed_at: "2025-03-10T14:30:53.182305Z", + status: "succeeded", + worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "0852bec0-7fa2-402f-8bc6-50c9053deced", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "dd778093-c676-428c-a02e-63aae4f2e780", + workspace_name: "c0", + }, + }, + { + id: "930521b2-7700-4fc3-a0e3-6c5ff978b4d0", + created_at: daysAgo(2), + started_at: "2025-03-10T14:30:44.804244Z", + completed_at: "2025-03-10T14:30:53.167478Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "cdf10951-24ab-4718-a0aa-8b39c399a312", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "9cf3a634-6da6-41fc-a9b4-47ff73a76d64", + workspace_name: "dev", + }, + }, + { + id: "52e329a7-83ad-473a-a62d-3b2fa5fb30a9", + created_at: daysAgo(2), + started_at: "2025-03-10T13:33:32.274361Z", + completed_at: "2025-03-10T13:33:46.461053Z", + status: "succeeded", + worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "6fb5219f-94d6-458c-8a45-b2245c836cec", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "314e2664-8c92-444d-9f4e-f2ba703a6766", + workspace_name: "docs", + }, + }, + { + id: "7d600f50-3948-4b39-b33f-041823287a86", + created_at: daysAgo(2), + started_at: "2025-03-10T13:26:57.942724Z", + completed_at: "2025-03-10T13:27:05.2834Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "9084af1b-9404-4c0f-aab7-7b40511ca7ec", + }, + type: "workspace_build", + metadata: { + template_version_name: "10f1e0b", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e3da7c66-d4ff-4d6b-a9fb-88707ab600f7", + workspace_name: "doom", + }, + }, + { + id: "1c257080-7b8e-45ed-8452-a232cce8fef8", + created_at: daysAgo(2), + started_at: "2025-03-10T13:26:52.784112Z", + completed_at: "2025-03-10T13:26:57.73707Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + template_version_id: "ac986c56-3757-4762-b969-88810c5bedbb", + }, + type: "template_version_dry_run", + metadata: { + template_version_name: "10f1e0b", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + }, + }, + { + id: "9fb5ab92-3ced-4b68-aeb4-8fb0f4687cab", + created_at: daysAgo(2), + started_at: "2025-03-10T13:07:47.492903Z", + completed_at: "2025-03-10T13:08:00.666302Z", + status: "succeeded", + worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", + file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "81cd23c8-f1a5-4aa0-884f-ce9880f735e0", + }, + type: "workspace_build", + metadata: { + template_version_name: "clever_nash3", + template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", + template_name: "coder-with-ai", + template_display_name: "Write Coder on Coder with AI", + template_icon: "/emojis/1f916.png", + workspace_id: "ddfecf3d-f0e1-46a9-8ede-737e7e07c519", + workspace_name: "fuchsia-bee-33", + }, + }, + { + id: "4804ece2-9fcb-4291-a7cf-a6e97ee41a29", + created_at: daysAgo(2), + started_at: "2025-03-10T12:00:42.768103Z", + completed_at: "2025-03-10T12:00:50.438421Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "e99057d6-af40-4c07-8375-2d3e9bf1b305", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "05998293-76d4-4ee5-afbb-5c303f675f77", + workspace_name: "dev", + }, + }, + { + id: "7d39786b-6bb3-402c-8f51-6195cec9a332", + created_at: daysAgo(2), + started_at: "2025-03-10T11:30:42.757916Z", + completed_at: "2025-03-10T11:30:52.551269Z", + status: "succeeded", + worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "10dc43be-982a-4e17-9908-fb562281856b", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "192acfe6-339b-4745-8cd5-1b44a4e76348", + workspace_name: "bruno-br-2", + }, + }, + { + id: "78e954dd-fdd0-4b8b-a4ec-77ff28275718", + created_at: daysAgo(2), + started_at: "2025-03-10T11:26:30.193632Z", + completed_at: "2025-03-10T11:26:39.468641Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "48143ccf-5008-4ab7-a792-ade7fe15c4f5", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "f6245ffc-af76-412e-9c02-064d6fdc8a4f", + workspace_name: "workspace-3", + }, + }, + { + id: "9bff874d-8fe4-4226-ba65-caf5613cd07a", + created_at: daysAgo(2), + started_at: "2025-03-10T10:06:35.369091Z", + completed_at: "2025-03-10T10:06:43.722892Z", + status: "succeeded", + worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "ec5b7ef8-8718-4815-a6f3-59fa1b8ecadc", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "866a36aa-e29d-428d-9938-9206d46fd49b", + workspace_name: "dogfood", + }, + }, + { + id: "6bf54158-0c06-41ea-918e-f9bbe4147966", + created_at: daysAgo(2), + started_at: "2025-03-10T08:50:42.77128Z", + completed_at: "2025-03-10T08:51:40.032627Z", + status: "succeeded", + worker_id: "f768db22-625d-4351-a6eb-cecfd19919e9", + file_id: "fc5790c4-ca1c-472a-8b19-c6df42439ad4", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "8c78aa6f-c2c0-48c3-830b-a1a7004db4be", + }, + type: "workspace_build", + metadata: { + template_version_name: "blissful_bouman7", + template_id: "6f256fea-64aa-4a41-8250-c955cba22369", + template_name: "coder-envbuilder", + template_display_name: "Write Coder on Coder in Envbuilder", + template_icon: "/emojis/1f3d7.png", + workspace_id: "7920a568-fa24-4d3d-aeca-2196956693f5", + workspace_name: "eb", + }, + }, + { + id: "fac5f2bb-5ea2-46aa-a01b-1162888740c2", + created_at: daysAgo(2), + started_at: "2025-03-10T08:30:53.08478Z", + completed_at: "2025-03-10T08:31:03.545016Z", + status: "succeeded", + worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "47bbc397-7632-4530-bf5b-f5f702da49a8", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "c1397037-97de-4cb7-a240-25e10ab8badb", + workspace_name: "main", + }, + }, + { + id: "23e15ceb-7fd3-4e9d-bbad-ba9d3c956559", + created_at: daysAgo(2), + started_at: "2025-03-10T08:30:42.792625Z", + completed_at: "2025-03-10T08:30:53.26441Z", + status: "succeeded", + worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "b4943958-0fce-4662-804a-993cd2cad29a", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", + workspace_name: "danielle-coder-on-coder", + }, + }, + { + id: "a066b7bb-2634-4b57-80b0-9b0010e4cdad", + created_at: daysAgo(2), + started_at: "2025-03-10T08:30:42.787308Z", + completed_at: "2025-03-10T08:30:52.85387Z", + status: "succeeded", + worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "966ce4a8-53cd-4c8b-995a-718e1d045dbd", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "c10a40d0-6065-47ee-b17a-2ac57846e81b", + workspace_name: "nonix", + }, + }, + { + id: "a6835d2f-3909-45f3-b9ca-5df90d1b1c3e", + created_at: daysAgo(2), + started_at: "2025-03-10T08:30:42.7873Z", + completed_at: "2025-03-10T08:30:53.571858Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "c4e60c95-3f95-4912-bebf-6b52f02e81ba", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "a99e9245-56bd-44b0-8e3c-134c5d084476", + workspace_name: "workspace-04092024", + }, + }, + { + id: "f9d7bd07-9dfb-433c-b4c5-4a3b59701a43", + created_at: daysAgo(2), + started_at: "2025-03-10T08:00:42.759499Z", + completed_at: "2025-03-10T08:00:53.053394Z", + status: "succeeded", + worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "9122d768-ae5a-4ce2-8e91-ad673c856cab", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "bb601d85-5354-4b72-a00a-a9293dcaf9fb", + workspace_name: "w", + }, + }, + { + id: "c77e6591-69f3-4ee5-bfc8-0f9504d98b6d", + created_at: daysAgo(2), + started_at: "2025-03-10T06:10:40.651867Z", + completed_at: "2025-03-10T06:10:51.661778Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a3b4ba80-9d57-47b3-b4c3-770a9f5fde24", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "94707512-82eb-4533-bb10-2e62642dd006", + workspace_name: "sebenza-nonix", + }, + }, + { + id: "96373e8e-92db-45a6-b6e1-6084a07abdcd", + created_at: daysAgo(2), + started_at: "2025-03-10T05:55:42.757189Z", + completed_at: "2025-03-10T05:55:56.527391Z", + status: "succeeded", + worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a1b8cade-e193-4010-8569-eb53c43f742f", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "2f7d7949-613e-485e-9d1f-d5d5f1bd1a65", + workspace_name: "catfood", + }, + }, + { + id: "e444fb5b-0e04-4c31-8e37-69cea1c124c0", + created_at: daysAgo(2), + started_at: "2025-03-10T05:43:42.751376Z", + completed_at: "2025-03-10T05:43:54.450549Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "dc38794d-f4a2-4a7e-a1db-fca7f72c776b", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", + workspace_name: "danielle-coder-on-coder", + }, + }, + { + id: "8808cb86-6c6f-489f-bece-1cf8ed531476", + created_at: daysAgo(2), + started_at: "2025-03-10T05:08:42.75558Z", + completed_at: "2025-03-10T05:08:45.089148Z", + error: "initialize terraform: exit status 1", + status: "failed", + worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", + file_id: "b90a6622-ad0f-4170-b61f-6dc0ef09d2a3", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "16dc6faa-271d-4708-b427-790ff350e935", + }, + type: "workspace_build", + metadata: { + template_version_name: "vigorous_hypatia1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "3bf5a699-6fb8-47ac-88dc-6b4e5d69e4ad", + workspace_name: "pog-us", + }, + }, + { + id: "85429a7a-ec79-46f3-9580-1908a86bee1b", + created_at: daysAgo(2), + started_at: "2025-03-10T05:00:42.783177Z", + completed_at: "2025-03-10T05:00:54.101971Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "1e66d273-a088-405d-94cb-ffe7e9e693c8", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", + workspace_name: "nowjosias", + }, + }, + { + id: "2e0608e6-34f7-490e-acef-058a30c117e5", + created_at: daysAgo(2), + started_at: "2025-03-10T04:13:42.764767Z", + completed_at: "2025-03-10T04:13:52.105225Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "8b41c3dd-7d79-416a-a4c5-8179aebe1ad2", + }, + type: "workspace_build", + metadata: { + template_version_name: "10f1e0b", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e3da7c66-d4ff-4d6b-a9fb-88707ab600f7", + workspace_name: "doom", + }, + }, + { + id: "1305b80b-dcdb-4c69-9cd7-2248bbc963f6", + created_at: daysAgo(2), + started_at: "2025-03-10T01:34:42.760435Z", + completed_at: "2025-03-10T01:34:50.748349Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "65d3ba09-3484-4b22-a6e0-7a6329804225", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "45466ea3-256e-4084-aca6-e4fcde12558a", + workspace_name: "fresh", + }, + }, + { + id: "a50ee303-6bee-4db8-a359-c9d51bc9d4eb", + created_at: daysAgo(2), + started_at: "2025-03-10T01:00:42.762717Z", + completed_at: "2025-03-10T01:00:53.338598Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "3762eb5a-55bf-464e-a8e6-fd9711684ae3", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "81b937d7-5777-4df5-b5cb-80241f30326f", + workspace_name: "pog2", + }, + }, + { + id: "51b0af99-d84e-4a09-a956-187c9dca7ee8", + created_at: daysAgo(2), + started_at: "2025-03-10T00:49:53.324941Z", + completed_at: "2025-03-10T00:50:06.154346Z", + status: "succeeded", + worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", + file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "843a70bb-37e5-4730-979c-9b7fd6b30b8b", + }, + type: "workspace_build", + metadata: { + template_version_name: "clever_nash3", + template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", + template_name: "coder-with-ai", + template_display_name: "Write Coder on Coder with AI", + template_icon: "/emojis/1f916.png", + workspace_id: "2e64b355-1238-4fce-b209-f0284b7ec73b", + workspace_name: "gold-hare-1", + }, + }, + { + id: "31e405ff-5be3-4fd2-9f64-52788425dbee", + created_at: daysAgo(2), + started_at: "2025-03-09T22:37:27.632825Z", + completed_at: "2025-03-09T22:40:59.993353Z", + status: "succeeded", + worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", + file_id: "69a5d2a6-c61a-493d-a2f0-047cc145a529", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "60763d5d-ef2c-459a-afbc-4f3b6f895d42", + }, + type: "workspace_build", + metadata: { + template_version_name: "blissful_cray3", + template_id: "f097e941-5c08-4032-b068-328154d13e66", + template_name: "docker-android", + template_display_name: "Android in Coder (Théo)", + template_icon: "/icon/android-studio.svg", + workspace_id: "320cb8ea-2687-4252-8ce9-6fcc1b4b0efc", + workspace_name: "crimson-mule-82", + }, + }, + { + id: "66854094-9848-4d5a-8a52-f7aa93b686ea", + created_at: daysAgo(2), + started_at: "2025-03-09T21:54:07.876842Z", + completed_at: "2025-03-09T21:54:20.427385Z", + status: "succeeded", + worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "69a47080-1456-4f6b-8587-6b19cbb748c5", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "2f7d7949-613e-485e-9d1f-d5d5f1bd1a65", + workspace_name: "catfood", + }, + }, + { + id: "d104b2a0-7351-44fc-82b7-3414761a48a9", + created_at: daysAgo(2), + started_at: "2025-03-09T21:38:53.551525Z", + completed_at: "2025-03-09T21:39:00.162185Z", + status: "succeeded", + worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", + file_id: "b0c6361a-d3c3-40d2-9b10-515d459e5aa6", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "83f9e3bb-da95-4de1-b7c7-cefbd1d6cfe8", + }, + type: "workspace_build", + metadata: { + template_version_name: "nifty_chatterjee1", + template_id: "220507c7-c609-41f9-82c0-771e07c1c7bb", + template_name: "dogfood-v2-psql", + template_display_name: "Connect to dogfood-v2 PostgreSQL database", + template_icon: "/emojis/1f418.png", + workspace_id: "d265ebaa-1cab-4668-b831-51272ad423d2", + workspace_name: "harlequin-junglefowl-90", + }, + }, + { + id: "c14c6aae-a3e8-451a-82ac-70011b4670b1", + created_at: daysAgo(2), + started_at: "2025-03-09T21:23:42.745993Z", + completed_at: "2025-03-09T21:23:48.28541Z", + status: "succeeded", + worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", + file_id: "71de01ae-2fd8-45a2-94dc-1f70b269f97a", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a18dc55d-621c-499e-ad55-d0ef10d6e898", + }, + type: "workspace_build", + metadata: { + template_version_name: "trusting_rhodes0", + template_id: "ba61a572-1f14-438f-8669-9c4996b802e6", + template_name: "chrome", + template_display_name: "Google Chrome", + template_icon: + "https://upload.wikimedia.org/wikipedia/commons/e/e1/Google_Chrome_icon_%28February_2022%29.svg", + workspace_id: "bf0dd1c5-3f76-4586-8f95-d5e568e92629", + workspace_name: "dlp", + }, + }, + { + id: "ed80c75c-393f-4986-a16f-2994bd6960b1", + created_at: daysAgo(2), + started_at: "2025-03-09T20:54:06.278404Z", + completed_at: "2025-03-09T20:54:17.42226Z", + status: "succeeded", + worker_id: "954fa457-b3a3-4420-ba13-e16c3eb9ae92", + file_id: "b0c6361a-d3c3-40d2-9b10-515d459e5aa6", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a3f0d013-c6d4-4520-8705-39089201c111", + }, + type: "workspace_build", + metadata: { + template_version_name: "nifty_chatterjee1", + template_id: "220507c7-c609-41f9-82c0-771e07c1c7bb", + template_name: "dogfood-v2-psql", + template_display_name: "Connect to dogfood-v2 PostgreSQL database", + template_icon: "/emojis/1f418.png", + workspace_id: "d265ebaa-1cab-4668-b831-51272ad423d2", + workspace_name: "harlequin-junglefowl-90", + }, + }, + { + id: "03d9e93a-139a-4acc-bc36-9d31848e7aa5", + created_at: daysAgo(2), + started_at: "2025-03-09T20:42:15.70548Z", + completed_at: "2025-03-09T20:42:26.144909Z", + status: "succeeded", + worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "bbf5a543-7b76-4509-b380-bcd2f9f4670c", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", + workspace_name: "danielle-coder-on-coder", + }, + }, + { + id: "8ff8c6b7-b7ce-4ec8-85ba-fdb9af0a78c8", + created_at: daysAgo(2), + started_at: "2025-03-09T17:33:45.909249Z", + completed_at: "2025-03-09T17:33:54.243355Z", + status: "succeeded", + worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", + file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "c13692b1-c9b2-447d-9c4b-67cfa98f9523", + }, + type: "workspace_build", + metadata: { + template_version_name: "clever_nash3", + template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", + template_name: "coder-with-ai", + template_display_name: "Write Coder on Coder with AI", + template_icon: "/emojis/1f916.png", + workspace_id: "1794a2ec-6083-4b3e-aa3c-770b2e19ec47", + workspace_name: "indigo-skink-45", + }, + }, + { + id: "77b93fde-7142-4a7c-9e04-6391578416d1", + created_at: daysAgo(2), + started_at: "2025-03-09T17:33:07.585278Z", + completed_at: "2025-03-09T17:33:16.406362Z", + status: "succeeded", + worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "9121e975-41a0-4f51-bafc-7035ecd47491", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "45466ea3-256e-4084-aca6-e4fcde12558a", + workspace_name: "fresh", + }, + }, + { + id: "366fa27c-c8db-4535-a493-676d42042c1c", + created_at: daysAgo(2), + started_at: "2025-03-09T15:46:22.101203Z", + completed_at: "2025-03-09T15:46:57.765089Z", + error: "terraform plan: exit status 1", + status: "failed", + worker_id: "28fe48b4-b2b1-46e6-8b9b-52c9ead9db31", + file_id: "89f2eafc-fffa-488b-8dba-8fefa7dbbd2f", + tags: { + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "4bbce962-d864-4c89-b615-c8e445e0e693", + }, + type: "workspace_build", + metadata: { + template_version_name: "eb72866", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "6124440f-84ee-4cb2-8080-3a285fc0380e", + workspace_name: "blah", + }, + }, + { + id: "750e8c6e-1471-4378-aa49-437420c57505", + created_at: daysAgo(2), + started_at: "2025-03-09T12:29:08.656319Z", + completed_at: "2025-03-09T12:29:19.81815Z", + status: "succeeded", + worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", + file_id: "f2534f2b-9fff-4e40-b356-b06d5e29c54d", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "0b0af776-f98d-479c-aae9-fbab6c19ffc1", + }, + type: "workspace_build", + metadata: { + template_version_name: "wizardly_ishizaka2", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "5d4989ac-d885-4666-a312-2b7a172b4a07", + workspace_name: "pog", + }, + }, + { + id: "373cb47a-c33b-4e35-83bf-23c64fde0293", + created_at: daysAgo(2), + started_at: "2025-03-09T08:01:22.118677Z", + completed_at: "2025-03-09T08:01:33.310184Z", + status: "succeeded", + worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", + file_id: "a99685a6-4441-4258-8102-f07e571204fb", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "0153584a-6cbe-4c90-8e9e-4ffb40fd1069", + }, + type: "workspace_build", + metadata: { + template_version_name: "54745b1", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", + workspace_name: "nowjosias", + }, + }, + { + id: "611cb463-5223-4c67-8105-3a48f94e7c99", + created_at: daysAgo(2), + started_at: "2025-03-09T07:04:49.996671Z", + completed_at: "2025-03-09T07:04:57.095615Z", + status: "succeeded", + worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", + file_id: "f2534f2b-9fff-4e40-b356-b06d5e29c54d", + tags: { + cluster: "dogfood-v2", + env: "gke", + owner: "", + scope: "organization", + }, + queue_position: 0, + queue_size: 24, + organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", + input: { + workspace_build_id: "a095476b-6c84-4c51-b88b-44a34ad1462f", + }, + type: "workspace_build", + metadata: { + template_version_name: "wizardly_ishizaka2", + template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", + template_name: "coder", + template_display_name: "Write Coder on Coder", + template_icon: "/emojis/1f3c5.png", + workspace_id: "65be8c8f-0cb1-49b2-a4e5-23652c4b686f", + workspace_name: "release", + }, + }, +]; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx new file mode 100644 index 0000000000000..af32bf449d1cb --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx @@ -0,0 +1,120 @@ +import { provisionerJobs } from "api/queries/organizations"; +import { Button } from "components/Button/Button"; +import { EmptyState } from "components/EmptyState/EmptyState"; +import { Link } from "components/Link/Link"; +import { Loader } from "components/Loader/Loader"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; +import type { FC } from "react"; +import { useQuery } from "react-query"; +import { docs } from "utils/docs"; +import { + type OrganizationSettingsValue, + useOrganizationSettings, +} from "modules/management/OrganizationSettingsLayout"; +import { Helmet } from "react-helmet-async"; +import { pageTitle } from "utils/page"; +import type { API } from "api/api"; +import { JobRow } from "./JobRow"; + +type OrganizationProvisionerJobsPageProps = { + defaultOrganizationSettingsValue?: OrganizationSettingsValue; + getProvisionerJobs?: typeof API.getProvisionerJobs; +}; + +const OrganizationProvisionerJobsPage: FC< + OrganizationProvisionerJobsPageProps +> = ({ defaultOrganizationSettingsValue, getProvisionerJobs }) => { + const { organization } = useOrganizationSettings( + defaultOrganizationSettingsValue, + ); + + if (!organization) { + return ; + } + + const { + data: jobs, + isLoadingError, + refetch, + } = useQuery(provisionerJobs(organization.id, getProvisionerJobs)); + + return ( + <> + + + {pageTitle( + "Provisioner Jobs", + organization.display_name || organization.name, + )} + + + +
+
+
+

Provisioner Jobs

+

+ Provisioner Jobs are the individual tasks assigned to Provisioners + when the workspaces are being built.{" "} + View docs +

+
+
+ + + + + Created + Type + Template + Tags + Status + + + + + {jobs ? ( + jobs.length > 0 ? ( + jobs.map((j) => ) + ) : ( + + + + + + ) + ) : isLoadingError ? ( + + + refetch()}> + Retry + + } + /> + + + ) : ( + + + + + + )} + +
+
+ + ); +}; + +export default OrganizationProvisionerJobsPage; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.stories.tsx new file mode 100644 index 0000000000000..8d4612d525bdf --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.stories.tsx @@ -0,0 +1,45 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { + Tag as TagComponent, + Tags as TagsComponent, + TruncateTags as TruncateTagsComponent, +} from "./Tags"; + +const meta: Meta = { + title: "pages/OrganizationProvisionerJobsPage/Tags", +}; + +export default meta; +type Story = StoryObj; + +export const Tag: Story = { + render: () => { + return ; + }, +}; + +export const Tags: Story = { + render: () => { + return ( + + + + + + ); + }, +}; + +export const TruncateTags: Story = { + render: () => { + return ( + + ); + }, +}; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/Tags.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.tsx similarity index 100% rename from site/src/pages/OrganizationSettingsPage/ProvisionersPage/Tags.tsx rename to site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/Tags.tsx diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/DataGrid.tsx b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/DataGrid.tsx deleted file mode 100644 index 7c9d11a238581..0000000000000 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/DataGrid.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { FC, HTMLProps } from "react"; -import { cn } from "utils/cn"; - -export const DataGrid: FC> = ({ - className, - ...props -}) => { - return ( -
- ); -}; - -export const DataGridSpace: FC> = ({ - className, - ...props -}) => { - return
; -}; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerDaemonsPage.tsx b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerDaemonsPage.tsx deleted file mode 100644 index ae57ebb90aad7..0000000000000 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerDaemonsPage.tsx +++ /dev/null @@ -1,274 +0,0 @@ -import { provisionerDaemons } from "api/queries/organizations"; -import type { ProvisionerDaemon } from "api/typesGenerated"; -import { Avatar } from "components/Avatar/Avatar"; -import { Button } from "components/Button/Button"; -import { EmptyState } from "components/EmptyState/EmptyState"; -import { Link } from "components/Link/Link"; -import { Loader } from "components/Loader/Loader"; -import { - StatusIndicator, - StatusIndicatorDot, - type StatusIndicatorProps, -} from "components/StatusIndicator/StatusIndicator"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "components/Table/Table"; -import { ChevronDownIcon, ChevronRightIcon } from "lucide-react"; -import { type FC, useState } from "react"; -import { useQuery } from "react-query"; -import { cn } from "utils/cn"; -import { docs } from "utils/docs"; -import { relativeTime } from "utils/time"; -import { DataGrid, DataGridSpace } from "./DataGrid"; -import { DaemonJobStatusIndicator } from "./JobStatusIndicator"; -import { Tag, Tags, TruncateTags } from "./Tags"; - -type ProvisionerDaemonsPageProps = { - orgId: string; -}; - -export const ProvisionerDaemonsPage: FC = ({ - orgId, -}) => { - const { - data: daemons, - isLoadingError, - refetch, - } = useQuery({ - ...provisionerDaemons(orgId), - select: (data) => - data.toSorted((a, b) => { - if (!a.last_seen_at && !b.last_seen_at) return 0; - if (!a.last_seen_at) return 1; - if (!b.last_seen_at) return -1; - return ( - new Date(b.last_seen_at).getTime() - - new Date(a.last_seen_at).getTime() - ); - }), - }); - - return ( -
-

Provisioner daemons

-

- Coder server runs provisioner daemons which execute terraform during - workspace and template builds.{" "} - - View docs - -

- - - - - Last seen - Name - Template - Tags - Status - - - - {daemons ? ( - daemons.length > 0 ? ( - daemons.map((d) => ) - ) : ( - - - - - - ) - ) : isLoadingError ? ( - - - refetch()}>Retry} - /> - - - ) : ( - - - - - - )} - -
-
- ); -}; - -type DaemonRowProps = { - daemon: ProvisionerDaemon; -}; - -const DaemonRow: FC = ({ daemon }) => { - const [isOpen, setIsOpen] = useState(false); - - return ( - <> - - - - - - - {daemon.name} - - - - {daemon.current_job ? ( -
- - {daemon.current_job.template_display_name ?? - daemon.current_job.template_name} -
- ) : ( - Not linked - )} -
- - - - - - - - {statusLabel(daemon)} - - - -
- - {isOpen && ( - - - -
Last seen:
-
{daemon.last_seen_at}
- -
Creation time:
-
{daemon.created_at}
- -
Version:
-
{daemon.version}
- -
Tags:
-
- - {Object.entries(daemon.tags).map(([key, value]) => ( - - ))} - -
- - {daemon.current_job && ( - <> - - -
Last job:
-
{daemon.current_job.id}
- -
Last job state:
-
- -
- - )} - - {daemon.previous_job && ( - <> - - -
Previous job:
-
{daemon.previous_job.id}
- -
Previous job state:
-
- -
- - )} -
-
-
- )} - - ); -}; - -function statusIndicatorVariant( - daemon: ProvisionerDaemon, -): StatusIndicatorProps["variant"] { - if (daemon.previous_job && daemon.previous_job.status === "failed") { - return "failed"; - } - - switch (daemon.status) { - case "idle": - return "success"; - case "busy": - return "pending"; - default: - return "inactive"; - } -} - -function statusLabel(daemon: ProvisionerDaemon) { - if (daemon.previous_job && daemon.previous_job.status === "failed") { - return "Last job failed"; - } - - switch (daemon.status) { - case "idle": - return "Idle"; - case "busy": - return "Busy..."; - case "offline": - return "Disconnected"; - default: - return "Unknown"; - } -} diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx deleted file mode 100644 index 4091b754f3be6..0000000000000 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { EmptyState } from "components/EmptyState/EmptyState"; -import { TabLink, Tabs, TabsList } from "components/Tabs/Tabs"; -import { useSearchParamsKey } from "hooks/useSearchParamsKey"; -import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; -import type { FC } from "react"; -import { Helmet } from "react-helmet-async"; -import { pageTitle } from "utils/page"; -import { ProvisionerDaemonsPage } from "./ProvisionerDaemonsPage"; -import ProvisionerJobsPage from "./ProvisionerJobsPage"; - -const ProvisionersPage: FC = () => { - const { organization, organizationPermissions } = useOrganizationSettings(); - const tab = useSearchParamsKey({ - key: "tab", - defaultValue: "jobs", - }); - - if (!organization || !organizationPermissions?.viewProvisionerJobs) { - return ( - <> - - {pageTitle("Provisioners")} - - - - ); - } - - return ( - <> - - - {pageTitle( - "Provisioners", - organization.display_name || organization.name, - )} - - - -
-
-
-

Provisioners

-
-
- -
- - - - Jobs - - - Daemons - - - - -
- {tab.value === "jobs" && } - {tab.value === "daemons" && ( - - )} -
-
-
- - ); -}; - -export default ProvisionersPage; diff --git a/site/src/router.tsx b/site/src/router.tsx index 898b7be234e47..f90d58f47876b 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -312,7 +312,7 @@ const IdpOrgSyncPage = lazy( const ProvisionerJobsPage = lazy( () => import( - "./pages/OrganizationSettingsPage/ProvisionersPage/ProvisionerJobsPage" + "./pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage" ), ); diff --git a/site/src/utils/time.ts b/site/src/utils/time.ts index f890cd3f7a6ea..e46ef276171f1 100644 --- a/site/src/utils/time.ts +++ b/site/src/utils/time.ts @@ -40,3 +40,9 @@ export function durationInDays(duration: number): number { export function relativeTime(date: Date) { return dayjs(date).fromNow(); } + +export function daysAgo(count: number) { + const date = new Date(); + date.setDate(date.getDate() - count); + return date.toISOString(); +} From 912cd8f2019114231a5467a208b8fad75090260a Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Mon, 10 Mar 2025 17:56:06 +0000 Subject: [PATCH 3/7] FMT --- .../OrganizationProvisionerJobsPage/JobRow.stories.tsx | 4 ++-- .../OrganizationProvisionerJobsPage/JobRow.tsx | 6 +++--- .../JobStatusIndicator.stories.tsx | 2 +- .../OrganizationProvisionerJobsPage.stories.tsx | 6 +++--- .../OrganizationProvisionerJobsPage.tsx | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx index 5f455a4c74043..2824e1441a2b2 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx @@ -1,8 +1,8 @@ import type { Meta, StoryObj } from "@storybook/react"; +import { expect, userEvent, waitFor, within } from "@storybook/test"; +import { Table, TableBody } from "components/Table/Table"; import { daysAgo } from "utils/time"; -import { userEvent, waitFor, within, expect } from "@storybook/test"; import { JobRow } from "./JobRow"; -import { Table, TableBody } from "components/Table/Table"; const meta: Meta = { title: "pages/OrganizationProvisionerJobsPage/JobRow", diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx index 6299f725e0a1d..2d84fe9625d67 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx @@ -1,4 +1,7 @@ import type { ProvisionerJob } from "api/typesGenerated"; +import { Avatar } from "components/Avatar/Avatar"; +import { Badge } from "components/Badge/Badge"; +import { TableCell, TableRow } from "components/Table/Table"; import { ChevronDownIcon, ChevronRightIcon, @@ -10,9 +13,6 @@ import { relativeTime } from "utils/time"; import { CancelJobButton } from "./CancelJobButton"; import { JobStatusIndicator } from "./JobStatusIndicator"; import { Tag, Tags, TruncateTags } from "./Tags"; -import { TableCell, TableRow } from "components/Table/Table"; -import { Avatar } from "components/Avatar/Avatar"; -import { Badge } from "components/Badge/Badge"; type JobRowProps = { job: ProvisionerJob; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx index 2c7ef63b6cf94..d77cc98cc168f 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobStatusIndicator.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { JobStatusIndicator } from "./JobStatusIndicator"; import { MockProvisionerJob } from "testHelpers/entities"; +import { JobStatusIndicator } from "./JobStatusIndicator"; const meta: Meta = { title: "pages/OrganizationProvisionerJobsPage/JobStatusIndicator", diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx index 073086a45d30d..1b03a93b1a07d 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx @@ -1,12 +1,12 @@ import type { Meta, StoryObj } from "@storybook/react"; -import OrganizationProvisionerJobsPage from "./OrganizationProvisionerJobsPage"; +import { expect, userEvent, waitFor, within } from "@storybook/test"; +import type { ProvisionerJob } from "api/typesGenerated"; import { MockOrganization, MockOrganizationPermissions, } from "testHelpers/entities"; -import type { ProvisionerJob } from "api/typesGenerated"; import { daysAgo } from "utils/time"; -import { userEvent, waitFor, within, expect } from "@storybook/test"; +import OrganizationProvisionerJobsPage from "./OrganizationProvisionerJobsPage"; const defaultOrganizationSettingsValue = { organization: MockOrganization, diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx index af32bf449d1cb..e26550b8f9b73 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx @@ -1,3 +1,4 @@ +import type { API } from "api/api"; import { provisionerJobs } from "api/queries/organizations"; import { Button } from "components/Button/Button"; import { EmptyState } from "components/EmptyState/EmptyState"; @@ -11,16 +12,15 @@ import { TableHeader, TableRow, } from "components/Table/Table"; -import type { FC } from "react"; -import { useQuery } from "react-query"; -import { docs } from "utils/docs"; import { type OrganizationSettingsValue, useOrganizationSettings, } from "modules/management/OrganizationSettingsLayout"; +import type { FC } from "react"; import { Helmet } from "react-helmet-async"; +import { useQuery } from "react-query"; +import { docs } from "utils/docs"; import { pageTitle } from "utils/page"; -import type { API } from "api/api"; import { JobRow } from "./JobRow"; type OrganizationProvisionerJobsPageProps = { From a56246f027bd7ca6028dd3fc65fc27e7f203a7b4 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Wed, 12 Mar 2025 13:49:40 +0000 Subject: [PATCH 4/7] Apply Kaylas suggestions --- .../management/OrganizationSettingsLayout.tsx | 6 +- .../JobRow.stories.tsx | 30 +- ...rganizationProvisionerJobsPage.stories.tsx | 1565 +---------------- .../OrganizationProvisionerJobsPage.tsx | 7 +- 4 files changed, 31 insertions(+), 1577 deletions(-) diff --git a/site/src/modules/management/OrganizationSettingsLayout.tsx b/site/src/modules/management/OrganizationSettingsLayout.tsx index 24f79fe3bd211..7d30b4d76921e 100644 --- a/site/src/modules/management/OrganizationSettingsLayout.tsx +++ b/site/src/modules/management/OrganizationSettingsLayout.tsx @@ -34,10 +34,8 @@ export type OrganizationSettingsValue = Readonly<{ organizationPermissions?: OrganizationPermissions; }>; -export const useOrganizationSettings = ( - defaultValues?: OrganizationSettingsValue, -): OrganizationSettingsValue => { - const context = useContext(OrganizationSettingsContext) ?? defaultValues; +export const useOrganizationSettings = (): OrganizationSettingsValue => { + const context = useContext(OrganizationSettingsContext); if (!context) { throw new Error( diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx index 2824e1441a2b2..67f760a463956 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { expect, userEvent, waitFor, within } from "@storybook/test"; import { Table, TableBody } from "components/Table/Table"; +import { MockProvisionerJob } from "testHelpers/entities"; import { daysAgo } from "utils/time"; import { JobRow } from "./JobRow"; @@ -9,35 +10,8 @@ const meta: Meta = { component: JobRow, args: { job: { - id: "373cb47a-c33b-4e35-83bf-23c64fde0293", + ...MockProvisionerJob, created_at: daysAgo(2), - started_at: "2025-03-09T08:01:22.118677Z", - completed_at: "2025-03-09T08:01:33.310184Z", - status: "succeeded", - worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "0153584a-6cbe-4c90-8e9e-4ffb40fd1069", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", - workspace_name: "nowjosias", - }, }, }, render: (args) => { diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx index 1b03a93b1a07d..3347f2f1bbf8e 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx @@ -1,9 +1,11 @@ import type { Meta, StoryObj } from "@storybook/react"; import { expect, userEvent, waitFor, within } from "@storybook/test"; import type { ProvisionerJob } from "api/typesGenerated"; +import { OrganizationSettingsContext } from "modules/management/OrganizationSettingsLayout"; import { MockOrganization, MockOrganizationPermissions, + MockProvisionerJob, } from "testHelpers/entities"; import { daysAgo } from "utils/time"; import OrganizationProvisionerJobsPage from "./OrganizationProvisionerJobsPage"; @@ -18,10 +20,21 @@ const defaultOrganizationSettingsValue = { const meta: Meta = { title: "pages/OrganizationProvisionerJobsPage", component: OrganizationProvisionerJobsPage, + decorators: [ + (Story, { parameters }) => ( + + + + ), + ], args: { - defaultOrganizationSettingsValue, getProvisionerJobs: async () => MockProvisionerJobs, }, + parameters: { + organizationSettingsValue: defaultOrganizationSettingsValue, + }, }; export default meta; @@ -30,10 +43,10 @@ type Story = StoryObj; export const Default: Story = {}; export const OrganizationNotFound: Story = { - args: { - defaultOrganizationSettingsValue: { + parameters: { + organizationSettingsValue: { ...defaultOrganizationSettingsValue, - organization: undefined, + organization: null, }, }, }; @@ -90,1539 +103,11 @@ export const Empty: Story = { }, }; -const MockProvisionerJobs: ProvisionerJob[] = [ - { - id: "f5de6c0a-953e-4b33-8589-aaea0a2b3ac1", - created_at: daysAgo(2), - started_at: "2025-03-10T16:55:38.725215Z", - completed_at: "2025-03-10T16:55:55.659245Z", - status: "succeeded", - worker_id: "9931f161-cb63-4fa2-91a4-04a0e49b530e", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "b917b683-0792-4c49-96cb-63ed544758d8", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "81b937d7-5777-4df5-b5cb-80241f30326f", - workspace_name: "pog2", - }, - }, - { - id: "f2414230-1f36-40a1-b91d-ba3d7942f5d4", - created_at: daysAgo(2), - started_at: "2025-03-10T15:56:16.747888Z", - completed_at: "2025-03-10T15:56:27.744942Z", - status: "succeeded", - worker_id: "c0c34314-de6c-4683-b31b-0f051857c6a1", - file_id: "1fc752d7-d518-444a-bfff-0613e57de6fc", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a9c10592-4c78-4243-b2eb-7048b9c33ac8", - }, - type: "workspace_build", - metadata: { - template_version_name: "546d915", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "bffd162c-f10c-4f15-856a-6af2d68d8ead", - workspace_name: "bagel", - }, - }, - { - id: "7cc08825-4c8c-45fa-8926-b6dd216b9fbb", - created_at: daysAgo(2), - started_at: "2025-03-10T15:56:11.233745Z", - completed_at: "2025-03-10T15:56:16.475245Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "1fc752d7-d518-444a-bfff-0613e57de6fc", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - template_version_id: "6efd4b22-e88a-4dec-8a6e-ffa1c97157e6", - }, - type: "template_version_dry_run", - metadata: { - template_version_name: "546d915", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - }, - }, - { - id: "6cceb4d7-5904-4ae7-ba65-b00c443a1ba2", - created_at: daysAgo(2), - started_at: "2025-03-10T15:47:44.778542Z", - completed_at: "2025-03-10T15:48:20.319366Z", - error: "terraform plan: exit status 1", - status: "failed", - worker_id: "c5df0266-1947-49c0-b422-ffea42f98295", - file_id: "89f2eafc-fffa-488b-8dba-8fefa7dbbd2f", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "c63ffdbe-79ef-4664-9575-47a25ad8d958", - }, - type: "workspace_build", - metadata: { - template_version_name: "eb72866", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "6124440f-84ee-4cb2-8080-3a285fc0380e", - workspace_name: "blah", - }, - }, - { - id: "f53cdfa6-3b8d-41fc-b03e-cfe7fb418d6a", - created_at: daysAgo(2), - started_at: "2025-03-10T15:30:44.804282Z", - completed_at: "2025-03-10T15:30:52.951307Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "bda3cc38-5d42-498d-b32b-ec76f7914f1d", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "d846be7b-7fd5-4f5b-ae2b-9d2ada5bee03", - workspace_name: "aspen", - }, - }, - { - id: "91c1b023-3ca3-4d56-a999-c5caf34462c3", - created_at: daysAgo(2), - started_at: "2025-03-10T15:28:30.311966Z", - completed_at: "2025-03-10T15:28:39.563397Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "d890b9ad-dbc3-4c14-8f21-2b266015b46a", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "7a878ab0-723b-4c93-8615-690091b617e5", - workspace_name: "another-k", - }, - }, - { - id: "17139da6-27af-4aef-8760-1e43a853811e", - created_at: daysAgo(2), - started_at: "2025-03-10T15:01:44.808341Z", - completed_at: "2025-03-10T15:01:52.539856Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "2971223b-5044-48db-8418-12c0d5d9c440", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "05998293-76d4-4ee5-afbb-5c303f675f77", - workspace_name: "dev", - }, - }, - { - id: "e6199254-3a57-4764-8b9b-7bb334e2a844", - created_at: daysAgo(2), - started_at: "2025-03-10T15:00:44.830301Z", - completed_at: "2025-03-10T15:00:53.159933Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "4a061c28-6f53-4188-a59e-a38075928aee", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "0227ff20-adca-4984-9c62-7de90bd48bff", - workspace_name: "dev", - }, - }, - { - id: "62e651c4-ca56-49c9-9437-b4317e9eab89", - created_at: daysAgo(2), - started_at: "2025-03-10T14:57:16.922776Z", - completed_at: "2025-03-10T14:57:26.825752Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "d24adfc2-557e-4e0a-988d-3d457a8e42b1", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e4cd7360-d2dd-4139-8717-0ba0fb8fba87", - workspace_name: "clawed", - }, - }, - { - id: "993c6a84-fed6-483b-939e-c29a8be479a8", - created_at: daysAgo(2), - started_at: "2025-03-10T14:47:43.194604Z", - completed_at: "2025-03-10T14:47:53.20559Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "d9a3edb5-8922-4ac7-85c1-9ed13d809057", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "cfc0a66c-316b-4d5f-af53-4757bf000ffe", - workspace_name: "peach-cricket-38", - }, - }, - { - id: "62134b38-3593-4e30-a889-4bddb1377354", - created_at: daysAgo(2), - started_at: "2025-03-10T14:44:27.34817Z", - completed_at: "2025-03-10T14:44:37.863161Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "72747879-46c4-4ec6-bcdf-38044cf00cbf", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "cfc0a66c-316b-4d5f-af53-4757bf000ffe", - workspace_name: "peach-cricket-38", - }, - }, - { - id: "a70dd91f-5254-4e77-8699-6250e2070263", - created_at: daysAgo(2), - started_at: "2025-03-10T14:43:23.121368Z", - completed_at: "2025-03-10T14:43:30.678666Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "d4c8c042-6821-44cc-b52a-70671700eae4", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - template_version_id: "8d103e49-5e35-4309-bcda-5a1b9f663647", - }, - type: "template_version_import", - metadata: { - template_version_name: "kind_bose1", - template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", - template_name: "coder-with-ai", - template_display_name: "Write Coder on Coder with AI", - template_icon: "/emojis/1f916.png", - }, - }, - { - id: "96c08785-5a50-4c8e-bd4f-0ba3fa546764", - created_at: daysAgo(2), - started_at: "2025-03-10T14:31:38.086908Z", - completed_at: "2025-03-10T14:31:46.266121Z", - status: "succeeded", - worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", - file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "532a04f1-caaf-4804-86ee-d90c7851b6c8", - }, - type: "workspace_build", - metadata: { - template_version_name: "clever_nash3", - template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", - template_name: "coder-with-ai", - template_display_name: "Write Coder on Coder with AI", - template_icon: "/emojis/1f916.png", - workspace_id: "a2d2f4f9-52dd-4c41-a3e5-8efe60481ea8", - workspace_name: "bronze-quail-81", - }, - }, - { - id: "2ab83d83-2927-4295-8e78-bc03b1cf3b8b", - created_at: daysAgo(2), - started_at: "2025-03-10T14:30:44.804225Z", - completed_at: "2025-03-10T14:30:53.182305Z", - status: "succeeded", - worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "0852bec0-7fa2-402f-8bc6-50c9053deced", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "dd778093-c676-428c-a02e-63aae4f2e780", - workspace_name: "c0", - }, - }, - { - id: "930521b2-7700-4fc3-a0e3-6c5ff978b4d0", - created_at: daysAgo(2), - started_at: "2025-03-10T14:30:44.804244Z", - completed_at: "2025-03-10T14:30:53.167478Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "cdf10951-24ab-4718-a0aa-8b39c399a312", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "9cf3a634-6da6-41fc-a9b4-47ff73a76d64", - workspace_name: "dev", - }, - }, - { - id: "52e329a7-83ad-473a-a62d-3b2fa5fb30a9", - created_at: daysAgo(2), - started_at: "2025-03-10T13:33:32.274361Z", - completed_at: "2025-03-10T13:33:46.461053Z", - status: "succeeded", - worker_id: "ade5b80f-a442-4fea-a50e-867975b607c8", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "6fb5219f-94d6-458c-8a45-b2245c836cec", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "314e2664-8c92-444d-9f4e-f2ba703a6766", - workspace_name: "docs", - }, - }, - { - id: "7d600f50-3948-4b39-b33f-041823287a86", - created_at: daysAgo(2), - started_at: "2025-03-10T13:26:57.942724Z", - completed_at: "2025-03-10T13:27:05.2834Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "9084af1b-9404-4c0f-aab7-7b40511ca7ec", - }, - type: "workspace_build", - metadata: { - template_version_name: "10f1e0b", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e3da7c66-d4ff-4d6b-a9fb-88707ab600f7", - workspace_name: "doom", - }, - }, - { - id: "1c257080-7b8e-45ed-8452-a232cce8fef8", - created_at: daysAgo(2), - started_at: "2025-03-10T13:26:52.784112Z", - completed_at: "2025-03-10T13:26:57.73707Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - template_version_id: "ac986c56-3757-4762-b969-88810c5bedbb", - }, - type: "template_version_dry_run", - metadata: { - template_version_name: "10f1e0b", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - }, - }, - { - id: "9fb5ab92-3ced-4b68-aeb4-8fb0f4687cab", - created_at: daysAgo(2), - started_at: "2025-03-10T13:07:47.492903Z", - completed_at: "2025-03-10T13:08:00.666302Z", - status: "succeeded", - worker_id: "8062ea04-9b0e-4f3b-b443-3f9ba221f908", - file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "81cd23c8-f1a5-4aa0-884f-ce9880f735e0", - }, - type: "workspace_build", - metadata: { - template_version_name: "clever_nash3", - template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", - template_name: "coder-with-ai", - template_display_name: "Write Coder on Coder with AI", - template_icon: "/emojis/1f916.png", - workspace_id: "ddfecf3d-f0e1-46a9-8ede-737e7e07c519", - workspace_name: "fuchsia-bee-33", - }, - }, - { - id: "4804ece2-9fcb-4291-a7cf-a6e97ee41a29", - created_at: daysAgo(2), - started_at: "2025-03-10T12:00:42.768103Z", - completed_at: "2025-03-10T12:00:50.438421Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "e99057d6-af40-4c07-8375-2d3e9bf1b305", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "05998293-76d4-4ee5-afbb-5c303f675f77", - workspace_name: "dev", - }, - }, - { - id: "7d39786b-6bb3-402c-8f51-6195cec9a332", - created_at: daysAgo(2), - started_at: "2025-03-10T11:30:42.757916Z", - completed_at: "2025-03-10T11:30:52.551269Z", - status: "succeeded", - worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "10dc43be-982a-4e17-9908-fb562281856b", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "192acfe6-339b-4745-8cd5-1b44a4e76348", - workspace_name: "bruno-br-2", - }, - }, - { - id: "78e954dd-fdd0-4b8b-a4ec-77ff28275718", - created_at: daysAgo(2), - started_at: "2025-03-10T11:26:30.193632Z", - completed_at: "2025-03-10T11:26:39.468641Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "48143ccf-5008-4ab7-a792-ade7fe15c4f5", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "f6245ffc-af76-412e-9c02-064d6fdc8a4f", - workspace_name: "workspace-3", - }, - }, - { - id: "9bff874d-8fe4-4226-ba65-caf5613cd07a", - created_at: daysAgo(2), - started_at: "2025-03-10T10:06:35.369091Z", - completed_at: "2025-03-10T10:06:43.722892Z", - status: "succeeded", - worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "ec5b7ef8-8718-4815-a6f3-59fa1b8ecadc", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "866a36aa-e29d-428d-9938-9206d46fd49b", - workspace_name: "dogfood", - }, - }, - { - id: "6bf54158-0c06-41ea-918e-f9bbe4147966", - created_at: daysAgo(2), - started_at: "2025-03-10T08:50:42.77128Z", - completed_at: "2025-03-10T08:51:40.032627Z", - status: "succeeded", - worker_id: "f768db22-625d-4351-a6eb-cecfd19919e9", - file_id: "fc5790c4-ca1c-472a-8b19-c6df42439ad4", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "8c78aa6f-c2c0-48c3-830b-a1a7004db4be", - }, - type: "workspace_build", - metadata: { - template_version_name: "blissful_bouman7", - template_id: "6f256fea-64aa-4a41-8250-c955cba22369", - template_name: "coder-envbuilder", - template_display_name: "Write Coder on Coder in Envbuilder", - template_icon: "/emojis/1f3d7.png", - workspace_id: "7920a568-fa24-4d3d-aeca-2196956693f5", - workspace_name: "eb", - }, - }, - { - id: "fac5f2bb-5ea2-46aa-a01b-1162888740c2", - created_at: daysAgo(2), - started_at: "2025-03-10T08:30:53.08478Z", - completed_at: "2025-03-10T08:31:03.545016Z", - status: "succeeded", - worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "47bbc397-7632-4530-bf5b-f5f702da49a8", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "c1397037-97de-4cb7-a240-25e10ab8badb", - workspace_name: "main", - }, - }, - { - id: "23e15ceb-7fd3-4e9d-bbad-ba9d3c956559", - created_at: daysAgo(2), - started_at: "2025-03-10T08:30:42.792625Z", - completed_at: "2025-03-10T08:30:53.26441Z", - status: "succeeded", - worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "b4943958-0fce-4662-804a-993cd2cad29a", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", - workspace_name: "danielle-coder-on-coder", - }, - }, - { - id: "a066b7bb-2634-4b57-80b0-9b0010e4cdad", - created_at: daysAgo(2), - started_at: "2025-03-10T08:30:42.787308Z", - completed_at: "2025-03-10T08:30:52.85387Z", - status: "succeeded", - worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "966ce4a8-53cd-4c8b-995a-718e1d045dbd", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "c10a40d0-6065-47ee-b17a-2ac57846e81b", - workspace_name: "nonix", - }, - }, - { - id: "a6835d2f-3909-45f3-b9ca-5df90d1b1c3e", - created_at: daysAgo(2), - started_at: "2025-03-10T08:30:42.7873Z", - completed_at: "2025-03-10T08:30:53.571858Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "c4e60c95-3f95-4912-bebf-6b52f02e81ba", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "a99e9245-56bd-44b0-8e3c-134c5d084476", - workspace_name: "workspace-04092024", - }, - }, - { - id: "f9d7bd07-9dfb-433c-b4c5-4a3b59701a43", - created_at: daysAgo(2), - started_at: "2025-03-10T08:00:42.759499Z", - completed_at: "2025-03-10T08:00:53.053394Z", - status: "succeeded", - worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "9122d768-ae5a-4ce2-8e91-ad673c856cab", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "bb601d85-5354-4b72-a00a-a9293dcaf9fb", - workspace_name: "w", - }, - }, - { - id: "c77e6591-69f3-4ee5-bfc8-0f9504d98b6d", - created_at: daysAgo(2), - started_at: "2025-03-10T06:10:40.651867Z", - completed_at: "2025-03-10T06:10:51.661778Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a3b4ba80-9d57-47b3-b4c3-770a9f5fde24", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "94707512-82eb-4533-bb10-2e62642dd006", - workspace_name: "sebenza-nonix", - }, - }, - { - id: "96373e8e-92db-45a6-b6e1-6084a07abdcd", - created_at: daysAgo(2), - started_at: "2025-03-10T05:55:42.757189Z", - completed_at: "2025-03-10T05:55:56.527391Z", - status: "succeeded", - worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a1b8cade-e193-4010-8569-eb53c43f742f", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "2f7d7949-613e-485e-9d1f-d5d5f1bd1a65", - workspace_name: "catfood", - }, - }, - { - id: "e444fb5b-0e04-4c31-8e37-69cea1c124c0", - created_at: daysAgo(2), - started_at: "2025-03-10T05:43:42.751376Z", - completed_at: "2025-03-10T05:43:54.450549Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "dc38794d-f4a2-4a7e-a1db-fca7f72c776b", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", - workspace_name: "danielle-coder-on-coder", - }, - }, - { - id: "8808cb86-6c6f-489f-bece-1cf8ed531476", - created_at: daysAgo(2), - started_at: "2025-03-10T05:08:42.75558Z", - completed_at: "2025-03-10T05:08:45.089148Z", - error: "initialize terraform: exit status 1", - status: "failed", - worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", - file_id: "b90a6622-ad0f-4170-b61f-6dc0ef09d2a3", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "16dc6faa-271d-4708-b427-790ff350e935", - }, - type: "workspace_build", - metadata: { - template_version_name: "vigorous_hypatia1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "3bf5a699-6fb8-47ac-88dc-6b4e5d69e4ad", - workspace_name: "pog-us", - }, - }, - { - id: "85429a7a-ec79-46f3-9580-1908a86bee1b", - created_at: daysAgo(2), - started_at: "2025-03-10T05:00:42.783177Z", - completed_at: "2025-03-10T05:00:54.101971Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "1e66d273-a088-405d-94cb-ffe7e9e693c8", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", - workspace_name: "nowjosias", - }, - }, - { - id: "2e0608e6-34f7-490e-acef-058a30c117e5", - created_at: daysAgo(2), - started_at: "2025-03-10T04:13:42.764767Z", - completed_at: "2025-03-10T04:13:52.105225Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "d813919a-85ef-49da-a2fb-1c90dc078725", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "8b41c3dd-7d79-416a-a4c5-8179aebe1ad2", - }, - type: "workspace_build", - metadata: { - template_version_name: "10f1e0b", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e3da7c66-d4ff-4d6b-a9fb-88707ab600f7", - workspace_name: "doom", - }, - }, - { - id: "1305b80b-dcdb-4c69-9cd7-2248bbc963f6", - created_at: daysAgo(2), - started_at: "2025-03-10T01:34:42.760435Z", - completed_at: "2025-03-10T01:34:50.748349Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "65d3ba09-3484-4b22-a6e0-7a6329804225", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "45466ea3-256e-4084-aca6-e4fcde12558a", - workspace_name: "fresh", - }, - }, - { - id: "a50ee303-6bee-4db8-a359-c9d51bc9d4eb", - created_at: daysAgo(2), - started_at: "2025-03-10T01:00:42.762717Z", - completed_at: "2025-03-10T01:00:53.338598Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "3762eb5a-55bf-464e-a8e6-fd9711684ae3", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "81b937d7-5777-4df5-b5cb-80241f30326f", - workspace_name: "pog2", - }, - }, - { - id: "51b0af99-d84e-4a09-a956-187c9dca7ee8", - created_at: daysAgo(2), - started_at: "2025-03-10T00:49:53.324941Z", - completed_at: "2025-03-10T00:50:06.154346Z", - status: "succeeded", - worker_id: "dc8f2c48-adac-492a-9865-daa1ae8fc1fe", - file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "843a70bb-37e5-4730-979c-9b7fd6b30b8b", - }, - type: "workspace_build", - metadata: { - template_version_name: "clever_nash3", - template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", - template_name: "coder-with-ai", - template_display_name: "Write Coder on Coder with AI", - template_icon: "/emojis/1f916.png", - workspace_id: "2e64b355-1238-4fce-b209-f0284b7ec73b", - workspace_name: "gold-hare-1", - }, - }, - { - id: "31e405ff-5be3-4fd2-9f64-52788425dbee", - created_at: daysAgo(2), - started_at: "2025-03-09T22:37:27.632825Z", - completed_at: "2025-03-09T22:40:59.993353Z", - status: "succeeded", - worker_id: "ea272096-3c46-4b31-8ede-7d8e16a7e6b0", - file_id: "69a5d2a6-c61a-493d-a2f0-047cc145a529", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "60763d5d-ef2c-459a-afbc-4f3b6f895d42", - }, - type: "workspace_build", - metadata: { - template_version_name: "blissful_cray3", - template_id: "f097e941-5c08-4032-b068-328154d13e66", - template_name: "docker-android", - template_display_name: "Android in Coder (Théo)", - template_icon: "/icon/android-studio.svg", - workspace_id: "320cb8ea-2687-4252-8ce9-6fcc1b4b0efc", - workspace_name: "crimson-mule-82", - }, - }, - { - id: "66854094-9848-4d5a-8a52-f7aa93b686ea", - created_at: daysAgo(2), - started_at: "2025-03-09T21:54:07.876842Z", - completed_at: "2025-03-09T21:54:20.427385Z", - status: "succeeded", - worker_id: "7ee752ec-ab89-42c8-ad02-151cff4b0407", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "69a47080-1456-4f6b-8587-6b19cbb748c5", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "2f7d7949-613e-485e-9d1f-d5d5f1bd1a65", - workspace_name: "catfood", - }, - }, - { - id: "d104b2a0-7351-44fc-82b7-3414761a48a9", - created_at: daysAgo(2), - started_at: "2025-03-09T21:38:53.551525Z", - completed_at: "2025-03-09T21:39:00.162185Z", - status: "succeeded", - worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", - file_id: "b0c6361a-d3c3-40d2-9b10-515d459e5aa6", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "83f9e3bb-da95-4de1-b7c7-cefbd1d6cfe8", - }, - type: "workspace_build", - metadata: { - template_version_name: "nifty_chatterjee1", - template_id: "220507c7-c609-41f9-82c0-771e07c1c7bb", - template_name: "dogfood-v2-psql", - template_display_name: "Connect to dogfood-v2 PostgreSQL database", - template_icon: "/emojis/1f418.png", - workspace_id: "d265ebaa-1cab-4668-b831-51272ad423d2", - workspace_name: "harlequin-junglefowl-90", - }, - }, - { - id: "c14c6aae-a3e8-451a-82ac-70011b4670b1", - created_at: daysAgo(2), - started_at: "2025-03-09T21:23:42.745993Z", - completed_at: "2025-03-09T21:23:48.28541Z", - status: "succeeded", - worker_id: "c2175eb9-a47e-41ac-9bc4-935700c1471a", - file_id: "71de01ae-2fd8-45a2-94dc-1f70b269f97a", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a18dc55d-621c-499e-ad55-d0ef10d6e898", - }, - type: "workspace_build", - metadata: { - template_version_name: "trusting_rhodes0", - template_id: "ba61a572-1f14-438f-8669-9c4996b802e6", - template_name: "chrome", - template_display_name: "Google Chrome", - template_icon: - "https://upload.wikimedia.org/wikipedia/commons/e/e1/Google_Chrome_icon_%28February_2022%29.svg", - workspace_id: "bf0dd1c5-3f76-4586-8f95-d5e568e92629", - workspace_name: "dlp", - }, - }, - { - id: "ed80c75c-393f-4986-a16f-2994bd6960b1", - created_at: daysAgo(2), - started_at: "2025-03-09T20:54:06.278404Z", - completed_at: "2025-03-09T20:54:17.42226Z", - status: "succeeded", - worker_id: "954fa457-b3a3-4420-ba13-e16c3eb9ae92", - file_id: "b0c6361a-d3c3-40d2-9b10-515d459e5aa6", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a3f0d013-c6d4-4520-8705-39089201c111", - }, - type: "workspace_build", - metadata: { - template_version_name: "nifty_chatterjee1", - template_id: "220507c7-c609-41f9-82c0-771e07c1c7bb", - template_name: "dogfood-v2-psql", - template_display_name: "Connect to dogfood-v2 PostgreSQL database", - template_icon: "/emojis/1f418.png", - workspace_id: "d265ebaa-1cab-4668-b831-51272ad423d2", - workspace_name: "harlequin-junglefowl-90", - }, - }, - { - id: "03d9e93a-139a-4acc-bc36-9d31848e7aa5", - created_at: daysAgo(2), - started_at: "2025-03-09T20:42:15.70548Z", - completed_at: "2025-03-09T20:42:26.144909Z", - status: "succeeded", - worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "bbf5a543-7b76-4509-b380-bcd2f9f4670c", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "8ef13a0d-a5c9-4fb4-abf2-f8f65c3830fb", - workspace_name: "danielle-coder-on-coder", - }, - }, - { - id: "8ff8c6b7-b7ce-4ec8-85ba-fdb9af0a78c8", - created_at: daysAgo(2), - started_at: "2025-03-09T17:33:45.909249Z", - completed_at: "2025-03-09T17:33:54.243355Z", - status: "succeeded", - worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", - file_id: "c9ed2a2a-903e-459c-8a1e-1d52bf42745c", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "c13692b1-c9b2-447d-9c4b-67cfa98f9523", - }, - type: "workspace_build", - metadata: { - template_version_name: "clever_nash3", - template_id: "81a22e85-7cd9-425e-9974-4b5190d8c500", - template_name: "coder-with-ai", - template_display_name: "Write Coder on Coder with AI", - template_icon: "/emojis/1f916.png", - workspace_id: "1794a2ec-6083-4b3e-aa3c-770b2e19ec47", - workspace_name: "indigo-skink-45", - }, - }, - { - id: "77b93fde-7142-4a7c-9e04-6391578416d1", - created_at: daysAgo(2), - started_at: "2025-03-09T17:33:07.585278Z", - completed_at: "2025-03-09T17:33:16.406362Z", - status: "succeeded", - worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "9121e975-41a0-4f51-bafc-7035ecd47491", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "45466ea3-256e-4084-aca6-e4fcde12558a", - workspace_name: "fresh", - }, - }, - { - id: "366fa27c-c8db-4535-a493-676d42042c1c", - created_at: daysAgo(2), - started_at: "2025-03-09T15:46:22.101203Z", - completed_at: "2025-03-09T15:46:57.765089Z", - error: "terraform plan: exit status 1", - status: "failed", - worker_id: "28fe48b4-b2b1-46e6-8b9b-52c9ead9db31", - file_id: "89f2eafc-fffa-488b-8dba-8fefa7dbbd2f", - tags: { - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "4bbce962-d864-4c89-b615-c8e445e0e693", - }, - type: "workspace_build", - metadata: { - template_version_name: "eb72866", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "6124440f-84ee-4cb2-8080-3a285fc0380e", - workspace_name: "blah", - }, - }, - { - id: "750e8c6e-1471-4378-aa49-437420c57505", - created_at: daysAgo(2), - started_at: "2025-03-09T12:29:08.656319Z", - completed_at: "2025-03-09T12:29:19.81815Z", - status: "succeeded", - worker_id: "244abe95-4e67-4cc8-89ec-aa267cf04522", - file_id: "f2534f2b-9fff-4e40-b356-b06d5e29c54d", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "0b0af776-f98d-479c-aae9-fbab6c19ffc1", - }, - type: "workspace_build", - metadata: { - template_version_name: "wizardly_ishizaka2", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "5d4989ac-d885-4666-a312-2b7a172b4a07", - workspace_name: "pog", - }, - }, - { - id: "373cb47a-c33b-4e35-83bf-23c64fde0293", - created_at: daysAgo(2), - started_at: "2025-03-09T08:01:22.118677Z", - completed_at: "2025-03-09T08:01:33.310184Z", - status: "succeeded", - worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", - file_id: "a99685a6-4441-4258-8102-f07e571204fb", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "0153584a-6cbe-4c90-8e9e-4ffb40fd1069", - }, - type: "workspace_build", - metadata: { - template_version_name: "54745b1", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "e1a7f977-28e7-4567-b91a-179a14c3658b", - workspace_name: "nowjosias", - }, - }, - { - id: "611cb463-5223-4c67-8105-3a48f94e7c99", - created_at: daysAgo(2), - started_at: "2025-03-09T07:04:49.996671Z", - completed_at: "2025-03-09T07:04:57.095615Z", - status: "succeeded", - worker_id: "d4f5452e-3d1b-4400-a7c1-233c2dee6f1a", - file_id: "f2534f2b-9fff-4e40-b356-b06d5e29c54d", - tags: { - cluster: "dogfood-v2", - env: "gke", - owner: "", - scope: "organization", - }, - queue_position: 0, - queue_size: 24, - organization_id: "703f72a1-76f6-4f89-9de6-8a3989693fe5", - input: { - workspace_build_id: "a095476b-6c84-4c51-b88b-44a34ad1462f", - }, - type: "workspace_build", - metadata: { - template_version_name: "wizardly_ishizaka2", - template_id: "0d286645-29aa-4eaf-9b52-cc5d2740c90b", - template_name: "coder", - template_display_name: "Write Coder on Coder", - template_icon: "/emojis/1f3c5.png", - workspace_id: "65be8c8f-0cb1-49b2-a4e5-23652c4b686f", - workspace_name: "release", - }, - }, -]; +const MockProvisionerJobs: ProvisionerJob[] = Array.from( + { length: 50 }, + (_, i) => ({ + ...MockProvisionerJob, + id: i.toString(), + created_at: daysAgo(2), + }), +); diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx index e26550b8f9b73..bf02b445724c1 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx @@ -24,16 +24,13 @@ import { pageTitle } from "utils/page"; import { JobRow } from "./JobRow"; type OrganizationProvisionerJobsPageProps = { - defaultOrganizationSettingsValue?: OrganizationSettingsValue; getProvisionerJobs?: typeof API.getProvisionerJobs; }; const OrganizationProvisionerJobsPage: FC< OrganizationProvisionerJobsPageProps -> = ({ defaultOrganizationSettingsValue, getProvisionerJobs }) => { - const { organization } = useOrganizationSettings( - defaultOrganizationSettingsValue, - ); +> = ({ getProvisionerJobs }) => { + const { organization } = useOrganizationSettings(); if (!organization) { return ; From 8a62eccdef121e7a41a805552fa69c5373aa9c43 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 13 Mar 2025 13:25:44 +0000 Subject: [PATCH 5/7] Apply Kaylas suggestion --- .../JobRow.stories.tsx | 24 +--- .../JobRow.tsx | 5 +- ...rganizationProvisionerJobsPage.stories.tsx | 113 ----------------- .../OrganizationProvisionerJobsPage.tsx | 115 ++---------------- ...izationProvisionerJobsPageView.stories.tsx | 77 ++++++++++++ .../OrganizationProvisionerJobsPageView.tsx | 113 +++++++++++++++++ 6 files changed, 209 insertions(+), 238 deletions(-) delete mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx create mode 100644 site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx index 67f760a463956..35818baeed2e3 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.stories.tsx @@ -30,12 +30,6 @@ type Story = StoryObj; export const Close: Story = {}; -export const Open: Story = { - args: { - defaultOpen: true, - }, -}; - export const OpenOnClick: Story = { play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); @@ -46,29 +40,19 @@ export const OpenOnClick: Story = { const jobId = canvas.getByText(args.job.id); expect(jobId).toBeInTheDocument(); }, - parameters: { - chromatic: { - disableSnapshot: true, - }, - }, }; export const HideOnClick: Story = { - args: { - defaultOpen: true, - }, play: async ({ canvasElement, args }) => { const canvas = within(canvasElement); - const showMoreButton = canvas.getByRole("button", { name: /hide/i }); + const showMoreButton = canvas.getByRole("button", { name: /show more/i }); await userEvent.click(showMoreButton); + const hideButton = canvas.getByRole("button", { name: /hide/i }); + await userEvent.click(hideButton); + const jobId = canvas.queryByText(args.job.id); expect(jobId).not.toBeInTheDocument(); }, - parameters: { - chromatic: { - disableSnapshot: true, - }, - }, }; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx index 2d84fe9625d67..9c7aecbba5c14 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/JobRow.tsx @@ -16,12 +16,11 @@ import { Tag, Tags, TruncateTags } from "./Tags"; type JobRowProps = { job: ProvisionerJob; - defaultOpen?: boolean; }; -export const JobRow: FC = ({ job, defaultOpen }) => { +export const JobRow: FC = ({ job }) => { const metadata = job.metadata; - const [isOpen, setIsOpen] = useState(defaultOpen); + const [isOpen, setIsOpen] = useState(false); return ( <> diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx deleted file mode 100644 index 3347f2f1bbf8e..0000000000000 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.stories.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react"; -import { expect, userEvent, waitFor, within } from "@storybook/test"; -import type { ProvisionerJob } from "api/typesGenerated"; -import { OrganizationSettingsContext } from "modules/management/OrganizationSettingsLayout"; -import { - MockOrganization, - MockOrganizationPermissions, - MockProvisionerJob, -} from "testHelpers/entities"; -import { daysAgo } from "utils/time"; -import OrganizationProvisionerJobsPage from "./OrganizationProvisionerJobsPage"; - -const defaultOrganizationSettingsValue = { - organization: MockOrganization, - organizationPermissionsByOrganizationId: {}, - organizations: [MockOrganization], - organizationPermissions: MockOrganizationPermissions, -}; - -const meta: Meta = { - title: "pages/OrganizationProvisionerJobsPage", - component: OrganizationProvisionerJobsPage, - decorators: [ - (Story, { parameters }) => ( - - - - ), - ], - args: { - getProvisionerJobs: async () => MockProvisionerJobs, - }, - parameters: { - organizationSettingsValue: defaultOrganizationSettingsValue, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; - -export const OrganizationNotFound: Story = { - parameters: { - organizationSettingsValue: { - ...defaultOrganizationSettingsValue, - organization: null, - }, - }, -}; - -export const Loading: Story = { - args: { - getProvisionerJobs: () => - new Promise((res) => { - setTimeout(res, 100_000); - }), - }, -}; - -export const LoadingError: Story = { - args: { - getProvisionerJobs: async () => { - throw new Error("Failed to load jobs"); - }, - }, -}; - -export const RetryAfterError: Story = { - args: { - getProvisionerJobs: (() => { - let count = 0; - - return async () => { - count++; - - if (count === 1) { - throw new Error("Failed to load jobs"); - } - - return MockProvisionerJobs; - }; - })(), - }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const retryButton = await canvas.findByRole("button", { name: "Retry" }); - - userEvent.click(retryButton); - - await waitFor(() => { - const rows = canvasElement.querySelectorAll("tbody > tr"); - expect(rows).toHaveLength(MockProvisionerJobs.length); - }); - }, -}; - -export const Empty: Story = { - args: { - getProvisionerJobs: async () => [], - }, -}; - -const MockProvisionerJobs: ProvisionerJob[] = Array.from( - { length: 50 }, - (_, i) => ({ - ...MockProvisionerJob, - id: i.toString(), - created_at: daysAgo(2), - }), -); diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx index bf02b445724c1..bae561c4a9ee3 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPage.tsx @@ -1,116 +1,27 @@ -import type { API } from "api/api"; import { provisionerJobs } from "api/queries/organizations"; -import { Button } from "components/Button/Button"; -import { EmptyState } from "components/EmptyState/EmptyState"; -import { Link } from "components/Link/Link"; -import { Loader } from "components/Loader/Loader"; -import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, -} from "components/Table/Table"; -import { - type OrganizationSettingsValue, - useOrganizationSettings, -} from "modules/management/OrganizationSettingsLayout"; +import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; import type { FC } from "react"; -import { Helmet } from "react-helmet-async"; import { useQuery } from "react-query"; -import { docs } from "utils/docs"; -import { pageTitle } from "utils/page"; -import { JobRow } from "./JobRow"; +import OrganizationProvisionerJobsPageView from "./OrganizationProvisionerJobsPageView"; -type OrganizationProvisionerJobsPageProps = { - getProvisionerJobs?: typeof API.getProvisionerJobs; -}; - -const OrganizationProvisionerJobsPage: FC< - OrganizationProvisionerJobsPageProps -> = ({ getProvisionerJobs }) => { +const OrganizationProvisionerJobsPage: FC = () => { const { organization } = useOrganizationSettings(); - - if (!organization) { - return ; - } - const { data: jobs, isLoadingError, refetch, - } = useQuery(provisionerJobs(organization.id, getProvisionerJobs)); + } = useQuery({ + ...provisionerJobs(organization?.id || ""), + enabled: organization !== undefined, + }); return ( - <> - - - {pageTitle( - "Provisioner Jobs", - organization.display_name || organization.name, - )} - - - -
-
-
-

Provisioner Jobs

-

- Provisioner Jobs are the individual tasks assigned to Provisioners - when the workspaces are being built.{" "} - View docs -

-
-
- - - - - Created - Type - Template - Tags - Status - - - - - {jobs ? ( - jobs.length > 0 ? ( - jobs.map((j) => ) - ) : ( - - - - - - ) - ) : isLoadingError ? ( - - - refetch()}> - Retry - - } - /> - - - ) : ( - - - - - - )} - -
-
- + ); }; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx new file mode 100644 index 0000000000000..9b6a25a3521ef --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.stories.tsx @@ -0,0 +1,77 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { expect, fn, userEvent, waitFor, within } from "@storybook/test"; +import type { ProvisionerJob } from "api/typesGenerated"; +import { MockOrganization, MockProvisionerJob } from "testHelpers/entities"; +import { daysAgo } from "utils/time"; +import OrganizationProvisionerJobsPageView from "./OrganizationProvisionerJobsPageView"; + +const MockProvisionerJobs: ProvisionerJob[] = Array.from( + { length: 50 }, + (_, i) => ({ + ...MockProvisionerJob, + id: i.toString(), + created_at: daysAgo(2), + }), +); + +const meta: Meta = { + title: "pages/OrganizationProvisionerJobsPage", + component: OrganizationProvisionerJobsPageView, + args: { + organization: MockOrganization, + jobs: MockProvisionerJobs, + onRetry: fn(), + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const OrganizationNotFound: Story = { + args: { + organization: undefined, + }, +}; + +export const Loading: Story = { + args: { + jobs: undefined, + }, +}; + +export const LoadingError: Story = { + args: { + jobs: undefined, + error: new Error("Failed to load jobs"), + }, +}; + +export const RetryAfterError: Story = { + args: { + jobs: undefined, + error: new Error("Failed to load jobs"), + onRetry: fn(), + }, + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement); + const retryButton = await canvas.findByRole("button", { name: "Retry" }); + userEvent.click(retryButton); + + await waitFor(() => { + expect(args.onRetry).toHaveBeenCalled(); + }); + }, + parameters: { + chromatic: { + disableSnapshot: true, + }, + }, +}; + +export const Empty: Story = { + args: { + jobs: [], + }, +}; diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx new file mode 100644 index 0000000000000..a9c189ee37f69 --- /dev/null +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx @@ -0,0 +1,113 @@ +import { Button } from "components/Button/Button"; +import { EmptyState } from "components/EmptyState/EmptyState"; +import { Link } from "components/Link/Link"; +import { Loader } from "components/Loader/Loader"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; +import type { FC } from "react"; +import { Helmet } from "react-helmet-async"; +import { docs } from "utils/docs"; +import { pageTitle } from "utils/page"; +import { JobRow } from "./JobRow"; +import type { ProvisionerJob, Organization } from "api/typesGenerated"; + +type OrganizationProvisionerJobsPageViewProps = { + jobs: ProvisionerJob[] | undefined; + organization: Organization | undefined; + error: unknown; + onRetry: () => void; +}; + +const OrganizationProvisionerJobsPageView: FC< + OrganizationProvisionerJobsPageViewProps +> = ({ jobs, organization, error, onRetry }) => { + if (!organization) { + return ( + <> + + {pageTitle("Provisioner Jobs")} + + + + ); + } + + return ( + <> + + + {pageTitle( + "Provisioner Jobs", + organization.display_name || organization.name, + )} + + + +
+
+
+

Provisioner Jobs

+

+ Provisioner Jobs are the individual tasks assigned to Provisioners + when the workspaces are being built.{" "} + View docs +

+
+
+ + + + + Created + Type + Template + Tags + Status + + + + + {jobs ? ( + jobs.length > 0 ? ( + jobs.map((j) => ) + ) : ( + + + + + + ) + ) : error ? ( + + + + Retry + + } + /> + + + ) : ( + + + + + + )} + +
+
+ + ); +}; + +export default OrganizationProvisionerJobsPageView; From 901ab23964010dd0d86c7d39adbbfcaed19f18c8 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 14 Mar 2025 11:12:06 +0000 Subject: [PATCH 6/7] Remove injection --- site/src/api/queries/organizations.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/site/src/api/queries/organizations.ts b/site/src/api/queries/organizations.ts index 50373bb0bbb3e..bca0bc6a72fff 100644 --- a/site/src/api/queries/organizations.ts +++ b/site/src/api/queries/organizations.ts @@ -207,13 +207,10 @@ export const provisionerJobQueryKey = (orgId: string) => [ "provisionerjobs", ]; -export const provisionerJobs = ( - orgId: string, - fetchProvisionerJobs = API.getProvisionerJobs, -) => { +export const provisionerJobs = (orgId: string) => { return { queryKey: provisionerJobQueryKey(orgId), - queryFn: () => fetchProvisionerJobs(orgId), + queryFn: () => API.getProvisionerJobs(orgId), }; }; From ed7359448e5b3ae7adb11318e836e61c75fe3220 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 14 Mar 2025 11:12:39 +0000 Subject: [PATCH 7/7] FMT --- .../OrganizationProvisionerJobsPageView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx index a9c189ee37f69..98168ef39adb8 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionerJobsPage/OrganizationProvisionerJobsPageView.tsx @@ -1,3 +1,4 @@ +import type { Organization, ProvisionerJob } from "api/typesGenerated"; import { Button } from "components/Button/Button"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Link } from "components/Link/Link"; @@ -15,7 +16,6 @@ import { Helmet } from "react-helmet-async"; import { docs } from "utils/docs"; import { pageTitle } from "utils/page"; import { JobRow } from "./JobRow"; -import type { ProvisionerJob, Organization } from "api/typesGenerated"; type OrganizationProvisionerJobsPageViewProps = { jobs: ProvisionerJob[] | undefined;