2023-11-09 06:15:29 +08:00
|
|
|
import { AdHocVariableModel, TypedVariableModel, VariableModel } from '@grafana/data';
|
2023-11-14 16:08:06 +08:00
|
|
|
import { config } from '@grafana/runtime';
|
2023-01-10 19:30:53 +08:00
|
|
|
import {
|
|
|
|
|
VizPanel,
|
|
|
|
|
SceneTimePicker,
|
|
|
|
|
SceneGridLayout,
|
|
|
|
|
SceneGridRow,
|
|
|
|
|
SceneTimeRange,
|
|
|
|
|
SceneVariableSet,
|
|
|
|
|
VariableValueSelectors,
|
|
|
|
|
SceneVariable,
|
|
|
|
|
CustomVariable,
|
|
|
|
|
DataSourceVariable,
|
|
|
|
|
QueryVariable,
|
|
|
|
|
ConstantVariable,
|
2023-10-16 23:34:09 +08:00
|
|
|
IntervalVariable,
|
2023-04-04 18:02:29 +08:00
|
|
|
SceneRefreshPicker,
|
2023-03-31 15:59:06 +08:00
|
|
|
SceneGridItem,
|
2023-07-06 17:21:03 +08:00
|
|
|
SceneObject,
|
2023-07-12 19:37:26 +08:00
|
|
|
VizPanelMenu,
|
2023-08-17 22:03:26 +08:00
|
|
|
behaviors,
|
2023-09-01 16:21:41 +08:00
|
|
|
VizPanelState,
|
2023-09-05 19:51:46 +08:00
|
|
|
SceneGridItemLike,
|
2023-09-20 17:50:35 +08:00
|
|
|
SceneDataLayers,
|
|
|
|
|
SceneDataLayerProvider,
|
|
|
|
|
SceneDataLayerControls,
|
2023-10-10 16:17:21 +08:00
|
|
|
AdHocFilterSet,
|
2023-11-22 20:43:27 +08:00
|
|
|
TextBoxVariable,
|
2023-12-06 23:24:15 +08:00
|
|
|
UserActionEvent,
|
2023-01-10 19:30:53 +08:00
|
|
|
} from '@grafana/scenes';
|
2022-11-17 23:15:51 +08:00
|
|
|
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
2024-01-04 23:34:15 +08:00
|
|
|
import { trackDashboardLoaded } from 'app/features/dashboard/utils/tracking';
|
2023-08-29 20:17:55 +08:00
|
|
|
import { DashboardDTO } from 'app/types';
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-11-14 16:08:06 +08:00
|
|
|
import { AlertStatesDataLayer } from '../scene/AlertStatesDataLayer';
|
2023-09-20 18:47:09 +08:00
|
|
|
import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer';
|
2023-11-15 23:49:51 +08:00
|
|
|
import { DashboardControls } from '../scene/DashboardControls';
|
|
|
|
|
import { DashboardLinksControls } from '../scene/DashboardLinksControls';
|
2023-11-15 20:05:54 +08:00
|
|
|
import { registerDashboardMacro } from '../scene/DashboardMacro';
|
2023-08-25 20:11:47 +08:00
|
|
|
import { DashboardScene } from '../scene/DashboardScene';
|
|
|
|
|
import { LibraryVizPanel } from '../scene/LibraryVizPanel';
|
2023-10-31 16:57:38 +08:00
|
|
|
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
|
2024-01-31 19:30:27 +08:00
|
|
|
import { panelLinksBehavior, panelMenuBehavior } from '../scene/PanelMenuBehavior';
|
2023-12-07 17:24:22 +08:00
|
|
|
import { PanelNotices } from '../scene/PanelNotices';
|
2023-09-05 19:51:46 +08:00
|
|
|
import { PanelRepeaterGridItem } from '../scene/PanelRepeaterGridItem';
|
2023-09-01 16:21:41 +08:00
|
|
|
import { PanelTimeRange } from '../scene/PanelTimeRange';
|
2023-09-11 18:02:04 +08:00
|
|
|
import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior';
|
2023-10-13 17:42:42 +08:00
|
|
|
import { setDashboardPanelContext } from '../scene/setDashboardPanelContext';
|
2023-08-25 20:11:47 +08:00
|
|
|
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
|
2023-12-06 23:24:15 +08:00
|
|
|
import { DashboardInteractions } from '../utils/interactions';
|
2023-10-16 23:34:09 +08:00
|
|
|
import {
|
|
|
|
|
getCurrentValueForOldIntervalModel,
|
2024-01-29 23:53:09 +08:00
|
|
|
getIntervalsFromQueryString,
|
2023-10-16 23:34:09 +08:00
|
|
|
getVizPanelKeyForPanelId,
|
|
|
|
|
} from '../utils/utils';
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-10-10 20:33:58 +08:00
|
|
|
import { getAngularPanelMigrationHandler } from './angularMigration';
|
|
|
|
|
|
2022-11-17 23:15:51 +08:00
|
|
|
export interface DashboardLoaderState {
|
|
|
|
|
dashboard?: DashboardScene;
|
|
|
|
|
isLoading?: boolean;
|
|
|
|
|
loadError?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-25 14:32:07 +08:00
|
|
|
export interface SaveModelToSceneOptions {
|
|
|
|
|
isEmbedded?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-29 20:17:55 +08:00
|
|
|
export function transformSaveModelToScene(rsp: DashboardDTO): DashboardScene {
|
|
|
|
|
// Just to have migrations run
|
|
|
|
|
const oldModel = new DashboardModel(rsp.dashboard, rsp.meta, {
|
2023-10-11 20:27:20 +08:00
|
|
|
autoMigrateOldPanels: false,
|
2023-08-29 20:17:55 +08:00
|
|
|
});
|
2023-03-16 16:19:50 +08:00
|
|
|
|
2024-01-29 19:04:45 +08:00
|
|
|
const scene = createDashboardSceneFromDashboardModel(oldModel);
|
|
|
|
|
// TODO: refactor createDashboardSceneFromDashboardModel to work on Dashboard schema model
|
|
|
|
|
scene.setInitialSaveModel(rsp.dashboard);
|
|
|
|
|
|
|
|
|
|
return scene;
|
2023-01-04 21:29:22 +08:00
|
|
|
}
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-09-05 19:51:46 +08:00
|
|
|
export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneGridItemLike[] {
|
2023-01-04 21:29:22 +08:00
|
|
|
// collects all panels and rows
|
2023-09-05 19:51:46 +08:00
|
|
|
const panels: SceneGridItemLike[] = [];
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
// indicates expanded row that's currently processed
|
|
|
|
|
let currentRow: PanelModel | null = null;
|
|
|
|
|
// collects panels in the currently processed, expanded row
|
2023-09-05 19:51:46 +08:00
|
|
|
let currentRowPanels: SceneGridItemLike[] = [];
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
for (const panel of oldPanels) {
|
|
|
|
|
if (panel.type === 'row') {
|
|
|
|
|
if (!currentRow) {
|
|
|
|
|
if (Boolean(panel.collapsed)) {
|
|
|
|
|
// collapsed rows contain their panels within the row model
|
2023-09-11 18:02:04 +08:00
|
|
|
panels.push(createRowFromPanelModel(panel, []));
|
2022-11-17 23:15:51 +08:00
|
|
|
} else {
|
2023-01-04 21:29:22 +08:00
|
|
|
// indicate new row to be processed
|
|
|
|
|
currentRow = panel;
|
2022-11-17 23:15:51 +08:00
|
|
|
}
|
|
|
|
|
} else {
|
2023-01-04 21:29:22 +08:00
|
|
|
// when a row has been processed, and we hit a next one for processing
|
|
|
|
|
if (currentRow.id !== panel.id) {
|
|
|
|
|
// commit previous row panels
|
2023-09-11 18:02:04 +08:00
|
|
|
panels.push(createRowFromPanelModel(currentRow, currentRowPanels));
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
currentRow = panel;
|
|
|
|
|
currentRowPanels = [];
|
2022-11-17 23:15:51 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-08-21 23:43:48 +08:00
|
|
|
} else if (panel.libraryPanel?.uid && !('model' in panel.libraryPanel)) {
|
2023-10-06 20:32:29 +08:00
|
|
|
const gridItem = buildGridItemForLibPanel(panel);
|
|
|
|
|
if (gridItem) {
|
|
|
|
|
panels.push(gridItem);
|
|
|
|
|
}
|
2023-01-04 21:29:22 +08:00
|
|
|
} else {
|
2023-09-05 19:51:46 +08:00
|
|
|
const panelObject = buildGridItemForPanel(panel);
|
2022-11-17 23:15:51 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
// when processing an expanded row, collect its panels
|
|
|
|
|
if (currentRow) {
|
|
|
|
|
currentRowPanels.push(panelObject);
|
|
|
|
|
} else {
|
|
|
|
|
panels.push(panelObject);
|
|
|
|
|
}
|
2022-11-17 23:15:51 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-12-29 21:34:22 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
// commit a row if it's the last one
|
|
|
|
|
if (currentRow) {
|
2023-09-11 18:02:04 +08:00
|
|
|
panels.push(createRowFromPanelModel(currentRow, currentRowPanels));
|
2022-12-29 21:34:22 +08:00
|
|
|
}
|
2023-01-04 21:29:22 +08:00
|
|
|
|
|
|
|
|
return panels;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-11 18:02:04 +08:00
|
|
|
function createRowFromPanelModel(row: PanelModel, content: SceneGridItemLike[]): SceneGridItemLike {
|
|
|
|
|
if (Boolean(row.collapsed)) {
|
|
|
|
|
if (row.panels) {
|
2023-11-23 22:15:36 +08:00
|
|
|
content = row.panels.map((saveModel) => {
|
|
|
|
|
// Collapsed panels are not actually PanelModel instances
|
|
|
|
|
if (!(saveModel instanceof PanelModel)) {
|
|
|
|
|
saveModel = new PanelModel(saveModel);
|
|
|
|
|
}
|
|
|
|
|
return buildGridItemForPanel(saveModel);
|
|
|
|
|
});
|
2023-09-11 18:02:04 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let behaviors: SceneObject[] | undefined;
|
|
|
|
|
let children = content;
|
|
|
|
|
|
|
|
|
|
if (row.repeat) {
|
|
|
|
|
// For repeated rows the children are stored in the behavior
|
|
|
|
|
children = [];
|
|
|
|
|
behaviors = [
|
|
|
|
|
new RowRepeaterBehavior({
|
|
|
|
|
variableName: row.repeat,
|
|
|
|
|
sources: content,
|
|
|
|
|
}),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new SceneGridRow({
|
|
|
|
|
key: getVizPanelKeyForPanelId(row.id),
|
|
|
|
|
title: row.title,
|
|
|
|
|
y: row.gridPos.y,
|
|
|
|
|
isCollapsed: row.collapsed,
|
|
|
|
|
children: children,
|
|
|
|
|
$behaviors: behaviors,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel) {
|
|
|
|
|
let variables: SceneVariableSet | undefined = undefined;
|
2023-09-20 17:50:35 +08:00
|
|
|
let layers: SceneDataLayerProvider[] = [];
|
2023-10-10 16:17:21 +08:00
|
|
|
let filtersSets: AdHocFilterSet[] = [];
|
2023-01-04 21:29:22 +08:00
|
|
|
|
2023-03-17 21:50:37 +08:00
|
|
|
if (oldModel.templating?.list?.length) {
|
2023-01-04 21:29:22 +08:00
|
|
|
const variableObjects = oldModel.templating.list
|
|
|
|
|
.map((v) => {
|
|
|
|
|
try {
|
2023-10-10 16:17:21 +08:00
|
|
|
if (isAdhocVariable(v)) {
|
|
|
|
|
filtersSets.push(
|
|
|
|
|
new AdHocFilterSet({
|
|
|
|
|
name: v.name,
|
|
|
|
|
datasource: v.datasource,
|
|
|
|
|
filters: v.filters ?? [],
|
|
|
|
|
baseFilters: v.baseFilters ?? [],
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
return createSceneVariableFromVariableModel(v);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// TODO: Remove filter
|
|
|
|
|
// Added temporarily to allow skipping non-compatible variables
|
|
|
|
|
.filter((v): v is SceneVariable => Boolean(v));
|
2023-01-18 01:02:46 +08:00
|
|
|
|
2023-01-04 21:29:22 +08:00
|
|
|
variables = new SceneVariableSet({
|
|
|
|
|
variables: variableObjects,
|
|
|
|
|
});
|
2023-12-14 19:54:15 +08:00
|
|
|
} else {
|
|
|
|
|
// Create empty variable set
|
|
|
|
|
variables = new SceneVariableSet({
|
|
|
|
|
variables: [],
|
|
|
|
|
});
|
2023-01-04 21:29:22 +08:00
|
|
|
}
|
|
|
|
|
|
2024-02-07 06:29:57 +08:00
|
|
|
if (oldModel.annotations?.list?.length && !oldModel.isSnapshot()) {
|
2023-09-20 17:50:35 +08:00
|
|
|
layers = oldModel.annotations?.list.map((a) => {
|
|
|
|
|
// Each annotation query is an individual data layer
|
2023-09-20 18:47:09 +08:00
|
|
|
return new DashboardAnnotationsDataLayer({
|
2024-01-31 00:38:26 +08:00
|
|
|
key: `annotations-${a.name}`,
|
2023-09-20 17:50:35 +08:00
|
|
|
query: a,
|
|
|
|
|
name: a.name,
|
|
|
|
|
isEnabled: Boolean(a.enable),
|
|
|
|
|
isHidden: Boolean(a.hide),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-14 16:08:06 +08:00
|
|
|
let shouldUseAlertStatesLayer = config.unifiedAlertingEnabled;
|
|
|
|
|
if (!shouldUseAlertStatesLayer) {
|
|
|
|
|
if (oldModel.panels.find((panel) => Boolean(panel.alert))) {
|
|
|
|
|
shouldUseAlertStatesLayer = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shouldUseAlertStatesLayer) {
|
|
|
|
|
layers.push(
|
|
|
|
|
new AlertStatesDataLayer({
|
|
|
|
|
key: 'alert-states',
|
|
|
|
|
name: 'Alert States',
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 23:24:15 +08:00
|
|
|
const dashboardScene = new DashboardScene({
|
2023-01-04 21:29:22 +08:00
|
|
|
title: oldModel.title,
|
2023-11-28 19:26:09 +08:00
|
|
|
tags: oldModel.tags || [],
|
2023-11-29 22:01:40 +08:00
|
|
|
links: oldModel.links || [],
|
2023-01-04 21:29:22 +08:00
|
|
|
uid: oldModel.uid,
|
2023-10-13 22:24:04 +08:00
|
|
|
id: oldModel.id,
|
2023-12-01 23:04:56 +08:00
|
|
|
description: oldModel.description,
|
|
|
|
|
editable: oldModel.editable,
|
2024-01-31 18:33:46 +08:00
|
|
|
isDirty: oldModel.meta.isNew,
|
|
|
|
|
isEditing: oldModel.meta.isNew,
|
2023-09-14 18:17:04 +08:00
|
|
|
meta: oldModel.meta,
|
2024-01-17 23:14:29 +08:00
|
|
|
version: oldModel.version,
|
2023-01-04 21:29:22 +08:00
|
|
|
body: new SceneGridLayout({
|
2023-08-21 23:43:48 +08:00
|
|
|
isLazy: true,
|
2023-01-04 21:29:22 +08:00
|
|
|
children: createSceneObjectsForPanels(oldModel.panels),
|
|
|
|
|
}),
|
2023-10-03 17:03:53 +08:00
|
|
|
$timeRange: new SceneTimeRange({
|
|
|
|
|
from: oldModel.time.from,
|
|
|
|
|
to: oldModel.time.to,
|
|
|
|
|
fiscalYearStartMonth: oldModel.fiscalYearStartMonth,
|
|
|
|
|
timeZone: oldModel.timezone,
|
|
|
|
|
weekStart: oldModel.weekStart,
|
2024-01-12 00:53:06 +08:00
|
|
|
UNSAFE_nowDelay: oldModel.timepicker?.nowDelay,
|
2023-10-03 17:03:53 +08:00
|
|
|
}),
|
2023-01-04 21:29:22 +08:00
|
|
|
$variables: variables,
|
2023-08-17 22:03:26 +08:00
|
|
|
$behaviors: [
|
|
|
|
|
new behaviors.CursorSync({
|
|
|
|
|
sync: oldModel.graphTooltip,
|
|
|
|
|
}),
|
2024-02-10 04:44:44 +08:00
|
|
|
new behaviors.SceneQueryController(),
|
|
|
|
|
registerDashboardMacro,
|
2024-01-05 20:32:06 +08:00
|
|
|
registerDashboardSceneTracking(oldModel),
|
2023-12-06 23:24:15 +08:00
|
|
|
registerPanelInteractionsReporter,
|
2023-08-17 22:03:26 +08:00
|
|
|
],
|
2023-09-20 17:50:35 +08:00
|
|
|
$data:
|
|
|
|
|
layers.length > 0
|
|
|
|
|
? new SceneDataLayers({
|
|
|
|
|
layers,
|
|
|
|
|
})
|
|
|
|
|
: undefined,
|
2023-11-15 23:49:51 +08:00
|
|
|
controls: [
|
|
|
|
|
new DashboardControls({
|
|
|
|
|
variableControls: [new VariableValueSelectors({}), ...filtersSets, new SceneDataLayerControls()],
|
2023-12-15 18:52:34 +08:00
|
|
|
timeControls: [
|
|
|
|
|
new SceneTimePicker({}),
|
|
|
|
|
new SceneRefreshPicker({
|
|
|
|
|
refresh: oldModel.refresh,
|
|
|
|
|
intervals: oldModel.timepicker.refresh_intervals,
|
2024-02-10 04:44:44 +08:00
|
|
|
withText: true,
|
2023-12-15 18:52:34 +08:00
|
|
|
}),
|
|
|
|
|
],
|
2023-11-29 22:01:40 +08:00
|
|
|
linkControls: new DashboardLinksControls({}),
|
2023-12-15 18:52:34 +08:00
|
|
|
hideTimeControls: oldModel.timepicker.hidden,
|
2023-11-15 23:49:51 +08:00
|
|
|
}),
|
|
|
|
|
],
|
2023-01-04 21:29:22 +08:00
|
|
|
});
|
2023-12-06 23:24:15 +08:00
|
|
|
|
|
|
|
|
return dashboardScene;
|
2022-12-29 21:34:22 +08:00
|
|
|
}
|
|
|
|
|
|
2023-11-09 06:15:29 +08:00
|
|
|
export function createSceneVariableFromVariableModel(variable: TypedVariableModel): SceneVariable {
|
2022-12-29 21:34:22 +08:00
|
|
|
const commonProperties = {
|
|
|
|
|
name: variable.name,
|
|
|
|
|
label: variable.label,
|
|
|
|
|
};
|
2023-11-09 06:15:29 +08:00
|
|
|
if (variable.type === 'custom') {
|
2022-12-29 21:34:22 +08:00
|
|
|
return new CustomVariable({
|
|
|
|
|
...commonProperties,
|
2023-11-22 16:40:39 +08:00
|
|
|
value: variable.current?.value ?? '',
|
|
|
|
|
text: variable.current?.text ?? '',
|
2022-12-29 21:34:22 +08:00
|
|
|
description: variable.description,
|
|
|
|
|
query: variable.query,
|
|
|
|
|
isMulti: variable.multi,
|
|
|
|
|
allValue: variable.allValue || undefined,
|
|
|
|
|
includeAll: variable.includeAll,
|
|
|
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
hide: variable.hide,
|
|
|
|
|
});
|
2023-11-09 06:15:29 +08:00
|
|
|
} else if (variable.type === 'query') {
|
2022-12-29 21:34:22 +08:00
|
|
|
return new QueryVariable({
|
|
|
|
|
...commonProperties,
|
2023-11-22 16:40:39 +08:00
|
|
|
value: variable.current?.value ?? '',
|
|
|
|
|
text: variable.current?.text ?? '',
|
2022-12-29 21:34:22 +08:00
|
|
|
description: variable.description,
|
|
|
|
|
query: variable.query,
|
|
|
|
|
datasource: variable.datasource,
|
|
|
|
|
sort: variable.sort,
|
|
|
|
|
refresh: variable.refresh,
|
|
|
|
|
regex: variable.regex,
|
|
|
|
|
allValue: variable.allValue || undefined,
|
|
|
|
|
includeAll: variable.includeAll,
|
|
|
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
|
|
|
isMulti: variable.multi,
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
hide: variable.hide,
|
2023-12-06 18:33:54 +08:00
|
|
|
definition: variable.definition,
|
2022-12-29 21:34:22 +08:00
|
|
|
});
|
2023-11-09 06:15:29 +08:00
|
|
|
} else if (variable.type === 'datasource') {
|
2022-12-29 21:34:22 +08:00
|
|
|
return new DataSourceVariable({
|
|
|
|
|
...commonProperties,
|
2023-11-22 16:40:39 +08:00
|
|
|
value: variable.current?.value ?? '',
|
|
|
|
|
text: variable.current?.text ?? '',
|
2022-12-29 21:34:22 +08:00
|
|
|
description: variable.description,
|
|
|
|
|
regex: variable.regex,
|
2023-03-23 17:31:25 +08:00
|
|
|
pluginId: variable.query,
|
2022-12-29 21:34:22 +08:00
|
|
|
allValue: variable.allValue || undefined,
|
|
|
|
|
includeAll: variable.includeAll,
|
|
|
|
|
defaultToAll: Boolean(variable.includeAll),
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
isMulti: variable.multi,
|
|
|
|
|
hide: variable.hide,
|
|
|
|
|
});
|
2023-11-09 06:15:29 +08:00
|
|
|
} else if (variable.type === 'interval') {
|
2024-01-29 23:53:09 +08:00
|
|
|
const intervals = getIntervalsFromQueryString(variable.query);
|
2023-10-16 23:34:09 +08:00
|
|
|
const currentInterval = getCurrentValueForOldIntervalModel(variable, intervals);
|
|
|
|
|
return new IntervalVariable({
|
|
|
|
|
...commonProperties,
|
|
|
|
|
value: currentInterval,
|
|
|
|
|
description: variable.description,
|
|
|
|
|
intervals: intervals,
|
|
|
|
|
autoEnabled: variable.auto,
|
|
|
|
|
autoStepCount: variable.auto_count,
|
|
|
|
|
autoMinInterval: variable.auto_min,
|
|
|
|
|
refresh: variable.refresh,
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
hide: variable.hide,
|
|
|
|
|
});
|
2023-11-09 06:15:29 +08:00
|
|
|
} else if (variable.type === 'constant') {
|
2022-12-29 21:34:22 +08:00
|
|
|
return new ConstantVariable({
|
|
|
|
|
...commonProperties,
|
|
|
|
|
description: variable.description,
|
|
|
|
|
value: variable.query,
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
hide: variable.hide,
|
|
|
|
|
});
|
2023-11-22 20:43:27 +08:00
|
|
|
} else if (variable.type === 'textbox') {
|
|
|
|
|
return new TextBoxVariable({
|
|
|
|
|
...commonProperties,
|
|
|
|
|
description: variable.description,
|
|
|
|
|
value: variable.query,
|
|
|
|
|
skipUrlSync: variable.skipUrlSync,
|
|
|
|
|
hide: variable.hide,
|
|
|
|
|
});
|
2022-12-29 21:34:22 +08:00
|
|
|
} else {
|
|
|
|
|
throw new Error(`Scenes: Unsupported variable type ${variable.type}`);
|
|
|
|
|
}
|
2022-11-17 23:15:51 +08:00
|
|
|
}
|
|
|
|
|
|
2023-10-06 20:32:29 +08:00
|
|
|
export function buildGridItemForLibPanel(panel: PanelModel) {
|
|
|
|
|
if (!panel.libraryPanel) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 23:24:15 +08:00
|
|
|
const body = new LibraryVizPanel({
|
|
|
|
|
title: panel.title,
|
|
|
|
|
uid: panel.libraryPanel.uid,
|
|
|
|
|
name: panel.libraryPanel.name,
|
|
|
|
|
key: getVizPanelKeyForPanelId(panel.id),
|
|
|
|
|
});
|
|
|
|
|
|
2023-10-06 20:32:29 +08:00
|
|
|
return new SceneGridItem({
|
2023-12-06 23:24:15 +08:00
|
|
|
body,
|
2023-10-06 20:32:29 +08:00
|
|
|
y: panel.gridPos.y,
|
|
|
|
|
x: panel.gridPos.x,
|
|
|
|
|
width: panel.gridPos.w,
|
|
|
|
|
height: panel.gridPos.h,
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-10-16 23:34:09 +08:00
|
|
|
|
2023-09-05 19:51:46 +08:00
|
|
|
export function buildGridItemForPanel(panel: PanelModel): SceneGridItemLike {
|
2023-12-07 17:24:22 +08:00
|
|
|
const titleItems: SceneObject[] = [];
|
2023-10-31 16:57:38 +08:00
|
|
|
|
2024-01-31 19:30:27 +08:00
|
|
|
titleItems.push(
|
|
|
|
|
new VizPanelLinks({
|
|
|
|
|
rawLinks: panel.links,
|
|
|
|
|
menu: new VizPanelLinksMenu({ $behaviors: [panelLinksBehavior] }),
|
|
|
|
|
})
|
|
|
|
|
);
|
2023-10-31 16:57:38 +08:00
|
|
|
|
2023-12-07 17:24:22 +08:00
|
|
|
titleItems.push(new PanelNotices());
|
|
|
|
|
|
2023-09-01 16:21:41 +08:00
|
|
|
const vizPanelState: VizPanelState = {
|
|
|
|
|
key: getVizPanelKeyForPanelId(panel.id),
|
|
|
|
|
title: panel.title,
|
2023-10-31 16:57:38 +08:00
|
|
|
description: panel.description,
|
2023-09-01 16:21:41 +08:00
|
|
|
pluginId: panel.type,
|
|
|
|
|
options: panel.options ?? {},
|
|
|
|
|
fieldConfig: panel.fieldConfig,
|
|
|
|
|
pluginVersion: panel.pluginVersion,
|
|
|
|
|
displayMode: panel.transparent ? 'transparent' : undefined,
|
|
|
|
|
// To be replaced with it's own option persited option instead derived
|
|
|
|
|
hoverHeader: !panel.title && !panel.timeFrom && !panel.timeShift,
|
|
|
|
|
$data: createPanelDataProvider(panel),
|
|
|
|
|
menu: new VizPanelMenu({
|
|
|
|
|
$behaviors: [panelMenuBehavior],
|
|
|
|
|
}),
|
2023-12-07 17:24:22 +08:00
|
|
|
titleItems,
|
2023-10-31 16:57:38 +08:00
|
|
|
|
2023-10-13 17:42:42 +08:00
|
|
|
extendPanelContext: setDashboardPanelContext,
|
2023-10-10 20:33:58 +08:00
|
|
|
_UNSAFE_customMigrationHandler: getAngularPanelMigrationHandler(panel),
|
2023-09-01 16:21:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (panel.timeFrom || panel.timeShift) {
|
|
|
|
|
vizPanelState.$timeRange = new PanelTimeRange({
|
|
|
|
|
timeFrom: panel.timeFrom,
|
|
|
|
|
timeShift: panel.timeShift,
|
|
|
|
|
hideTimeOverride: panel.hideTimeOverride,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 19:51:46 +08:00
|
|
|
if (panel.repeat) {
|
|
|
|
|
const repeatDirection = panel.repeatDirection ?? 'h';
|
|
|
|
|
return new PanelRepeaterGridItem({
|
|
|
|
|
key: `grid-item-${panel.id}`,
|
|
|
|
|
x: panel.gridPos.x,
|
|
|
|
|
y: panel.gridPos.y,
|
|
|
|
|
width: repeatDirection === 'h' ? 24 : panel.gridPos.w,
|
|
|
|
|
height: panel.gridPos.h,
|
|
|
|
|
itemHeight: panel.gridPos.h,
|
|
|
|
|
source: new VizPanel(vizPanelState),
|
|
|
|
|
variableName: panel.repeat,
|
|
|
|
|
repeatedPanels: [],
|
|
|
|
|
repeatDirection: panel.repeatDirection,
|
|
|
|
|
maxPerRow: panel.maxPerRow,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 23:24:15 +08:00
|
|
|
const body = new VizPanel(vizPanelState);
|
|
|
|
|
|
2023-03-31 15:59:06 +08:00
|
|
|
return new SceneGridItem({
|
2023-08-29 20:17:55 +08:00
|
|
|
key: `grid-item-${panel.id}`,
|
2023-03-31 15:59:06 +08:00
|
|
|
x: panel.gridPos.x,
|
|
|
|
|
y: panel.gridPos.y,
|
|
|
|
|
width: panel.gridPos.w,
|
|
|
|
|
height: panel.gridPos.h,
|
2023-12-06 23:24:15 +08:00
|
|
|
body,
|
2022-11-21 22:31:01 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-10 16:17:21 +08:00
|
|
|
const isAdhocVariable = (v: VariableModel): v is AdHocVariableModel => v.type === 'adhoc';
|
2023-12-06 23:24:15 +08:00
|
|
|
|
|
|
|
|
const getLimitedDescriptionReporter = () => {
|
|
|
|
|
const reportedPanels: string[] = [];
|
|
|
|
|
|
|
|
|
|
return (key: string) => {
|
|
|
|
|
if (reportedPanels.includes(key)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
reportedPanels.push(key);
|
|
|
|
|
DashboardInteractions.panelDescriptionShown();
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-05 20:32:06 +08:00
|
|
|
function registerDashboardSceneTracking(model: DashboardModel) {
|
2024-01-04 23:34:15 +08:00
|
|
|
return () => {
|
|
|
|
|
const unsetDashboardInteractionsScenesContext = DashboardInteractions.setScenesContext();
|
|
|
|
|
|
2024-01-05 20:32:06 +08:00
|
|
|
trackDashboardLoaded(model, model.version);
|
2024-01-04 23:34:15 +08:00
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
unsetDashboardInteractionsScenesContext();
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-06 23:24:15 +08:00
|
|
|
function registerPanelInteractionsReporter(scene: DashboardScene) {
|
|
|
|
|
const descriptionReporter = getLimitedDescriptionReporter();
|
|
|
|
|
|
|
|
|
|
// Subscriptions set with subscribeToEvent are automatically unsubscribed when the scene deactivated
|
|
|
|
|
scene.subscribeToEvent(UserActionEvent, (e) => {
|
|
|
|
|
const { interaction } = e.payload;
|
|
|
|
|
switch (interaction) {
|
|
|
|
|
case 'panel-description-shown':
|
|
|
|
|
descriptionReporter(e.payload.origin.state.key || '');
|
|
|
|
|
break;
|
|
|
|
|
case 'panel-status-message-clicked':
|
|
|
|
|
DashboardInteractions.panelStatusMessageClicked();
|
|
|
|
|
break;
|
|
|
|
|
case 'panel-cancel-query-clicked':
|
|
|
|
|
DashboardInteractions.panelCancelQueryClicked();
|
|
|
|
|
break;
|
|
|
|
|
case 'panel-menu-shown':
|
|
|
|
|
DashboardInteractions.panelMenuShown();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|