From 6db2d1a411693ad7c9a64f9836e0ee966b93c16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 20 Feb 2024 08:43:02 +0100 Subject: [PATCH] DashboardScene: Simplify controls a bit (#82908) * DashboardScene: Simplify controls a bit * update tests * more test updates * Update * improvements * Fix * Fix merge * Update * update --- .../embedding/EmbeddedDashboard.tsx | 8 +- .../panel-edit/PanelEditorRenderer.tsx | 8 +- .../scene/DashboardControls.tsx | 82 +++++++++++++++---- .../scene/DashboardLinksControls.tsx | 13 +-- .../scene/DashboardScene.test.tsx | 18 +--- .../dashboard-scene/scene/DashboardScene.tsx | 2 +- .../scene/DashboardSceneRenderer.tsx | 32 +------- .../transformSaveModelToScene.test.ts | 26 ++---- .../transformSaveModelToScene.ts | 24 ++---- .../transformSceneToSaveModel.ts | 20 +---- .../settings/DashboardLinksEditView.test.tsx | 23 +----- .../settings/GeneralSettingsEditView.test.tsx | 33 +------- .../settings/GeneralSettingsEditView.tsx | 9 +- ...DashboardModelCompatibilityWrapper.test.ts | 25 ++---- .../DashboardModelCompatibilityWrapper.ts | 5 +- .../utils/dashboardSceneGraph.test.ts | 77 +---------------- .../utils/dashboardSceneGraph.ts | 41 +--------- 17 files changed, 115 insertions(+), 331 deletions(-) diff --git a/public/app/features/dashboard-scene/embedding/EmbeddedDashboard.tsx b/public/app/features/dashboard-scene/embedding/EmbeddedDashboard.tsx index a13376d3116..a0e9854173e 100644 --- a/public/app/features/dashboard-scene/embedding/EmbeddedDashboard.tsx +++ b/public/app/features/dashboard-scene/embedding/EmbeddedDashboard.tsx @@ -65,13 +65,7 @@ function EmbeddedDashboardRenderer({ model, initialState, onStateChange }: Rende return (
- {controls && ( -
- {controls.map((control) => ( - - ))} -
- )} + {controls && }
diff --git a/public/app/features/dashboard-scene/panel-edit/PanelEditorRenderer.tsx b/public/app/features/dashboard-scene/panel-edit/PanelEditorRenderer.tsx index 6b0bce117fc..a464b0a538b 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelEditorRenderer.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelEditorRenderer.tsx @@ -37,13 +37,7 @@ export function PanelEditorRenderer({ model }: SceneComponentProps) >
- {controls && ( -
- {controls.map((control) => ( - - ))} -
- )} + {controls && } { static Component = DashboardControlsRenderer; + + public constructor(state: Partial) { + super({ + variableControls: [], + timePicker: state.timePicker ?? new SceneTimePicker({}), + refreshPicker: state.refreshPicker ?? new SceneRefreshPicker({}), + ...state, + }); + } } function DashboardControlsRenderer({ model }: SceneComponentProps) { - const { variableControls, linkControls, timeControls, hideTimeControls } = model.useState(); + const { variableControls, refreshPicker, timePicker, hideTimeControls } = model.useState(); + const dashboard = getDashboardSceneFor(model); + const { links, meta, editPanel } = dashboard.useState(); + const styles = useStyles2(getStyles); + const showDebugger = location.search.includes('scene-debugger'); return ( - +
{variableControls.map((c) => ( ))} - - - - {!hideTimeControls && timeControls.map((c) => )} + {!editPanel && } - + {!hideTimeControls && ( + + + + + )} + {showDebugger && } +
); } + +function getStyles(theme: GrafanaTheme2) { + return { + controls: css({ + display: 'flex', + alignItems: 'flex-start', + gap: theme.spacing(1), + position: 'sticky', + top: 0, + background: theme.colors.background.canvas, + zIndex: theme.zIndex.activePanel, + padding: theme.spacing(2, 0), + width: '100%', + marginLeft: 'auto', + [theme.breakpoints.down('sm')]: { + flexDirection: 'column-reverse', + alignItems: 'stretch', + }, + }), + embedded: css({ + background: 'unset', + position: 'unset', + }), + }; +} diff --git a/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx b/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx index d557b4efccd..a535b3517fe 100644 --- a/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { sanitizeUrl } from '@grafana/data/src/text/sanitize'; import { selectors } from '@grafana/e2e-selectors'; -import { SceneComponentProps, SceneObjectBase, SceneObjectState } from '@grafana/scenes'; import { DashboardLink } from '@grafana/schema'; import { Tooltip } from '@grafana/ui'; import { @@ -12,17 +11,13 @@ import { import { getLinkSrv } from 'app/features/panel/panellinks/link_srv'; import { LINK_ICON_MAP } from '../settings/links/utils'; -import { getDashboardSceneFor } from '../utils/utils'; -interface DashboardLinksControlsState extends SceneObjectState {} - -export class DashboardLinksControls extends SceneObjectBase { - static Component = DashboardLinksControlsRenderer; +export interface Props { + links: DashboardLink[]; + uid?: string; } -function DashboardLinksControlsRenderer({ model }: SceneComponentProps) { - const { links, uid } = getDashboardSceneFor(model).useState(); - +export function DashboardLinksControls({ links, uid }: Props) { if (!links || !uid) { return null; } diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx index 320fa0d7c41..ed36aba0442 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.test.tsx @@ -3,7 +3,6 @@ import { sceneGraph, SceneGridItem, SceneGridLayout, - SceneRefreshPicker, SceneTimeRange, SceneQueryRunner, SceneVariableSet, @@ -22,7 +21,6 @@ import { dashboardSceneGraph } from '../utils/dashboardSceneGraph'; import { djb2Hash } from '../utils/djb2Hash'; import { DashboardControls } from './DashboardControls'; -import { DashboardLinksControls } from './DashboardLinksControls'; import { DashboardScene, DashboardSceneState } from './DashboardScene'; jest.mock('../settings/version-history/HistorySrv'); @@ -94,14 +92,14 @@ describe('DashboardScene', () => { }); it('A change to time picker visibility settings should set isDirty true', () => { - const dashboardControls = dashboardSceneGraph.getDashboardControls(scene)!; + const dashboardControls = scene.state.controls!; const prevState = dashboardControls.state.hideTimeControls; dashboardControls.setState({ hideTimeControls: true }); expect(scene.state.isDirty).toBe(true); scene.exitEditMode({ skipConfirm: true }); - expect(dashboardSceneGraph.getDashboardControls(scene)!.state.hideTimeControls).toEqual(prevState); + expect(scene.state.controls!.state.hideTimeControls).toEqual(prevState); }); it('A change to time zone should set isDirty true', () => { @@ -217,17 +215,7 @@ function buildTestScene(overrides?: Partial) { $timeRange: new SceneTimeRange({ timeZone: 'browser', }), - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [ - new SceneRefreshPicker({ - intervals: ['1s'], - }), - ], - }), - ], + controls: new DashboardControls({}), body: new SceneGridLayout({ children: [ new SceneGridItem({ diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx index 701cdbfc709..e78c453fa88 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx @@ -75,7 +75,7 @@ export interface DashboardSceneState extends SceneObjectState { /** NavToolbar actions */ actions?: SceneObject[]; /** Fixed row at the top of the canvas with for example variables and time range controls */ - controls?: SceneObject[]; + controls?: DashboardControls; /** True when editing */ isEditing?: boolean; /** True when user made a change */ diff --git a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx index 84950c6c999..cd58d311fdd 100644 --- a/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardSceneRenderer.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import { GrafanaTheme2, PageLayoutType } from '@grafana/data'; -import { SceneComponentProps, SceneDebugger } from '@grafana/scenes'; +import { SceneComponentProps } from '@grafana/scenes'; import { CustomScrollbar, useStyles2 } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { getNavModel } from 'app/core/selectors/navModel'; @@ -21,7 +21,6 @@ export function DashboardSceneRenderer({ model }: SceneComponentProps -
{showDebugger && }
- - - ); + const emptyState = ; const withPanels = ( <> - {controls && ( -
- {controls.map((control) => ( - - ))} - {showDebugger && } -
- )} + {controls && }
@@ -88,18 +75,5 @@ function getStyles(theme: GrafanaTheme2) { gap: '8px', marginBottom: theme.spacing(2), }), - - controls: css({ - display: 'flex', - flexWrap: 'wrap', - alignItems: 'center', - gap: theme.spacing(1), - position: 'sticky', - top: 0, - background: theme.colors.background.canvas, - zIndex: theme.zIndex.activePanel, - padding: theme.spacing(2, 0), - marginLeft: 'auto', - }), }; } diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts index 490732bf0ee..2567575f3bf 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts @@ -26,8 +26,6 @@ import { SceneGridLayout, SceneGridRow, SceneQueryRunner, - SceneRefreshPicker, - SceneTimePicker, VizPanel, } from '@grafana/scenes'; import { @@ -44,7 +42,6 @@ import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard'; import { DASHBOARD_DATASOURCE_PLUGIN_ID } from 'app/plugins/datasource/dashboard/types'; import { DashboardDataDTO } from 'app/types'; -import { DashboardControls } from '../scene/DashboardControls'; import { PanelRepeaterGridItem } from '../scene/PanelRepeaterGridItem'; import { PanelTimeRange } from '../scene/PanelTimeRange'; import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior'; @@ -112,7 +109,7 @@ describe('transformSaveModelToScene', () => { const oldModel = new DashboardModel(dash); const scene = createDashboardSceneFromDashboardModel(oldModel); - const dashboardControls = scene.state.controls![0] as DashboardControls; + const dashboardControls = scene.state.controls!; expect(scene.state.title).toBe('test'); expect(scene.state.uid).toBe('test-uid'); @@ -127,13 +124,8 @@ describe('transformSaveModelToScene', () => { expect(scene.state?.$variables?.getByName('constant')).toBeInstanceOf(ConstantVariable); expect(scene.state?.$variables?.getByName('CoolFilters')).toBeInstanceOf(AdHocFiltersVariable); expect(dashboardControls).toBeDefined(); - expect(dashboardControls).toBeInstanceOf(DashboardControls); - expect(dashboardControls.state.timeControls).toHaveLength(2); - expect(dashboardControls.state.timeControls[0]).toBeInstanceOf(SceneTimePicker); - expect(dashboardControls.state.timeControls[1]).toBeInstanceOf(SceneRefreshPicker); - expect((dashboardControls.state.timeControls[1] as SceneRefreshPicker).state.intervals).toEqual( - defaultTimePickerConfig.refresh_intervals - ); + + expect(dashboardControls.state.refreshPicker.state.intervals).toEqual(defaultTimePickerConfig.refresh_intervals); expect(dashboardControls.state.hideTimeControls).toBe(true); }); @@ -1039,9 +1031,7 @@ describe('transformSaveModelToScene', () => { const scene = transformSaveModelToScene({ dashboard: dashboard_to_load1 as any, meta: {} }); expect(scene.state.$data).toBeInstanceOf(SceneDataLayers); - expect((scene.state.controls![0] as DashboardControls)!.state.variableControls[1]).toBeInstanceOf( - SceneDataLayerControls - ); + expect(scene.state.controls!.state.variableControls[1]).toBeInstanceOf(SceneDataLayerControls); const dataLayers = scene.state.$data as SceneDataLayers; expect(dataLayers.state.layers).toHaveLength(4); @@ -1069,9 +1059,7 @@ describe('transformSaveModelToScene', () => { const scene = transformSaveModelToScene({ dashboard: dashboard_to_load1 as any, meta: {} }); expect(scene.state.$data).toBeInstanceOf(SceneDataLayers); - expect((scene.state.controls![0] as DashboardControls)!.state.variableControls[1]).toBeInstanceOf( - SceneDataLayerControls - ); + expect(scene.state.controls!.state.variableControls[1]).toBeInstanceOf(SceneDataLayerControls); const dataLayers = scene.state.$data as SceneDataLayers; expect(dataLayers.state.layers).toHaveLength(5); @@ -1085,9 +1073,7 @@ describe('transformSaveModelToScene', () => { const scene = transformSaveModelToScene({ dashboard: dashboard_to_load1 as any, meta: {} }); expect(scene.state.$data).toBeInstanceOf(SceneDataLayers); - expect((scene.state.controls![0] as DashboardControls)!.state.variableControls[1]).toBeInstanceOf( - SceneDataLayerControls - ); + expect(scene.state.controls!.state.variableControls[1]).toBeInstanceOf(SceneDataLayerControls); const dataLayers = scene.state.$data as SceneDataLayers; expect(dataLayers.state.layers).toHaveLength(5); diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index b85744efcfe..9b7e0c988c5 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -36,7 +36,6 @@ import { DashboardDTO } from 'app/types'; import { AlertStatesDataLayer } from '../scene/AlertStatesDataLayer'; import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer'; import { DashboardControls } from '../scene/DashboardControls'; -import { DashboardLinksControls } from '../scene/DashboardLinksControls'; import { registerDashboardMacro } from '../scene/DashboardMacro'; import { DashboardScene } from '../scene/DashboardScene'; import { LibraryVizPanel } from '../scene/LibraryVizPanel'; @@ -268,21 +267,16 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel) layers, }) : undefined, - controls: [ - new DashboardControls({ - variableControls: [new VariableValueSelectors({}), new SceneDataLayerControls()], - timeControls: [ - new SceneTimePicker({}), - new SceneRefreshPicker({ - refresh: oldModel.refresh, - intervals: oldModel.timepicker.refresh_intervals, - withText: true, - }), - ], - linkControls: new DashboardLinksControls({}), - hideTimeControls: oldModel.timepicker.hidden, + controls: new DashboardControls({ + variableControls: [new VariableValueSelectors({}), new SceneDataLayerControls()], + timePicker: new SceneTimePicker({}), + refreshPicker: new SceneRefreshPicker({ + refresh: oldModel.refresh, + intervals: oldModel.timepicker.refresh_intervals, + withText: true, }), - ], + hideTimeControls: oldModel.timepicker.hidden, + }), }); return dashboardScene; diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts index b47bd847fd4..d452f99539e 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts @@ -12,7 +12,6 @@ import { SceneDataTransformer, SceneVariableSet, LocalValueVariable, - SceneRefreshPicker, } from '@grafana/scenes'; import { AnnotationQuery, @@ -34,7 +33,6 @@ import { getPanelDataFrames } from 'app/features/dashboard/components/HelpWizard import { DASHBOARD_SCHEMA_VERSION } from 'app/features/dashboard/state/DashboardMigrator'; import { GrafanaQueryType } from 'app/plugins/datasource/grafana/types'; -import { DashboardControls } from '../scene/DashboardControls'; import { DashboardScene } from '../scene/DashboardScene'; import { LibraryVizPanel } from '../scene/LibraryVizPanel'; import { PanelRepeaterGridItem } from '../scene/PanelRepeaterGridItem'; @@ -54,9 +52,6 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa const variablesSet = state.$variables; const body = state.body; - let refreshIntervals: string[] | undefined; - let hideTimePicker: boolean | undefined; - let panels: Panel[] = []; let graphTooltip = defaultDashboard.graphTooltip; let variables: VariableModel[] = []; @@ -92,16 +87,7 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa variables = sceneVariablesSetToVariables(variablesSet); } - if (state.controls && state.controls[0] instanceof DashboardControls) { - hideTimePicker = state.controls[0].state.hideTimeControls; - - const timeControls = state.controls[0].state.timeControls; - for (const control of timeControls) { - if (control instanceof SceneRefreshPicker && control.state.intervals) { - refreshIntervals = control.state.intervals; - } - } - } + const controlsState = state.controls?.state; if (state.$behaviors) { for (const behavior of state.$behaviors!) { @@ -113,8 +99,8 @@ export function transformSceneToSaveModel(scene: DashboardScene, isSnapshot = fa const timePickerWithoutDefaults = removeDefaults( { - refresh_intervals: refreshIntervals, - hidden: hideTimePicker, + refresh_intervals: controlsState?.refreshPicker.state.intervals, + hidden: controlsState?.hideTimeControls, nowDelay: timeRange.UNSAFE_nowDelay, }, defaultTimePickerConfig diff --git a/public/app/features/dashboard-scene/settings/DashboardLinksEditView.test.tsx b/public/app/features/dashboard-scene/settings/DashboardLinksEditView.test.tsx index 0143dfd43eb..e9e04c6a702 100644 --- a/public/app/features/dashboard-scene/settings/DashboardLinksEditView.test.tsx +++ b/public/app/features/dashboard-scene/settings/DashboardLinksEditView.test.tsx @@ -2,18 +2,10 @@ import { render as RTLRender } from '@testing-library/react'; import React from 'react'; import { TestProvider } from 'test/helpers/TestProvider'; -import { - behaviors, - SceneGridLayout, - SceneGridItem, - SceneRefreshPicker, - SceneTimeRange, - SceneTimePicker, -} from '@grafana/scenes'; +import { behaviors, SceneGridLayout, SceneGridItem, SceneTimeRange } from '@grafana/scenes'; import { DashboardCursorSync } from '@grafana/schema'; import { DashboardControls } from '../scene/DashboardControls'; -import { DashboardLinksControls } from '../scene/DashboardLinksControls'; import { DashboardScene } from '../scene/DashboardScene'; import { activateFullSceneTree } from '../utils/test-utils'; @@ -225,18 +217,7 @@ async function buildTestScene() { const dashboard = new DashboardScene({ $timeRange: new SceneTimeRange({}), $behaviors: [new behaviors.CursorSync({ sync: DashboardCursorSync.Off })], - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [ - new SceneTimePicker({}), - new SceneRefreshPicker({ - intervals: ['1s'], - }), - ], - }), - ], + controls: new DashboardControls({}), title: 'hello', uid: 'dash-1', meta: { diff --git a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.test.tsx b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.test.tsx index 245f9334fdd..4becbbb2c77 100644 --- a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.test.tsx +++ b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.test.tsx @@ -1,15 +1,7 @@ -import { - behaviors, - SceneGridLayout, - SceneGridItem, - SceneRefreshPicker, - SceneTimeRange, - SceneTimePicker, -} from '@grafana/scenes'; +import { behaviors, SceneGridLayout, SceneGridItem, SceneTimeRange } from '@grafana/scenes'; import { DashboardCursorSync } from '@grafana/schema'; import { DashboardControls } from '../scene/DashboardControls'; -import { DashboardLinksControls } from '../scene/DashboardLinksControls'; import { DashboardScene } from '../scene/DashboardScene'; import { activateFullSceneTree } from '../utils/test-utils'; @@ -38,19 +30,9 @@ describe('GeneralSettingsEditView', () => { expect(settings.getTimeRange()).toBe(dashboard.state.$timeRange); }); - it('should return the dashboard refresh picker', () => { - expect(settings.getRefreshPicker()).toBe( - (dashboard.state?.controls?.[0] as DashboardControls)?.state?.timeControls?.[1] - ); - }); - it('should return the cursor sync', () => { expect(settings.getCursorSync()).toBe(dashboard.state.$behaviors?.[0]); }); - - it('should return the dashboard controls', () => { - expect(settings.getDashboardControls()).toBe(dashboard.state.controls?.[0]); - }); }); describe('Dashboard updates', () => { @@ -133,18 +115,7 @@ async function buildTestScene() { const dashboard = new DashboardScene({ $timeRange: new SceneTimeRange({}), $behaviors: [new behaviors.CursorSync({ sync: DashboardCursorSync.Off })], - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [ - new SceneTimePicker({}), - new SceneRefreshPicker({ - intervals: ['1s'], - }), - ], - }), - ], + controls: new DashboardControls({}), title: 'hello', uid: 'dash-1', meta: { diff --git a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx index fc84309fdc9..3c1315b0a79 100644 --- a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx +++ b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx @@ -22,7 +22,6 @@ import { DeleteDashboardButton } from 'app/features/dashboard/components/DeleteD import { DashboardScene } from '../scene/DashboardScene'; import { NavToolbarActions } from '../scene/NavToolbarActions'; -import { dashboardSceneGraph } from '../utils/dashboardSceneGraph'; import { getDashboardSceneFor } from '../utils/utils'; import { DashboardEditView, DashboardEditViewState, useDashboardEditPageNav } from './utils'; @@ -61,7 +60,7 @@ export class GeneralSettingsEditView } public getRefreshPicker() { - return dashboardSceneGraph.getRefreshPicker(this._dashboard); + return this.getDashboardControls().state.refreshPicker; } public getCursorSync() { @@ -75,7 +74,7 @@ export class GeneralSettingsEditView } public getDashboardControls() { - return dashboardSceneGraph.getDashboardControls(this._dashboard); + return this._dashboard.state.controls!; } public onTitleChange = (value: string) => { @@ -151,8 +150,8 @@ export class GeneralSettingsEditView const { title, description, tags, meta, editable } = model.getDashboard().useState(); const { sync: graphTooltip } = model.getCursorSync()?.useState() || {}; const { timeZone, weekStart, UNSAFE_nowDelay: nowDelay } = model.getTimeRange().useState(); - const { intervals } = model.getRefreshPicker()?.useState() || {}; - const { hideTimeControls } = model.getDashboardControls()?.useState() || {}; + const { intervals } = model.getRefreshPicker().useState(); + const { hideTimeControls } = model.getDashboardControls().useState(); return ( diff --git a/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.test.ts b/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.test.ts index 93c7a45b45f..be5d199260a 100644 --- a/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.test.ts +++ b/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.test.ts @@ -3,11 +3,9 @@ import { behaviors, SceneGridItem, SceneGridLayout, - SceneRefreshPicker, SceneQueryRunner, SceneTimeRange, VizPanel, - SceneTimePicker, SceneDataTransformer, SceneDataLayers, } from '@grafana/scenes'; @@ -17,7 +15,6 @@ import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard'; import { AlertStatesDataLayer } from '../scene/AlertStatesDataLayer'; import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer'; import { DashboardControls } from '../scene/DashboardControls'; -import { DashboardLinksControls } from '../scene/DashboardLinksControls'; import { DashboardScene } from '../scene/DashboardScene'; import { NEW_LINK } from '../settings/links/utils'; @@ -37,7 +34,7 @@ describe('DashboardModelCompatibilityWrapper', () => { expect(wrapper.time.from).toBe('now-6h'); expect(wrapper.timezone).toBe('America/New_York'); expect(wrapper.weekStart).toBe('friday'); - expect(wrapper.timepicker.refresh_intervals).toEqual(['1s']); + expect(wrapper.timepicker.refresh_intervals![0]).toEqual('5s'); expect(wrapper.timepicker.hidden).toEqual(true); expect(wrapper.panels).toHaveLength(5); @@ -60,9 +57,7 @@ describe('DashboardModelCompatibilityWrapper', () => { expect(wrapper.panels[3].datasource).toEqual({ uid: 'gdev-testdata', type: 'grafana-testdata-datasource' }); expect(wrapper.panels[4].datasource).toEqual({ uid: SHARED_DASHBOARD_QUERY, type: 'datasource' }); - (scene.state.controls![0] as DashboardControls).setState({ - hideTimeControls: false, - }); + scene.state.controls!.setState({ hideTimeControls: false }); const wrapper2 = new DashboardModelCompatibilityWrapper(scene); expect(wrapper2.timepicker.hidden).toEqual(false); @@ -175,19 +170,9 @@ function setup() { }), ], }), - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [ - new SceneTimePicker({}), - new SceneRefreshPicker({ - intervals: ['1s'], - }), - ], - hideTimeControls: true, - }), - ], + controls: new DashboardControls({ + hideTimeControls: true, + }), body: new SceneGridLayout({ children: [ new SceneGridItem({ diff --git a/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.ts b/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.ts index 4e4b6c12ed2..21b83ce910b 100644 --- a/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.ts +++ b/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.ts @@ -17,7 +17,6 @@ import { DashboardScene } from '../scene/DashboardScene'; import { dataLayersToAnnotations } from '../serialization/dataLayersToAnnotations'; import { PanelModelCompatibilityWrapper } from './PanelModelCompatibilityWrapper'; -import { dashboardSceneGraph } from './dashboardSceneGraph'; import { findVizPanelByKey, getVizPanelKeyForPanelId } from './utils'; /** @@ -68,8 +67,8 @@ export class DashboardModelCompatibilityWrapper { public get timepicker() { return { - refresh_intervals: dashboardSceneGraph.getRefreshPicker(this._scene)?.state.intervals, - hidden: dashboardSceneGraph.getDashboardControls(this._scene)?.state.hideTimeControls ?? false, + refresh_intervals: this._scene.state.controls!.state.refreshPicker.state.intervals, + hidden: this._scene.state.controls!.state.hideTimeControls ?? false, }; } diff --git a/public/app/features/dashboard-scene/utils/dashboardSceneGraph.test.ts b/public/app/features/dashboard-scene/utils/dashboardSceneGraph.test.ts index 927e9bf6313..5e106d15d90 100644 --- a/public/app/features/dashboard-scene/utils/dashboardSceneGraph.test.ts +++ b/public/app/features/dashboard-scene/utils/dashboardSceneGraph.test.ts @@ -4,8 +4,6 @@ import { SceneGridLayout, SceneGridRow, SceneQueryRunner, - SceneRefreshPicker, - SceneTimePicker, SceneTimeRange, VizPanel, } from '@grafana/scenes'; @@ -13,7 +11,6 @@ import { import { AlertStatesDataLayer } from '../scene/AlertStatesDataLayer'; import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer'; import { DashboardControls } from '../scene/DashboardControls'; -import { DashboardLinksControls } from '../scene/DashboardLinksControls'; import { DashboardScene, DashboardSceneState } from '../scene/DashboardScene'; import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks'; @@ -21,67 +18,6 @@ import { dashboardSceneGraph } from './dashboardSceneGraph'; import { findVizPanelByKey } from './utils'; describe('dashboardSceneGraph', () => { - describe('getTimePicker', () => { - it('should return null if no time picker', () => { - const scene = buildTestScene({ - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [], - }), - ], - }); - - const timePicker = dashboardSceneGraph.getTimePicker(scene); - expect(timePicker).toBeNull(); - }); - - it('should return time picker', () => { - const scene = buildTestScene(); - const timePicker = dashboardSceneGraph.getTimePicker(scene); - expect(timePicker).not.toBeNull(); - }); - }); - - describe('getRefreshPicker', () => { - it('should return null if no refresh picker', () => { - const scene = buildTestScene({ - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [], - }), - ], - }); - - const refreshPicker = dashboardSceneGraph.getRefreshPicker(scene); - expect(refreshPicker).toBeNull(); - }); - - it('should return refresh picker', () => { - const scene = buildTestScene(); - const refreshPicker = dashboardSceneGraph.getRefreshPicker(scene); - expect(refreshPicker).not.toBeNull(); - }); - }); - - describe('getDashboardControls', () => { - it('should return null if no dashboard controls', () => { - const scene = buildTestScene({ controls: [] }); - - const dashboardControls = dashboardSceneGraph.getDashboardControls(scene); - expect(dashboardControls).toBeNull(); - }); - - it('should return dashboard controls', () => { - const scene = buildTestScene(); - const dashboardControls = dashboardSceneGraph.getDashboardControls(scene); - expect(dashboardControls).not.toBeNull(); - }); - }); - describe('getPanelLinks', () => { it('should throw if no links object defined', () => { const scene = buildTestScene(); @@ -155,18 +91,7 @@ function buildTestScene(overrides?: Partial) { title: 'hello', uid: 'dash-1', $timeRange: new SceneTimeRange({}), - controls: [ - new DashboardControls({ - variableControls: [], - linkControls: new DashboardLinksControls({}), - timeControls: [ - new SceneTimePicker({}), - new SceneRefreshPicker({ - intervals: ['1s'], - }), - ], - }), - ], + controls: new DashboardControls({}), $data: new SceneDataLayers({ layers: [ new DashboardAnnotationsDataLayer({ diff --git a/public/app/features/dashboard-scene/utils/dashboardSceneGraph.ts b/public/app/features/dashboard-scene/utils/dashboardSceneGraph.ts index cfea3809e6a..3047692da5b 100644 --- a/public/app/features/dashboard-scene/utils/dashboardSceneGraph.ts +++ b/public/app/features/dashboard-scene/utils/dashboardSceneGraph.ts @@ -1,48 +1,14 @@ -import { - SceneTimePicker, - SceneRefreshPicker, - VizPanel, - SceneGridItem, - SceneGridRow, - SceneDataLayers, - sceneGraph, -} from '@grafana/scenes'; +import { VizPanel, SceneGridItem, SceneGridRow, SceneDataLayers, sceneGraph } from '@grafana/scenes'; -import { DashboardControls } from '../scene/DashboardControls'; import { DashboardScene } from '../scene/DashboardScene'; import { VizPanelLinks } from '../scene/PanelLinks'; function getTimePicker(scene: DashboardScene) { - const dashboardControls = getDashboardControls(scene); - - if (dashboardControls) { - const timePicker = dashboardControls.state.timeControls.find((c) => c instanceof SceneTimePicker); - if (timePicker && timePicker instanceof SceneTimePicker) { - return timePicker; - } - } - - return null; + return scene.state.controls?.state.timePicker; } function getRefreshPicker(scene: DashboardScene) { - const dashboardControls = getDashboardControls(scene); - - if (dashboardControls) { - for (const control of dashboardControls.state.timeControls) { - if (control instanceof SceneRefreshPicker) { - return control; - } - } - } - return null; -} - -function getDashboardControls(scene: DashboardScene) { - if (scene.state.controls?.[0] instanceof DashboardControls) { - return scene.state.controls[0]; - } - return null; + return scene.state.controls?.state.refreshPicker; } function getPanelLinks(panel: VizPanel) { @@ -92,7 +58,6 @@ function getDataLayers(scene: DashboardScene): SceneDataLayers { export const dashboardSceneGraph = { getTimePicker, getRefreshPicker, - getDashboardControls, getPanelLinks, getVizPanels, getDataLayers,