From 344fc5606fa27146613d5406628a95ccd70808a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 30 Oct 2025 10:50:05 +0100 Subject: [PATCH] PanelTimeCompare: Support saving time compare window (#113150) * PanelTimeCompare: Support saving time compare window * fix indentation * Fix merge issue * Update * Update * make gen-cue --------- Co-authored-by: oscarkilhed --- apps/dashboard/kinds/v2beta1/dashboard_spec.cue | 1 + .../pkg/apis/dashboard/v0alpha1/dashboard_kind.cue | 4 ++++ .../dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue | 4 ++++ .../dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue | 1 + .../pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go | 1 + .../pkg/apis/dashboard/v2beta1/zz_generated.openapi.go | 6 ++++++ kinds/dashboard/dashboard_kind.cue | 4 ++++ .../src/raw/dashboard/x/dashboard_types.gen.ts | 5 +++++ .../src/schema/dashboard/v2alpha0/dashboard.schema.cue | 1 + .../src/schema/dashboard/v2beta1/types.spec.gen.ts | 1 + pkg/kinds/dashboard/dashboard_spec_gen.go | 3 +++ .../serialization/transformSaveModelToScene.ts | 3 ++- .../serialization/transformSceneToSaveModel.ts | 1 + .../serialization/transformSceneToSaveModelSchemaV2.ts | 1 + public/app/features/dashboard/state/PanelModel.ts | 1 + 15 files changed, 36 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue index f0278fc431c..ef1490091c2 100644 --- a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue @@ -452,6 +452,7 @@ QueryOptionsSpec: { interval?: string cacheTimeout?: string hideTimeOverride?: bool + timeCompare?: string } DataQueryKind: { diff --git a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue index 526ddba3bfc..7d8a0e551bf 100644 --- a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue @@ -670,6 +670,10 @@ lineage: schemas: [{ // Controls if the timeFrom or timeShift overrides are shown in the panel header hideTimeOverride?: bool + // Compare the current time range with a previous period + // For example "1d" to compare current period but shifted back 1 day + timeCompare?: string + // Dynamically load the panel libraryPanel?: #LibraryPanelRef diff --git a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue index 526ddba3bfc..7d8a0e551bf 100644 --- a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue @@ -670,6 +670,10 @@ lineage: schemas: [{ // Controls if the timeFrom or timeShift overrides are shown in the panel header hideTimeOverride?: bool + // Compare the current time range with a previous period + // For example "1d" to compare current period but shifted back 1 day + timeCompare?: string + // Dynamically load the panel libraryPanel?: #LibraryPanelRef diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue index fb46afb5c76..31603c6240b 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue @@ -456,6 +456,7 @@ QueryOptionsSpec: { interval?: string cacheTimeout?: string hideTimeOverride?: bool + timeCompare?: string } DataQueryKind: { diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go index 35674997511..4229e5765d1 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go @@ -278,6 +278,7 @@ type DashboardQueryOptionsSpec struct { Interval *string `json:"interval,omitempty"` CacheTimeout *string `json:"cacheTimeout,omitempty"` HideTimeOverride *bool `json:"hideTimeOverride,omitempty"` + TimeCompare *string `json:"timeCompare,omitempty"` } // NewDashboardQueryOptionsSpec creates a new DashboardQueryOptionsSpec object. diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go index 5e51134e80c..97fb1c10326 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go @@ -3426,6 +3426,12 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardQueryOptionsSpec(ref common.Refe Format: "", }, }, + "timeCompare": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index 13c2b4f25f6..e32b8b6725e 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -666,6 +666,10 @@ lineage: schemas: [{ // Controls if the timeFrom or timeShift overrides are shown in the panel header hideTimeOverride?: bool + // Compare the current time range with a previous period + // For example "1d" to compare current period but shifted back 1 day + timeCompare?: string + // Dynamically load the panel libraryPanel?: #LibraryPanelRef diff --git a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts index b370fc6206c..973f10bfb21 100644 --- a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts +++ b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts @@ -885,6 +885,11 @@ export interface Panel { * Depends on the panel plugin. See the plugin documentation for details. */ targets?: Array>; + /** + * Compare the current time range with a previous period + * For example "1d" to compare current period but shifted back 1 day + */ + timeCompare?: string; /** * Overrides the relative time range for individual panels, * which causes them to be different than what is selected in diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue index 5369503d6f2..ba637656ed8 100644 --- a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue @@ -409,6 +409,7 @@ QueryOptionsSpec: { interval?: string cacheTimeout?: string hideTimeOverride?: bool + timeCompare?: string } DataQueryKind: { diff --git a/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts index 19c324f1cd9..e9cbe9e649a 100644 --- a/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts +++ b/packages/grafana-schema/src/schema/dashboard/v2beta1/types.spec.gen.ts @@ -219,6 +219,7 @@ export interface QueryOptionsSpec { interval?: string; cacheTimeout?: string; hideTimeOverride?: boolean; + timeCompare?: string; } export const defaultQueryOptionsSpec = (): QueryOptionsSpec => ({ diff --git a/pkg/kinds/dashboard/dashboard_spec_gen.go b/pkg/kinds/dashboard/dashboard_spec_gen.go index 2ebe81760c9..43877fbca7b 100644 --- a/pkg/kinds/dashboard/dashboard_spec_gen.go +++ b/pkg/kinds/dashboard/dashboard_spec_gen.go @@ -191,6 +191,9 @@ type Panel struct { TimeShift *string `json:"timeShift,omitempty"` // Controls if the timeFrom or timeShift overrides are shown in the panel header HideTimeOverride *bool `json:"hideTimeOverride,omitempty"` + // Compare the current time range with a previous period + // For example "1d" to compare current period but shifted back 1 day + TimeCompare *string `json:"timeCompare,omitempty"` // Dynamically load the panel LibraryPanel *LibraryPanelRef `json:"libraryPanel,omitempty"` // Sets panel queries cache timeout. diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index aab1f181854..7646b7df68c 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -456,11 +456,12 @@ export function buildGridItemForPanel(panel: PanelModel): DashboardGridItem { }); } - if (panel.timeFrom || panel.timeShift) { + if (panel.timeFrom || panel.timeShift || panel.timeCompare) { vizPanelState.$timeRange = new PanelTimeRange({ timeFrom: panel.timeFrom, timeShift: panel.timeShift, hideTimeOverride: panel.hideTimeOverride, + compareWith: panel.timeCompare, }); } diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts index 16b3957435f..bd5a1139848 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts @@ -232,6 +232,7 @@ export function vizPanelToPanel( panel.timeFrom = panelTime.state.timeFrom; panel.timeShift = panelTime.state.timeShift; panel.hideTimeOverride = panelTime.state.hideTimeOverride; + panel.timeCompare = panelTime.state.compareWith; } if (gridItem instanceof DashboardGridItem) { diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts index da7e19d3a41..85cd9e8ee7b 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts @@ -387,6 +387,7 @@ function getVizPanelQueryOptions(vizPanel: VizPanel): QueryOptionsSpec { queryOptions.timeFrom = panelTime.state.timeFrom; queryOptions.timeShift = panelTime.state.timeShift; queryOptions.hideTimeOverride = panelTime.state.hideTimeOverride; + queryOptions.timeCompare = panelTime.state.compareWith; } return queryOptions; } diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 7e67a270ed4..4b06df7c8bc 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -170,6 +170,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { timeFrom?: any; timeShift?: any; hideTimeOverride?: boolean; + timeCompare?: string; declare options: { [key: string]: any; };