diff --git a/packages/grafana-data/src/types/templateVars.ts b/packages/grafana-data/src/types/templateVars.ts index 62ce2862af2..99716d15b1a 100644 --- a/packages/grafana-data/src/types/templateVars.ts +++ b/packages/grafana-data/src/types/templateVars.ts @@ -91,6 +91,7 @@ export interface VariableOption { text: string | string[]; value: string | string[]; isNone?: boolean; + properties?: Record; } export interface IntervalVariableModel extends VariableWithOptions { diff --git a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts index cc83c131fed..2196776bcf4 100644 --- a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts +++ b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts @@ -284,6 +284,7 @@ function variableValueOptionsToVariableOptions(varState: MultiValueVariable['sta value: String(o.value), text: o.label, selected: Array.isArray(varState.value) ? varState.value.includes(o.value) : varState.value === o.value, + ...(o.properties && { properties: o.properties }), })); } diff --git a/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx b/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx index eb78f34a45b..1de62a2bcbd 100644 --- a/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx +++ b/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx @@ -69,7 +69,6 @@ export function VariableEditorForm({ variable, onTypeChange, onGoBack, onDelete const isHasVariableOptions = hasVariableOptions(variable); const optionsForSelect = isHasVariableOptions ? variable.getOptionsForSelect(false) : []; - const hasMultiProps = 'valuesFormat' in variable.state && variable.state.valuesFormat === 'json'; const onDeleteVariable = (hideModal: () => void) => () => { reportInteraction('Delete variable'); @@ -125,7 +124,7 @@ export function VariableEditorForm({ variable, onTypeChange, onGoBack, onDelete {EditorToRender && } - {isHasVariableOptions && } + {isHasVariableOptions && }
diff --git a/public/app/features/dashboard-scene/settings/variables/components/VariableValuesPreview.tsx b/public/app/features/dashboard-scene/settings/variables/components/VariableValuesPreview.tsx index 87707d0530d..dbf89ad9fa2 100644 --- a/public/app/features/dashboard-scene/settings/variables/components/VariableValuesPreview.tsx +++ b/public/app/features/dashboard-scene/settings/variables/components/VariableValuesPreview.tsx @@ -10,13 +10,16 @@ import { Button, InlineFieldRow, InlineLabel, InteractiveTable, Text, useStyles2 export interface Props { options: VariableValueOption[]; - hasMultiProps?: boolean; } -export const VariableValuesPreview = ({ options, hasMultiProps }: Props) => { +const hasMultiProps = (options: Props['options']) => { + return Object.keys(options[1]?.properties ?? options[0]?.properties ?? {}).length > 0; +}; + +export const VariableValuesPreview = ({ options }: Props) => { const styles = useStyles2(getStyles); const hasOptions = options.length > 0; - const displayMultiPropsPreview = config.featureToggles.multiPropsVariables && hasMultiProps; + const displayMultiPropsPreview = config.featureToggles.multiPropsVariables && hasOptions && hasMultiProps(options); return (
@@ -43,7 +46,8 @@ function VariableValuesWithPropsPreview({ options }: { options: VariableValueOpt return { data, - columns: Object.keys(data[0] ?? {}).map((id) => ({ + // the option at index 0 can be "All" so we try to grab the column names from the 2nd option + columns: Object.keys(data[1] ?? data[0] ?? {}).map((id) => ({ id, // see https://github.com/TanStack/table/issues/1671 header: unsanitizeKey(id), @@ -62,7 +66,6 @@ function VariableValuesWithPropsPreview({ options }: { options: VariableValueOpt /> ); } - const sanitizeKey = (key: string) => key.replace(/\./g, '__dot__'); const unsanitizeKey = (key: string) => key.replace(/__dot__/g, '.'); diff --git a/public/app/features/dashboard-scene/settings/variables/editors/CustomVariableEditor/ModalEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/CustomVariableEditor/ModalEditor.tsx index aeb2be59af6..6c278aa720e 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/CustomVariableEditor/ModalEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/CustomVariableEditor/ModalEditor.tsx @@ -69,7 +69,7 @@ function ModalEditorMultiProps(props: ModalEditorProps) { {queryValidationError && {queryValidationError.message}}
- +
diff --git a/public/app/features/panel/panellinks/link_srv.ts b/public/app/features/panel/panellinks/link_srv.ts index 679740c5592..ee10b22f5ce 100644 --- a/public/app/features/panel/panellinks/link_srv.ts +++ b/public/app/features/panel/panellinks/link_srv.ts @@ -81,16 +81,16 @@ const buildLabelPath = (label: string) => { }; const getVariableValueProperties = (variable: TypedVariableModel): string[] => { - if (!('valuesFormat' in variable) || variable.valuesFormat !== 'json') { + if (!('options' in variable) || !variable.options[0].properties) { return []; } - function collectFieldPaths(option: Record, currentPath: string) { + function collectFieldPaths(properties: Record, currentPath: string) { let paths: string[] = []; - for (const field in option) { - if (option.hasOwnProperty(field)) { + for (const field in properties) { + if (properties.hasOwnProperty(field)) { const newPath = `${currentPath}.${field}`; - const value = option[field]; + const value = properties[field]; if (typeof value === 'object' && value !== null) { paths = [...paths, ...collectFieldPaths(value, newPath)]; } @@ -100,11 +100,7 @@ const getVariableValueProperties = (variable: TypedVariableModel): string[] => { return paths; } - try { - return collectFieldPaths(JSON.parse(variable.query)[0], variable.name); - } catch { - return []; - } + return collectFieldPaths(variable.options[0].properties, variable.name); }; export const getPanelLinksVariableSuggestions = (): VariableSuggestion[] => [ diff --git a/public/app/features/panel/panellinks/specs/link_srv.test.ts b/public/app/features/panel/panellinks/specs/link_srv.test.ts index 1ed95ccbf22..82b96eb80b0 100644 --- a/public/app/features/panel/panellinks/specs/link_srv.test.ts +++ b/public/app/features/panel/panellinks/specs/link_srv.test.ts @@ -503,13 +503,16 @@ describe('linkSrv', () => { }); describe('getPanelLinksVariableSuggestions', () => { - it('then it should return template variables, json properties and built-ins', () => { + it('then it should return template variables, options properties and built-ins', () => { const templateSrvWithJsonValues = initTemplateSrv('key', [ { type: 'custom', name: 'customServers', valuesFormat: 'json', - query: '[{"name":"web","ip":"192.168.0.100"},{"name":"ads","ip":"192.168.0.142"}]', + options: [ + { text: 'web', value: 'web', properties: { name: 'web', ip: '192.168.0.100' } }, + { text: 'ads', value: 'ads', properties: { name: 'ads', ip: '192.168.0.142' } }, + ], }, ]); setTemplateSrv(templateSrvWithJsonValues);