mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardScene: Fixes issues with relative time range in panel edit (#86862)
* DashboardScene: Fixes deleting dirty dashboard * Update * Progress * Update * Update * Update * Update * Update * Update * update * Update
This commit is contained in:
parent
01f8301504
commit
a4bb4c8400
@ -42,11 +42,19 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
|
|||||||
|
|
||||||
constructor(panelManager: VizPanelManager) {
|
constructor(panelManager: VizPanelManager) {
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.TabComponent = (props: PanelDataTabHeaderProps) => {
|
this.TabComponent = (props: PanelDataTabHeaderProps) => {
|
||||||
return QueriesTab({ ...props, model: this });
|
return QueriesTab({ ...props, model: this });
|
||||||
};
|
};
|
||||||
|
|
||||||
this._panelManager = panelManager;
|
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 {
|
buildQueryOptions(): QueryGroupOptions {
|
||||||
@ -179,7 +187,7 @@ export class PanelDataQueriesTab extends SceneObjectBase<PanelDataQueriesTabStat
|
|||||||
|
|
||||||
function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQueriesTab>) {
|
function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQueriesTab>) {
|
||||||
const { datasource, dsSettings } = model.panelManager.useState();
|
const { datasource, dsSettings } = model.panelManager.useState();
|
||||||
const { data } = model.panelManager.queryRunner.useState();
|
const { data, queries } = model.panelManager.queryRunner.useState();
|
||||||
|
|
||||||
if (!datasource || !dsSettings || !data) {
|
if (!datasource || !dsSettings || !data) {
|
||||||
return null;
|
return null;
|
||||||
@ -201,7 +209,7 @@ function PanelDataQueriesTabRendered({ model }: SceneComponentProps<PanelDataQue
|
|||||||
|
|
||||||
<QueryEditorRows
|
<QueryEditorRows
|
||||||
data={data}
|
data={data}
|
||||||
queries={model.getQueries()}
|
queries={queries}
|
||||||
dsSettings={dsSettings}
|
dsSettings={dsSettings}
|
||||||
onAddQuery={model.onAddQuery}
|
onAddQuery={model.onAddQuery}
|
||||||
onQueriesChange={model.onQueriesChange}
|
onQueriesChange={model.onQueriesChange}
|
||||||
|
@ -136,7 +136,7 @@ export class PanelEditor extends SceneObjectBase<PanelEditorState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
panelRepeater.setState({
|
panelRepeater.setState({
|
||||||
body: panelManager.getPanelCloneWithData(),
|
body: panelManager.state.panel.clone(),
|
||||||
repeatDirection: panelManager.state.repeatDirection,
|
repeatDirection: panelManager.state.repeatDirection,
|
||||||
variableName: panelManager.state.repeat,
|
variableName: panelManager.state.repeat,
|
||||||
maxPerRow: panelManager.state.maxPerRow,
|
maxPerRow: panelManager.state.maxPerRow,
|
||||||
|
@ -22,7 +22,6 @@ import {
|
|||||||
SceneObjectState,
|
SceneObjectState,
|
||||||
SceneQueryRunner,
|
SceneQueryRunner,
|
||||||
VizPanel,
|
VizPanel,
|
||||||
sceneGraph,
|
|
||||||
sceneUtils,
|
sceneUtils,
|
||||||
} from '@grafana/scenes';
|
} from '@grafana/scenes';
|
||||||
import { DataQuery, DataTransformerConfig, Panel } from '@grafana/schema';
|
import { DataQuery, DataTransformerConfig, Panel } from '@grafana/schema';
|
||||||
@ -88,8 +87,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
repeatOptions = { repeat, repeatDirection, maxPerRow };
|
repeatOptions = { repeat, repeatDirection, maxPerRow };
|
||||||
|
|
||||||
return new VizPanelManager({
|
return new VizPanelManager({
|
||||||
panel: sourcePanel.clone({ $data: undefined }),
|
panel: sourcePanel.clone(),
|
||||||
$data: sourcePanel.state.$data?.clone(),
|
|
||||||
sourcePanel: sourcePanel.getRef(),
|
sourcePanel: sourcePanel.getRef(),
|
||||||
...repeatOptions,
|
...repeatOptions,
|
||||||
});
|
});
|
||||||
@ -100,7 +98,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async loadDataSource() {
|
private async loadDataSource() {
|
||||||
const dataObj = this.state.$data;
|
const dataObj = this.state.panel.state.$data;
|
||||||
|
|
||||||
if (!dataObj) {
|
if (!dataObj) {
|
||||||
return;
|
return;
|
||||||
@ -207,14 +205,14 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// When changing from non-data to data panel, we need to add a new data provider
|
// 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;
|
let ds = getLastUsedDatasourceFromStorage(getDashboardSceneFor(this).state.uid!)?.datasourceUid;
|
||||||
|
|
||||||
if (!ds) {
|
if (!ds) {
|
||||||
ds = config.defaultDatasource;
|
ds = config.defaultDatasource;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
newPanel.setState({
|
||||||
$data: new SceneDataTransformer({
|
$data: new SceneDataTransformer({
|
||||||
$data: new SceneQueryRunner({
|
$data: new SceneQueryRunner({
|
||||||
datasource: {
|
datasource: {
|
||||||
@ -281,7 +279,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
public changeQueryOptions(options: QueryGroupOptions) {
|
public changeQueryOptions(options: QueryGroupOptions) {
|
||||||
const panelObj = this.state.panel;
|
const panelObj = this.state.panel;
|
||||||
const dataObj = this.queryRunner;
|
const dataObj = this.queryRunner;
|
||||||
let timeRangeObj = sceneGraph.getTimeRange(panelObj);
|
const timeRangeObj = panelObj.state.$timeRange;
|
||||||
|
|
||||||
const dataObjStateUpdate: Partial<SceneQueryRunner['state']> = {};
|
const dataObjStateUpdate: Partial<SceneQueryRunner['state']> = {};
|
||||||
const timeRangeObjStateUpdate: Partial<PanelTimeRangeState> = {};
|
const timeRangeObjStateUpdate: Partial<PanelTimeRangeState> = {};
|
||||||
@ -348,7 +346,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
|
|
||||||
get queryRunner(): SceneQueryRunner {
|
get queryRunner(): SceneQueryRunner {
|
||||||
// Panel data object is always SceneQueryRunner wrapped in a SceneDataTransformer
|
// Panel data object is always SceneQueryRunner wrapped in a SceneDataTransformer
|
||||||
const runner = getQueryRunnerFor(this);
|
const runner = getQueryRunnerFor(this.state.panel);
|
||||||
|
|
||||||
if (!runner) {
|
if (!runner) {
|
||||||
throw new Error('Query runner not found');
|
throw new Error('Query runner not found');
|
||||||
@ -358,7 +356,7 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dataTransformer(): SceneDataTransformer {
|
get dataTransformer(): SceneDataTransformer {
|
||||||
const provider = this.state.$data;
|
const provider = this.state.panel.state.$data;
|
||||||
if (!provider || !(provider instanceof SceneDataTransformer)) {
|
if (!provider || !(provider instanceof SceneDataTransformer)) {
|
||||||
throw new Error('Could not find SceneDataTransformer for panel');
|
throw new Error('Could not find SceneDataTransformer for panel');
|
||||||
}
|
}
|
||||||
@ -376,6 +374,9 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
.setTitle('')
|
.setTitle('')
|
||||||
.setOption('showTypeIcons', true)
|
.setOption('showTypeIcons', true)
|
||||||
.setOption('showHeader', 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(),
|
.build(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -415,23 +416,21 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
if (sourcePanel.parent instanceof DashboardGridItem) {
|
if (sourcePanel.parent instanceof DashboardGridItem) {
|
||||||
sourcePanel.parent.setState({
|
sourcePanel.parent.setState({
|
||||||
...repeatUpdate,
|
...repeatUpdate,
|
||||||
body: this.state.panel.clone({
|
body: this.state.panel.clone(),
|
||||||
$data: this.state.$data?.clone(),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourcePanel.parent instanceof LibraryVizPanel) {
|
if (sourcePanel.parent instanceof LibraryVizPanel) {
|
||||||
if (sourcePanel.parent.parent instanceof DashboardGridItem) {
|
if (sourcePanel.parent.parent instanceof DashboardGridItem) {
|
||||||
const newLibPanel = sourcePanel.parent.clone({
|
const newLibPanel = sourcePanel.parent.clone({
|
||||||
panel: this.state.panel.clone({
|
panel: this.state.panel.clone(),
|
||||||
$data: this.state.$data?.clone(),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
sourcePanel.parent.parent.setState({
|
sourcePanel.parent.parent.setState({
|
||||||
body: newLibPanel,
|
body: newLibPanel,
|
||||||
...repeatUpdate,
|
...repeatUpdate,
|
||||||
});
|
});
|
||||||
|
|
||||||
updateLibraryVizPanel(newLibPanel!).then((p) => {
|
updateLibraryVizPanel(newLibPanel!).then((p) => {
|
||||||
if (sourcePanel.parent instanceof LibraryVizPanel) {
|
if (sourcePanel.parent instanceof LibraryVizPanel) {
|
||||||
newLibPanel.setPanelFromLibPanel(p);
|
newLibPanel.setPanelFromLibPanel(p);
|
||||||
@ -455,18 +454,12 @@ export class VizPanelManager extends SceneObjectBase<VizPanelManagerState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const parentClone = gridItem.clone({
|
const parentClone = gridItem.clone({
|
||||||
body: this.state.panel.clone({
|
body: this.state.panel.clone(),
|
||||||
$data: this.state.$data?.clone(),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return gridItemToPanel(parentClone);
|
return gridItemToPanel(parentClone);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPanelCloneWithData(): VizPanel {
|
|
||||||
return this.state.panel.clone({ $data: this.state.$data?.clone() });
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPanelTitle(newTitle: string) {
|
public setPanelTitle(newTitle: string) {
|
||||||
this.state.panel.setState({ title: newTitle, hoverHeader: newTitle === '' });
|
this.state.panel.setState({ title: newTitle, hoverHeader: newTitle === '' });
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@ export class PanelTimeRange extends SceneTimeRangeTransformerBase<PanelTimeRange
|
|||||||
this.subscribeToState((n, p) => {
|
this.subscribeToState((n, p) => {
|
||||||
// Listen to own changes and update time info when required
|
// Listen to own changes and update time info when required
|
||||||
if (n.timeFrom !== p.timeFrom || n.timeShift !== p.timeShift) {
|
if (n.timeFrom !== p.timeFrom || n.timeShift !== p.timeShift) {
|
||||||
const { timeInfo } = this.getTimeOverride(this.getAncestorTimeRange().state.value);
|
const { timeInfo, timeRange } = this.getTimeOverride(this.getAncestorTimeRange().state.value);
|
||||||
this.setState({ timeInfo });
|
this.setState({ timeInfo, value: timeRange });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user