diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx index 1b9eeded9e4..7c79f5798cc 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.test.tsx @@ -4,7 +4,14 @@ import { DataQueryRequest, DataSourceApi, DataSourceInstanceSettings, LoadingSta import { calculateFieldTransformer } from '@grafana/data/src/transformations/transformers/calculateField'; import { mockTransformationsRegistry } from '@grafana/data/src/utils/tests/mockTransformationsRegistry'; import { config, locationService } from '@grafana/runtime'; -import { LocalValueVariable, SceneGridRow, SceneVariableSet, VizPanel, sceneGraph } from '@grafana/scenes'; +import { + CustomVariable, + LocalValueVariable, + SceneGridRow, + SceneVariableSet, + VizPanel, + sceneGraph, +} from '@grafana/scenes'; import { DataQuery, DataSourceJsonData, DataSourceRef } from '@grafana/schema'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import { InspectTab } from 'app/features/inspector/types'; @@ -801,6 +808,26 @@ describe('VizPanelManager', () => { expect(vizPanelManager.state.dsSettings).toEqual(instance1SettingsMock); }); + it('Should default to the first variable value if panel is repeated', async () => { + const { scene, panel } = setupTest('panel-10'); + + scene.setState({ + $variables: new SceneVariableSet({ + variables: [ + new CustomVariable({ name: 'custom', query: 'A,B,C', value: ['A', 'B', 'C'], text: ['A', 'B', 'C'] }), + ], + }), + }); + + scene.setState({ editPanel: buildPanelEditScene(panel) }); + + const vizPanelManager = scene.state.editPanel!.state.vizManager; + vizPanelManager.activate(); + + const variable = sceneGraph.lookupVariable('custom', vizPanelManager); + expect(variable?.getValue()).toBe('A'); + }); + describe('Given a panel inside repeated row', () => { it('Should include row variable scope', () => { const { panel } = setupTest('panel-9'); diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx index 3e8721302ca..6878fd5e569 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx @@ -15,6 +15,8 @@ import { import { config, getDataSourceSrv, locationService } from '@grafana/runtime'; import { DeepPartial, + LocalValueVariable, + MultiValueVariable, PanelBuilders, SceneComponentProps, SceneDataTransformer, @@ -23,8 +25,10 @@ import { SceneObjectState, SceneObjectStateChangedEvent, SceneQueryRunner, + SceneVariableSet, SceneVariables, VizPanel, + sceneGraph, } from '@grafana/scenes'; import { DataQuery, DataTransformerConfig, Panel } from '@grafana/schema'; import { useStyles2 } from '@grafana/ui'; @@ -41,7 +45,7 @@ import { DashboardGridItem, RepeatDirection } from '../scene/DashboardGridItem'; import { LibraryVizPanel } from '../scene/LibraryVizPanel'; import { PanelTimeRange, PanelTimeRangeState } from '../scene/PanelTimeRange'; import { gridItemToPanel, vizPanelToPanel } from '../serialization/transformSceneToSaveModel'; -import { getDashboardSceneFor, getPanelIdForVizPanel, getQueryRunnerFor } from '../utils/utils'; +import { getDashboardSceneFor, getMultiVariableValues, getPanelIdForVizPanel, getQueryRunnerFor } from '../utils/utils'; export interface VizPanelManagerState extends SceneObjectState { panel: VizPanel; @@ -97,6 +101,28 @@ export class VizPanelManager extends SceneObjectBase { variables = gridItem.parent.state.$variables.clone(); } + if (repeatOptions.repeat) { + const variable = sceneGraph.lookupVariable(repeatOptions.repeat, gridItem); + + if (variable instanceof MultiValueVariable && variable.state.value.length) { + const { values, texts } = getMultiVariableValues(variable); + + const varWithDefaultValue = new LocalValueVariable({ + name: variable.state.name, + value: values[0], + text: String(texts[0]), + }); + + if (!variables) { + variables = new SceneVariableSet({ + variables: [varWithDefaultValue], + }); + } else { + variables.setState({ variables: [varWithDefaultValue] }); + } + } + } + return new VizPanelManager({ $variables: variables, panel: sourcePanel.clone(), diff --git a/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts b/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts index a439bb2541d..f596a026b25 100644 --- a/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts +++ b/public/app/features/dashboard-scene/panel-edit/testfiles/testDashboard.ts @@ -91,6 +91,102 @@ export const panelWithQueriesOnly = { type: 'timeseries', }; +export const repeatedPanel = { + datasource: { + type: 'grafana-testdata-datasource', + uid: 'gdev-testdata', + }, + repeat: 'custom', + repeatDirection: 'h', + maxPerRow: 4, + fieldConfig: { + defaults: { + color: { + mode: 'palette-classic', + }, + custom: { + axisBorderShow: false, + axisCenteredZero: false, + axisColorMode: 'text', + axisLabel: '', + axisPlacement: 'auto', + barAlignment: 0, + drawStyle: 'line', + fillOpacity: 0, + gradientMode: 'none', + hideFrom: { + legend: false, + tooltip: false, + viz: false, + }, + insertNulls: false, + lineInterpolation: 'linear', + lineWidth: 1, + pointSize: 5, + scaleDistribution: { + type: 'linear', + }, + showPoints: 'auto', + spanNulls: false, + stacking: { + group: 'A', + mode: 'none', + }, + thresholdsStyle: { + mode: 'off', + }, + }, + mappings: [], + thresholds: { + mode: 'absolute', + steps: [ + { + color: 'green', + value: null, + }, + { + color: 'red', + value: 80, + }, + ], + }, + }, + overrides: [], + }, + gridPos: { + h: 8, + w: 12, + x: 0, + y: 0, + }, + id: 1, + options: { + legend: { + calcs: [], + displayMode: 'list', + placement: 'bottom', + showLegend: true, + }, + tooltip: { + mode: 'single', + sort: 'none', + }, + }, + targets: [ + { + datasource: { + type: 'grafana-testdata-datasource', + uid: 'gdev-testdata', + }, + refId: 'A', + scenarioId: 'random_walk', + seriesCount: 1, + }, + ], + title: 'Panel with just queries', + type: 'timeseries', +}; + export const panelWithTransformations = { datasource: { type: 'grafana-testdata-datasource', @@ -636,6 +732,7 @@ export const testDashboard = { panelWithQueriesAndMixedDatasource, row, rowChild, + repeatedPanel, ], refresh: '', schemaVersion: 39,