From a942bf8718d82621f41ae724e6f077ed491dc27d Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Mon, 28 Apr 2025 17:52:49 +0000 Subject: [PATCH 1/2] fix: handle missed actions in workspace timings --- .../WorkspaceTiming/ResourcesChart.tsx | 16 +++- .../WorkspaceTimings.stories.tsx | 78 +++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/site/src/modules/workspaces/WorkspaceTiming/ResourcesChart.tsx b/site/src/modules/workspaces/WorkspaceTiming/ResourcesChart.tsx index b1c0bd89bc5fe..2d940c6d56191 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/ResourcesChart.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/ResourcesChart.tsx @@ -57,7 +57,7 @@ export const ResourcesChart: FC = ({ const theme = useTheme(); const legendsByAction = getLegendsByAction(theme); const visibleLegends = [...new Set(visibleTimings.map((t) => t.action))].map( - (a) => legendsByAction[a], + (a) => legendsByAction[a] ?? { label: a }, ); return ( @@ -99,6 +99,7 @@ export const ResourcesChart: FC = ({ {visibleTimings.map((t) => { const duration = calcDuration(t.range); + const legend = legendsByAction[t.action] ?? { label: t.action }; return ( = ({ value={duration} offset={calcOffset(t.range, generalTiming)} scale={scale} - colors={legendsByAction[t.action].colors} + colors={legend.colors} /> {formatTime(duration)} @@ -139,11 +140,20 @@ export const isCoderResource = (resource: string) => { ); }; -function getLegendsByAction(theme: Theme): Record { +// TODO: We should probably strongly type the action attribute on +// ProvisionerTiming to catch missing actions in the record. As a "workaround" +// for now, we are using undefined since we don't have noUncheckedIndexedAccess +// enabled. +function getLegendsByAction( + theme: Theme, +): Record { return { "state refresh": { label: "state refresh", }, + provision: { + label: "provision", + }, create: { label: "create", colors: { diff --git a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx index 9c93b4bf6806e..03207b409c0e9 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx @@ -152,3 +152,81 @@ export const LongTimeRange = { ], }, }; + +// We want to gracefully handle the case when the action is added in the BE but +// not in the FE. This is a temporary fix until we can have strongly provisioner +// timing action types in the BE. +export const MissedAction: Story = { + args: { + agentConnectionTimings: [ + { + ended_at: "2025-03-12T18:15:13.651163Z", + stage: "connect", + started_at: "2025-03-12T18:15:10.249068Z", + workspace_agent_id: "41ab4fd4-44f8-4f3a-bb69-262ae85fba0b", + workspace_agent_name: "Interface", + }, + ], + agentScriptTimings: [ + { + display_name: "Startup Script", + ended_at: "2025-03-12T18:16:44.771508Z", + exit_code: 0, + stage: "start", + started_at: "2025-03-12T18:15:13.847336Z", + status: "ok", + workspace_agent_id: "41ab4fd4-44f8-4f3a-bb69-262ae85fba0b", + workspace_agent_name: "Interface", + }, + ], + provisionerTimings: [ + { + action: "create", + ended_at: "2025-03-12T18:08:07.402358Z", + job_id: "a7c4a05d-1c36-4264-8275-8107c93c5fc8", + resource: "coder_agent.Interface", + source: "coder", + stage: "apply", + started_at: "2025-03-12T18:08:07.194957Z", + }, + { + action: "create", + ended_at: "2025-03-12T18:08:08.029908Z", + job_id: "a7c4a05d-1c36-4264-8275-8107c93c5fc8", + resource: "null_resource.validate_url", + source: "null", + stage: "apply", + started_at: "2025-03-12T18:08:07.399387Z", + }, + { + action: "create", + ended_at: "2025-03-12T18:08:07.440785Z", + job_id: "a7c4a05d-1c36-4264-8275-8107c93c5fc8", + resource: "module.emu_host.random_id.emulator_host_id", + source: "random", + stage: "apply", + started_at: "2025-03-12T18:08:07.403171Z", + }, + { + action: "missed action", + ended_at: "2025-03-12T18:08:08.029752Z", + job_id: "a7c4a05d-1c36-4264-8275-8107c93c5fc8", + resource: "null_resource.validate_url", + source: "null", + stage: "apply", + started_at: "2025-03-12T18:08:07.410219Z", + }, + ], + }, + play: async ({ canvasElement }) => { + const user = userEvent.setup(); + const canvas = within(canvasElement); + const applyButton = canvas.getByRole("button", { + name: "View apply details", + }); + await user.click(applyButton); + await canvas.findByText( + WorkspaceTimingsResponse.provisioner_timings[0].resource, + ); + }, +}; From 17ac34e77be8c5dbe4e99ab3f95d0ca8d0eab1b4 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Mon, 28 Apr 2025 18:01:11 +0000 Subject: [PATCH 2/2] Fix test --- .../workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx index 03207b409c0e9..c2d1193d37fc1 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx @@ -225,8 +225,6 @@ export const MissedAction: Story = { name: "View apply details", }); await user.click(applyButton); - await canvas.findByText( - WorkspaceTimingsResponse.provisioner_timings[0].resource, - ); + await canvas.findByText("missed action"); }, };