From 70005d3e37e21042e97d888c0fa6645f9d003ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Fri, 13 Oct 2017 14:50:16 +0200 Subject: [PATCH] grid: repeat refactoring and unit tests --- public/app/core/constants.ts | 1 + .../app/features/dashboard/dashboard_model.ts | 28 +++++++++---- .../features/dashboard/folder_modal/folder.ts | 2 - public/app/features/dashboard/panel_model.ts | 9 ++-- .../dashboard/specs/dashboard_model_specs.ts | 42 ++++++++++++++++++- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/public/app/core/constants.ts b/public/app/core/constants.ts index f94bb73b398..93bff05689e 100644 --- a/public/app/core/constants.ts +++ b/public/app/core/constants.ts @@ -2,5 +2,6 @@ export const GRID_CELL_HEIGHT = 20; export const GRID_CELL_VMARGIN = 10; export const GRID_COLUMN_COUNT = 24; +export const REPEAT_DIR_VERTICAL = 'v'; diff --git a/public/app/features/dashboard/dashboard_model.ts b/public/app/features/dashboard/dashboard_model.ts index 9ad8291b677..97c018d700c 100644 --- a/public/app/features/dashboard/dashboard_model.ts +++ b/public/app/features/dashboard/dashboard_model.ts @@ -1,7 +1,7 @@ import moment from 'moment'; import _ from 'lodash'; -import {GRID_COLUMN_COUNT, GRID_CELL_HEIGHT} from 'app/core/constants'; +import {GRID_COLUMN_COUNT, GRID_CELL_HEIGHT, REPEAT_DIR_VERTICAL} from 'app/core/constants'; import {DEFAULT_ANNOTATION_COLOR} from 'app/core/utils/colors'; import {Emitter, contextSrv} from 'app/core/core'; import sortByKeys from 'app/core/utils/sort_by_keys'; @@ -283,6 +283,9 @@ export class DashboardModel { selected = _.filter(variable.options, {selected: true}); } + let minWidth = panel.minSpan || 6; + let xIndex = 0; + for (let index = 0; index < selected.length; index++) { var option = selected[index]; var copy = this.getRepeatClone(panel, index); @@ -290,15 +293,26 @@ export class DashboardModel { copy.scopedVars = {}; copy.scopedVars[variable.name] = option; - // souce panel uses original possition - if (index === 0) { - continue; - } + if (panel.repeatDirection === REPEAT_DIR_VERTICAL) { + if (index === 0) { + continue; + } - if (panel.repeatDirection === 'Y') { copy.gridPos.y = panel.gridPos.y + panel.gridPos.h * index; } else { - copy.gridPos.x = panel.gridPos.x + panel.gridPos.w * index; + // 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; + + // 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; + } } } } diff --git a/public/app/features/dashboard/folder_modal/folder.ts b/public/app/features/dashboard/folder_modal/folder.ts index be0efbc6f9b..c788d54351f 100644 --- a/public/app/features/dashboard/folder_modal/folder.ts +++ b/public/app/features/dashboard/folder_modal/folder.ts @@ -1,5 +1,3 @@ -/// - import coreModule from 'app/core/core_module'; import appEvents from 'app/core/app_events'; diff --git a/public/app/features/dashboard/panel_model.ts b/public/app/features/dashboard/panel_model.ts index 90583d6be71..f4df8a1d7a5 100644 --- a/public/app/features/dashboard/panel_model.ts +++ b/public/app/features/dashboard/panel_model.ts @@ -21,10 +21,11 @@ export class PanelModel { title: string; alert?: any; scopedVars?: any; - repeat?: any; - repeatIteration?: any; - repeatPanelId?: any; - repeatDirection?: any; + repeat?: string; + repeatIteration?: number; + repeatPanelId?: number; + repeatDirection?: string; + minSpan?: number; // non persisted fullscreen: boolean; diff --git a/public/app/features/dashboard/specs/dashboard_model_specs.ts b/public/app/features/dashboard/specs/dashboard_model_specs.ts index 26ae2d0a6b2..5ca8122e3bd 100644 --- a/public/app/features/dashboard/specs/dashboard_model_specs.ts +++ b/public/app/features/dashboard/specs/dashboard_model_specs.ts @@ -416,12 +416,12 @@ describe('DashboardModel', function() { }); }); - describe('given dashboard with panel repeat', function(ctx) { + describe('given dashboard with panel repeat in horizontal direction', function(ctx) { var dashboard; beforeEach(function() { dashboard = new DashboardModel({ - panels: [{id: 2, repeat: 'apps'}], + panels: [{id: 2, repeat: 'apps', repeatDirection: 'h', gridPos: {x: 0, y: 0, h: 2, w: 24}}], templating: { list: [{ name: 'apps', @@ -456,6 +456,12 @@ describe('DashboardModel', function() { expect(dashboard.panels[2].scopedVars.apps.value).to.be('se3'); }); + it('should place on first row and adjust width so all fit', function() { + expect(dashboard.panels[0].gridPos).to.eql({x: 0, y: 0, h: 2, w: 8}); + expect(dashboard.panels[1].gridPos).to.eql({x: 8, y: 0, h: 2, w: 8}); + expect(dashboard.panels[2].gridPos).to.eql({x: 16, y: 0, h: 2, w: 8}); + }); + describe('After a second iteration', function() { var repeatedPanelAfterIteration1; @@ -522,4 +528,36 @@ describe('DashboardModel', function() { }); + describe('given dashboard with panel repeat in vertical direction', function(ctx) { + var dashboard; + + beforeEach(function() { + dashboard = new DashboardModel({ + panels: [{id: 2, repeat: 'apps', repeatDirection: 'v', gridPos: {x: 5, y: 0, h: 2, w: 8}}], + templating: { + list: [{ + name: 'apps', + current: { + text: 'se1, se2, se3', + value: ['se1', 'se2', 'se3'] + }, + options: [ + {text: 'se1', value: 'se1', selected: true}, + {text: 'se2', value: 'se2', selected: true}, + {text: 'se3', value: 'se3', selected: true}, + {text: 'se4', value: 'se4', selected: false} + ] + }] + } + }); + dashboard.processRepeats(); + }); + + it('should place on items on top of each other and keep witdh', function() { + expect(dashboard.panels[0].gridPos).to.eql({x: 5, y: 0, h: 2, w: 8}); + expect(dashboard.panels[1].gridPos).to.eql({x: 5, y: 2, h: 2, w: 8}); + expect(dashboard.panels[2].gridPos).to.eql({x: 5, y: 4, h: 2, w: 8}); + }); + }); + });