mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
import { Unsubscribable } from 'rxjs';
|
|
|
|
import { AppEvents } from '@grafana/data';
|
|
import { locationService } from '@grafana/runtime';
|
|
import { SceneObjectUrlSyncHandler, SceneObjectUrlValues } from '@grafana/scenes';
|
|
import appEvents from 'app/core/app_events';
|
|
|
|
import { PanelInspectDrawer } from '../inspect/PanelInspectDrawer';
|
|
import { createDashboardEditViewFor } from '../settings/utils';
|
|
import { findVizPanelByKey } from '../utils/utils';
|
|
|
|
import { DashboardScene, DashboardSceneState } from './DashboardScene';
|
|
import { DashboardRepeatsProcessedEvent } from './types';
|
|
|
|
export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
|
private _eventSub?: Unsubscribable;
|
|
|
|
constructor(private _scene: DashboardScene) {}
|
|
|
|
getKeys(): string[] {
|
|
return ['inspect', 'viewPanel', 'editview'];
|
|
}
|
|
|
|
getUrlState(): SceneObjectUrlValues {
|
|
const state = this._scene.state;
|
|
return {
|
|
inspect: state.inspectPanelKey,
|
|
viewPanel: state.viewPanelKey,
|
|
editview: state.editview?.getUrlKey(),
|
|
};
|
|
}
|
|
|
|
updateFromUrl(values: SceneObjectUrlValues): void {
|
|
const { inspectPanelKey, viewPanelKey, meta, isEditing } = this._scene.state;
|
|
const update: Partial<DashboardSceneState> = {};
|
|
|
|
if (typeof values.editview === 'string' && meta.canEdit) {
|
|
update.editview = createDashboardEditViewFor(values.editview);
|
|
|
|
// If we are not in editing (for example after full page reload)
|
|
if (!isEditing) {
|
|
// Not sure what is best to do here.
|
|
// The reason for the timeout is for this change to happen after the url sync has completed
|
|
setTimeout(() => this._scene.onEnterEditMode());
|
|
}
|
|
} else if (values.hasOwnProperty('editview')) {
|
|
update.editview = undefined;
|
|
}
|
|
|
|
// Handle inspect object state
|
|
if (typeof values.inspect === 'string') {
|
|
const panel = findVizPanelByKey(this._scene, values.inspect);
|
|
if (!panel) {
|
|
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
|
locationService.partial({ inspect: null });
|
|
return;
|
|
}
|
|
|
|
update.inspectPanelKey = values.inspect;
|
|
update.overlay = new PanelInspectDrawer({ panelRef: panel.getRef() });
|
|
} else if (inspectPanelKey) {
|
|
update.inspectPanelKey = undefined;
|
|
update.overlay = undefined;
|
|
}
|
|
|
|
// Handle view panel state
|
|
if (typeof values.viewPanel === 'string') {
|
|
const panel = findVizPanelByKey(this._scene, values.viewPanel);
|
|
if (!panel) {
|
|
// // If we are trying to view a repeat clone that can't be found it might be that the repeats have not been processed yet
|
|
if (values.viewPanel.indexOf('clone')) {
|
|
this._handleViewRepeatClone(values.viewPanel);
|
|
return;
|
|
}
|
|
|
|
appEvents.emit(AppEvents.alertError, ['Panel not found']);
|
|
locationService.partial({ viewPanel: null });
|
|
return;
|
|
}
|
|
|
|
update.viewPanelKey = values.viewPanel;
|
|
} else if (viewPanelKey) {
|
|
update.viewPanelKey = undefined;
|
|
}
|
|
|
|
if (Object.keys(update).length > 0) {
|
|
this._scene.setState(update);
|
|
}
|
|
}
|
|
|
|
private _handleViewRepeatClone(viewPanel: string) {
|
|
if (!this._eventSub) {
|
|
this._eventSub = this._scene.subscribeToEvent(DashboardRepeatsProcessedEvent, () => {
|
|
const panel = findVizPanelByKey(this._scene, viewPanel);
|
|
if (panel) {
|
|
this._eventSub?.unsubscribe();
|
|
this._scene.setState({ viewPanelKey: viewPanel });
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|