From aa0e3c5b8a3336aa0f3601266acb7ab1905a8b47 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Tue, 10 Feb 2026 16:19:20 -0800 Subject: [PATCH] add load icon --- .../execution-stages-pane.tsx | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/web-console/src/views/workbench-view/execution-stages-pane/execution-stages-pane.tsx b/web-console/src/views/workbench-view/execution-stages-pane/execution-stages-pane.tsx index a49c568ed1eb..26a1f005ff68 100644 --- a/web-console/src/views/workbench-view/execution-stages-pane/execution-stages-pane.tsx +++ b/web-console/src/views/workbench-view/execution-stages-pane/execution-stages-pane.tsx @@ -51,6 +51,7 @@ import { clamp, deepGet, filterMap, + formatByteRate, formatBytesCompact, formatDurationWithMs, formatDurationWithMsIfNeeded, @@ -97,6 +98,23 @@ const formatFileOfTotal = (files: number, totalFiles: number) => const formatFileOfTotalForBrace = (files: number, totalFiles: number) => `(${formatInteger(files)} /GB ${formatInteger(totalFiles)})`; +function formatLoadTooltip( + loadFiles: number, + loadBytes?: number, + loadTime?: number, + loadWait?: number, +): string { + return assemble( + `Loaded files: ${formatInteger(loadFiles)}`, + loadBytes != null && `Loaded bytes: ${formatBytesCompact(loadBytes)}`, + loadTime != null && loadTime > 0 && `Load time: ${formatDurationWithMs(loadTime)}`, + loadTime && loadBytes + ? `Load rate: ${formatByteRate(loadBytes / (loadTime / 1000))}` + : undefined, + loadWait != null && loadWait > 0 && `Load wait: ${formatDurationWithMs(loadWait)}`, + ).join('\n'); +} + function inputLabelContent(stage: StageDefinition, inputIndex: number) { const { input, broadcast } = stage.definition; const stageInput = input[inputIndex]; @@ -337,6 +355,22 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane( /> )} + {Boolean(c.loadFiles) && ( + <> + {' '} +  {' '} + + + )} ); }, @@ -505,6 +539,10 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane( const hasCounter = stages.hasCounterForStage(stage, inputCounter); const bytes = stages.getTotalCounterForStage(stage, inputCounter, 'bytes'); const inputFileCount = stages.getTotalCounterForStage(stage, inputCounter, 'totalFiles'); + const loadFiles = stages.getTotalCounterForStage(stage, inputCounter, 'loadFiles'); + const loadBytes = stages.getTotalCounterForStage(stage, inputCounter, 'loadBytes'); + const loadTime = stages.getTotalCounterForStage(stage, inputCounter, 'loadTime'); + const loadWait = stages.getTotalCounterForStage(stage, inputCounter, 'loadWait'); const inputLabel = `${formatInputLabel(stage, inputNumber)} (input${inputNumber})`; return (
- {inputFileCount ? ( + {Boolean(inputFileCount) && ( <> {' '}  {' '} @@ -536,7 +574,18 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane( braces={filesValues} /> - ) : undefined} + )} + {Boolean(loadFiles) && ( + <> + {' '} +  {' '} + + + )}
); }