Dashboard Controls (#111245)

* refactor: use the `hide` property for the dashboard controls

* tests: fix failing tests

* fix: linting issues
This commit is contained in:
Levente Balogh
2025-09-18 10:43:08 +02:00
committed by GitHub
parent db170d3642
commit 2aa979b863
10 changed files with 64 additions and 74 deletions
@@ -116,7 +116,7 @@ export class DashboardControls extends SceneObjectBase<DashboardControlsState> {
const { links } = dashboard.state;
const hasControlMenuVariables = sceneGraph
.getVariables(dashboard)
?.state.variables.some((v) => v.state.showInControlsMenu === true);
?.state.variables.some((v) => v.state.hide === VariableHide.inControlsMenu);
const hasControlMenuLinks = links.some((link) => link.placement === 'inControlsMenu');
return hasControlMenuVariables || hasControlMenuLinks;
@@ -1,6 +1,7 @@
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VariableHide } from '@grafana/data';
import { SceneVariableSet, TextBoxVariable, QueryVariable, CustomVariable, SceneVariable } from '@grafana/scenes';
import {
@@ -21,7 +22,6 @@ describe('DashboardControlsMenu', () => {
new TextBoxVariable({
name: 'textVar',
value: 'test',
showInControlsMenu: false,
}),
];
const { container } = render(<DashboardControlsButton dashboard={getDashboard(variables)} />);
@@ -33,7 +33,7 @@ describe('DashboardControlsMenu', () => {
new TextBoxVariable({
name: 'textVar',
value: 'test',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
];
@@ -51,17 +51,17 @@ describe('DashboardControlsMenu', () => {
new TextBoxVariable({
name: 'textVar1',
value: 'test1',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
new TextBoxVariable({
name: 'textVar2',
value: 'test2',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
new QueryVariable({
name: 'queryVar',
query: 'test query',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
];
@@ -79,28 +79,28 @@ describe('DashboardControlsMenu', () => {
expect(await screen.findByText('queryVar')).toBeInTheDocument();
});
it('should filter out variables with showInControlsMenu=false', async () => {
it('should filter out variables with hide=VariableHide.inControlsMenu', async () => {
const variables = [
new TextBoxVariable({
name: 'textVar1',
value: 'test1',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
// This should be filtered out
new TextBoxVariable({
name: 'textVar2',
value: 'test2',
showInControlsMenu: false, // This should be filtered out
}),
new CustomVariable({
name: 'customVar',
query: 'option1,option2',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
}),
];
render(<DashboardControlsButton dashboard={getDashboard(variables)} />);
// Should still render dropdown since we have variables with showInControlsMenu=true
// Should still render dropdown since we have variables with hide=VariableHide.inControlsMenu
expect(screen.getByRole('button')).toBeInTheDocument();
// Open the dropdown
@@ -3,7 +3,7 @@ import { css, cx } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { sceneGraph, SceneVariable } from '@grafana/scenes';
import { DashboardLink } from '@grafana/schema';
import { DashboardLink, VariableHide } from '@grafana/schema';
import { Box, Dropdown, Menu, ToolbarButton, useStyles2 } from '@grafana/ui';
import { DashboardLinkRenderer } from './DashboardLinkRenderer';
@@ -23,7 +23,7 @@ export function DashboardControlsButton({ dashboard }: { dashboard: DashboardSce
const variables = sceneGraph
.getVariables(dashboard)!
.useState()
.variables.filter((v) => v.state.showInControlsMenu === true);
.variables.filter((v) => v.state.hide === VariableHide.inControlsMenu);
if ((variables.length === 0 && filteredLinks.length === 0) || !uid) {
return null;
@@ -20,7 +20,7 @@ export function VariableControls({ dashboard }: { dashboard: DashboardScene }) {
return (
<>
{variables
.filter((v) => !v.state.showInControlsMenu)
.filter((v) => v.state.hide !== VariableHide.inControlsMenu)
.map((variable) => (
<VariableValueSelectWrapper key={variable.state.key} variable={variable} />
))}
@@ -23,7 +23,7 @@ import {
SceneVariableSet,
TextBoxVariable,
} from '@grafana/scenes';
import { DataSourceRef, VariableRefresh } from '@grafana/schema';
import { DataSourceRef, VariableHide, VariableRefresh } from '@grafana/schema';
import { sceneVariablesSetToSchemaV2Variables, sceneVariablesSetToVariables } from './sceneVariablesSetToVariables';
@@ -93,7 +93,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['selected-value'],
text: ['selected-value-text'],
datasource: { uid: 'fake-uid', type: 'fake-type' },
@@ -131,6 +131,7 @@ describe('sceneVariablesSetToVariables', () => {
},
"definition": undefined,
"description": "test-desc",
"hide": 3,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -139,7 +140,6 @@ describe('sceneVariablesSetToVariables', () => {
"query": "query",
"refresh": 1,
"regex": "",
"showInControlsMenu": true,
"staticOptions": [
{
"text": "test",
@@ -157,7 +157,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['selected-value'],
text: ['selected-value-text'],
datasource: { uid: 'fake-uid', type: 'fake-type' },
@@ -195,6 +195,7 @@ describe('sceneVariablesSetToVariables', () => {
},
"definition": "query",
"description": "test-desc",
"hide": 3,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -203,7 +204,6 @@ describe('sceneVariablesSetToVariables', () => {
"query": "query",
"refresh": 1,
"regex": "",
"showInControlsMenu": true,
"staticOptions": [
{
"text": "test",
@@ -221,7 +221,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['selected-value'],
text: ['selected-value-text'],
datasource: { uid: 'fake-uid', type: 'fake-type' },
@@ -249,7 +249,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['test'],
text: ['test'],
datasource: { uid: 'fake-uid', type: 'fake-type' },
@@ -279,7 +279,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['selected-ds-1', 'selected-ds-2'],
text: ['selected-ds-1-text', 'selected-ds-2-text'],
pluginId: 'fake-std',
@@ -310,6 +310,7 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": 3,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -318,7 +319,6 @@ describe('sceneVariablesSetToVariables', () => {
"query": "fake-std",
"refresh": 1,
"regex": "",
"showInControlsMenu": true,
"type": "datasource",
}
`);
@@ -329,7 +329,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: ['test', 'test2'],
text: ['test', 'test2'],
query: 'test,test1,test2',
@@ -365,6 +365,7 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": 3,
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -387,7 +388,6 @@ describe('sceneVariablesSetToVariables', () => {
},
],
"query": "test,test1,test2",
"showInControlsMenu": true,
"type": "custom",
}
`);
@@ -398,7 +398,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: 'constant value',
skipUrlSync: true,
});
@@ -420,7 +420,6 @@ describe('sceneVariablesSetToVariables', () => {
"label": "test-label",
"name": "test",
"query": "constant value",
"showInControlsMenu": true,
"skipUrlSync": true,
"type": "constant",
}
@@ -432,7 +431,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
value: 'text value',
skipUrlSync: true,
});
@@ -450,6 +449,7 @@ describe('sceneVariablesSetToVariables', () => {
"value": "text value",
},
"description": "test-desc",
"hide": 3,
"label": "test-label",
"name": "test",
"options": [
@@ -460,7 +460,6 @@ describe('sceneVariablesSetToVariables', () => {
},
],
"query": "text value",
"showInControlsMenu": true,
"skipUrlSync": true,
"type": "textbox",
}
@@ -472,7 +471,7 @@ describe('sceneVariablesSetToVariables', () => {
intervals: ['1m', '2m', '3m', '1h', '1d'],
value: '1m',
refresh: VariableRefresh.onDashboardLoad,
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
});
const set = new SceneVariableSet({
variables: [variable],
@@ -490,6 +489,7 @@ describe('sceneVariablesSetToVariables', () => {
"value": "1m",
},
"description": undefined,
"hide": 3,
"label": undefined,
"name": "",
"options": [
@@ -521,7 +521,6 @@ describe('sceneVariablesSetToVariables', () => {
],
"query": "1m,2m,3m,1h,1d",
"refresh": 1,
"showInControlsMenu": true,
"type": "interval",
}
`);
@@ -533,7 +532,7 @@ describe('sceneVariablesSetToVariables', () => {
allowCustomValue: true,
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
filters: [
{
@@ -580,9 +579,9 @@ describe('sceneVariablesSetToVariables', () => {
"value": "test",
},
],
"hide": 3,
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"type": "adhoc",
}
`);
@@ -595,7 +594,7 @@ describe('sceneVariablesSetToVariables', () => {
allowCustomValue: true,
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-std', type: 'fake-std' },
originFilters: [
{
@@ -625,9 +624,9 @@ describe('sceneVariablesSetToVariables', () => {
"defaultKeys": undefined,
"description": "test-desc",
"filters": [],
"hide": 3,
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"type": "adhoc",
}
`);
@@ -639,7 +638,7 @@ describe('sceneVariablesSetToVariables', () => {
allowCustomValue: true,
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-std', type: 'fake-std' },
originFilters: [
{
@@ -687,9 +686,9 @@ describe('sceneVariablesSetToVariables', () => {
"value": "test2",
},
],
"hide": 3,
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"type": "adhoc",
}
`);
@@ -702,7 +701,7 @@ describe('sceneVariablesSetToVariables', () => {
allowCustomValue: true,
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultKeys: [
{
@@ -776,9 +775,9 @@ describe('sceneVariablesSetToVariables', () => {
"value": "test",
},
],
"hide": 3,
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"type": "adhoc",
}
`);
@@ -799,7 +798,7 @@ describe('sceneVariablesSetToVariables', () => {
label: 'test-label',
description: 'test-desc',
allowCustomValue: true,
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultOptions: [
{
@@ -832,6 +831,7 @@ describe('sceneVariablesSetToVariables', () => {
},
"defaultValue": undefined,
"description": "test-desc",
"hide": 3,
"label": "test-label",
"name": "test",
"options": [
@@ -844,7 +844,6 @@ describe('sceneVariablesSetToVariables', () => {
"value": "bar",
},
],
"showInControlsMenu": true,
"type": "groupby",
}
`);
@@ -857,7 +856,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultOptions: [
{
@@ -893,7 +892,7 @@ describe('sceneVariablesSetToVariables', () => {
isMulti: true,
staticOptions: [{ label: 'test', value: 'test' }],
staticOptionsOrder: 'after',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
});
const set = new SceneVariableSet({
@@ -919,7 +918,7 @@ describe('sceneVariablesSetToVariables', () => {
},
"definition": undefined,
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -938,7 +937,6 @@ describe('sceneVariablesSetToVariables', () => {
},
"refresh": "onDashboardLoad",
"regex": "",
"showInControlsMenu": true,
"skipUrlSync": false,
"sort": "disabled",
"staticOptions": [
@@ -961,7 +959,7 @@ describe('sceneVariablesSetToVariables', () => {
value: ['test', 'test2'],
text: ['test', 'test2'],
query: 'test,test1,test2',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
options: [
{ label: 'test', value: 'test' },
{ label: 'test1', value: 'test1' },
@@ -995,7 +993,7 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -1018,7 +1016,6 @@ describe('sceneVariablesSetToVariables', () => {
},
],
"query": "test,test1,test2",
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1036,7 +1033,7 @@ describe('sceneVariablesSetToVariables', () => {
includeAll: true,
allValue: 'test-all',
isMulti: true,
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
});
const set = new SceneVariableSet({
variables: [variable],
@@ -1062,7 +1059,7 @@ describe('sceneVariablesSetToVariables', () => {
],
},
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"includeAll": true,
"label": "test-label",
"multi": true,
@@ -1071,7 +1068,6 @@ describe('sceneVariablesSetToVariables', () => {
"pluginId": "fake-std",
"refresh": "onDashboardLoad",
"regex": "",
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1084,7 +1080,7 @@ describe('sceneVariablesSetToVariables', () => {
label: 'test-label',
description: 'test-desc',
value: 'constant value',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
skipUrlSync: true,
});
const set = new SceneVariableSet({
@@ -1103,11 +1099,10 @@ describe('sceneVariablesSetToVariables', () => {
"value": "constant value",
},
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"label": "test-label",
"name": "test",
"query": "constant value",
"showInControlsMenu": true,
"skipUrlSync": true,
},
}
@@ -1120,7 +1115,7 @@ describe('sceneVariablesSetToVariables', () => {
label: 'test-label',
description: 'test-desc',
value: 'text value',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
skipUrlSync: true,
});
const set = new SceneVariableSet({
@@ -1139,11 +1134,10 @@ describe('sceneVariablesSetToVariables', () => {
"value": "text value",
},
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"label": "test-label",
"name": "test",
"query": "text value",
"showInControlsMenu": true,
"skipUrlSync": true,
},
}
@@ -1154,7 +1148,7 @@ describe('sceneVariablesSetToVariables', () => {
const variable = new IntervalVariable({
intervals: ['1m', '2m', '3m', '1h', '1d'],
value: '1m',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
refresh: VariableRefresh.onDashboardLoad,
});
const set = new SceneVariableSet({
@@ -1175,7 +1169,7 @@ describe('sceneVariablesSetToVariables', () => {
"value": "1m",
},
"description": undefined,
"hide": "dontHide",
"hide": "inControlsMenu",
"label": undefined,
"name": "",
"options": [
@@ -1207,7 +1201,6 @@ describe('sceneVariablesSetToVariables', () => {
],
"query": "1m,2m,3m,1h,1d",
"refresh": "onTimeRangeChanged",
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1219,7 +1212,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
filters: [
{
@@ -1268,10 +1261,9 @@ describe('sceneVariablesSetToVariables', () => {
"value": "test",
},
],
"hide": "dontHide",
"hide": "inControlsMenu",
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1283,7 +1275,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultKeys: [
{
@@ -1359,10 +1351,9 @@ describe('sceneVariablesSetToVariables', () => {
"value": "test",
},
],
"hide": "dontHide",
"hide": "inControlsMenu",
"label": "test-label",
"name": "test",
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1383,7 +1374,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultOptions: [
{
@@ -1417,7 +1408,7 @@ describe('sceneVariablesSetToVariables', () => {
},
"defaultValue": undefined,
"description": "test-desc",
"hide": "dontHide",
"hide": "inControlsMenu",
"label": "test-label",
"multi": true,
"name": "test",
@@ -1431,7 +1422,6 @@ describe('sceneVariablesSetToVariables', () => {
"value": "bar",
},
],
"showInControlsMenu": true,
"skipUrlSync": false,
},
}
@@ -1445,7 +1435,7 @@ describe('sceneVariablesSetToVariables', () => {
name: 'test',
label: 'test-label',
description: 'test-desc',
showInControlsMenu: true,
hide: VariableHide.inControlsMenu,
datasource: { uid: 'fake-uid', type: 'fake-type' },
defaultOptions: [
{
@@ -60,7 +60,6 @@ export function sceneVariablesSetToVariables(set: SceneVariables, keepQueryOptio
skipUrlSync: Boolean(variable.state.skipUrlSync),
hide: variable.state.hide || OldVariableHide.dontHide,
type: variable.state.type,
showInControlsMenu: variable.state.showInControlsMenu,
};
if (sceneUtils.isQueryVariable(variable)) {
@@ -284,7 +283,6 @@ export function sceneVariablesSetToSchemaV2Variables(
description: variable.state.description ?? undefined,
skipUrlSync: Boolean(variable.state.skipUrlSync),
hide: transformVariableHideToEnum(variable.state.hide) || defaultVariableHide(),
showInControlsMenu: variable.state.showInControlsMenu,
};
// current: VariableOption;
@@ -273,7 +273,6 @@ function createSceneVariableFromVariableModel(variable: TypedVariableModelV2): S
name: variable.spec.name,
label: variable.spec.label,
description: variable.spec.description,
showInControlsMenu: variable.spec.showInControlsMenu,
};
if (variable.kind === defaultAdhocVariableKind().kind) {
const ds = getDataSourceForQuery(
@@ -39,6 +39,8 @@ export function transformVariableHideToEnumV1(hide?: VariableHide): VariableHide
return VariableHideV1.hideLabel;
case 'hideVariable':
return VariableHideV1.hideVariable;
case 'inControlsMenu':
return VariableHideV1.inControlsMenu;
default:
return VariableHideV1.dontHide;
}
@@ -55,6 +55,8 @@ export function transformVariableHideToEnum(hide?: VariableHideV1): VariableHide
return 'hideLabel';
case 2:
return 'hideVariable';
case 3:
return 'inControlsMenu';
default:
return defaultVariableHide();
}
@@ -131,7 +131,6 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode
name: variable.name,
label: variable.label,
description: variable.description,
showInControlsMenu: variable.showInControlsMenu,
};
if (variable.type === 'adhoc') {
const originFilters: AdHocVariableFilter[] = [];