mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
newgrid: added constants, changed grid to 24 cols, added tests for panel repeats
This commit is contained in:
6
public/app/core/constants.ts
Normal file
6
public/app/core/constants.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export const GRID_CELL_HEIGHT = 20;
|
||||||
|
export const GRID_CELL_VMARGIN = 10;
|
||||||
|
export const GRID_COLUMN_COUNT = 24;
|
||||||
|
|
||||||
|
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import {GRID_COLUMN_COUNT, GRID_CELL_HEIGHT} from 'app/core/constants';
|
||||||
import {DEFAULT_ANNOTATION_COLOR} from 'app/core/utils/colors';
|
import {DEFAULT_ANNOTATION_COLOR} from 'app/core/utils/colors';
|
||||||
import {Emitter, contextSrv} from 'app/core/core';
|
import {Emitter, contextSrv} from 'app/core/core';
|
||||||
import {DashboardRow} from './row/row_model';
|
|
||||||
import {PanelModel} from './panel_model';
|
|
||||||
import sortByKeys from 'app/core/utils/sort_by_keys';
|
import sortByKeys from 'app/core/utils/sort_by_keys';
|
||||||
|
|
||||||
export const CELL_HEIGHT = 30;
|
import {DashboardRow} from './row/row_model';
|
||||||
export const CELL_VMARGIN = 10;
|
import {PanelModel} from './panel_model';
|
||||||
export const COL_COUNT = 12;
|
|
||||||
|
|
||||||
export class DashboardModel {
|
export class DashboardModel {
|
||||||
id: any;
|
id: any;
|
||||||
@@ -48,10 +46,10 @@ export class DashboardModel {
|
|||||||
events: Emitter;
|
events: Emitter;
|
||||||
|
|
||||||
static nonPersistedProperties: {[str: string]: boolean} = {
|
static nonPersistedProperties: {[str: string]: boolean} = {
|
||||||
"events": true,
|
events: true,
|
||||||
"meta": true,
|
meta: true,
|
||||||
"panels": true, // needs special handling
|
panels: true, // needs special handling
|
||||||
"templating": true, // needs special handling
|
templating: true, // needs special handling
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(data, meta?) {
|
constructor(data, meta?) {
|
||||||
@@ -66,12 +64,12 @@ export class DashboardModel {
|
|||||||
this.autoUpdate = data.autoUpdate;
|
this.autoUpdate = data.autoUpdate;
|
||||||
this.description = data.description;
|
this.description = data.description;
|
||||||
this.tags = data.tags || [];
|
this.tags = data.tags || [];
|
||||||
this.style = data.style || "dark";
|
this.style = data.style || 'dark';
|
||||||
this.timezone = data.timezone || '';
|
this.timezone = data.timezone || '';
|
||||||
this.editable = data.editable !== false;
|
this.editable = data.editable !== false;
|
||||||
this.graphTooltip = data.graphTooltip || 0;
|
this.graphTooltip = data.graphTooltip || 0;
|
||||||
this.hideControls = data.hideControls || false;
|
this.hideControls = data.hideControls || false;
|
||||||
this.time = data.time || { from: 'now-6h', to: 'now' };
|
this.time = data.time || {from: 'now-6h', to: 'now'};
|
||||||
this.timepicker = data.timepicker || {};
|
this.timepicker = data.timepicker || {};
|
||||||
this.templating = this.ensureListExist(data.templating);
|
this.templating = this.ensureListExist(data.templating);
|
||||||
this.annotations = this.ensureListExist(data.annotations);
|
this.annotations = this.ensureListExist(data.annotations);
|
||||||
@@ -144,7 +142,7 @@ export class DashboardModel {
|
|||||||
|
|
||||||
// get variable save models
|
// get variable save models
|
||||||
copy.templating = {
|
copy.templating = {
|
||||||
list: _.map(this.templating.list, variable => variable.getSaveModel ? variable.getSaveModel() : variable),
|
list: _.map(this.templating.list, variable => (variable.getSaveModel ? variable.getSaveModel() : variable)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// get panel save models
|
// get panel save models
|
||||||
@@ -166,17 +164,24 @@ export class DashboardModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ensureListExist(data) {
|
private ensureListExist(data) {
|
||||||
if (!data) { data = {}; }
|
if (!data) {
|
||||||
if (!data.list) { data.list = []; }
|
data = {};
|
||||||
|
}
|
||||||
|
if (!data.list) {
|
||||||
|
data.list = [];
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextPanelId() {
|
getNextPanelId() {
|
||||||
var j, panel, max = 0;
|
let max = 0;
|
||||||
for (j = 0; j < this.panels.length; j++) {
|
|
||||||
panel = this.panels[j];
|
for (let panel of this.panels) {
|
||||||
if (panel.id > max) { max = panel.id; }
|
if (panel.id > max) {
|
||||||
|
max = panel.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return max + 1;
|
return max + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,9 +230,13 @@ export class DashboardModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.iteration = (this.iteration || new Date().getTime()) + 1;
|
this.iteration = (this.iteration || new Date().getTime()) + 1;
|
||||||
|
|
||||||
let panelsToRemove = [];
|
let panelsToRemove = [];
|
||||||
|
|
||||||
|
// cleanup scopedVars
|
||||||
|
for (let panel of this.panels) {
|
||||||
|
delete panel.scopedVars;
|
||||||
|
}
|
||||||
|
|
||||||
for (let panel of this.panels) {
|
for (let panel of this.panels) {
|
||||||
if (panel.repeat) {
|
if (panel.repeat) {
|
||||||
if (!cleanUpOnly) {
|
if (!cleanUpOnly) {
|
||||||
@@ -263,7 +272,9 @@ export class DashboardModel {
|
|||||||
|
|
||||||
repeatPanel(panel: PanelModel) {
|
repeatPanel(panel: PanelModel) {
|
||||||
var variable = _.find(this.templating.list, {name: panel.repeat});
|
var variable = _.find(this.templating.list, {name: panel.repeat});
|
||||||
if (!variable) { return; }
|
if (!variable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var selected;
|
var selected;
|
||||||
if (variable.current.text === 'All') {
|
if (variable.current.text === 'All') {
|
||||||
@@ -276,7 +287,7 @@ export class DashboardModel {
|
|||||||
var option = selected[index];
|
var option = selected[index];
|
||||||
var copy = this.getRepeatClone(panel, index);
|
var copy = this.getRepeatClone(panel, index);
|
||||||
|
|
||||||
copy.scopedVars = copy.scopedVars || {};
|
copy.scopedVars = {};
|
||||||
copy.scopedVars[variable.name] = option;
|
copy.scopedVars[variable.name] = option;
|
||||||
|
|
||||||
// souce panel uses original possition
|
// souce panel uses original possition
|
||||||
@@ -285,9 +296,9 @@ export class DashboardModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (panel.repeatDirection === 'Y') {
|
if (panel.repeatDirection === 'Y') {
|
||||||
copy.gridPos.y = panel.gridPos.y + (panel.gridPos.h*index);
|
copy.gridPos.y = panel.gridPos.y + panel.gridPos.h * index;
|
||||||
} else {
|
} else {
|
||||||
copy.gridPos.x = panel.gridPos.x + (panel.gridPos.w*index);
|
copy.gridPos.x = panel.gridPos.x + panel.gridPos.w * index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,46 +315,39 @@ export class DashboardModel {
|
|||||||
|
|
||||||
updateSubmenuVisibility() {
|
updateSubmenuVisibility() {
|
||||||
this.meta.submenuEnabled = (() => {
|
this.meta.submenuEnabled = (() => {
|
||||||
if (this.links.length > 0) { return true; }
|
if (this.links.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
|
var visibleVars = _.filter(this.templating.list, variable => variable.hide !== 2);
|
||||||
if (visibleVars.length > 0) { return true; }
|
if (visibleVars.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
|
var visibleAnnotations = _.filter(this.annotations.list, annotation => annotation.hide !== true);
|
||||||
if (visibleAnnotations.length > 0) { return true; }
|
if (visibleAnnotations.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
getPanelInfoById(panelId) {
|
getPanelInfoById(panelId) {
|
||||||
var result: any = {};
|
for (let i = 0; i < this.panels.length; i++) {
|
||||||
_.each(this.rows, function(row) {
|
if (this.panels[i].id === panelId) {
|
||||||
_.each(row.panels, function(panel, index) {
|
return {
|
||||||
if (panel.id === panelId) {
|
panel: this.panels[i],
|
||||||
result.panel = panel;
|
index: i,
|
||||||
result.row = row;
|
};
|
||||||
result.index = index;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
_.each(this.panels, function(panel, index) {
|
|
||||||
if (panel.id === panelId) {
|
|
||||||
result.panel = panel;
|
|
||||||
result.index = index;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.panel) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
duplicatePanel(panel) {
|
duplicatePanel(panel) {
|
||||||
const newPanel = _.cloneDeep(panel.getSaveModel());
|
const newPanel = panel.getSaveModel();
|
||||||
newPanel.id = this.getNextPanelId();
|
newPanel.id = this.getNextPanelId();
|
||||||
|
|
||||||
delete newPanel.repeat;
|
delete newPanel.repeat;
|
||||||
@@ -356,7 +360,7 @@ export class DashboardModel {
|
|||||||
delete newPanel.alert;
|
delete newPanel.alert;
|
||||||
|
|
||||||
// does it fit to the right?
|
// does it fit to the right?
|
||||||
if (panel.gridPos.x + (panel.gridPos.w*2) <= COL_COUNT) {
|
if (panel.gridPos.x + panel.gridPos.w * 2 <= GRID_COLUMN_COUNT) {
|
||||||
newPanel.gridPos.x += panel.gridPos.w;
|
newPanel.gridPos.x += panel.gridPos.w;
|
||||||
} else {
|
} else {
|
||||||
// add bellow
|
// add bellow
|
||||||
@@ -372,9 +376,7 @@ export class DashboardModel {
|
|||||||
format = format || 'YYYY-MM-DD HH:mm:ss';
|
format = format || 'YYYY-MM-DD HH:mm:ss';
|
||||||
let timezone = this.getTimezone();
|
let timezone = this.getTimezone();
|
||||||
|
|
||||||
return timezone === 'browser' ?
|
return timezone === 'browser' ? moment(date).format(format) : moment.utc(date).format(format);
|
||||||
moment(date).format(format) :
|
|
||||||
moment.utc(date).format(format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
@@ -407,9 +409,7 @@ export class DashboardModel {
|
|||||||
getRelativeTime(date) {
|
getRelativeTime(date) {
|
||||||
date = moment.isMoment(date) ? date : moment(date);
|
date = moment.isMoment(date) ? date : moment(date);
|
||||||
|
|
||||||
return this.timezone === 'browser' ?
|
return this.timezone === 'browser' ? moment(date).fromNow() : moment.utc(date).fromNow();
|
||||||
moment(date).fromNow() :
|
|
||||||
moment.utc(date).fromNow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextQueryLetter(panel) {
|
getNextQueryLetter(panel) {
|
||||||
@@ -442,7 +442,6 @@ export class DashboardModel {
|
|||||||
|
|
||||||
// version 2 schema changes
|
// version 2 schema changes
|
||||||
if (oldVersion < 2) {
|
if (oldVersion < 2) {
|
||||||
|
|
||||||
if (old.services) {
|
if (old.services) {
|
||||||
if (old.services.filter) {
|
if (old.services.filter) {
|
||||||
this.time = old.services.filter.time;
|
this.time = old.services.filter.time;
|
||||||
@@ -460,7 +459,9 @@ export class DashboardModel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.isBoolean(panel.legend)) { panel.legend = { show: panel.legend }; }
|
if (_.isBoolean(panel.legend)) {
|
||||||
|
panel.legend = {show: panel.legend};
|
||||||
|
}
|
||||||
|
|
||||||
if (panel.grid) {
|
if (panel.grid) {
|
||||||
if (panel.grid.min) {
|
if (panel.grid.min) {
|
||||||
@@ -502,9 +503,11 @@ export class DashboardModel {
|
|||||||
if (oldVersion < 4) {
|
if (oldVersion < 4) {
|
||||||
// move aliasYAxis changes
|
// move aliasYAxis changes
|
||||||
panelUpgrades.push(function(panel) {
|
panelUpgrades.push(function(panel) {
|
||||||
if (panel.type !== 'graph') { return; }
|
if (panel.type !== 'graph') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_.each(panel.aliasYAxis, function(value, key) {
|
_.each(panel.aliasYAxis, function(value, key) {
|
||||||
panel.seriesOverrides = [{ alias: key, yaxis: value }];
|
panel.seriesOverrides = [{alias: key, yaxis: value}];
|
||||||
});
|
});
|
||||||
delete panel.aliasYAxis;
|
delete panel.aliasYAxis;
|
||||||
});
|
});
|
||||||
@@ -512,7 +515,7 @@ export class DashboardModel {
|
|||||||
|
|
||||||
if (oldVersion < 6) {
|
if (oldVersion < 6) {
|
||||||
// move pulldowns to new schema
|
// move pulldowns to new schema
|
||||||
var annotations = _.find(old.pulldowns, { type: 'annotations' });
|
var annotations = _.find(old.pulldowns, {type: 'annotations'});
|
||||||
|
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
this.annotations = {
|
this.annotations = {
|
||||||
@@ -521,12 +524,20 @@ export class DashboardModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update template variables
|
// update template variables
|
||||||
for (i = 0 ; i < this.templating.list.length; i++) {
|
for (i = 0; i < this.templating.list.length; i++) {
|
||||||
var variable = this.templating.list[i];
|
var variable = this.templating.list[i];
|
||||||
if (variable.datasource === void 0) { variable.datasource = null; }
|
if (variable.datasource === void 0) {
|
||||||
if (variable.type === 'filter') { variable.type = 'query'; }
|
variable.datasource = null;
|
||||||
if (variable.type === void 0) { variable.type = 'query'; }
|
}
|
||||||
if (variable.allFormat === void 0) { variable.allFormat = 'glob'; }
|
if (variable.type === 'filter') {
|
||||||
|
variable.type = 'query';
|
||||||
|
}
|
||||||
|
if (variable.type === void 0) {
|
||||||
|
variable.type = 'query';
|
||||||
|
}
|
||||||
|
if (variable.allFormat === void 0) {
|
||||||
|
variable.allFormat = 'glob';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,278 +547,300 @@ export class DashboardModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure query refIds
|
// ensure query refIds
|
||||||
|
panelUpgrades.push(function(panel) {
|
||||||
|
_.each(
|
||||||
|
panel.targets,
|
||||||
|
function(target) {
|
||||||
|
if (!target.refId) {
|
||||||
|
target.refId = this.getNextQueryLetter(panel);
|
||||||
|
}
|
||||||
|
}.bind(this),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 8) {
|
||||||
panelUpgrades.push(function(panel) {
|
panelUpgrades.push(function(panel) {
|
||||||
_.each(panel.targets, function(target) {
|
_.each(panel.targets, function(target) {
|
||||||
if (!target.refId) {
|
// update old influxdb query schema
|
||||||
target.refId = this.getNextQueryLetter(panel);
|
if (target.fields && target.tags && target.groupBy) {
|
||||||
}
|
if (target.rawQuery) {
|
||||||
}.bind(this));
|
delete target.fields;
|
||||||
});
|
delete target.fill;
|
||||||
}
|
} else {
|
||||||
|
target.select = _.map(target.fields, function(field) {
|
||||||
if (oldVersion < 8) {
|
var parts = [];
|
||||||
panelUpgrades.push(function(panel) {
|
parts.push({type: 'field', params: [field.name]});
|
||||||
_.each(panel.targets, function(target) {
|
parts.push({type: field.func, params: []});
|
||||||
// update old influxdb query schema
|
if (field.mathExpr) {
|
||||||
if (target.fields && target.tags && target.groupBy) {
|
parts.push({type: 'math', params: [field.mathExpr]});
|
||||||
if (target.rawQuery) {
|
|
||||||
delete target.fields;
|
|
||||||
delete target.fill;
|
|
||||||
} else {
|
|
||||||
target.select = _.map(target.fields, function(field) {
|
|
||||||
var parts = [];
|
|
||||||
parts.push({type: 'field', params: [field.name]});
|
|
||||||
parts.push({type: field.func, params: []});
|
|
||||||
if (field.mathExpr) {
|
|
||||||
parts.push({type: 'math', params: [field.mathExpr]});
|
|
||||||
}
|
|
||||||
if (field.asExpr) {
|
|
||||||
parts.push({type: 'alias', params: [field.asExpr]});
|
|
||||||
}
|
|
||||||
return parts;
|
|
||||||
});
|
|
||||||
delete target.fields;
|
|
||||||
_.each(target.groupBy, function(part) {
|
|
||||||
if (part.type === 'time' && part.interval) {
|
|
||||||
part.params = [part.interval];
|
|
||||||
delete part.interval;
|
|
||||||
}
|
|
||||||
if (part.type === 'tag' && part.key) {
|
|
||||||
part.params = [part.key];
|
|
||||||
delete part.key;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (target.fill) {
|
|
||||||
target.groupBy.push({type: 'fill', params: [target.fill]});
|
|
||||||
delete target.fill;
|
|
||||||
}
|
}
|
||||||
|
if (field.asExpr) {
|
||||||
|
parts.push({type: 'alias', params: [field.asExpr]});
|
||||||
|
}
|
||||||
|
return parts;
|
||||||
|
});
|
||||||
|
delete target.fields;
|
||||||
|
_.each(target.groupBy, function(part) {
|
||||||
|
if (part.type === 'time' && part.interval) {
|
||||||
|
part.params = [part.interval];
|
||||||
|
delete part.interval;
|
||||||
|
}
|
||||||
|
if (part.type === 'tag' && part.key) {
|
||||||
|
part.params = [part.key];
|
||||||
|
delete part.key;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (target.fill) {
|
||||||
|
target.groupBy.push({type: 'fill', params: [target.fill]});
|
||||||
|
delete target.fill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// schema version 9 changes
|
|
||||||
if (oldVersion < 9) {
|
|
||||||
// move aliasYAxis changes
|
|
||||||
panelUpgrades.push(function(panel) {
|
|
||||||
if (panel.type !== 'singlestat' && panel.thresholds !== "") { return; }
|
|
||||||
|
|
||||||
if (panel.thresholds) {
|
|
||||||
var k = panel.thresholds.split(",");
|
|
||||||
|
|
||||||
if (k.length >= 3) {
|
|
||||||
k.shift();
|
|
||||||
panel.thresholds = k.join(",");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// schema version 10 changes
|
// schema version 9 changes
|
||||||
if (oldVersion < 10) {
|
if (oldVersion < 9) {
|
||||||
// move aliasYAxis changes
|
// move aliasYAxis changes
|
||||||
panelUpgrades.push(function(panel) {
|
panelUpgrades.push(function(panel) {
|
||||||
if (panel.type !== 'table') { return; }
|
if (panel.type !== 'singlestat' && panel.thresholds !== '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_.each(panel.styles, function(style) {
|
if (panel.thresholds) {
|
||||||
if (style.thresholds && style.thresholds.length >= 3) {
|
var k = panel.thresholds.split(',');
|
||||||
var k = style.thresholds;
|
|
||||||
k.shift();
|
|
||||||
style.thresholds = k;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldVersion < 12) {
|
if (k.length >= 3) {
|
||||||
// update template variables
|
k.shift();
|
||||||
_.each(this.templating.list, function(templateVariable) {
|
panel.thresholds = k.join(',');
|
||||||
if (templateVariable.refresh) { templateVariable.refresh = 1; }
|
}
|
||||||
if (!templateVariable.refresh) { templateVariable.refresh = 0; }
|
}
|
||||||
if (templateVariable.hideVariable) {
|
});
|
||||||
templateVariable.hide = 2;
|
}
|
||||||
} else if (templateVariable.hideLabel) {
|
|
||||||
templateVariable.hide = 1;
|
// schema version 10 changes
|
||||||
|
if (oldVersion < 10) {
|
||||||
|
// move aliasYAxis changes
|
||||||
|
panelUpgrades.push(function(panel) {
|
||||||
|
if (panel.type !== 'table') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(panel.styles, function(style) {
|
||||||
|
if (style.thresholds && style.thresholds.length >= 3) {
|
||||||
|
var k = style.thresholds;
|
||||||
|
k.shift();
|
||||||
|
style.thresholds = k;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (oldVersion < 12) {
|
if (oldVersion < 12) {
|
||||||
// update graph yaxes changes
|
// update template variables
|
||||||
panelUpgrades.push(function(panel) {
|
_.each(this.templating.list, function(templateVariable) {
|
||||||
if (panel.type !== 'graph') { return; }
|
if (templateVariable.refresh) {
|
||||||
if (!panel.grid) { return; }
|
templateVariable.refresh = 1;
|
||||||
|
}
|
||||||
|
if (!templateVariable.refresh) {
|
||||||
|
templateVariable.refresh = 0;
|
||||||
|
}
|
||||||
|
if (templateVariable.hideVariable) {
|
||||||
|
templateVariable.hide = 2;
|
||||||
|
} else if (templateVariable.hideLabel) {
|
||||||
|
templateVariable.hide = 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!panel.yaxes) {
|
if (oldVersion < 12) {
|
||||||
panel.yaxes = [
|
// update graph yaxes changes
|
||||||
{
|
panelUpgrades.push(function(panel) {
|
||||||
show: panel['y-axis'],
|
if (panel.type !== 'graph') {
|
||||||
min: panel.grid.leftMin,
|
return;
|
||||||
max: panel.grid.leftMax,
|
}
|
||||||
logBase: panel.grid.leftLogBase,
|
if (!panel.grid) {
|
||||||
format: panel.y_formats[0],
|
return;
|
||||||
label: panel.leftYAxisLabel,
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
show: panel['y-axis'],
|
|
||||||
min: panel.grid.rightMin,
|
|
||||||
max: panel.grid.rightMax,
|
|
||||||
logBase: panel.grid.rightLogBase,
|
|
||||||
format: panel.y_formats[1],
|
|
||||||
label: panel.rightYAxisLabel,
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
panel.xaxis = {
|
if (!panel.yaxes) {
|
||||||
show: panel['x-axis'],
|
panel.yaxes = [
|
||||||
};
|
{
|
||||||
|
show: panel['y-axis'],
|
||||||
|
min: panel.grid.leftMin,
|
||||||
|
max: panel.grid.leftMax,
|
||||||
|
logBase: panel.grid.leftLogBase,
|
||||||
|
format: panel.y_formats[0],
|
||||||
|
label: panel.leftYAxisLabel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
show: panel['y-axis'],
|
||||||
|
min: panel.grid.rightMin,
|
||||||
|
max: panel.grid.rightMax,
|
||||||
|
logBase: panel.grid.rightLogBase,
|
||||||
|
format: panel.y_formats[1],
|
||||||
|
label: panel.rightYAxisLabel,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
delete panel.grid.leftMin;
|
panel.xaxis = {
|
||||||
delete panel.grid.leftMax;
|
show: panel['x-axis'],
|
||||||
delete panel.grid.leftLogBase;
|
};
|
||||||
delete panel.grid.rightMin;
|
|
||||||
delete panel.grid.rightMax;
|
delete panel.grid.leftMin;
|
||||||
delete panel.grid.rightLogBase;
|
delete panel.grid.leftMax;
|
||||||
delete panel.y_formats;
|
delete panel.grid.leftLogBase;
|
||||||
delete panel.leftYAxisLabel;
|
delete panel.grid.rightMin;
|
||||||
delete panel.rightYAxisLabel;
|
delete panel.grid.rightMax;
|
||||||
delete panel['y-axis'];
|
delete panel.grid.rightLogBase;
|
||||||
delete panel['x-axis'];
|
delete panel.y_formats;
|
||||||
|
delete panel.leftYAxisLabel;
|
||||||
|
delete panel.rightYAxisLabel;
|
||||||
|
delete panel['y-axis'];
|
||||||
|
delete panel['x-axis'];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 13) {
|
||||||
|
// update graph yaxes changes
|
||||||
|
panelUpgrades.push(function(panel) {
|
||||||
|
if (panel.type !== 'graph') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!panel.grid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.thresholds = [];
|
||||||
|
var t1: any = {},
|
||||||
|
t2: any = {};
|
||||||
|
|
||||||
|
if (panel.grid.threshold1 !== null) {
|
||||||
|
t1.value = panel.grid.threshold1;
|
||||||
|
if (panel.grid.thresholdLine) {
|
||||||
|
t1.line = true;
|
||||||
|
t1.lineColor = panel.grid.threshold1Color;
|
||||||
|
t1.colorMode = 'custom';
|
||||||
|
} else {
|
||||||
|
t1.fill = true;
|
||||||
|
t1.fillColor = panel.grid.threshold1Color;
|
||||||
|
t1.colorMode = 'custom';
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (oldVersion < 13) {
|
if (panel.grid.threshold2 !== null) {
|
||||||
// update graph yaxes changes
|
t2.value = panel.grid.threshold2;
|
||||||
panelUpgrades.push(function(panel) {
|
if (panel.grid.thresholdLine) {
|
||||||
if (panel.type !== 'graph') { return; }
|
t2.line = true;
|
||||||
if (!panel.grid) { return; }
|
t2.lineColor = panel.grid.threshold2Color;
|
||||||
|
t2.colorMode = 'custom';
|
||||||
panel.thresholds = [];
|
} else {
|
||||||
var t1: any = {}, t2: any = {};
|
t2.fill = true;
|
||||||
|
t2.fillColor = panel.grid.threshold2Color;
|
||||||
if (panel.grid.threshold1 !== null) {
|
t2.colorMode = 'custom';
|
||||||
t1.value = panel.grid.threshold1;
|
|
||||||
if (panel.grid.thresholdLine) {
|
|
||||||
t1.line = true;
|
|
||||||
t1.lineColor = panel.grid.threshold1Color;
|
|
||||||
t1.colorMode = 'custom';
|
|
||||||
} else {
|
|
||||||
t1.fill = true;
|
|
||||||
t1.fillColor = panel.grid.threshold1Color;
|
|
||||||
t1.colorMode = 'custom';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (panel.grid.threshold2 !== null) {
|
if (_.isNumber(t1.value)) {
|
||||||
t2.value = panel.grid.threshold2;
|
if (_.isNumber(t2.value)) {
|
||||||
if (panel.grid.thresholdLine) {
|
if (t1.value > t2.value) {
|
||||||
t2.line = true;
|
t1.op = t2.op = 'lt';
|
||||||
t2.lineColor = panel.grid.threshold2Color;
|
|
||||||
t2.colorMode = 'custom';
|
|
||||||
} else {
|
|
||||||
t2.fill = true;
|
|
||||||
t2.fillColor = panel.grid.threshold2Color;
|
|
||||||
t2.colorMode = 'custom';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_.isNumber(t1.value)) {
|
|
||||||
if (_.isNumber(t2.value)) {
|
|
||||||
if (t1.value > t2.value) {
|
|
||||||
t1.op = t2.op = 'lt';
|
|
||||||
panel.thresholds.push(t1);
|
|
||||||
panel.thresholds.push(t2);
|
|
||||||
} else {
|
|
||||||
t1.op = t2.op = 'gt';
|
|
||||||
panel.thresholds.push(t1);
|
|
||||||
panel.thresholds.push(t2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t1.op = 'gt';
|
|
||||||
panel.thresholds.push(t1);
|
panel.thresholds.push(t1);
|
||||||
|
panel.thresholds.push(t2);
|
||||||
|
} else {
|
||||||
|
t1.op = t2.op = 'gt';
|
||||||
|
panel.thresholds.push(t1);
|
||||||
|
panel.thresholds.push(t2);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t1.op = 'gt';
|
||||||
|
panel.thresholds.push(t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete panel.grid.threshold1;
|
|
||||||
delete panel.grid.threshold1Color;
|
|
||||||
delete panel.grid.threshold2;
|
|
||||||
delete panel.grid.threshold2Color;
|
|
||||||
delete panel.grid.thresholdLine;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldVersion < 14) {
|
|
||||||
this.graphTooltip = old.sharedCrosshair ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldVersion < 16) {
|
|
||||||
this.upgradeToGridLayout(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (panelUpgrades.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < this.panels.length; j++) {
|
|
||||||
for (k = 0; k < panelUpgrades.length; k++) {
|
|
||||||
panelUpgrades[k].call(this, this.panels[j]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
delete panel.grid.threshold1;
|
||||||
|
delete panel.grid.threshold1Color;
|
||||||
|
delete panel.grid.threshold2;
|
||||||
|
delete panel.grid.threshold2Color;
|
||||||
|
delete panel.grid.thresholdLine;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeToGridLayout(old) {
|
if (oldVersion < 14) {
|
||||||
let yPos = 0;
|
this.graphTooltip = old.sharedCrosshair ? 1 : 0;
|
||||||
//let rowIds = 1000;
|
}
|
||||||
|
|
||||||
|
if (oldVersion < 16) {
|
||||||
|
this.upgradeToGridLayout(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panelUpgrades.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < this.panels.length; j++) {
|
||||||
|
for (k = 0; k < panelUpgrades.length; k++) {
|
||||||
|
panelUpgrades[k].call(this, this.panels[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
upgradeToGridLayout(old) {
|
||||||
|
let yPos = 0;
|
||||||
|
let widthFactor = GRID_COLUMN_COUNT / 12;
|
||||||
|
//let rowIds = 1000;
|
||||||
|
//
|
||||||
|
|
||||||
|
if (!old.rows) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let row of old.rows) {
|
||||||
|
let xPos = 0;
|
||||||
|
let height: any = row.height || 250;
|
||||||
|
|
||||||
|
// if (this.meta.keepRows) {
|
||||||
|
// this.panels.push({
|
||||||
|
// id: rowIds++,
|
||||||
|
// type: 'row',
|
||||||
|
// title: row.title,
|
||||||
|
// x: 0,
|
||||||
|
// y: yPos,
|
||||||
|
// height: 1,
|
||||||
|
// width: 12
|
||||||
|
// });
|
||||||
//
|
//
|
||||||
|
// yPos += 1;
|
||||||
|
// }
|
||||||
|
|
||||||
if (!old.rows) {
|
if (_.isString(height)) {
|
||||||
return;
|
height = parseInt(height.replace('px', ''), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let row of old.rows) {
|
const rowGridHeight = Math.ceil(height / GRID_CELL_HEIGHT);
|
||||||
let xPos = 0;
|
|
||||||
let height: any = row.height || 250;
|
|
||||||
|
|
||||||
// if (this.meta.keepRows) {
|
for (let panel of row.panels) {
|
||||||
// this.panels.push({
|
const panelWidth = Math.floor(panel.span) * widthFactor;
|
||||||
// id: rowIds++,
|
|
||||||
// type: 'row',
|
|
||||||
// title: row.title,
|
|
||||||
// x: 0,
|
|
||||||
// y: yPos,
|
|
||||||
// height: 1,
|
|
||||||
// width: 12
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// yPos += 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (_.isString(height)) {
|
// should wrap to next row?
|
||||||
height = parseInt(height.replace('px', ''), 10);
|
if (xPos + panelWidth >= GRID_COLUMN_COUNT) {
|
||||||
|
yPos += rowGridHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rowGridHeight = Math.ceil(height / CELL_HEIGHT);
|
panel.gridPos = {x: xPos, y: yPos, w: panelWidth, h: rowGridHeight};
|
||||||
|
|
||||||
for (let panel of row.panels) {
|
delete panel.span;
|
||||||
// should wrap to next row?
|
|
||||||
if (xPos + panel.span >= 12) {
|
|
||||||
yPos += rowGridHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel.gridPos = { x: xPos, y: yPos, w: panel.span, h: rowGridHeight };
|
xPos += panel.gridPos.w;
|
||||||
|
|
||||||
delete panel.span;
|
this.panels.push(new PanelModel(panel));
|
||||||
|
|
||||||
xPos += panel.gridPos.w;
|
|
||||||
|
|
||||||
this.panels.push(new PanelModel(panel));
|
|
||||||
}
|
|
||||||
|
|
||||||
yPos += rowGridHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yPos += rowGridHeight;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
import ReactGridLayout from 'react-grid-layout';
|
import ReactGridLayout from 'react-grid-layout';
|
||||||
import {CELL_HEIGHT, CELL_VMARGIN} from '../dashboard_model';
|
import {GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT} from 'app/core/constants';
|
||||||
import {DashboardPanel} from './DashboardPanel';
|
import {DashboardPanel} from './DashboardPanel';
|
||||||
import {DashboardModel} from '../dashboard_model';
|
import {DashboardModel} from '../dashboard_model';
|
||||||
import {PanelContainer} from './PanelContainer';
|
import {PanelContainer} from './PanelContainer';
|
||||||
@@ -9,7 +9,6 @@ import {PanelModel} from '../panel_model';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import sizeMe from 'react-sizeme';
|
import sizeMe from 'react-sizeme';
|
||||||
|
|
||||||
const COLUMN_COUNT = 12;
|
|
||||||
let lastGridWidth = 1200;
|
let lastGridWidth = 1200;
|
||||||
|
|
||||||
function GridWrapper({size, layout, onLayoutChange, children, onResize, onResizeStop, onWidthChange}) {
|
function GridWrapper({size, layout, onLayoutChange, children, onResize, onResizeStop, onWidthChange}) {
|
||||||
@@ -32,9 +31,9 @@ function GridWrapper({size, layout, onLayoutChange, children, onResize, onResize
|
|||||||
measureBeforeMount={false}
|
measureBeforeMount={false}
|
||||||
containerPadding={[0, 0]}
|
containerPadding={[0, 0]}
|
||||||
useCSSTransforms={false}
|
useCSSTransforms={false}
|
||||||
margin={[CELL_VMARGIN, CELL_VMARGIN]}
|
margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
|
||||||
cols={COLUMN_COUNT}
|
cols={GRID_COLUMN_COUNT}
|
||||||
rowHeight={CELL_HEIGHT}
|
rowHeight={GRID_CELL_HEIGHT}
|
||||||
draggableHandle=".grid-drag-handle"
|
draggableHandle=".grid-drag-handle"
|
||||||
layout={layout}
|
layout={layout}
|
||||||
onResize={onResize}
|
onResize={onResize}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
///<reference path="../../../headers/common.d.ts" />
|
|
||||||
|
|
||||||
import {coreModule} from 'app/core/core';
|
import {coreModule} from 'app/core/core';
|
||||||
|
|
||||||
var template = `
|
var template = `
|
||||||
<div class="gf-form-select-wrapper max-width-13">
|
<div class="gf-form-select-wrapper max-width-13">
|
||||||
<select class="gf-form-input" ng-model="model.repeat" ng-options="f.value as f.text for f in variables">
|
<select class="gf-form-input" ng-model="model.repeat" ng-options="f.value as f.text for f in variables" ng-change="optionChanged()">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -29,6 +27,17 @@ function dashRepeatOptionDirective(variableSrv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scope.variables.unshift({text: 'Disabled', value: null});
|
scope.variables.unshift({text: 'Disabled', value: null});
|
||||||
|
|
||||||
|
// if repeat is set and no direction set to horizontal
|
||||||
|
if (scope.panel.repeat && !scope.panel.repeatDirection) {
|
||||||
|
scope.panel.repeatDirection = 'h';
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.optionChanged = function() {
|
||||||
|
if (scope.panel.repeat) {
|
||||||
|
scope.panel.repeatDirection = 'h';
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,20 +400,126 @@ describe('DashboardModel', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('updateSubmenuVisibility with hidden annotation toggle', function() {
|
describe('updateSubmenuVisibility with hidden annotation toggle', function() {
|
||||||
var model;
|
var dashboard;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
model = new DashboardModel({
|
dashboard = new DashboardModel({
|
||||||
annotations: {
|
annotations: {
|
||||||
list: [{hide: true}]
|
list: [{hide: true}]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
model.updateSubmenuVisibility();
|
dashboard.updateSubmenuVisibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not enable submmenu', function() {
|
it('should not enable submmenu', function() {
|
||||||
expect(model.meta.submenuEnabled).to.be(false);
|
expect(dashboard.meta.submenuEnabled).to.be(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('given dashboard with panel repeat', function(ctx) {
|
||||||
|
var dashboard;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
dashboard = new DashboardModel({
|
||||||
|
panels: [{id: 2, repeat: 'apps'}],
|
||||||
|
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 repeat panel 3 times', function() {
|
||||||
|
expect(dashboard.panels.length).to.be(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mark panel repeated', function() {
|
||||||
|
expect(dashboard.panels[0].repeat).to.be('apps');
|
||||||
|
expect(dashboard.panels[1].repeatPanelId).to.be(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set scopedVars on panels', function() {
|
||||||
|
expect(dashboard.panels[0].scopedVars.apps.value).to.be('se1');
|
||||||
|
expect(dashboard.panels[1].scopedVars.apps.value).to.be('se2');
|
||||||
|
expect(dashboard.panels[2].scopedVars.apps.value).to.be('se3');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration', function() {
|
||||||
|
var repeatedPanelAfterIteration1;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
repeatedPanelAfterIteration1 = dashboard.panels[1];
|
||||||
|
dashboard.panels[0].fill = 10;
|
||||||
|
dashboard.processRepeats();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('reused panel should copy properties from source', function() {
|
||||||
|
expect(dashboard.panels[1].fill).to.be(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have same panel count', function() {
|
||||||
|
expect(dashboard.panels.length).to.be(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration with different variable', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
dashboard.templating.list.push({
|
||||||
|
name: 'server',
|
||||||
|
current: { text: 'se1, se2, se3', value: ['se1']},
|
||||||
|
options: [{text: 'se1', value: 'se1', selected: true}]
|
||||||
|
});
|
||||||
|
dashboard.panels[0].repeat = "server";
|
||||||
|
dashboard.processRepeats();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove scopedVars value for last variable', function() {
|
||||||
|
expect(dashboard.panels[0].scopedVars.apps).to.be(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have new variable value in scopedVars', function() {
|
||||||
|
expect(dashboard.panels[0].scopedVars.server.value).to.be("se1");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration and selected values reduced', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
dashboard.templating.list[0].options[1].selected = false;
|
||||||
|
dashboard.processRepeats();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clean up repeated panel', function() {
|
||||||
|
expect(dashboard.panels.length).to.be(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('After a second iteration and panel repeat is turned off', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
dashboard.panels[0].repeat = null;
|
||||||
|
dashboard.processRepeats();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clean up repeated panel', function() {
|
||||||
|
expect(dashboard.panels.length).to.be(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove scoped vars from reused panel', function() {
|
||||||
|
expect(dashboard.panels[0].scopedVars).to.be(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,287 +0,0 @@
|
|||||||
// import {describe, beforeEach, it, expect, angularMocks} from 'test/lib/common';
|
|
||||||
//
|
|
||||||
// import '../dashboard_srv';
|
|
||||||
// import {DynamicDashboardSrv} from '../dynamic_dashboard_srv';
|
|
||||||
//
|
|
||||||
// function dynamicDashScenario(desc, func) {
|
|
||||||
//
|
|
||||||
// describe.skip(desc, function() {
|
|
||||||
// var ctx: any = {};
|
|
||||||
//
|
|
||||||
// ctx.setup = function (setupFunc) {
|
|
||||||
//
|
|
||||||
// beforeEach(angularMocks.module('grafana.core'));
|
|
||||||
// beforeEach(angularMocks.module('grafana.services'));
|
|
||||||
// beforeEach(angularMocks.module(function($provide) {
|
|
||||||
// $provide.value('contextSrv', {
|
|
||||||
// user: { timezone: 'utc'}
|
|
||||||
// });
|
|
||||||
// }));
|
|
||||||
//
|
|
||||||
// beforeEach(angularMocks.inject(function(dashboardSrv) {
|
|
||||||
// ctx.dashboardSrv = dashboardSrv;
|
|
||||||
//
|
|
||||||
// var model = {
|
|
||||||
// rows: [],
|
|
||||||
// templating: { list: [] }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// setupFunc(model);
|
|
||||||
// ctx.dash = ctx.dashboardSrv.create(model);
|
|
||||||
// ctx.dynamicDashboardSrv = new DynamicDashboardSrv();
|
|
||||||
// ctx.dynamicDashboardSrv.init(ctx.dash);
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// ctx.rows = ctx.dash.rows;
|
|
||||||
// }));
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// func(ctx);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// dynamicDashScenario('given dashboard with panel repeat', function(ctx) {
|
|
||||||
// ctx.setup(function(dash) {
|
|
||||||
// dash.rows.push({
|
|
||||||
// panels: [{id: 2, repeat: 'apps'}]
|
|
||||||
// });
|
|
||||||
// dash.templating.list.push({
|
|
||||||
// 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}
|
|
||||||
// ]
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should repeat panel one time', function() {
|
|
||||||
// expect(ctx.rows[0].panels.length).to.be(3);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should mark panel repeated', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].repeat).to.be('apps');
|
|
||||||
// expect(ctx.rows[0].panels[1].repeatPanelId).to.be(2);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should set scopedVars on panels', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars.apps.value).to.be('se1');
|
|
||||||
// expect(ctx.rows[0].panels[1].scopedVars.apps.value).to.be('se2');
|
|
||||||
// expect(ctx.rows[0].panels[2].scopedVars.apps.value).to.be('se3');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration', function() {
|
|
||||||
// var repeatedPanelAfterIteration1;
|
|
||||||
//
|
|
||||||
// beforeEach(function() {
|
|
||||||
// repeatedPanelAfterIteration1 = ctx.rows[0].panels[1];
|
|
||||||
// ctx.rows[0].panels[0].fill = 10;
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should have reused same panel instances', function() {
|
|
||||||
// expect(ctx.rows[0].panels[1]).to.be(repeatedPanelAfterIteration1);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('reused panel should copy properties from source', function() {
|
|
||||||
// expect(ctx.rows[0].panels[1].fill).to.be(10);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should have same panel count', function() {
|
|
||||||
// expect(ctx.rows[0].panels.length).to.be(3);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration with different variable', function() {
|
|
||||||
// beforeEach(function() {
|
|
||||||
// ctx.dash.templating.list.push({
|
|
||||||
// name: 'server',
|
|
||||||
// current: { text: 'se1, se2, se3', value: ['se1']},
|
|
||||||
// options: [{text: 'se1', value: 'se1', selected: true}]
|
|
||||||
// });
|
|
||||||
// ctx.rows[0].panels[0].repeat = "server";
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should remove scopedVars value for last variable', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars.apps).to.be(undefined);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should have new variable value in scopedVars', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars.server.value).to.be("se1");
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration and selected values reduced', function() {
|
|
||||||
// beforeEach(function() {
|
|
||||||
// ctx.dash.templating.list[0].options[1].selected = false;
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should clean up repeated panel', function() {
|
|
||||||
// expect(ctx.rows[0].panels.length).to.be(2);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration and panel repeat is turned off', function() {
|
|
||||||
// beforeEach(function() {
|
|
||||||
// ctx.rows[0].panels[0].repeat = null;
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should clean up repeated panel', function() {
|
|
||||||
// expect(ctx.rows[0].panels.length).to.be(1);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should remove scoped vars from reused panel', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars).to.be(undefined);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// dynamicDashScenario('given dashboard with row repeat', function(ctx) {
|
|
||||||
// ctx.setup(function(dash) {
|
|
||||||
// dash.rows.push({
|
|
||||||
// repeat: 'servers',
|
|
||||||
// panels: [{id: 2}]
|
|
||||||
// });
|
|
||||||
// dash.rows.push({panels: []});
|
|
||||||
// dash.templating.list.push({
|
|
||||||
// name: 'servers',
|
|
||||||
// current: {
|
|
||||||
// text: 'se1, se2',
|
|
||||||
// value: ['se1', 'se2']
|
|
||||||
// },
|
|
||||||
// options: [
|
|
||||||
// {text: 'se1', value: 'se1', selected: true},
|
|
||||||
// {text: 'se2', value: 'se2', selected: true},
|
|
||||||
// ]
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should repeat row one time', function() {
|
|
||||||
// expect(ctx.rows.length).to.be(3);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should keep panel ids on first row', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].id).to.be(2);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should keep first row as repeat', function() {
|
|
||||||
// expect(ctx.rows[0].repeat).to.be('servers');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should clear repeat field on repeated row', function() {
|
|
||||||
// expect(ctx.rows[1].repeat).to.be(null);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should add scopedVars to rows', function() {
|
|
||||||
// expect(ctx.rows[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
// expect(ctx.rows[1].scopedVars.servers.value).to.be('se2');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should generate a repeartRowId based on repeat row index', function() {
|
|
||||||
// expect(ctx.rows[1].repeatRowId).to.be(1);
|
|
||||||
// expect(ctx.rows[1].repeatIteration).to.be(ctx.dynamicDashboardSrv.iteration);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should set scopedVars on row panels', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
// expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration', function() {
|
|
||||||
// var repeatedRowAfterFirstIteration;
|
|
||||||
//
|
|
||||||
// beforeEach(function() {
|
|
||||||
// repeatedRowAfterFirstIteration = ctx.rows[1];
|
|
||||||
// ctx.rows[0].height = 500;
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should still only have 2 rows', function() {
|
|
||||||
// expect(ctx.rows.length).to.be(3);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it.skip('should have updated props from source', function() {
|
|
||||||
// expect(ctx.rows[1].height).to.be(500);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should reuse row instance', function() {
|
|
||||||
// expect(ctx.rows[1]).to.be(repeatedRowAfterFirstIteration);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('After a second iteration and selected values reduced', function() {
|
|
||||||
// beforeEach(function() {
|
|
||||||
// ctx.dash.templating.list[0].options[1].selected = false;
|
|
||||||
// ctx.dynamicDashboardSrv.process();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should remove repeated second row', function() {
|
|
||||||
// expect(ctx.rows.length).to.be(2);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// dynamicDashScenario('given dashboard with row repeat and panel repeat', function(ctx) {
|
|
||||||
// ctx.setup(function(dash) {
|
|
||||||
// dash.rows.push({
|
|
||||||
// repeat: 'servers',
|
|
||||||
// panels: [{id: 2, repeat: 'metric'}]
|
|
||||||
// });
|
|
||||||
// dash.templating.list.push({
|
|
||||||
// name: 'servers',
|
|
||||||
// current: { text: 'se1, se2', value: ['se1', 'se2'] },
|
|
||||||
// options: [
|
|
||||||
// {text: 'se1', value: 'se1', selected: true},
|
|
||||||
// {text: 'se2', value: 'se2', selected: true},
|
|
||||||
// ]
|
|
||||||
// });
|
|
||||||
// dash.templating.list.push({
|
|
||||||
// name: 'metric',
|
|
||||||
// current: { text: 'm1, m2', value: ['m1', 'm2'] },
|
|
||||||
// options: [
|
|
||||||
// {text: 'm1', value: 'm1', selected: true},
|
|
||||||
// {text: 'm2', value: 'm2', selected: true},
|
|
||||||
// ]
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should repeat row one time', function() {
|
|
||||||
// expect(ctx.rows.length).to.be(2);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should repeat panel on both rows', function() {
|
|
||||||
// expect(ctx.rows[0].panels.length).to.be(2);
|
|
||||||
// expect(ctx.rows[1].panels.length).to.be(2);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should keep panel ids on first row', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].id).to.be(2);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should mark second row as repeated', function() {
|
|
||||||
// expect(ctx.rows[0].repeat).to.be('servers');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should clear repeat field on repeated row', function() {
|
|
||||||
// expect(ctx.rows[1].repeat).to.be(null);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should generate a repeartRowId based on repeat row index', function() {
|
|
||||||
// expect(ctx.rows[1].repeatRowId).to.be(1);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should set scopedVars on row panels', function() {
|
|
||||||
// expect(ctx.rows[0].panels[0].scopedVars.servers.value).to.be('se1');
|
|
||||||
// expect(ctx.rows[1].panels[0].scopedVars.servers.value).to.be('se2');
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import {appEvents, profiler} from 'app/core/core';
|
import {appEvents, profiler} from 'app/core/core';
|
||||||
import Remarkable from 'remarkable';
|
import Remarkable from 'remarkable';
|
||||||
import {CELL_HEIGHT, CELL_VMARGIN} from '../dashboard/dashboard_model';
|
import {GRID_CELL_HEIGHT, GRID_CELL_VMARGIN} from 'app/core/constants';
|
||||||
|
|
||||||
const TITLE_HEIGHT = 25;
|
const TITLE_HEIGHT = 25;
|
||||||
const EMPTY_TITLE_HEIGHT = 9;
|
const EMPTY_TITLE_HEIGHT = 9;
|
||||||
@@ -163,7 +163,7 @@ export class PanelCtrl {
|
|||||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||||
this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
||||||
} else {
|
} else {
|
||||||
this.containerHeight = this.panel.gridPos.h * CELL_HEIGHT + ((this.panel.gridPos.h-1) * CELL_VMARGIN);
|
this.containerHeight = this.panel.gridPos.h * GRID_CELL_HEIGHT + ((this.panel.gridPos.h-1) * GRID_CELL_VMARGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.height = this.containerHeight - (PANEL_BORDER + PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
|
this.height = this.containerHeight - (PANEL_BORDER + PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
|
||||||
|
|||||||
@@ -9,24 +9,24 @@
|
|||||||
<span class="gf-form-label width-7">Description</span>
|
<span class="gf-form-label width-7">Description</span>
|
||||||
<textarea class="gf-form-input width-25" rows="3" ng-model="ctrl.panel.description" placeholder="Panel description, supports markdown & links"></textarea>
|
<textarea class="gf-form-input width-25" rows="3" ng-model="ctrl.panel.description" placeholder="Panel description, supports markdown & links"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
<gf-form-switch class="gf-form" label-class="width-7" switch-class="max-width-6" label="Transparent" checked="ctrl.panel.transparent" on-change="ctrl.render()"></gf-form-switch>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section gf-form-group">
|
<div class="section gf-form-group">
|
||||||
<h5 class="section-heading">Options</h5>
|
<h5 class="section-heading">Repeat</h5>
|
||||||
<gf-form-switch class="gf-form" label-class="width-8" switch-class="max-width-6" label="Transparent" checked="ctrl.panel.transparent" on-change="ctrl.render()"></gf-form-switch>
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label width-8">Repeat Panel</span>
|
<span class="gf-form-label width-9">For each value of</span>
|
||||||
<dash-repeat-option model="ctrl.panel"></dash-repeat-option>
|
<dash-repeat-option model="ctrl.panel"></dash-repeat-option>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form" ng-show="ctrl.panel.repeat">
|
||||||
<span class="gf-form-label width-8">Min width</span>
|
<span class="gf-form-label width-9">Min width</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]">
|
<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]">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form" ng-show="ctrl.panel.repeat">
|
||||||
<span class="gf-form-label width-8">Direction</span>
|
<span class="gf-form-label width-9">Direction</span>
|
||||||
<select class="gf-form-input" ng-model="ctrl.panel.repeatDirection" ng-options="f for f in ['X', 'Y']">
|
<select class="gf-form-input" ng-model="ctrl.panel.repeatDirection" ng-options="f.value as f.text for f in [{value: 'v', text: 'Vertical'}, {value: 'h', text: 'Horizontal'}]">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
"transparent": true,
|
"transparent": true,
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
"w": 12,
|
"w": 24,
|
||||||
"h": 2,
|
"h": 3,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 0
|
"y": 0
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"transparent": false,
|
"transparent": false,
|
||||||
"type": "dashlist",
|
"type": "dashlist",
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
"w": 7,
|
"w": 12,
|
||||||
"h": 17,
|
"h": 17,
|
||||||
"x": 0,
|
"x": 0,
|
||||||
"y": 6
|
"y": 6
|
||||||
@@ -57,9 +57,9 @@
|
|||||||
"transparent": false,
|
"transparent": false,
|
||||||
"type": "pluginlist",
|
"type": "pluginlist",
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
"w": 5,
|
"w": 12,
|
||||||
"h": 17,
|
"h": 17,
|
||||||
"x": 7,
|
"x": 12,
|
||||||
"y": 6
|
"y": 6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user