From eb453959f4c2eed26ec7511d94f71afc0cd6c61c Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Tue, 22 Apr 2025 16:45:53 +0000 Subject: [PATCH 1/2] fix: build timeline scale for longer builds --- .../workspaces/WorkspaceTiming/Chart/utils.ts | 40 ++++++++++++++++++- .../WorkspaceTimings.stories.tsx | 26 ++++++++++++ .../WorkspaceTiming/WorkspaceTimings.tsx | 9 ++++- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts b/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts index 45c6f5bf681d1..dcfb546842292 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts +++ b/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts @@ -29,7 +29,20 @@ export const calcDuration = (range: TimeRange): number => { // data in 200ms intervals. However, if the total time is 1 minute, we should // display the data in 5 seconds intervals. To achieve this, we define the // dimensions object that contains the time intervals for the chart. -const scales = [5_000, 500, 100]; +const second = 1_000; +const minute = 60 * second; +const hour = 60 * minute; +const day = 24 * hour; +const scales = [ + day, + hour, + 5 * minute, + minute, + 10 * second, + 5 * second, + 500, + 100, +]; const pickScale = (totalTime: number): number => { for (const s of scales) { @@ -48,7 +61,30 @@ export const makeTicks = (time: number) => { }; export const formatTime = (time: number): string => { - return `${time.toLocaleString()}ms`; + const seconds = Math.floor((time / 1000) % 60); + const minutes = Math.floor((time / (1000 * 60)) % 60); + const hours = Math.floor((time / (1000 * 60 * 60)) % 24); + const days = Math.floor(time / (1000 * 60 * 60 * 24)); + + const timeParts = []; + + if (days > 0) { + timeParts.push(`${days} day${days > 1 ? "s" : ""}`); + } + if (hours > 0) { + timeParts.push(`${hours} hour${hours > 1 ? "s" : ""}`); + } + if (minutes > 0) { + timeParts.push(`${minutes} minute${minutes > 1 ? "s" : ""}`); + } + if (seconds > 0) { + timeParts.push(`${seconds}s`); + } + if (time > 0 && time < 1000) { + timeParts.push(`${time}ms`); + } + + return timeParts.join(", "); }; export const calcOffset = (range: TimeRange, baseRange: TimeRange): number => { diff --git a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx index 0210353488257..9c93b4bf6806e 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.stories.tsx @@ -126,3 +126,29 @@ export const LoadingWhenAgentScriptTimingsAreEmpty: Story = { agentScriptTimings: undefined, }, }; + +export const LongTimeRange = { + args: { + provisionerTimings: [ + { + ...WorkspaceTimingsResponse.provisioner_timings[0], + started_at: "2021-09-01T00:00:00Z", + ended_at: "2021-09-01T00:10:00Z", + }, + ], + agentConnectionTimings: [ + { + ...WorkspaceTimingsResponse.agent_connection_timings[0], + started_at: "2021-09-01T00:10:00Z", + ended_at: "2021-09-01T00:35:00Z", + }, + ], + agentScriptTimings: [ + { + ...WorkspaceTimingsResponse.agent_script_timings[0], + started_at: "2021-09-01T00:35:00Z", + ended_at: "2021-09-01T01:00:00Z", + }, + ], + }, +}; diff --git a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx index 63fc03ad2a3de..2cb0a7c20d5d8 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx +++ b/site/src/modules/workspaces/WorkspaceTiming/WorkspaceTimings.tsx @@ -12,7 +12,12 @@ import type { import sortBy from "lodash/sortBy"; import uniqBy from "lodash/uniqBy"; import { type FC, useState } from "react"; -import { type TimeRange, calcDuration, mergeTimeRanges } from "./Chart/utils"; +import { + type TimeRange, + calcDuration, + formatTime, + mergeTimeRanges, +} from "./Chart/utils"; import { ResourcesChart, isCoderResource } from "./ResourcesChart"; import { ScriptsChart } from "./ScriptsChart"; import { @@ -85,7 +90,7 @@ export const WorkspaceTimings: FC = ({ const displayProvisioningTime = () => { const totalRange = mergeTimeRanges(timings.map(toTimeRange)); const totalDuration = calcDuration(totalRange); - return humanizeDuration(totalDuration); + return formatTime(totalDuration); }; return ( From ef7226cb657cc6131b2f558a2847addc637d6a51 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Tue, 22 Apr 2025 17:22:23 +0000 Subject: [PATCH 2/2] Fix format --- .../workspaces/WorkspaceTiming/Chart/utils.ts | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts b/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts index dcfb546842292..55df5b9ffad48 100644 --- a/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts +++ b/site/src/modules/workspaces/WorkspaceTiming/Chart/utils.ts @@ -61,30 +61,29 @@ export const makeTicks = (time: number) => { }; export const formatTime = (time: number): string => { - const seconds = Math.floor((time / 1000) % 60); - const minutes = Math.floor((time / (1000 * 60)) % 60); - const hours = Math.floor((time / (1000 * 60 * 60)) % 24); - const days = Math.floor(time / (1000 * 60 * 60 * 24)); - - const timeParts = []; + const seconds = Math.floor(time / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + const parts: string[] = []; if (days > 0) { - timeParts.push(`${days} day${days > 1 ? "s" : ""}`); + parts.push(`${days}d`); } if (hours > 0) { - timeParts.push(`${hours} hour${hours > 1 ? "s" : ""}`); + parts.push(`${hours % 24}h`); } if (minutes > 0) { - timeParts.push(`${minutes} minute${minutes > 1 ? "s" : ""}`); + parts.push(`${minutes % 60}m`); } if (seconds > 0) { - timeParts.push(`${seconds}s`); + parts.push(`${seconds % 60}s`); } - if (time > 0 && time < 1000) { - timeParts.push(`${time}ms`); + if (time % 1000 > 0) { + parts.push(`${time % 1000}ms`); } - return timeParts.join(", "); + return parts.join(" "); }; export const calcOffset = (range: TimeRange, baseRange: TimeRange): number => { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy