diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx index 324a7f9e232..a8bde9e9c93 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx @@ -42,11 +42,19 @@ export class PanelDataQueriesTab extends SceneObjectBase { return QueriesTab({ ...props, model: this }); }; this._panelManager = panelManager; + this.addActivationHandler(this.onActivate.bind(this)); + } + + private onActivate() { + // This is to preserve SceneQueryRunner stays alive when switching between visualizations and table view + const deactivate = this._panelManager.queryRunner.activate(); + return () => deactivate(); } buildQueryOptions(): QueryGroupOptions { @@ -179,7 +187,7 @@ export class PanelDataQueriesTab extends SceneObjectBase) { const { datasource, dsSettings } = model.panelManager.useState(); - const { data } = model.panelManager.queryRunner.useState(); + const { data, queries } = model.panelManager.queryRunner.useState(); if (!datasource || !dsSettings || !data) { return null; @@ -201,7 +209,7 @@ function PanelDataQueriesTabRendered({ model }: SceneComponentProps { } panelRepeater.setState({ - body: panelManager.getPanelCloneWithData(), + body: panelManager.state.panel.clone(), repeatDirection: panelManager.state.repeatDirection, variableName: panelManager.state.repeat, maxPerRow: panelManager.state.maxPerRow, diff --git a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx index a58b3860262..ed43cefb919 100644 --- a/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx +++ b/public/app/features/dashboard-scene/panel-edit/VizPanelManager.tsx @@ -22,7 +22,6 @@ import { SceneObjectState, SceneQueryRunner, VizPanel, - sceneGraph, sceneUtils, } from '@grafana/scenes'; import { DataQuery, DataTransformerConfig, Panel } from '@grafana/schema'; @@ -88,8 +87,7 @@ export class VizPanelManager extends SceneObjectBase { repeatOptions = { repeat, repeatDirection, maxPerRow }; return new VizPanelManager({ - panel: sourcePanel.clone({ $data: undefined }), - $data: sourcePanel.state.$data?.clone(), + panel: sourcePanel.clone(), sourcePanel: sourcePanel.getRef(), ...repeatOptions, }); @@ -100,7 +98,7 @@ export class VizPanelManager extends SceneObjectBase { } private async loadDataSource() { - const dataObj = this.state.$data; + const dataObj = this.state.panel.state.$data; if (!dataObj) { return; @@ -207,14 +205,14 @@ export class VizPanelManager extends SceneObjectBase { }); // When changing from non-data to data panel, we need to add a new data provider - if (!this.state.$data && !config.panels[pluginId].skipDataQuery) { + if (!this.state.panel.state.$data && !config.panels[pluginId].skipDataQuery) { let ds = getLastUsedDatasourceFromStorage(getDashboardSceneFor(this).state.uid!)?.datasourceUid; if (!ds) { ds = config.defaultDatasource; } - this.setState({ + newPanel.setState({ $data: new SceneDataTransformer({ $data: new SceneQueryRunner({ datasource: { @@ -281,7 +279,7 @@ export class VizPanelManager extends SceneObjectBase { public changeQueryOptions(options: QueryGroupOptions) { const panelObj = this.state.panel; const dataObj = this.queryRunner; - let timeRangeObj = sceneGraph.getTimeRange(panelObj); + const timeRangeObj = panelObj.state.$timeRange; const dataObjStateUpdate: Partial = {}; const timeRangeObjStateUpdate: Partial = {}; @@ -348,7 +346,7 @@ export class VizPanelManager extends SceneObjectBase { get queryRunner(): SceneQueryRunner { // Panel data object is always SceneQueryRunner wrapped in a SceneDataTransformer - const runner = getQueryRunnerFor(this); + const runner = getQueryRunnerFor(this.state.panel); if (!runner) { throw new Error('Query runner not found'); @@ -358,7 +356,7 @@ export class VizPanelManager extends SceneObjectBase { } get dataTransformer(): SceneDataTransformer { - const provider = this.state.$data; + const provider = this.state.panel.state.$data; if (!provider || !(provider instanceof SceneDataTransformer)) { throw new Error('Could not find SceneDataTransformer for panel'); } @@ -376,6 +374,9 @@ export class VizPanelManager extends SceneObjectBase { .setTitle('') .setOption('showTypeIcons', true) .setOption('showHeader', true) + // Here we are breaking a scene rule and changing the parent of the main panel data provider + // But we need to share this same instance as the queries tab is subscribing to it + .setData(this.dataTransformer) .build(), }); } @@ -415,23 +416,21 @@ export class VizPanelManager extends SceneObjectBase { if (sourcePanel.parent instanceof DashboardGridItem) { sourcePanel.parent.setState({ ...repeatUpdate, - body: this.state.panel.clone({ - $data: this.state.$data?.clone(), - }), + body: this.state.panel.clone(), }); } if (sourcePanel.parent instanceof LibraryVizPanel) { if (sourcePanel.parent.parent instanceof DashboardGridItem) { const newLibPanel = sourcePanel.parent.clone({ - panel: this.state.panel.clone({ - $data: this.state.$data?.clone(), - }), + panel: this.state.panel.clone(), }); + sourcePanel.parent.parent.setState({ body: newLibPanel, ...repeatUpdate, }); + updateLibraryVizPanel(newLibPanel!).then((p) => { if (sourcePanel.parent instanceof LibraryVizPanel) { newLibPanel.setPanelFromLibPanel(p); @@ -455,18 +454,12 @@ export class VizPanelManager extends SceneObjectBase { } const parentClone = gridItem.clone({ - body: this.state.panel.clone({ - $data: this.state.$data?.clone(), - }), + body: this.state.panel.clone(), }); return gridItemToPanel(parentClone); } - public getPanelCloneWithData(): VizPanel { - return this.state.panel.clone({ $data: this.state.$data?.clone() }); - } - public setPanelTitle(newTitle: string) { this.state.panel.setState({ title: newTitle, hoverHeader: newTitle === '' }); } diff --git a/public/app/features/dashboard-scene/scene/PanelTimeRange.tsx b/public/app/features/dashboard-scene/scene/PanelTimeRange.tsx index 8a217c49fdb..cd4d0637c65 100644 --- a/public/app/features/dashboard-scene/scene/PanelTimeRange.tsx +++ b/public/app/features/dashboard-scene/scene/PanelTimeRange.tsx @@ -39,8 +39,8 @@ export class PanelTimeRange extends SceneTimeRangeTransformerBase { // Listen to own changes and update time info when required if (n.timeFrom !== p.timeFrom || n.timeShift !== p.timeShift) { - const { timeInfo } = this.getTimeOverride(this.getAncestorTimeRange().state.value); - this.setState({ timeInfo }); + const { timeInfo, timeRange } = this.getTimeOverride(this.getAncestorTimeRange().state.value); + this.setState({ timeInfo, value: timeRange }); } }) );