From 7d013dc236453f5c09ef8a360030242f427fc447 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Sat, 17 Jun 2023 04:26:38 -0400 Subject: [PATCH] [v10.0.x] fix: allow `{}` type in `VariableWithOptions.current ` (#70238) Variables: allow `{}` type in `VariableWithOptions.current ` (#64358) (cherry picked from commit 6f880b713afcd83519d89c506609f31b6b7bc1df) Co-authored-by: Simon Podlipsky --- packages/grafana-data/src/types/templateVars.ts | 2 +- packages/grafana-data/src/utils/object.ts | 4 ++++ public/app/features/dashboard/state/DashboardMigrator.ts | 4 ++++ .../features/variables/pickers/OptionsPicker/actions.ts | 5 +++++ public/app/features/variables/state/actions.ts | 3 ++- .../features/variables/textbox/TextBoxVariablePicker.tsx | 3 ++- .../datasource/cloudwatch/utils/templateVariableUtils.ts | 7 ++++++- 7 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/grafana-data/src/types/templateVars.ts b/packages/grafana-data/src/types/templateVars.ts index 0395556f8ef..96ecef01e54 100644 --- a/packages/grafana-data/src/types/templateVars.ts +++ b/packages/grafana-data/src/types/templateVars.ts @@ -109,7 +109,7 @@ export interface VariableWithMultiSupport extends VariableWithOptions { } export interface VariableWithOptions extends BaseVariableModel { - current: VariableOption; + current: VariableOption | Record; options: VariableOption[]; query: string; } diff --git a/packages/grafana-data/src/utils/object.ts b/packages/grafana-data/src/utils/object.ts index 47c1ee0e629..0f40f8e636a 100644 --- a/packages/grafana-data/src/utils/object.ts +++ b/packages/grafana-data/src/utils/object.ts @@ -6,3 +6,7 @@ return acc; }, {}); }; + +export const isEmptyObject = (value: unknown): value is Record => { + return typeof value === 'object' && value !== null && Object.keys(value).length === 0; +}; diff --git a/public/app/features/dashboard/state/DashboardMigrator.ts b/public/app/features/dashboard/state/DashboardMigrator.ts index 7fb0ca83103..20d5e4e05da 100644 --- a/public/app/features/dashboard/state/DashboardMigrator.ts +++ b/public/app/features/dashboard/state/DashboardMigrator.ts @@ -12,6 +12,7 @@ import { getActiveThreshold, getDataSourceRef, isDataSourceRef, + isEmptyObject, MappingType, PanelPlugin, SpecialValueMatch, @@ -584,6 +585,9 @@ export class DashboardMigrator { continue; } const { multi, current } = variable; + if (isEmptyObject(current)) { + continue; + } variable.current = alignCurrentWithMulti(current, multi); } } diff --git a/public/app/features/variables/pickers/OptionsPicker/actions.ts b/public/app/features/variables/pickers/OptionsPicker/actions.ts index a4c5b3bd134..81a89fba611 100644 --- a/public/app/features/variables/pickers/OptionsPicker/actions.ts +++ b/public/app/features/variables/pickers/OptionsPicker/actions.ts @@ -1,5 +1,6 @@ import { debounce, trim } from 'lodash'; +import { isEmptyObject } from '@grafana/data'; import { StoreState, ThunkDispatch, ThunkResult } from 'app/types'; import { variableAdapters } from '../../adapters'; @@ -83,6 +84,10 @@ export const filterOrSearchOptions = ( }; const setVariable = async (updated: VariableWithOptions) => { + if (isEmptyObject(updated.current)) { + return; + } + const adapter = variableAdapters.get(updated.type); await adapter.setValue(updated, updated.current, true); return; diff --git a/public/app/features/variables/state/actions.ts b/public/app/features/variables/state/actions.ts index 4cd626cba7d..798e1a90f5d 100644 --- a/public/app/features/variables/state/actions.ts +++ b/public/app/features/variables/state/actions.ts @@ -4,6 +4,7 @@ import { DataQuery, getDataSourceRef, isDataSourceRef, + isEmptyObject, LoadingState, TimeRange, UrlQueryMap, @@ -256,7 +257,7 @@ export const changeVariableMultiValue = (identifier: KeyedVariableIdentifier, mu return (dispatch, getState) => { const { rootStateKey: key } = identifier; const variable = getVariable(identifier, getState()); - if (!isMulti(variable)) { + if (!isMulti(variable) || isEmptyObject(variable.current)) { return; } diff --git a/public/app/features/variables/textbox/TextBoxVariablePicker.tsx b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx index a9de57bba48..54f9395cf15 100644 --- a/public/app/features/variables/textbox/TextBoxVariablePicker.tsx +++ b/public/app/features/variables/textbox/TextBoxVariablePicker.tsx @@ -1,5 +1,6 @@ import React, { ChangeEvent, FocusEvent, KeyboardEvent, ReactElement, useCallback, useEffect, useState } from 'react'; +import { isEmptyObject } from '@grafana/data'; import { Input } from '@grafana/ui'; import { t } from 'app/core/internationalization'; import { useDispatch } from 'app/types'; @@ -43,7 +44,7 @@ export function TextBoxVariablePicker({ variable, onVariableChange, readOnly }: if (onVariableChange) { onVariableChange({ ...variable, - current: { ...variable.current, value: updatedValue }, + current: isEmptyObject(variable.current) ? {} : { ...variable.current, value: updatedValue }, }); return; } diff --git a/public/app/plugins/datasource/cloudwatch/utils/templateVariableUtils.ts b/public/app/plugins/datasource/cloudwatch/utils/templateVariableUtils.ts index bf5458a793c..be1e2043754 100644 --- a/public/app/plugins/datasource/cloudwatch/utils/templateVariableUtils.ts +++ b/public/app/plugins/datasource/cloudwatch/utils/templateVariableUtils.ts @@ -48,7 +48,12 @@ export const isTemplateVariable = (templateSrv: TemplateSrv, string: string) => }; const isVariableOption = ( - current: VariableOption | { value: UserProps } | { value: OrgProps } | { value: DashboardProps } + current: + | VariableOption + | Record + | { value: UserProps } + | { value: OrgProps } + | { value: DashboardProps } ): current is VariableOption => { return current.hasOwnProperty('value') && current.hasOwnProperty('text'); };