From c0e7062eb81c4f901bd1734ce15ef62bc2be2a5c Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Wed, 29 Mar 2023 07:47:13 -0700 Subject: [PATCH] Dashboards: Ensure panels have unique ids (#65468) --- .../dashboard/state/DashboardModel.test.ts | 19 +++++++++++++++++++ .../dashboard/state/DashboardModel.ts | 10 +++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard/state/DashboardModel.test.ts b/public/app/features/dashboard/state/DashboardModel.test.ts index 3803121e5d4..f7b9d8b6faa 100644 --- a/public/app/features/dashboard/state/DashboardModel.test.ts +++ b/public/app/features/dashboard/state/DashboardModel.test.ts @@ -66,6 +66,25 @@ describe('DashboardModel', () => { }); }); + describe('when initalized with duplicate panel ids', () => { + let model: DashboardModel; + + beforeEach(() => { + model = createDashboardModelFixture({ + panels: [ + createPanelJSONFixture({ id: 6 }), + createPanelJSONFixture({ id: 2 }), + createPanelJSONFixture({}), // undefined + createPanelJSONFixture({ id: 2 }), + ], + }); + }); + + it('should ensure unique panel ids', () => { + expect(model.panels.map((p) => p.id)).toEqual([6, 2, 7, 8]); + }); + }); + describe('getSaveModelClone', () => { it('should sort keys', () => { const model = createDashboardModelFixture(); diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index daaa617bf06..ebca913d348 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -165,7 +165,7 @@ export class DashboardModel implements TimeModel { this.links = data.links ?? []; this.gnetId = data.gnetId || null; this.panels = map(data.panels ?? [], (panelData: any) => new PanelModel(panelData)); - this.ensurePanelsHaveIds(); + this.ensurePanelsHaveUniqueIds(); this.formatDate = this.formatDate.bind(this); this.resetOriginalVariables(true); @@ -447,10 +447,14 @@ export class DashboardModel implements TimeModel { this.panelsAffectedByVariableChange = null; } - private ensurePanelsHaveIds() { + private ensurePanelsHaveUniqueIds() { + const ids = new Set(); let nextPanelId = this.getNextPanelId(); for (const panel of this.panelIterator()) { - panel.id ??= nextPanelId++; + if (!panel.id || ids.has(panel.id)) { + panel.id = nextPanelId++; + } + ids.add(panel.id); } }