From 7c8184d5bfa05867f7d25305053259f271da56f9 Mon Sep 17 00:00:00 2001 From: Sergej-Vlasov <37613182+Sergej-Vlasov@users.noreply.github.com> Date: Tue, 20 Aug 2024 11:55:04 +0300 Subject: [PATCH] DashboardModel - Add fallback for variable current value fallback (#91833) * add variable current value fallback when null * refactor to avoid loosing reference --- .../dashboard/state/DashboardModel.ts | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index fce70c7f03d..057d621d706 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -19,7 +19,7 @@ import { } from '@grafana/data'; import { PromQuery } from '@grafana/prometheus'; import { RefreshEvent, TimeRangeUpdatedEvent, config } from '@grafana/runtime'; -import { Dashboard, DashboardLink } from '@grafana/schema'; +import { Dashboard, DashboardLink, VariableModel } from '@grafana/schema'; import { DEFAULT_ANNOTATION_COLOR } from '@grafana/ui'; import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERTICAL } from 'app/core/constants'; import { contextSrv } from 'app/core/services/context_srv'; @@ -145,7 +145,7 @@ export class DashboardModel implements TimeModel { this.time = data.time ?? { from: 'now-6h', to: 'now' }; this.timepicker = data.timepicker ?? {}; this.liveNow = data.liveNow; - this.templating = this.ensureListExist(data.templating); + this.templating = this.removeNullValuesFromVariables(this.ensureListExist(data.templating)); this.annotations = this.ensureListExist(data.annotations); this.refresh = data.refresh; this.snapshot = data.snapshot; @@ -471,6 +471,28 @@ export class DashboardModel implements TimeModel { } } + private removeNullValuesFromVariables(templating: { list: VariableModel[] }) { + if (!templating.list.length) { + return templating; + } + + for (const variable of templating.list) { + if (variable.current) { + // this is a safeguard for null value that breaks scenes dashboards. + // expecting error at .includes(null) in order to not adjust + // VariableOption type to avoid breaking changes + if ( + variable.current.value === null || + //@ts-expect-error + (Array.isArray(variable.current.value) && variable.current.value.includes(null)) + ) { + variable.current = undefined; + } + } + } + return templating; + } + private ensureListExist(data: any = {}) { data.list ??= []; return data;