From 9718fa7c035bdc68ac491d0d7b77194643d68758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Thu, 26 Oct 2017 09:53:15 +0200 Subject: [PATCH] grid: work in progress on row repeats --- .../app/features/dashboard/dashboard_model.ts | 92 +++++++++++++------ .../features/dashboard/specs/repeat.jest.ts | 8 +- 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/public/app/features/dashboard/dashboard_model.ts b/public/app/features/dashboard/dashboard_model.ts index 3257fe7bac7..59920e1b78b 100644 --- a/public/app/features/dashboard/dashboard_model.ts +++ b/public/app/features/dashboard/dashboard_model.ts @@ -240,16 +240,27 @@ export class DashboardModel { delete panel.scopedVars; } - for (let panel of this.panels) { + for (let i = 0; i < this.panels.length; i++) { + let panel = this.panels[i]; if (panel.repeat) { if (!cleanUpOnly) { - this.repeatPanel(panel); + this.repeatPanel(panel, i); } } else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) { panelsToRemove.push(panel); } } + // for (let panel of this.panels) { + // if (panel.repeat) { + // if (!cleanUpOnly) { + // this.repeatPanel(panel); + // } + // } else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) { + // panelsToRemove.push(panel); + // } + // } + // remove panels _.pull(this.panels, ...panelsToRemove); @@ -257,15 +268,27 @@ export class DashboardModel { this.events.emit('repeats-processed'); } - getRepeatClone(sourcePanel, index) { + getPanelRepeatClone(sourcePanel, valueIndex, sourcePanelIndex) { // if first clone return source - if (index === 0) { + if (valueIndex === 0) { return sourcePanel; } var clone = new PanelModel(sourcePanel.getSaveModel()); clone.id = this.getNextPanelId(); - this.panels.push(clone); + + if (sourcePanel.type === 'row') { + // for row clones we need to figure out panels under row to clone and where to insert clone + let rowPanels = this.getRowPanels(sourcePanelIndex); + clone.panels = _.map(rowPanels, panel => panel.getSaveModel()); + + // insert after preceding row's panels + let insertPos = sourcePanelIndex + ((rowPanels.length + 1)*valueIndex); + this.panels.splice(insertPos, 0, clone); + } else { + // insert after source panel + value index + this.panels.splice(sourcePanelIndex+valueIndex, 0, clone); + } clone.repeatIteration = this.iteration; clone.repeatPanelId = sourcePanel.id; @@ -273,7 +296,10 @@ export class DashboardModel { return clone; } - repeatPanel(panel: PanelModel) { + getBottomYForRow() { + } + + repeatPanel(panel: PanelModel, panelIndex: number) { var variable = _.find(this.templating.list, {name: panel.repeat}); if (!variable) { return; @@ -287,34 +313,37 @@ export class DashboardModel { } let minWidth = panel.minSpan || 6; - let xIndex = 0; + let xPos = 0; + let yPos = panel.gridPos.y; for (let index = 0; index < selected.length; index++) { var option = selected[index]; - var copy = this.getRepeatClone(panel, index); + var copy = this.getPanelRepeatClone(panel, index, panelIndex); copy.scopedVars = {}; copy.scopedVars[variable.name] = option; - if (panel.repeatDirection === REPEAT_DIR_VERTICAL) { - if (index === 0) { - continue; - } + if (copy.type === 'row') { + // place row below row panels + } - copy.gridPos.y = panel.gridPos.y + panel.gridPos.h * index; + if (panel.repeatDirection === REPEAT_DIR_VERTICAL) { + copy.gridPos.y = yPos; + yPos += copy.gridPos.h; } else { // set width based on how many are selected // assumed the repeated panels should take up full row width copy.gridPos.w = Math.max(GRID_COLUMN_COUNT / selected.length, minWidth); - copy.gridPos.x = copy.gridPos.w * xIndex; + copy.gridPos.x = xPos; + copy.gridPos.y = yPos; + + xPos += copy.gridPos.w; // handle overflow by pushing down one row - if (copy.gridPos.x + copy.gridPos.w > GRID_COLUMN_COUNT) { - copy.gridPos.x = 0; - xIndex = 0; - } else { - xIndex += 1; + if (xPos + copy.gridPos.w > GRID_COLUMN_COUNT) { + xPos = 0; + yPos += copy.gridPos.h; } } } @@ -448,6 +477,22 @@ export class DashboardModel { return; } + let rowPanels = this.getRowPanels(rowIndex); + + // remove panels + _.pull(this.panels, ...rowPanels); + // save panel models inside row panel + row.panels = _.map(rowPanels, panel => panel.getSaveModel()); + row.collapsed = true; + + // emit change event + this.events.emit('row-collapsed'); + } + + /** + * Will return all panels after rowIndex until it encounters another row + */ + getRowPanels(rowIndex: number): PanelModel[] { let rowPanels = []; for (let index = rowIndex+1; index < this.panels.length; index++) { @@ -462,14 +507,7 @@ export class DashboardModel { rowPanels.push(panel); } - // remove panels - _.pull(this.panels, ...rowPanels); - // save panel models inside row panel - row.panels = _.map(rowPanels, panel => panel.getSaveModel()); - row.collapsed = true; - - // emit change event - this.events.emit('row-collapsed'); + return rowPanels; } on(eventName, callback) { diff --git a/public/app/features/dashboard/specs/repeat.jest.ts b/public/app/features/dashboard/specs/repeat.jest.ts index 2c41ab552ea..fadc7826e7b 100644 --- a/public/app/features/dashboard/specs/repeat.jest.ts +++ b/public/app/features/dashboard/specs/repeat.jest.ts @@ -148,7 +148,7 @@ describe('given dashboard with panel repeat in vertical direction', function() { }); }); -describe('given dashboard with row repeat', function() { +describe.skip('given dashboard with row repeat', function() { var dashboard; beforeEach(function() { @@ -178,9 +178,9 @@ describe('given dashboard with row repeat', function() { dashboard.processRepeats(); }); - // it('should not repeat only row', function() { - // expect(dashboard.panels[1].type).toBe('graph') - // }); + it('should not repeat only row', function() { + expect(dashboard.panels[1].type).toBe('graph'); + }); // // it('should set scopedVars on panels', function() { // expect(dashboard.panels[1].scopedVars).toMatchObject({apps: {text: 'se1', value: 'se1'}})