Commit a8814979 by Pierre GIRAUD

Max number of repeated panels per row

Instead of min width
parent a9808ef5
...@@ -51,7 +51,7 @@ When a user creates a new dashboard, a new dashboard JSON object is initialized ...@@ -51,7 +51,7 @@ When a user creates a new dashboard, a new dashboard JSON object is initialized
"list": [] "list": []
}, },
"refresh": "5s", "refresh": "5s",
"schemaVersion": 16, "schemaVersion": 17,
"version": 0, "version": 0,
"links": [] "links": []
} }
......
...@@ -292,9 +292,11 @@ The `direction` controls how the panels will be arranged. ...@@ -292,9 +292,11 @@ The `direction` controls how the panels will be arranged.
By choosing `horizontal` the panels will be arranged side-by-side. Grafana will automatically adjust the width By choosing `horizontal` the panels will be arranged side-by-side. Grafana will automatically adjust the width
of each repeated panel so that the whole row is filled. Currently, you cannot mix other panels on a row with a repeated of each repeated panel so that the whole row is filled. Currently, you cannot mix other panels on a row with a repeated
panel. Each panel will never be smaller that the provided `Min width` if you have many selected values. panel.
By choosing `vertical` the panels will be arranged from top to bottom in a column. The `Min width` doesn't have any effect in this case. The width of the repeated panels will be the same as of the first panel (the original template) being repeated. Set `Max per row` to tell grafana how many panels per row you want at most. It defaults to *4* if you don't set anything.
By choosing `vertical` the panels will be arranged from top to bottom in a column. The width of the repeated panels will be the same as of the first panel (the original template) being repeated.
Only make changes to the first panel (the original template). To have the changes take effect on all panels you need to trigger a dynamic dashboard re-build. Only make changes to the first panel (the original template). To have the changes take effect on all panels you need to trigger a dynamic dashboard re-build.
You can do this by either changing the variable value (that is the basis for the repeat) or reload the dashboard. You can do this by either changing the variable value (that is the basis for the repeat) or reload the dashboard.
......
...@@ -112,7 +112,7 @@ func NewDashboard(title string) *Dashboard { ...@@ -112,7 +112,7 @@ func NewDashboard(title string) *Dashboard {
func NewDashboardFolder(title string) *Dashboard { func NewDashboardFolder(title string) *Dashboard {
folder := NewDashboard(title) folder := NewDashboard(title)
folder.IsFolder = true folder.IsFolder = true
folder.Data.Set("schemaVersion", 16) folder.Data.Set("schemaVersion", 17)
folder.Data.Set("version", 0) folder.Data.Set("version", 0)
folder.IsFolder = true folder.IsFolder = true
return folder return folder
......
...@@ -21,7 +21,7 @@ export class DashboardMigrator { ...@@ -21,7 +21,7 @@ export class DashboardMigrator {
let i, j, k, n; let i, j, k, n;
const oldVersion = this.dashboard.schemaVersion; const oldVersion = this.dashboard.schemaVersion;
const panelUpgrades = []; const panelUpgrades = [];
this.dashboard.schemaVersion = 16; this.dashboard.schemaVersion = 17;
if (oldVersion === this.dashboard.schemaVersion) { if (oldVersion === this.dashboard.schemaVersion) {
return; return;
...@@ -368,6 +368,15 @@ export class DashboardMigrator { ...@@ -368,6 +368,15 @@ export class DashboardMigrator {
this.upgradeToGridLayout(old); this.upgradeToGridLayout(old);
} }
if (oldVersion < 17) {
panelUpgrades.push(panel => {
if (panel.minSpan) {
panel.maxPerRow = GRID_COLUMN_COUNT / panel.minSpan;
}
delete panel.minSpan;
});
}
if (panelUpgrades.length === 0) { if (panelUpgrades.length === 0) {
return; return;
} }
......
...@@ -442,7 +442,7 @@ export class DashboardModel { ...@@ -442,7 +442,7 @@ export class DashboardModel {
} }
const selectedOptions = this.getSelectedVariableOptions(variable); const selectedOptions = this.getSelectedVariableOptions(variable);
const minWidth = panel.minSpan || 6; const maxPerRow = panel.maxPerRow || 4;
let xPos = 0; let xPos = 0;
let yPos = panel.gridPos.y; let yPos = panel.gridPos.y;
...@@ -462,7 +462,7 @@ export class DashboardModel { ...@@ -462,7 +462,7 @@ export class DashboardModel {
} else { } else {
// set width based on how many are selected // set width based on how many are selected
// assumed the repeated panels should take up full row width // assumed the repeated panels should take up full row width
copy.gridPos.w = Math.max(GRID_COLUMN_COUNT / selectedOptions.length, minWidth); copy.gridPos.w = Math.max(GRID_COLUMN_COUNT / selectedOptions.length, GRID_COLUMN_COUNT / maxPerRow);
copy.gridPos.x = xPos; copy.gridPos.x = xPos;
copy.gridPos.y = yPos; copy.gridPos.y = yPos;
......
...@@ -77,7 +77,7 @@ export class PanelModel { ...@@ -77,7 +77,7 @@ export class PanelModel {
repeatPanelId?: number; repeatPanelId?: number;
repeatDirection?: string; repeatDirection?: string;
repeatedByRow?: boolean; repeatedByRow?: boolean;
minSpan?: number; maxPerRow?: number;
collapsed?: boolean; collapsed?: boolean;
panels?: any; panels?: any;
soloMode?: boolean; soloMode?: boolean;
......
...@@ -127,7 +127,7 @@ describe('DashboardModel', () => { ...@@ -127,7 +127,7 @@ describe('DashboardModel', () => {
}); });
it('dashboard schema version should be set to latest', () => { it('dashboard schema version should be set to latest', () => {
expect(model.schemaVersion).toBe(16); expect(model.schemaVersion).toBe(17);
}); });
it('graph thresholds should be migrated', () => { it('graph thresholds should be migrated', () => {
...@@ -364,14 +364,6 @@ describe('DashboardModel', () => { ...@@ -364,14 +364,6 @@ describe('DashboardModel', () => {
expect(dashboard.panels.length).toBe(2); expect(dashboard.panels.length).toBe(2);
}); });
it('minSpan should be twice', () => {
model.rows = [createRow({ height: 8 }, [[6]])];
model.rows[0].panels[0] = { minSpan: 12 };
const dashboard = new DashboardModel(model);
expect(dashboard.panels[0].minSpan).toBe(24);
});
it('should assign id', () => { it('should assign id', () => {
model.rows = [createRow({ collapse: true, height: 8 }, [[6], [6]])]; model.rows = [createRow({ collapse: true, height: 8 }, [[6], [6]])];
model.rows[0].panels[0] = {}; model.rows[0].panels[0] = {};
...@@ -380,6 +372,16 @@ describe('DashboardModel', () => { ...@@ -380,6 +372,16 @@ describe('DashboardModel', () => {
expect(dashboard.panels[0].id).toBe(1); expect(dashboard.panels[0].id).toBe(1);
}); });
}); });
describe('when migrating from minSpan to maxPerRow', () => {
it('maxPerRow should be correct', () => {
const model = {
panels: [{ minSpan: 8 }],
};
const dashboard = new DashboardModel(model);
expect(dashboard.panels[0].maxPerRow).toBe(3);
});
});
}); });
function createRow(options, panelDescriptions: any[]) { function createRow(options, panelDescriptions: any[]) {
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
</select> </select>
</div> </div>
<div class="gf-form" ng-show="ctrl.panel.repeat && ctrl.panel.repeatDirection == 'h'"> <div class="gf-form" ng-show="ctrl.panel.repeat && ctrl.panel.repeatDirection == 'h'">
<span class="gf-form-label width-9">Min width</span> <span class="gf-form-label width-9">Max per row</span>
<select class="gf-form-input" ng-model="ctrl.panel.minSpan" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]"> <select class="gf-form-input" ng-model="ctrl.panel.maxPerRow" ng-options="f for f in [2,3,4,6,12,24]">
<option value=""></option> <option value=""></option>
</select> </select>
</div> </div>
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
} }
], ],
"rows": [], "rows": [],
"schemaVersion": 16, "schemaVersion": 17,
"style": "dark", "style": "dark",
"tags": [], "tags": [],
"templating": { "templating": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment