mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardScene: Support auto migration for angular panels (#76100)
* DashboardScene: Support auto migration for angular panels * minor tweak * Update scenes * Review fix * Update
This commit is contained in:
parent
ea741dda6b
commit
42218fbdbb
@ -3007,6 +3007,10 @@ exports[`better eslint`] = {
|
|||||||
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
|
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
|
||||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||||
],
|
],
|
||||||
|
"public/app/features/dashboard-scene/serialization/angularMigration.test.ts:5381": [
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||||
|
],
|
||||||
"public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts:5381": [
|
"public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||||
@ -3579,18 +3583,19 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Do not use any type assertions.", "9"],
|
[0, 0, 0, "Do not use any type assertions.", "9"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "11"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "12"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "12"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
|
[0, 0, 0, "Do not use any type assertions.", "13"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "14"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
|
[0, 0, 0, "Do not use any type assertions.", "15"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "18"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
|
[0, 0, 0, "Do not use any type assertions.", "19"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "20"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
|
[0, 0, 0, "Do not use any type assertions.", "21"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "23"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "24"]
|
||||||
],
|
],
|
||||||
"public/app/features/dashboard/state/TimeModel.ts:5381": [
|
"public/app/features/dashboard/state/TimeModel.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
@ -250,7 +250,7 @@
|
|||||||
"@grafana/lezer-traceql": "0.0.6",
|
"@grafana/lezer-traceql": "0.0.6",
|
||||||
"@grafana/monaco-logql": "^0.0.7",
|
"@grafana/monaco-logql": "^0.0.7",
|
||||||
"@grafana/runtime": "workspace:*",
|
"@grafana/runtime": "workspace:*",
|
||||||
"@grafana/scenes": "^1.13.0",
|
"@grafana/scenes": "^1.15.0",
|
||||||
"@grafana/schema": "workspace:*",
|
"@grafana/schema": "workspace:*",
|
||||||
"@grafana/ui": "workspace:*",
|
"@grafana/ui": "workspace:*",
|
||||||
"@kusto/monaco-kusto": "^7.4.0",
|
"@kusto/monaco-kusto": "^7.4.0",
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks';
|
||||||
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
|
|
||||||
|
import { getAngularPanelMigrationHandler } from './angularMigration';
|
||||||
|
|
||||||
|
describe('getAngularPanelMigrationHandler', () => {
|
||||||
|
describe('Given an old angular panel', () => {
|
||||||
|
it('Should call migration handler', () => {
|
||||||
|
const onPanelTypeChanged = (panel: PanelModel, prevPluginId: string, prevOptions: Record<string, any>) => {
|
||||||
|
panel.fieldConfig = { defaults: { unit: 'bytes' }, overrides: [] };
|
||||||
|
return { name: prevOptions.angular.oldOptionProp };
|
||||||
|
};
|
||||||
|
|
||||||
|
const reactPlugin = getPanelPlugin({ id: 'timeseries' }).setPanelChangeHandler(onPanelTypeChanged as any);
|
||||||
|
|
||||||
|
const oldModel = new PanelModel({
|
||||||
|
autoMigrateFrom: 'graph',
|
||||||
|
oldOptionProp: 'old name',
|
||||||
|
type: 'timeseries',
|
||||||
|
});
|
||||||
|
|
||||||
|
const mutatedModel = {
|
||||||
|
id: 1,
|
||||||
|
type: 'timeseries',
|
||||||
|
options: {},
|
||||||
|
fieldConfig: { defaults: {}, overrides: [] },
|
||||||
|
};
|
||||||
|
|
||||||
|
getAngularPanelMigrationHandler(oldModel)(mutatedModel, reactPlugin);
|
||||||
|
|
||||||
|
expect(mutatedModel.options).toEqual({ name: 'old name' });
|
||||||
|
expect(mutatedModel.fieldConfig).toEqual({ defaults: { unit: 'bytes' }, overrides: [] });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,22 @@
|
|||||||
|
import { PanelModel as PanelModelFromData, PanelPlugin } from '@grafana/data';
|
||||||
|
import { autoMigrateAngular, PanelModel } from 'app/features/dashboard/state/PanelModel';
|
||||||
|
|
||||||
|
export function getAngularPanelMigrationHandler(oldModel: PanelModel) {
|
||||||
|
return function handleAngularPanelMigrations(panel: PanelModelFromData, plugin: PanelPlugin) {
|
||||||
|
if (plugin.angularPanelCtrl) {
|
||||||
|
panel.options = { angularOptions: oldModel.getOptionsToRemember() };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldModel.autoMigrateFrom) {
|
||||||
|
const wasAngular = autoMigrateAngular[oldModel.autoMigrateFrom] != null;
|
||||||
|
const oldOptions = oldModel.getOptionsToRemember();
|
||||||
|
const prevPluginId = oldModel.autoMigrateFrom;
|
||||||
|
|
||||||
|
if (plugin.onPanelTypeChanged) {
|
||||||
|
const prevOptions = wasAngular ? { angular: oldOptions } : oldOptions.options;
|
||||||
|
Object.assign(panel.options, plugin.onPanelTypeChanged(panel, prevPluginId, prevOptions, panel.fieldConfig));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -122,7 +122,6 @@ describe('sceneVariablesSetToVariables', () => {
|
|||||||
"query": "query",
|
"query": "query",
|
||||||
"refresh": 1,
|
"refresh": 1,
|
||||||
"regex": "",
|
"regex": "",
|
||||||
"sort": 1,
|
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
@ -46,6 +46,8 @@ import { RowRepeaterBehavior } from '../scene/RowRepeaterBehavior';
|
|||||||
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
|
import { createPanelDataProvider } from '../utils/createPanelDataProvider';
|
||||||
import { getVizPanelKeyForPanelId } from '../utils/utils';
|
import { getVizPanelKeyForPanelId } from '../utils/utils';
|
||||||
|
|
||||||
|
import { getAngularPanelMigrationHandler } from './angularMigration';
|
||||||
|
|
||||||
export interface DashboardLoaderState {
|
export interface DashboardLoaderState {
|
||||||
dashboard?: DashboardScene;
|
dashboard?: DashboardScene;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
@ -338,6 +340,7 @@ export function buildGridItemForPanel(panel: PanelModel): SceneGridItemLike {
|
|||||||
menu: new VizPanelMenu({
|
menu: new VizPanelMenu({
|
||||||
$behaviors: [panelMenuBehavior],
|
$behaviors: [panelMenuBehavior],
|
||||||
}),
|
}),
|
||||||
|
_UNSAFE_customMigrationHandler: getAngularPanelMigrationHandler(panel),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (panel.timeFrom || panel.timeShift) {
|
if (panel.timeFrom || panel.timeShift) {
|
||||||
|
@ -394,7 +394,7 @@ export class PanelModel implements DataConfigSource, IPanelModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOptionsToRemember() {
|
public getOptionsToRemember(): any {
|
||||||
return Object.keys(this).reduce((acc, property) => {
|
return Object.keys(this).reduce((acc, property) => {
|
||||||
if (notPersistedProperties[property] || mustKeepProps[property]) {
|
if (notPersistedProperties[property] || mustKeepProps[property]) {
|
||||||
return acc;
|
return acc;
|
||||||
|
@ -50,7 +50,7 @@ export function getVariablesDefinitions() {
|
|||||||
new QueryVariable({
|
new QueryVariable({
|
||||||
name: 'instance',
|
name: 'instance',
|
||||||
datasource: { uid: 'gdev-prometheus' },
|
datasource: { uid: 'gdev-prometheus' },
|
||||||
query: { query: 'label_values(grafana_http_request_duration_seconds_sum, instance)' },
|
query: { query: 'label_values(grafana_http_request_duration_seconds_sum, instance)', refId: 'A' },
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -31,19 +31,19 @@ export function getQueryVariableDemo(): DashboardScene {
|
|||||||
new QueryVariable({
|
new QueryVariable({
|
||||||
name: 'instance (using datasource variable)',
|
name: 'instance (using datasource variable)',
|
||||||
refresh: VariableRefresh.onTimeRangeChanged,
|
refresh: VariableRefresh.onTimeRangeChanged,
|
||||||
query: { query: 'label_values(go_gc_duration_seconds, ${metric})' },
|
query: { query: 'label_values(go_gc_duration_seconds, ${metric})', refId: 'A' },
|
||||||
datasource: { uid: '${datasource}' },
|
datasource: { uid: '${datasource}' },
|
||||||
}),
|
}),
|
||||||
new QueryVariable({
|
new QueryVariable({
|
||||||
name: 'label values (on time range refresh)',
|
name: 'label values (on time range refresh)',
|
||||||
refresh: VariableRefresh.onTimeRangeChanged,
|
refresh: VariableRefresh.onTimeRangeChanged,
|
||||||
query: { query: 'label_values(go_gc_duration_seconds, ${metric})' },
|
query: { query: 'label_values(go_gc_duration_seconds, ${metric})', refId: 'B' },
|
||||||
datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
|
datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
|
||||||
}),
|
}),
|
||||||
new QueryVariable({
|
new QueryVariable({
|
||||||
name: 'legacy (graphite)',
|
name: 'legacy (graphite)',
|
||||||
refresh: VariableRefresh.onTimeRangeChanged,
|
refresh: VariableRefresh.onTimeRangeChanged,
|
||||||
query: { queryType: 'Default', target: 'stats.response.*' },
|
query: { queryType: 'Default', target: 'stats.response.*', refId: 'C' },
|
||||||
datasource: { uid: 'gdev-graphite', type: 'graphite' },
|
datasource: { uid: 'gdev-graphite', type: 'graphite' },
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
@ -79,7 +79,7 @@ export function getRepeatingPanelsDemo(): DashboardScene {
|
|||||||
function changeVariable(variable: TestVariable) {
|
function changeVariable(variable: TestVariable) {
|
||||||
const sub = variable.subscribeToState((state, old) => {
|
const sub = variable.subscribeToState((state, old) => {
|
||||||
if (!state.loading && old.loading) {
|
if (!state.loading && old.loading) {
|
||||||
if (variable.state.optionsToReturn.length === 2) {
|
if (variable.state.optionsToReturn?.length === 2) {
|
||||||
variable.setState({
|
variable.setState({
|
||||||
query: 'ABC',
|
query: 'ABC',
|
||||||
optionsToReturn: [
|
optionsToReturn: [
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -3343,9 +3343,9 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@grafana/scenes@npm:^1.13.0":
|
"@grafana/scenes@npm:^1.15.0":
|
||||||
version: 1.13.0
|
version: 1.15.0
|
||||||
resolution: "@grafana/scenes@npm:1.13.0"
|
resolution: "@grafana/scenes@npm:1.15.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@grafana/e2e-selectors": 10.0.2
|
"@grafana/e2e-selectors": 10.0.2
|
||||||
react-grid-layout: 1.3.4
|
react-grid-layout: 1.3.4
|
||||||
@ -3357,7 +3357,7 @@ __metadata:
|
|||||||
"@grafana/runtime": 10.0.3
|
"@grafana/runtime": 10.0.3
|
||||||
"@grafana/schema": 10.0.3
|
"@grafana/schema": 10.0.3
|
||||||
"@grafana/ui": 10.0.3
|
"@grafana/ui": 10.0.3
|
||||||
checksum: 3a6c4419ee324d49f41b9569dc86ca7ffa926438eedd762aa79c3327c39cd16b9671047ad02f5de3c52190a81b4139cdb75653a4b3741753f851ca0c9155b9bf
|
checksum: 8416327ad9a0e3be35d5a106788248d5886f6aa220777cf0772ef73a3f64ecac889f58a8e804beea0de339acd571d6e49a10278180cf1c50a2a51f44e03bf93e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -17654,7 +17654,7 @@ __metadata:
|
|||||||
"@grafana/lezer-traceql": 0.0.6
|
"@grafana/lezer-traceql": 0.0.6
|
||||||
"@grafana/monaco-logql": ^0.0.7
|
"@grafana/monaco-logql": ^0.0.7
|
||||||
"@grafana/runtime": "workspace:*"
|
"@grafana/runtime": "workspace:*"
|
||||||
"@grafana/scenes": ^1.13.0
|
"@grafana/scenes": ^1.15.0
|
||||||
"@grafana/schema": "workspace:*"
|
"@grafana/schema": "workspace:*"
|
||||||
"@grafana/tsconfig": ^1.3.0-rc1
|
"@grafana/tsconfig": ^1.3.0-rc1
|
||||||
"@grafana/ui": "workspace:*"
|
"@grafana/ui": "workspace:*"
|
||||||
|
Loading…
Reference in New Issue
Block a user