grafana_bak/public/app/features/dashboard-scene/utils/DashboardModelCompatibilityWrapper.ts
2025-04-01 10:38:02 +09:00

209 lines
5.3 KiB
TypeScript

import { Subscription } from 'rxjs';
import { AnnotationQuery, DashboardCursorSync, dateTimeFormat, DateTimeInput, EventBusSrv } from '@grafana/data';
import { TimeRangeUpdatedEvent } from '@grafana/runtime';
import { behaviors, sceneGraph, SceneObject, VizPanel } from '@grafana/scenes';
import { DashboardDataLayerSet } from '../scene/DashboardDataLayerSet';
import { DashboardScene } from '../scene/DashboardScene';
import { dataLayersToAnnotations } from '../serialization/dataLayersToAnnotations';
import { PanelModelCompatibilityWrapper } from './PanelModelCompatibilityWrapper';
import { findVizPanelByKey, getVizPanelKeyForPanelId } from './utils';
/**
* Will move this to make it the main way we remain somewhat compatible with getDashboardSrv().getCurrent
*/
export class DashboardModelCompatibilityWrapper {
public events = new EventBusSrv();
private _subs = new Subscription();
public constructor(private _scene: DashboardScene) {
const timeRange = sceneGraph.getTimeRange(_scene);
// Copied from DashboardModel, as this function is passed around
this.formatDate = this.formatDate.bind(this);
this._subs.add(
timeRange.subscribeToState((state, prev) => {
if (state.value !== prev.value) {
this.events.publish(new TimeRangeUpdatedEvent(state.value));
}
})
);
}
public get id(): number | null {
return this._scene.state.id ?? null;
}
public get uid() {
return this._scene.state.uid ?? null;
}
public get title() {
return this._scene.state.title;
}
public get description() {
return this._scene.state.description;
}
public get editable() {
return this._scene.state.editable;
}
public get graphTooltip() {
return this._getSyncMode();
}
public get timepicker() {
return {
refresh_intervals: this._scene.state.controls!.state.refreshPicker.state.intervals,
hidden: this._scene.state.controls!.state.hideTimeControls ?? false,
};
}
public get timezone() {
return this.getTimezone();
}
public get weekStart() {
return sceneGraph.getTimeRange(this._scene).state.weekStart;
}
public get tags() {
return this._scene.state.tags;
}
public get links() {
return this._scene.state.links;
}
public get meta() {
return this._scene.state.meta;
}
public get time() {
const time = sceneGraph.getTimeRange(this._scene);
return {
from: time.state.from,
to: time.state.to,
};
}
public get panels() {
const panels = findAllObjects(this._scene, (o) => {
return Boolean(o instanceof VizPanel);
});
return panels.map((p) => new PanelModelCompatibilityWrapper(p as VizPanel));
}
/**
* Used from from timeseries migration handler to migrate time regions to dashboard annotations
*/
public get annotations(): { list: AnnotationQuery[] } {
const annotations: { list: AnnotationQuery[] } = { list: [] };
if (this._scene.state.$data instanceof DashboardDataLayerSet) {
annotations.list = dataLayersToAnnotations(this._scene.state.$data.state.annotationLayers);
}
return annotations;
}
public getTimezone() {
const time = sceneGraph.getTimeRange(this._scene);
return time.getTimeZone();
}
public sharedTooltipModeEnabled() {
return this._getSyncMode() > 0;
}
public sharedCrosshairModeOnly() {
return this._getSyncMode() === 1;
}
private _getSyncMode() {
if (this._scene.state.$behaviors) {
for (const behavior of this._scene.state.$behaviors) {
if (behavior instanceof behaviors.CursorSync) {
return behavior.state.sync;
}
}
}
return DashboardCursorSync.Off;
}
public otherPanelInFullscreen(panel: unknown) {
return false;
}
public formatDate(date: DateTimeInput, format?: string) {
return dateTimeFormat(date, {
format,
timeZone: this.getTimezone(),
});
}
public getPanelById(id: number): PanelModelCompatibilityWrapper | null {
const vizPanel = findVizPanelByKey(this._scene, getVizPanelKeyForPanelId(id));
if (vizPanel) {
return new PanelModelCompatibilityWrapper(vizPanel);
}
return null;
}
/**
* Mainly implemented to support Getting started panel's dissmis button.
*/
public removePanel(panel: PanelModelCompatibilityWrapper) {
const vizPanel = findVizPanelByKey(this._scene, getVizPanelKeyForPanelId(panel.id));
if (!vizPanel) {
console.error('Trying to remove a panel that was not found in scene', panel);
return;
}
this._scene.removePanel(vizPanel);
}
public canEditAnnotations(dashboardUID?: string) {
if (!this._scene.canEditDashboard()) {
return false;
}
if (dashboardUID) {
return Boolean(this._scene.state.meta.annotationsPermissions?.dashboard.canEdit);
}
return Boolean(this._scene.state.meta.annotationsPermissions?.organization.canEdit);
}
public panelInitialized() {}
public destroy() {
this.events.removeAllListeners();
this._subs.unsubscribe();
}
public hasUnsavedChanges() {
return this._scene.state.isDirty;
}
}
function findAllObjects(root: SceneObject, check: (o: SceneObject) => boolean) {
let result: SceneObject[] = [];
root.forEachChild((child) => {
if (check(child)) {
result.push(child);
} else {
result = result.concat(findAllObjects(child, check));
}
});
return result;
}