From 349408d78c6b3746b4672c0087ed93881037fdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 11 Sep 2023 08:34:13 +0200 Subject: [PATCH] DashboardMigrator: Add migration that removes repeats (#74296) * DashboardMigrator: Add migration that removes repeats * Update --- .../dashboard/state/DashboardMigrator.test.ts | 32 ++++++++++++++++++- .../dashboard/state/DashboardMigrator.ts | 23 +++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/public/app/features/dashboard/state/DashboardMigrator.test.ts b/public/app/features/dashboard/state/DashboardMigrator.test.ts index 099cd0797d9..9bdb545c119 100644 --- a/public/app/features/dashboard/state/DashboardMigrator.test.ts +++ b/public/app/features/dashboard/state/DashboardMigrator.test.ts @@ -49,6 +49,7 @@ describe('DashboardModel', () => { let singlestat: any; let table: any; let singlestatGauge: any; + const panelIdWithRepeatId = 500; config.panels = { stat: getPanelPlugin({ id: 'stat' }).meta, @@ -116,6 +117,31 @@ describe('DashboardModel', () => { styles: [{ thresholds: ['10', '20', '30'] }, { thresholds: ['100', '200', '300'] }], targets: [{ refId: 'A' }, {}], }, + // Old left-over repeated panel + // @ts-expect-error + { + type: 'table', + id: panelIdWithRepeatId, + repeatPanelId: 1, + }, + // Collapsed row with left-over repeated panels + { + type: 'row', + panels: [ + // @ts-expect-error + { + id: 501, + type: 'table', + repeat: 'server', + }, + // Old left-over repeated panel + { + id: 502, + // @ts-expect-error + repeatedPanelId: 501, + }, + ], + }, ], }); @@ -130,7 +156,7 @@ describe('DashboardModel', () => { }); it('should have panel id', () => { - expect(graph.id).toBe(1); + expect(graph.id).toBe(503); }); it('should not have style', () => { @@ -236,6 +262,10 @@ describe('DashboardModel', () => { expect(graph.thresholds[1].value).toBe(200); expect(graph.thresholds[2].value).toBe(400); }); + + it('Shoud ignore repeated panels', () => { + expect(model.getPanelById(panelIdWithRepeatId)).toBe(null); + }); }); describe('when migrating to the grid layout', () => { diff --git a/public/app/features/dashboard/state/DashboardMigrator.ts b/public/app/features/dashboard/state/DashboardMigrator.ts index 20d5e4e05da..6ab70552a50 100644 --- a/public/app/features/dashboard/state/DashboardMigrator.ts +++ b/public/app/features/dashboard/state/DashboardMigrator.ts @@ -627,6 +627,9 @@ export class DashboardMigrator { } if (oldVersion < 27) { + // remove old repeated panel left-overs + this.removeRepeatedPanels(); + this.dashboard.templating.list = this.dashboard.templating.list.map((variable) => { if (!isConstant(variable)) { return variable; @@ -863,6 +866,26 @@ export class DashboardMigrator { } } + private removeRepeatedPanels() { + const newPanels = []; + + for (const panel of this.dashboard.panels) { + // @ts-expect-error + if (panel.repeatPanelId || panel.repeatByRow) { + continue; + } + + // Filter out repeats in collapsed rows + if (panel.type === 'row' && Array.isArray(panel.panels)) { + panel.panels = panel.panels.filter((x) => !x.repeatPanelId); + } + + newPanels.push(panel); + } + + this.dashboard.panels = newPanels; + } + // Migrates metric queries and/or annotation queries that use more than one statistic. // E.g query.statistics = ['Max', 'Min'] will be migrated to two queries - query1.statistic = 'Max' and query2.statistic = 'Min' // New queries, that were created during migration, are put at the end of the array.