mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Fix variables values passing when both repeat rows and panels is used (#10488)
* dashboard: repeat rows and panels tests * fix variable values passing when both repeat rows and panels is used
This commit is contained in:
parent
b76958f07b
commit
bfd7e1043b
@ -230,10 +230,6 @@ export class DashboardModel {
|
||||
}
|
||||
|
||||
cleanUpRepeats() {
|
||||
this.processRepeats(true);
|
||||
}
|
||||
|
||||
processRepeats(cleanUpOnly?: boolean) {
|
||||
if (this.snapshot || this.templating.list.length === 0) {
|
||||
return;
|
||||
}
|
||||
@ -248,11 +244,7 @@ export class DashboardModel {
|
||||
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
let panel = this.panels[i];
|
||||
if (panel.repeat) {
|
||||
if (!cleanUpOnly) {
|
||||
this.repeatPanel(panel, i);
|
||||
}
|
||||
} else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
|
||||
if ((!panel.repeat || panel.repeatedByRow) && panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
|
||||
panelsToRemove.push(panel);
|
||||
}
|
||||
}
|
||||
@ -264,6 +256,26 @@ export class DashboardModel {
|
||||
this.events.emit('repeats-processed');
|
||||
}
|
||||
|
||||
processRepeats(cleanUpOnly?: boolean) {
|
||||
if (this.snapshot || this.templating.list.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cleanUpRepeats();
|
||||
|
||||
this.iteration = (this.iteration || new Date().getTime()) + 1;
|
||||
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
let panel = this.panels[i];
|
||||
if (panel.repeat) {
|
||||
this.repeatPanel(panel, i);
|
||||
}
|
||||
}
|
||||
|
||||
this.sortPanelsByGridPos();
|
||||
this.events.emit('repeats-processed');
|
||||
}
|
||||
|
||||
getPanelRepeatClone(sourcePanel, valueIndex, sourcePanelIndex) {
|
||||
// if first clone return source
|
||||
if (valueIndex === 0) {
|
||||
@ -282,21 +294,21 @@ export class DashboardModel {
|
||||
return clone;
|
||||
}
|
||||
|
||||
getRowRepeatClone(sourcePanel, valueIndex, sourcePanelIndex) {
|
||||
getRowRepeatClone(sourceRowPanel, valueIndex, sourcePanelIndex) {
|
||||
// if first clone return source
|
||||
if (valueIndex === 0) {
|
||||
if (!sourcePanel.collapsed) {
|
||||
if (!sourceRowPanel.collapsed) {
|
||||
let rowPanels = this.getRowPanels(sourcePanelIndex);
|
||||
sourcePanel.panels = rowPanels;
|
||||
sourceRowPanel.panels = rowPanels;
|
||||
}
|
||||
return sourcePanel;
|
||||
return sourceRowPanel;
|
||||
}
|
||||
|
||||
let clone = new PanelModel(sourcePanel.getSaveModel());
|
||||
let clone = new PanelModel(sourceRowPanel.getSaveModel());
|
||||
// for row clones we need to figure out panels under row to clone and where to insert clone
|
||||
let rowPanels, insertPos;
|
||||
if (sourcePanel.collapsed) {
|
||||
rowPanels = _.cloneDeep(sourcePanel.panels);
|
||||
if (sourceRowPanel.collapsed) {
|
||||
rowPanels = _.cloneDeep(sourceRowPanel.panels);
|
||||
clone.panels = rowPanels;
|
||||
// insert copied row after preceding row
|
||||
insertPos = sourcePanelIndex + valueIndex;
|
||||
@ -333,7 +345,7 @@ export class DashboardModel {
|
||||
let copy;
|
||||
|
||||
copy = this.getPanelRepeatClone(panel, index, panelIndex);
|
||||
copy.scopedVars = {};
|
||||
copy.scopedVars = copy.scopedVars || {};
|
||||
copy.scopedVars[variable.name] = option;
|
||||
|
||||
if (panel.repeatDirection === REPEAT_DIR_VERTICAL) {
|
||||
@ -342,7 +354,6 @@ export class DashboardModel {
|
||||
} 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 / selectedOptions.length, minWidth);
|
||||
copy.gridPos.x = xPos;
|
||||
copy.gridPos.y = yPos;
|
||||
@ -363,7 +374,7 @@ export class DashboardModel {
|
||||
let yPos = panel.gridPos.y;
|
||||
|
||||
function setScopedVars(panel, variableOption) {
|
||||
panel.scopedVars = {};
|
||||
panel.scopedVars = panel.scopedVars || {};
|
||||
panel.scopedVars[variable.name] = variableOption;
|
||||
}
|
||||
|
||||
@ -381,7 +392,7 @@ export class DashboardModel {
|
||||
_.each(rowPanels, (rowPanel, i) => {
|
||||
setScopedVars(rowPanel, option);
|
||||
if (optionIndex > 0) {
|
||||
this.updateRepeatedPanelIds(rowPanel);
|
||||
this.updateRepeatedPanelIds(rowPanel, true);
|
||||
}
|
||||
});
|
||||
rowCopy.gridPos.y += optionIndex;
|
||||
@ -394,7 +405,7 @@ export class DashboardModel {
|
||||
setScopedVars(rowPanel, option);
|
||||
if (optionIndex > 0) {
|
||||
let cloneRowPanel = new PanelModel(rowPanel);
|
||||
this.updateRepeatedPanelIds(cloneRowPanel);
|
||||
this.updateRepeatedPanelIds(cloneRowPanel, true);
|
||||
// For exposed row additionally set proper Y grid position and add it to dashboard panels
|
||||
cloneRowPanel.gridPos.y += rowHeight * optionIndex;
|
||||
this.panels.splice(insertPos + i, 0, cloneRowPanel);
|
||||
@ -413,11 +424,15 @@ export class DashboardModel {
|
||||
}
|
||||
}
|
||||
|
||||
updateRepeatedPanelIds(panel: PanelModel) {
|
||||
updateRepeatedPanelIds(panel: PanelModel, repeatedByRow?: boolean) {
|
||||
panel.repeatPanelId = panel.id;
|
||||
panel.id = this.getNextPanelId();
|
||||
panel.repeatIteration = this.iteration;
|
||||
panel.repeat = null;
|
||||
if (repeatedByRow) {
|
||||
panel.repeatedByRow = true;
|
||||
} else {
|
||||
panel.repeat = null;
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ export class PanelModel {
|
||||
repeatIteration?: number;
|
||||
repeatPanelId?: number;
|
||||
repeatDirection?: string;
|
||||
repeatedByRow?: boolean;
|
||||
minSpan?: number;
|
||||
collapsed?: boolean;
|
||||
panels?: any;
|
||||
|
@ -382,3 +382,132 @@ describe('given dashboard with row repeat', function() {
|
||||
expect(panel_ids.length).toEqual(_.uniq(panel_ids).length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('given dashboard with row and panel repeat', () => {
|
||||
let dashboard, dashboardJSON;
|
||||
|
||||
beforeEach(() => {
|
||||
dashboardJSON = {
|
||||
panels: [
|
||||
{
|
||||
id: 1,
|
||||
type: 'row',
|
||||
repeat: 'region',
|
||||
gridPos: { x: 0, y: 0, h: 1, w: 24 },
|
||||
},
|
||||
{ id: 2, type: 'graph', repeat: 'app', gridPos: { x: 0, y: 1, h: 1, w: 6 } },
|
||||
],
|
||||
templating: {
|
||||
list: [
|
||||
{
|
||||
name: 'region',
|
||||
current: {
|
||||
text: 'reg1, reg2',
|
||||
value: ['reg1', 'reg2'],
|
||||
},
|
||||
options: [
|
||||
{ text: 'reg1', value: 'reg1', selected: true },
|
||||
{ text: 'reg2', value: 'reg2', selected: true },
|
||||
{ text: 'reg3', value: 'reg3', selected: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'app',
|
||||
current: {
|
||||
text: 'se1, se2',
|
||||
value: ['se1', 'se2'],
|
||||
},
|
||||
options: [
|
||||
{ text: 'se1', value: 'se1', selected: true },
|
||||
{ text: 'se2', value: 'se2', selected: true },
|
||||
{ text: 'se3', value: 'se3', selected: false },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
});
|
||||
|
||||
it('should repeat row and panels for each row', () => {
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
});
|
||||
|
||||
it('should clean up old repeated panels', () => {
|
||||
dashboardJSON.panels = [
|
||||
{
|
||||
id: 1,
|
||||
type: 'row',
|
||||
repeat: 'region',
|
||||
gridPos: { x: 0, y: 0, h: 1, w: 24 },
|
||||
},
|
||||
{ id: 2, type: 'graph', repeat: 'app', gridPos: { x: 0, y: 1, h: 1, w: 6 } },
|
||||
{ id: 3, type: 'graph', repeatPanelId: 2, repeatIteration: 101, gridPos: { x: 7, y: 1, h: 1, w: 6 } },
|
||||
{
|
||||
id: 11,
|
||||
type: 'row',
|
||||
repeatPanelId: 1,
|
||||
repeatIteration: 101,
|
||||
gridPos: { x: 0, y: 2, h: 1, w: 24 },
|
||||
},
|
||||
{ id: 12, type: 'graph', repeatPanelId: 2, repeatIteration: 101, gridPos: { x: 0, y: 3, h: 1, w: 6 } },
|
||||
];
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
const panel_types = _.map(dashboard.panels, 'type');
|
||||
expect(panel_types).toEqual(['row', 'graph', 'graph', 'row', 'graph', 'graph']);
|
||||
});
|
||||
|
||||
it('should set scopedVars for each row', () => {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
expect(dashboard.panels[0].scopedVars).toMatchObject({
|
||||
region: { text: 'reg1', value: 'reg1' },
|
||||
});
|
||||
expect(dashboard.panels[3].scopedVars).toMatchObject({
|
||||
region: { text: 'reg2', value: 'reg2' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should set panel-repeat variable for each panel', () => {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
expect(dashboard.panels[1].scopedVars).toMatchObject({
|
||||
app: { text: 'se1', value: 'se1' },
|
||||
});
|
||||
expect(dashboard.panels[2].scopedVars).toMatchObject({
|
||||
app: { text: 'se2', value: 'se2' },
|
||||
});
|
||||
|
||||
expect(dashboard.panels[4].scopedVars).toMatchObject({
|
||||
app: { text: 'se1', value: 'se1' },
|
||||
});
|
||||
expect(dashboard.panels[5].scopedVars).toMatchObject({
|
||||
app: { text: 'se2', value: 'se2' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should set row-repeat variable for each panel', () => {
|
||||
dashboard = new DashboardModel(dashboardJSON);
|
||||
dashboard.processRepeats();
|
||||
|
||||
expect(dashboard.panels[1].scopedVars).toMatchObject({
|
||||
region: { text: 'reg1', value: 'reg1' },
|
||||
});
|
||||
expect(dashboard.panels[2].scopedVars).toMatchObject({
|
||||
region: { text: 'reg1', value: 'reg1' },
|
||||
});
|
||||
|
||||
expect(dashboard.panels[4].scopedVars).toMatchObject({
|
||||
region: { text: 'reg2', value: 'reg2' },
|
||||
});
|
||||
expect(dashboard.panels[5].scopedVars).toMatchObject({
|
||||
region: { text: 'reg2', value: 'reg2' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user