Scenes: Render old snapshots (#82277)

This commit is contained in:
Ezequiel Victorero 2024-02-22 16:56:31 -03:00 committed by GitHub
parent 086e60488f
commit 455bccea2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 2 deletions

View File

@ -159,6 +159,7 @@ const dashboard = {
folderId: 1,
folderTitle: 'super folder',
},
isSnapshot: () => false,
} as unknown as DashboardModel;
const panel = new PanelModel({

View File

@ -49,6 +49,7 @@ import { NEW_LINK } from '../settings/links/utils';
import { getQueryRunnerFor } from '../utils/utils';
import { buildNewDashboardSaveModel } from './buildNewDashboardSaveModel';
import { GRAFANA_DATASOURCE_REF } from './const';
import dashboard_to_load1 from './testfiles/dashboard_to_load1.json';
import repeatingRowsAndPanelsDashboardJson from './testfiles/repeating_rows_and_panels.json';
import {
@ -56,6 +57,7 @@ import {
buildGridItemForPanel,
createSceneVariableFromVariableModel,
transformSaveModelToScene,
convertOldSnapshotToScenesSnapshot,
} from './transformSaveModelToScene';
describe('transformSaveModelToScene', () => {
@ -1080,6 +1082,52 @@ describe('transformSaveModelToScene', () => {
expect(dataLayers.state.layers[4].state.name).toBe('Alert States');
});
});
describe('when rendering a legacy snapshot as scene', () => {
it('should convert snapshotData to snapshot inside targets', () => {
const panel = createPanelSaveModel({
title: 'test',
gridPos: { x: 1, y: 0, w: 12, h: 8 },
// @ts-ignore
snapshotData: [
{
fields: [
{
name: 'Field 1',
type: 'time',
values: ['value1', 'value2'],
config: {},
},
{
name: 'Field 2',
type: 'number',
values: [1],
config: {},
},
],
},
],
}) as Panel;
const oldPanelModel = new PanelModel(panel);
convertOldSnapshotToScenesSnapshot(oldPanelModel);
expect(oldPanelModel.snapshotData?.length).toStrictEqual(0);
expect(oldPanelModel.targets.length).toStrictEqual(1);
expect(oldPanelModel.datasource).toStrictEqual(GRAFANA_DATASOURCE_REF);
expect(oldPanelModel.targets[0].datasource).toStrictEqual(GRAFANA_DATASOURCE_REF);
expect(oldPanelModel.targets[0].queryType).toStrictEqual('snapshot');
// @ts-ignore
expect(oldPanelModel.targets[0].snapshot.length).toBe(1);
// @ts-ignore
expect(oldPanelModel.targets[0].snapshot[0].data.values).toStrictEqual([['value1', 'value2'], [1]]);
// @ts-ignore
expect(oldPanelModel.targets[0].snapshot[0].schema.fields).toStrictEqual([
{ config: {}, name: 'Field 1', type: 'time' },
{ config: {}, name: 'Field 2', type: 'number' },
]);
});
});
});
function buildGridItemForTest(saveModel: Partial<Panel>): { gridItem: SceneGridItem; vizPanel: VizPanel } {

View File

@ -1,4 +1,4 @@
import { TypedVariableModel } from '@grafana/data';
import { DataFrameDTO, DataFrameJSON, TypedVariableModel } from '@grafana/data';
import { config } from '@grafana/runtime';
import {
VizPanel,
@ -55,6 +55,7 @@ import {
} from '../utils/utils';
import { getAngularPanelMigrationHandler } from './angularMigration';
import { GRAFANA_DATASOURCE_REF } from './const';
export interface DashboardLoaderState {
dashboard?: DashboardScene;
@ -114,6 +115,11 @@ export function createSceneObjectsForPanels(oldPanels: PanelModel[]): SceneGridI
panels.push(gridItem);
}
} else {
// when rendering a snapshot created with the legacy Dashboards convert data to new snapshot format to be compatible with Scenes
if (panel.snapshotData) {
convertOldSnapshotToScenesSnapshot(panel);
}
const panelObject = buildGridItemForPanel(panel);
// when processing an expanded row, collect its panels
@ -371,7 +377,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode
} else if (variable.type === 'textbox') {
return new TextBoxVariable({
...commonProperties,
value: variable.query,
value: variable?.current?.value?.[0] ?? variable.query,
skipUrlSync: variable.skipUrlSync,
hide: variable.hide,
});
@ -528,3 +534,38 @@ function registerPanelInteractionsReporter(scene: DashboardScene) {
}
});
}
const convertSnapshotData = (snapshotData: DataFrameDTO[]): DataFrameJSON[] => {
return snapshotData.map((data) => {
return {
data: {
values: data.fields.map((field) => field.values).filter((values): values is unknown[] => values !== undefined),
},
schema: {
fields: data.fields.map((field) => ({
name: field.name,
type: field.type,
config: field.config,
})),
},
};
});
};
// override panel datasource and targets with snapshot data using the Grafana datasource
export const convertOldSnapshotToScenesSnapshot = (panel: PanelModel) => {
// only old snapshots created with old dashboards contains snapshotData
if (panel.snapshotData) {
panel.datasource = GRAFANA_DATASOURCE_REF;
panel.targets = [
{
refId: panel.snapshotData[0]?.refId ?? '',
datasource: panel.datasource,
queryType: 'snapshot',
// @ts-ignore
snapshot: convertSnapshotData(panel.snapshotData),
},
];
panel.snapshotData = [];
}
};