From 6f1c36099b835c7ee2ca8b605ce2a3209bf7087a Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Thu, 18 Jun 2026 10:29:12 +0200 Subject: [PATCH] fix(web): adapt metric plots to policy-based resample config The backend resample config changed from {trigger, resolutions[]} to a policy/targetPoints model, but several components still spread resampleConfig.resolutions, throwing "resolutions is not iterable" and breaking the job list render. Default the initial resolution to null (the backend resolves it from the configured policy; zoom overrides it) and drop the now-obsolete resolution selector and admin display fields. Co-Authored-By: Claude Opus 4.8 (1M context) Entire-Checkpoint: 27516ce259fd --- web/frontend/src/Systems.root.svelte | 22 +++---------------- web/frontend/src/config/admin/Options.svelte | 4 ++-- .../src/generic/joblist/JobListRow.svelte | 5 +++-- web/frontend/src/job/Metric.svelte | 5 +++-- 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/web/frontend/src/Systems.root.svelte b/web/frontend/src/Systems.root.svelte index 4cb85079..b543b20f 100644 --- a/web/frontend/src/Systems.root.svelte +++ b/web/frontend/src/Systems.root.svelte @@ -70,8 +70,6 @@ const ccconfig = $derived(thisInit ? getContext("cc-config") : null); const globalMetrics = $derived(thisInit ? getContext("globalMetrics") : null); const resampleConfig = $derived(thisInit ? getContext("resampling") : null); - const resampleResolutions = $derived(resampleConfig ? [...resampleConfig.resolutions] : []); - const resampleDefault = $derived(resampleConfig ? Math.max(...resampleConfig.resolutions) : 0); const displayNodeOverview = $derived((displayType === 'OVERVIEW')); const systemMetrics = $derived(globalMetrics ? [...globalMetrics.filter((gm) => gm?.availability.find((av) => av.cluster == cluster))] : []); @@ -85,7 +83,8 @@ return {...pendingUnits}; }); - let selectedResolution = $derived(resampleDefault); + // null lets the backend resolve the resolution from the configured resample policy. + let selectedResolution = $state(null); let to = $derived(presetTo ? presetTo : new Date(Date.now())); let from = $derived(presetFrom ? presetFrom : new Date(nowDate.setHours(nowDate.getHours() - 4))); @@ -159,7 +158,7 @@ - + {#if thisInit} {#if !displayNodeOverview} @@ -176,21 +175,6 @@ - {#if resampleConfig} - - - - Resolution - - {#each resampleResolutions as res} - - {/each} - - - - {/if} {/if} diff --git a/web/frontend/src/config/admin/Options.svelte b/web/frontend/src/config/admin/Options.svelte index ea6809f3..50e1fcf4 100644 --- a/web/frontend/src/config/admin/Options.svelte +++ b/web/frontend/src/config/admin/Options.svelte @@ -77,8 +77,8 @@ Metric Plot Resampling Info -

Triggered at {resampleConfig.trigger} datapoints.

-

Configured resolutions: {resampleConfig.resolutions}

+

Resampling is enabled.

+

Target data points per plot: {resampleConfig.targetPoints}

diff --git a/web/frontend/src/generic/joblist/JobListRow.svelte b/web/frontend/src/generic/joblist/JobListRow.svelte index c0b18e63..43c4d22d 100644 --- a/web/frontend/src/generic/joblist/JobListRow.svelte +++ b/web/frontend/src/generic/joblist/JobListRow.svelte @@ -84,7 +84,6 @@ let thresholdStates = $state({}); /* Derived */ - const resampleDefault = $derived(resampleConfig ? Math.max(...resampleConfig.resolutions) : 0); const jobId = $derived(job.id); const scopes = $derived.by(() => { if (job.numNodes == 1) { @@ -95,7 +94,9 @@ }; }); - let selectedResolution = $derived(resampleDefault); + // null lets the backend resolve the resolution from the configured resample + // policy; zoom interactions override it with an explicit value. + let selectedResolution = $state(null); let isSelected = $derived(previousSelect); let metricsQuery = $derived(queryStore({ client: client, diff --git a/web/frontend/src/job/Metric.svelte b/web/frontend/src/job/Metric.svelte index a0ab18e5..192d8f22 100644 --- a/web/frontend/src/job/Metric.svelte +++ b/web/frontend/src/job/Metric.svelte @@ -44,7 +44,6 @@ const client = getContextClient(); const statsPattern = /(.*)-stat$/; const resampleConfig = getContext("resampling") || null; - const resampleDefault = resampleConfig ? Math.max(...resampleConfig.resolutions) : 0; const subQuery = gql` query ($dbid: ID!, $selectedMetrics: [String!]!, $selectedScopes: [MetricScope!]!, $selectedResolution: Int) { singleUpdate: jobMetrics(id: $dbid, metrics: $selectedMetrics, scopes: $selectedScopes, resolution: $selectedResolution) { @@ -78,7 +77,9 @@ `; /* State Init */ - let selectedResolution = $state(resampleDefault); + // null lets the backend resolve the resolution from the configured resample + // policy; zoom interactions override it with an explicit value. + let selectedResolution = $state(null); let selectedHost = $state(null); let zoomState = $state(null); let thresholdState = $state(null);