Skip to content

Commit 97a86e0

Browse files
committed
chore: ranges instead of range
1 parent feaa3ea commit 97a86e0

File tree

2 files changed

+74
-57
lines changed

2 files changed

+74
-57
lines changed

site/src/modules/workspaces/WorkspaceTiming/StagesChart.tsx

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Interpolation, Theme } from "@emotion/react";
22
import type { TimingStage } from "api/typesGenerated";
3+
import { T } from "lodash/fp";
34
import { CircleAlertIcon, InfoIcon } from "lucide-react";
45
import type { FC } from "react";
56
import { Bar, ClickableBar } from "./Chart/Bar";
@@ -52,7 +53,7 @@ export type Stage = {
5253
tooltip: Omit<TooltipProps, "children">;
5354
};
5455

55-
type StageTiming = {
56+
export type StageTiming = {
5657
stage: Stage;
5758
/**
5859
* Represents the number of resources included in this stage that can be
@@ -65,7 +66,7 @@ type StageTiming = {
6566
* duration of the stage and to position the stage within the chart. This can
6667
* be undefined if a stage has no timing data.
6768
*/
68-
range: TimeRange | undefined;
69+
ranges: TimeRange[] | undefined;
6970
/**
7071
* Display an error icon within the bar to indicate when a stage has failed.
7172
* This is used in the agent scripts stage.
@@ -83,7 +84,10 @@ export const StagesChart: FC<StagesChartProps> = ({
8384
onSelectStage,
8485
}) => {
8586
const totalRange = mergeTimeRanges(
86-
timings.map((t) => t.range).filter((t) => t !== undefined),
87+
timings
88+
.map((t) => t.ranges)
89+
.filter((t) => t !== undefined)
90+
.flat(),
8791
);
8892
const totalTime = calcDuration(totalRange);
8993
const [ticks, scale] = makeTicks(totalTime);
@@ -129,11 +133,12 @@ export const StagesChart: FC<StagesChartProps> = ({
129133
const stageTimings = timings.filter(
130134
(t) => t.stage.section === section,
131135
);
136+
132137
return (
133138
<XAxisSection key={section}>
134139
{stageTimings.map((t) => {
135140
// If the stage has no timing data, we just want to render an empty row
136-
if (t.range === undefined) {
141+
if (t.ranges === undefined) {
137142
return (
138143
<XAxisRow
139144
key={t.stage.name}
@@ -142,53 +147,55 @@ export const StagesChart: FC<StagesChartProps> = ({
142147
);
143148
}
144149

145-
const value = calcDuration(t.range);
146-
const offset = calcOffset(t.range, totalRange);
147-
const validDuration = value > 0 && !Number.isNaN(value);
150+
return t.ranges?.map((range, index) => {
151+
const value = calcDuration(range);
152+
const offset = calcOffset(range, totalRange);
153+
const validDuration = value > 0 && !Number.isNaN(value);
148154

149-
return (
150-
<XAxisRow
151-
key={t.stage.name}
152-
yAxisLabelId={encodeURIComponent(t.stage.name)}
153-
>
154-
{/** We only want to expand stages with more than one resource */}
155-
{t.visibleResources > 1 ? (
156-
<ClickableBar
157-
aria-label={`View ${t.stage.label} details`}
158-
scale={scale}
159-
value={value}
160-
offset={offset}
161-
onClick={() => {
162-
onSelectStage(t.stage);
163-
}}
164-
>
165-
{t.error && (
166-
<CircleAlertIcon
167-
className="size-icon-sm"
168-
css={{
169-
color: "#F87171",
170-
marginRight: 4,
171-
}}
172-
/>
173-
)}
174-
<Blocks count={t.visibleResources} />
175-
</ClickableBar>
176-
) : (
177-
<Bar scale={scale} value={value} offset={offset} />
178-
)}
179-
{validDuration ? (
180-
<span>{formatTime(value)}</span>
181-
) : (
182-
<span
183-
css={(theme) => ({
184-
color: theme.palette.error.main,
185-
})}
186-
>
187-
Invalid
188-
</span>
189-
)}
190-
</XAxisRow>
191-
);
155+
return (
156+
<XAxisRow
157+
key={t.stage.name + index}
158+
yAxisLabelId={encodeURIComponent(t.stage.name)}
159+
>
160+
{/** We only want to expand stages with more than one resource */}
161+
{t.visibleResources > 1 ? (
162+
<ClickableBar
163+
aria-label={`View ${t.stage.label} details`}
164+
scale={scale}
165+
value={value}
166+
offset={offset}
167+
onClick={() => {
168+
onSelectStage(t.stage);
169+
}}
170+
>
171+
{t.error && (
172+
<CircleAlertIcon
173+
className="size-icon-sm"
174+
css={{
175+
color: "#F87171",
176+
marginRight: 4,
177+
}}
178+
/>
179+
)}
180+
<Blocks count={t.visibleResources} />
181+
</ClickableBar>
182+
) : (
183+
<Bar scale={scale} value={value} offset={offset} />
184+
)}
185+
{validDuration ? (
186+
<span>{formatTime(value)}</span>
187+
) : (
188+
<span
189+
css={(theme) => ({
190+
color: theme.palette.error.main,
191+
})}
192+
>
193+
Invalid
194+
</span>
195+
)}
196+
</XAxisRow>
197+
);
198+
});
192199
})}
193200
</XAxisSection>
194201
);

site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
provisioningStages,
2929
type Stage,
3030
StagesChart,
31+
type StageTiming,
3132
} from "./StagesChart";
3233

3334
type TimingView =
@@ -130,16 +131,25 @@ export const WorkspaceTimings: FC<WorkspaceTimingsProps> = ({
130131
<div css={styles.collapseBody}>
131132
{view.name === "default" && (
132133
<StagesChart
133-
timings={stages.map((s) => {
134+
timings={stages.map((s): StageTiming => {
134135
const stageTimings = timings.filter(
135136
// graph has 2 stages, `graph` and `graph_second`
136-
(t) => t.stage === s.name || s.alternativeNames?.includes(t.stage),
137+
(t) =>
138+
t.stage === s.name ||
139+
s.alternativeNames?.includes(t.stage),
137140
);
138-
// console.log(s.name, stageTimings)
139-
const stageRange =
140-
stageTimings.length === 0
141+
142+
143+
const keyedRanges = stageTimings.reduce<Record<string, TimeRange[]>>(
144+
(acc, t) => {
145+
acc[t.stage] = acc[t.stage] || [];
146+
acc[t.stage].push(toTimeRange(t));
147+
return acc;
148+
}, {});
149+
150+
const stageRanges = stageTimings.length === 0
141151
? undefined
142-
: mergeTimeRanges(stageTimings.map(toTimeRange));
152+
: Object.entries(keyedRanges).map(([_, ranges]) => mergeTimeRanges(ranges));
143153

144154
// Prevent users from inspecting internal coder resources in
145155
// provisioner timings because they were not useful to the
@@ -160,7 +170,7 @@ export const WorkspaceTimings: FC<WorkspaceTimingsProps> = ({
160170

161171
return {
162172
stage: s,
163-
range: stageRange,
173+
ranges: stageRanges,
164174
visibleResources: visibleResources.length,
165175
error: stageTimings.some(
166176
(t) => "status" in t && t.status === "exit_failure",

0 commit comments

Comments
 (0)