mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
grid: progress on new grid, resize & saving layouts works
This commit is contained in:
parent
207773e07e
commit
10a3504309
@ -1,11 +1,62 @@
|
||||
import {Emitter} from 'app/core/core';
|
||||
|
||||
export interface PanelModel {
|
||||
id: number;
|
||||
export interface GridPos {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
type: string;
|
||||
title: string;
|
||||
w: number;
|
||||
h: number;
|
||||
}
|
||||
|
||||
const notPersistedProperties: {[str: string]: boolean} = {
|
||||
"model": true,
|
||||
"events": true,
|
||||
};
|
||||
|
||||
export class PanelModel {
|
||||
id: number;
|
||||
gridPos: GridPos;
|
||||
type: string;
|
||||
title: string;
|
||||
events: Emitter;
|
||||
|
||||
constructor(private model) {
|
||||
// copy properties from persisted model
|
||||
for (var property in model) {
|
||||
this[property] = model[property];
|
||||
}
|
||||
|
||||
this.events = new Emitter();
|
||||
}
|
||||
|
||||
getSaveModel() {
|
||||
this.model = {};
|
||||
for (var property in this) {
|
||||
if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
|
||||
console.log('PanelModel.getSaveModel() skiping property', property);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.model[property] = this[property];
|
||||
}
|
||||
return this.model;
|
||||
}
|
||||
|
||||
updateGridPos(newPos: GridPos) {
|
||||
let sizeChanged = false;
|
||||
|
||||
if (this.gridPos.w !== newPos.w || this.gridPos.h !== newPos.h) {
|
||||
sizeChanged = true;
|
||||
}
|
||||
|
||||
this.gridPos.x = newPos.x;
|
||||
this.gridPos.y = newPos.y;
|
||||
this.gridPos.w = newPos.w;
|
||||
this.gridPos.h = newPos.h;
|
||||
|
||||
if (sizeChanged) {
|
||||
console.log('PanelModel sizeChanged event and render events fired');
|
||||
this.events.emit('panel-size-changed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,8 @@ export class DashboardCtrl implements PanelContainer {
|
||||
}
|
||||
|
||||
panelPossitionUpdated(panel: PanelModel) {
|
||||
console.log('panel pos updated', panel);
|
||||
//console.log('panel pos updated', panel);
|
||||
//this.$rootScope.$broadcast('render');
|
||||
}
|
||||
|
||||
timezoneChanged() {
|
||||
|
@ -4,6 +4,7 @@ import ReactGridLayout from 'react-grid-layout';
|
||||
import {CELL_HEIGHT, CELL_VMARGIN} from '../model';
|
||||
import {DashboardPanel} from './DashboardPanel';
|
||||
import {PanelContainer} from './PanelContainer';
|
||||
import {PanelModel} from '../PanelModel';
|
||||
import sizeMe from 'react-sizeme';
|
||||
|
||||
const COLUMN_COUNT = 12;
|
||||
@ -22,6 +23,8 @@ function GridWrapper({size, layout, onLayoutChange, children}) {
|
||||
isDraggable={true}
|
||||
isResizable={true}
|
||||
measureBeforeMount={false}
|
||||
containerPadding={[0, 0]}
|
||||
useCSSTransforms={true}
|
||||
margin={[CELL_VMARGIN, CELL_VMARGIN]}
|
||||
cols={COLUMN_COUNT}
|
||||
rowHeight={CELL_HEIGHT}
|
||||
@ -42,6 +45,7 @@ export interface DashboardGridProps {
|
||||
export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
gridToPanelMap: any;
|
||||
panelContainer: PanelContainer;
|
||||
panelMap: {[id: string]: PanelModel};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -52,22 +56,34 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
buildLayout() {
|
||||
const layout = [];
|
||||
const panels = this.panelContainer.getPanels();
|
||||
this.panelMap = {};
|
||||
|
||||
for (let panel of panels) {
|
||||
let stringId = panel.id.toString();
|
||||
this.panelMap[stringId] = panel;
|
||||
|
||||
if (!panel.gridPos) {
|
||||
console.log('panel without gridpos');
|
||||
continue;
|
||||
}
|
||||
|
||||
layout.push({
|
||||
i: panel.id.toString(),
|
||||
x: panel.x,
|
||||
y: panel.y,
|
||||
w: panel.width,
|
||||
h: panel.height,
|
||||
i: stringId,
|
||||
x: panel.gridPos.x,
|
||||
y: panel.gridPos.y,
|
||||
w: panel.gridPos.w,
|
||||
h: panel.gridPos.h,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('layout', layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
onLayoutChange() {}
|
||||
onLayoutChange(newLayout) {
|
||||
for (const newPos of newLayout) {
|
||||
this.panelMap[newPos.i].updateGridPos(newPos);
|
||||
}
|
||||
}
|
||||
|
||||
renderPanels() {
|
||||
const panels = this.panelContainer.getPanels();
|
||||
@ -76,10 +92,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
|
||||
for (let panel of panels) {
|
||||
panelElements.push(
|
||||
<div key={panel.id.toString()} className="panel">
|
||||
<DashboardPanel
|
||||
panel={panel}
|
||||
getPanelContainer={this.props.getPanelContainer}
|
||||
/>
|
||||
<DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} />
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
|
@ -1,211 +0,0 @@
|
||||
// ///<reference path="../../../headers/common.d.ts" />
|
||||
//
|
||||
// import coreModule from 'app/core/core_module';
|
||||
// import {CELL_HEIGHT, CELL_VMARGIN} from '../model';
|
||||
//
|
||||
// import 'jquery-ui';
|
||||
// import 'gridstack/dist/jquery.jQueryUI';
|
||||
// import 'gridstack';
|
||||
//
|
||||
// const template = `
|
||||
// <div class="grid-stack">
|
||||
// <dash-grid-item ng-repeat="panel in ctrl.dashboard.panels track by panel.id"
|
||||
// class="grid-stack-item"
|
||||
// grid-ctrl="ctrl"
|
||||
// panel="panel">
|
||||
// <plugin-component type="panel" class="grid-stack-item-content">
|
||||
// </plugin-component>
|
||||
// </dash-grid-item>
|
||||
// </div>
|
||||
// `;
|
||||
//
|
||||
// var rowIndex = 0;
|
||||
//
|
||||
// export class GridCtrl {
|
||||
// options: any;
|
||||
// dashboard: any;
|
||||
// panels: any;
|
||||
// gridstack: any;
|
||||
// gridElem: any;
|
||||
// isInitialized: boolean;
|
||||
// isDestroyed: boolean;
|
||||
// index: number;
|
||||
// changeRenderPromise: any;
|
||||
//
|
||||
// #<{(|* @ngInject |)}>#
|
||||
// constructor(private $scope, private $element, private $timeout) {
|
||||
// console.log(this.dashboard);
|
||||
// this.index = rowIndex;
|
||||
// rowIndex += 1;
|
||||
// }
|
||||
//
|
||||
// init() {
|
||||
// this.gridElem = this.$element.find('.grid-stack');
|
||||
//
|
||||
// this.gridstack = this.gridElem.gridstack({
|
||||
// animate: true,
|
||||
// cellHeight: CELL_HEIGHT,
|
||||
// verticalMargin: CELL_VMARGIN,
|
||||
// acceptWidgets: '.grid-stack-item',
|
||||
// handle: '.grid-drag-handle'
|
||||
// }).data('gridstack');
|
||||
//
|
||||
// this.isInitialized = true;
|
||||
//
|
||||
// this.gridElem.on('added', (e, items) => {
|
||||
// for (let item of items) {
|
||||
// this.onGridStackItemAdded(item);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// this.gridElem.on('removed', (e, items) => {
|
||||
// for (let item of items) {
|
||||
// this.onGridStackItemRemoved(item);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// this.gridElem.on('change', (e, items) => {
|
||||
// this.$timeout(() => this.onGridStackItemsChanged(items), 50);
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// onGridStackItemAdded(item) {
|
||||
// console.log('row: ' + this.index + ' item added', item);
|
||||
// }
|
||||
//
|
||||
// onGridStackItemRemoved(item) {
|
||||
// console.log('row: ' + this.index + ' item removed', item.id, item);
|
||||
// }
|
||||
//
|
||||
// onGridStackItemsChanged(items) {
|
||||
// console.log('onGridStackItemsChanged');
|
||||
//
|
||||
// for (let item of items) {
|
||||
// // find panel
|
||||
// var panel = this.dashboard.getPanelById(parseInt(item.id));
|
||||
//
|
||||
// if (!panel) {
|
||||
// console.log('item change but no panel found for item', item);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// // update panel model position
|
||||
// panel.x = item.x;
|
||||
// panel.y = item.y;
|
||||
// panel.width = item.width;
|
||||
// panel.height = item.height;
|
||||
//
|
||||
// console.log('updating panel: ' + panel.id + ' x: ' + panel.x + ' y: ' + panel.y);
|
||||
// }
|
||||
//
|
||||
// this.dashboard.panels.sort(function (a, b) {
|
||||
// let aScore = a.x + (a.y * 12);
|
||||
// let bScore = b.x + (b.y * 12);
|
||||
// if (aScore < bScore) { return -1; }
|
||||
// if (aScore > bScore) { return 1; }
|
||||
// return 0;
|
||||
// });
|
||||
//
|
||||
// if (this.changeRenderPromise) {
|
||||
// this.$timeout.cancel(this.changeRenderPromise);
|
||||
// }
|
||||
//
|
||||
// this.changeRenderPromise = this.$timeout(() => {
|
||||
// console.log('broadcasting render');
|
||||
// this.$scope.$broadcast('render');
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// destroy() {
|
||||
// this.gridstack.destroy();
|
||||
// this.gridstack = null;
|
||||
// this.isDestroyed = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #<{(|* @ngInject *|)}>#
|
||||
// export function dashGrid($timeout) {
|
||||
// return {
|
||||
// restrict: 'E',
|
||||
// template: template,
|
||||
// controller: GridCtrl,
|
||||
// bindToController: true,
|
||||
// controllerAs: 'ctrl',
|
||||
// scope: {
|
||||
// dashboard: "=",
|
||||
// },
|
||||
// link: function(scope, elem, attrs, ctrl) {
|
||||
// $timeout(function() {
|
||||
// ctrl.init();
|
||||
// });
|
||||
//
|
||||
// scope.$on('$destroy', () => {
|
||||
// ctrl.destroy();
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// #<{(|* @ngInject *|)}>#
|
||||
// export function dashGridItem($timeout, $rootScope) {
|
||||
// return {
|
||||
// restrict: "E",
|
||||
// scope: {
|
||||
// panel: '=',
|
||||
// gridCtrl: '='
|
||||
// },
|
||||
// link: function (scope, element, attrs) {
|
||||
// let gridCtrl = scope.gridCtrl;
|
||||
// let panel = scope.panel;
|
||||
// let gridStackNode = null;
|
||||
//
|
||||
// element.attr({
|
||||
// 'data-gs-id': panel.id,
|
||||
// 'data-gs-x': panel.x,
|
||||
// 'data-gs-y': panel.y,
|
||||
// 'data-gs-width': panel.width,
|
||||
// 'data-gs-height': panel.height,
|
||||
// 'data-gs-no-resize': panel.type === 'row',
|
||||
// });
|
||||
//
|
||||
// $rootScope.onAppEvent('panel-fullscreen-exit', (evt, payload) => {
|
||||
// if (panel.id !== payload.panelId) {
|
||||
// return;
|
||||
// }
|
||||
// gridCtrl.gridstack.locked(element, false);
|
||||
// element.removeClass('panel-fullscreen');
|
||||
// }, scope);
|
||||
//
|
||||
// $rootScope.onAppEvent('panel-fullscreen-enter', (evt, payload) => {
|
||||
// if (panel.id !== payload.panelId) {
|
||||
// return;
|
||||
// }
|
||||
// element.addClass('panel-fullscreen');
|
||||
// }, scope);
|
||||
//
|
||||
// scope.$on('$destroy', () => {
|
||||
// console.log('grid-item scope $destroy');
|
||||
// if (gridCtrl.isDestroyed) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (gridStackNode) {
|
||||
// console.log('grid-item scope $destroy removeWidget');
|
||||
// gridStackNode._grid.removeWidget(element);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// if (gridCtrl.isInitialized) {
|
||||
// gridCtrl.gridstack.makeWidget(element);
|
||||
// gridStackNode = element.data('_gridstack_node');
|
||||
// } else {
|
||||
// setTimeout(function() {
|
||||
// gridStackNode = element.data('_gridstack_node');
|
||||
// }, 500);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// coreModule.directive('dashGrid', dashGrid);
|
||||
// coreModule.directive('dashGridItem', dashGridItem);
|
@ -1,232 +0,0 @@
|
||||
Skip to content
|
||||
This repository
|
||||
Search
|
||||
Pull requests
|
||||
Issues
|
||||
Marketplace
|
||||
Gist
|
||||
@torkelo
|
||||
Sign out
|
||||
Unwatch 946
|
||||
Unstar 17,021
|
||||
Fork 2,862 grafana/grafana
|
||||
Code Issues 1,079 Pull requests 46 Projects 1 Wiki Settings Insights
|
||||
Branch: gridstack Find file Copy pathgrafana/public/app/core/components/dashgrid/dashgrid.ts
|
||||
a6bbcb8 on Jun 13
|
||||
@torkelo torkelo ux: gridstack poc
|
||||
1 contributor
|
||||
RawBlameHistory
|
||||
213 lines (181 sloc) 5.45 KB
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import $ from 'jquery';
|
||||
import coreModule from '../../core_module';
|
||||
|
||||
import 'jquery-ui';
|
||||
import 'gridstack';
|
||||
import 'gridstack.jquery-ui';
|
||||
|
||||
const template = `
|
||||
<div gridstack gridstack-handler="ctrl.gridstack" class="grid-stack"
|
||||
options="ctrl.options"
|
||||
on-change="ctrl.onChange(event,items)"
|
||||
on-drag-start="ctrl.onDragStart(event,ui)"
|
||||
on-drag-stop="ctrl.onDragStop(event, ui)"
|
||||
on-resize-start="ctrl.onResizeStart(event, ui)"
|
||||
on-resize-stop="ctrl.onResizeStop(event, ui)">
|
||||
<div gridstack-item ng-repeat="panel in ctrl.panels"
|
||||
class="grid-stack-item"
|
||||
gs-item-id="panel.id"
|
||||
gs-item-x="panel.x"
|
||||
gs-item-y="panel.y"
|
||||
gs-item-width="panel.width"
|
||||
gs-item-height="panel.height"
|
||||
gs-item-autopos="1"
|
||||
on-item-added="ctrl.onItemAdded(item)"
|
||||
on-item-removed="ctrl.onItemRemoved(item)">
|
||||
<plugin-component type="panel" class="panel-margin grid-stack-item-content">
|
||||
</plugin-component>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export class DashGridCtrl {
|
||||
options: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope) {
|
||||
this.options = {
|
||||
animate: true,
|
||||
};
|
||||
}
|
||||
|
||||
onResizeStop() {
|
||||
this.$rootScope.$broadcast('render');
|
||||
}
|
||||
}
|
||||
|
||||
export function dashGrid($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
controller: DashGridCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
dashboard: "="
|
||||
},
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
|
||||
ctrl.panels = [];
|
||||
ctrl.dashboard.forEachPanel((panel, panelIndex, row, rowIndex) => {
|
||||
panel.width = 4;
|
||||
panel.height = 4;
|
||||
panel.x = panelIndex * 4;
|
||||
panel.y = rowIndex * 4;
|
||||
ctrl.panels.push(panel);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.controller('GridstackController', ['$scope', function($scope) {
|
||||
|
||||
var gridstack = null;
|
||||
|
||||
this.init = function(element, options) {
|
||||
gridstack = element.gridstack(options).data('gridstack');
|
||||
return gridstack;
|
||||
};
|
||||
|
||||
this.removeItem = function(element) {
|
||||
if (gridstack) {
|
||||
return gridstack.removeWidget(element, false);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.addItem = function(element) {
|
||||
if (gridstack) {
|
||||
gridstack.makeWidget(element);
|
||||
return element;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.directive('gridstack', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: "A",
|
||||
controller: 'GridstackController',
|
||||
scope: {
|
||||
onChange: '&',
|
||||
onDragStart: '&',
|
||||
onDragStop: '&',
|
||||
onResizeStart: '&',
|
||||
onResizeStop: '&',
|
||||
gridstackHandler: '=',
|
||||
options: '='
|
||||
},
|
||||
link: function (scope, element, attrs, controller, ngModel) {
|
||||
|
||||
var gridstack = controller.init(element, scope.options);
|
||||
scope.gridstackHandler = gridstack;
|
||||
|
||||
element.on('change', function (e, items) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onChange({event: e, items: items});
|
||||
});
|
||||
});
|
||||
|
||||
element.on('dragstart', function(e, ui) {
|
||||
scope.onDragStart({event: e, ui: ui});
|
||||
});
|
||||
|
||||
element.on('dragstop', function(e, ui) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onDragStop({event: e, ui: ui});
|
||||
});
|
||||
});
|
||||
|
||||
element.on('resizestart', function(e, ui) {
|
||||
scope.onResizeStart({event: e, ui: ui});
|
||||
});
|
||||
|
||||
element.on('resizestop', function(e, ui) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onResizeStop({event: e, ui: ui});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.directive('gridstackItem', ['$timeout', function($timeout) {
|
||||
|
||||
return {
|
||||
restrict: "A",
|
||||
controller: 'GridstackController',
|
||||
require: '^gridstack',
|
||||
scope: {
|
||||
gridstackItem: '=',
|
||||
onItemAdded: '&',
|
||||
onItemRemoved: '&',
|
||||
gsItemId: '=',
|
||||
gsItemX: '=',
|
||||
gsItemY: '=',
|
||||
gsItemWidth: '=',
|
||||
gsItemHeight: '=',
|
||||
gsItemAutopos: '='
|
||||
},
|
||||
link: function (scope, element, attrs, controller) {
|
||||
$(element).attr('data-gs-id', scope.gsItemId);
|
||||
$(element).attr('data-gs-x', scope.gsItemX);
|
||||
$(element).attr('data-gs-y', scope.gsItemY);
|
||||
$(element).attr('data-gs-width', scope.gsItemWidth);
|
||||
$(element).attr('data-gs-height', scope.gsItemHeight);
|
||||
$(element).attr('data-gs-auto-position', scope.gsItemAutopos);
|
||||
var widget = controller.addItem(element);
|
||||
var item = element.data('_gridstack_node');
|
||||
$timeout(function() {
|
||||
scope.onItemAdded({item: item});
|
||||
});
|
||||
scope.$watch(function () { return $(element).attr('data-gs-id'); }, function (val) {
|
||||
scope.gsItemId = val;
|
||||
});
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-x'); }, function(val) {
|
||||
scope.gsItemX = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-y'); }, function(val) {
|
||||
scope.gsItemY = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-width'); }, function(val) {
|
||||
scope.gsItemWidth = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-height'); }, function(val) {
|
||||
scope.gsItemHeight = val;
|
||||
});
|
||||
|
||||
element.bind('$destroy', function() {
|
||||
var item = element.data('_gridstack_node');
|
||||
scope.onItemRemoved({item: item});
|
||||
controller.removeItem(element);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
coreModule.directive('dashGrid', dashGrid);
|
||||
Contact GitHub API Training Shop Blog About
|
||||
© 2017 GitHub, Inc. Terms Privacy Security Status Help
|
@ -69,8 +69,7 @@ export class DashboardModel {
|
||||
this.links = data.links || [];
|
||||
this.gnetId = data.gnetId || null;
|
||||
this.folderId = data.folderId || null;
|
||||
this.panels = data.panels || [];
|
||||
this.rows = [];
|
||||
this.panels = _.map(data.panels || [], panelData => new PanelModel(panelData));
|
||||
|
||||
this.addBuiltInAnnotationQuery();
|
||||
this.initMeta(meta);
|
||||
@ -123,34 +122,32 @@ export class DashboardModel {
|
||||
// temp remove stuff
|
||||
var events = this.events;
|
||||
var meta = this.meta;
|
||||
var rows = this.rows;
|
||||
var variables = this.templating.list;
|
||||
var panels = this.panels;
|
||||
|
||||
delete this.events;
|
||||
delete this.meta;
|
||||
delete this.panels;
|
||||
|
||||
// prepare save model
|
||||
this.rows = _.map(rows, row => row.getSaveModel());
|
||||
this.templating.list = _.map(variables, variable => variable.getSaveModel ? variable.getSaveModel() : variable);
|
||||
this.panels = _.map(panels, panel => panel.getSaveModel());
|
||||
|
||||
// make clone
|
||||
var copy = $.extend(true, {}, this);
|
||||
// sort clone
|
||||
copy = sortByKeys(copy);
|
||||
console.log(copy.panels);
|
||||
|
||||
// restore properties
|
||||
this.events = events;
|
||||
this.meta = meta;
|
||||
this.rows = rows;
|
||||
this.templating.list = variables;
|
||||
this.panels = panels;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
addEmptyRow() {
|
||||
this.rows.push(new DashboardRow({isNew: true}));
|
||||
}
|
||||
|
||||
private ensureListExist(data) {
|
||||
if (!data) { data = {}; }
|
||||
if (!data.list) { data.list = []; }
|
||||
@ -327,7 +324,7 @@ export class DashboardModel {
|
||||
var i, j, k;
|
||||
var oldVersion = this.schemaVersion;
|
||||
var panelUpgrades = [];
|
||||
this.schemaVersion = 15;
|
||||
this.schemaVersion = 16;
|
||||
|
||||
if (oldVersion === this.schemaVersion) {
|
||||
return;
|
||||
@ -636,7 +633,7 @@ export class DashboardModel {
|
||||
this.graphTooltip = old.sharedCrosshair ? 1 : 0;
|
||||
}
|
||||
|
||||
if (oldVersion < 15) {
|
||||
if (oldVersion < 16) {
|
||||
this.upgradeToGridLayout(old);
|
||||
}
|
||||
|
||||
@ -644,60 +641,54 @@ export class DashboardModel {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < this.rows.length; i++) {
|
||||
var row = this.rows[i];
|
||||
for (j = 0; j < row.panels.length; j++) {
|
||||
for (k = 0; k < panelUpgrades.length; k++) {
|
||||
panelUpgrades[k].call(this, row.panels[j]);
|
||||
}
|
||||
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 rowIds = 1000;
|
||||
//let rowIds = 1000;
|
||||
|
||||
for (let row of old.rows) {
|
||||
let xPos = 0;
|
||||
let height: any = row.height;
|
||||
|
||||
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 (this.meta.keepRows) {
|
||||
// this.panels.push({
|
||||
// id: rowIds++,
|
||||
// type: 'row',
|
||||
// title: row.title,
|
||||
// x: 0,
|
||||
// y: yPos,
|
||||
// height: 1,
|
||||
// width: 12
|
||||
// });
|
||||
//
|
||||
// yPos += 1;
|
||||
// }
|
||||
|
||||
if (_.isString(height)) {
|
||||
height = parseInt(height.replace('px', ''), 10);
|
||||
}
|
||||
|
||||
height = Math.ceil(height / CELL_HEIGHT);
|
||||
const rowGridHeight = Math.ceil(height / CELL_HEIGHT);
|
||||
|
||||
for (let panel of row.panels) {
|
||||
// should wrap to next row?
|
||||
if (xPos + panel.span >= 12) {
|
||||
yPos += height;
|
||||
yPos += rowGridHeight;
|
||||
}
|
||||
|
||||
panel.x = xPos;
|
||||
panel.y = yPos;
|
||||
panel.width = panel.span;
|
||||
panel.height = height;
|
||||
panel.gridPos = { x: xPos, y: yPos, w: panel.span, h: rowGridHeight };
|
||||
|
||||
delete panel.span;
|
||||
|
||||
xPos += panel.width;
|
||||
xPos += rowGridHeight;
|
||||
|
||||
this.panels.push(panel);
|
||||
this.panels.push(new PanelModel(panel));
|
||||
}
|
||||
|
||||
yPos += height;
|
||||
|
@ -55,11 +55,9 @@ export class SaveDashboardAsModalCtrl {
|
||||
// remove alerts if source dashboard is already persisted
|
||||
// do not want to create alert dupes
|
||||
if (dashboard.id > 0) {
|
||||
this.clone.rows.forEach(row => {
|
||||
row.panels.forEach(panel => {
|
||||
delete panel.thresholds;
|
||||
delete panel.alert;
|
||||
});
|
||||
this.clone.panels.forEach(panel => {
|
||||
delete panel.thresholds;
|
||||
delete panel.alert;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class PanelCtrl {
|
||||
this.$scope = $scope;
|
||||
this.$timeout = $injector.get('$timeout');
|
||||
this.editorTabIndex = 0;
|
||||
this.events = new Emitter();
|
||||
this.events = this.panel.events;
|
||||
this.timing = {};
|
||||
|
||||
var plugin = config.panels[this.panel.type];
|
||||
@ -47,21 +47,14 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
$scope.$on("refresh", () => this.refresh());
|
||||
$scope.$on("render", () => this.render());
|
||||
$scope.$on("$destroy", () => {
|
||||
this.events.emit('panel-teardown');
|
||||
this.events.removeAllListeners();
|
||||
});
|
||||
|
||||
// we should do something interesting
|
||||
// with newly added panels
|
||||
if (this.panel.isNew) {
|
||||
delete this.panel.isNew;
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.calculatePanelHeight();
|
||||
this.events.on('panel-size-changed', this.onSizeChanged.bind(this));
|
||||
this.publishAppEvent('panel-initialized', {scope: this.$scope});
|
||||
this.events.emit('panel-initialized');
|
||||
}
|
||||
@ -71,7 +64,7 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.events.emit('refresh', null);
|
||||
this.events.emit('refresh', null);
|
||||
}
|
||||
|
||||
publishAppEvent(evtName, evt) {
|
||||
@ -170,23 +163,24 @@ export class PanelCtrl {
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
this.containerHeight = this.panel.height * CELL_HEIGHT + ((this.panel.height-1) * CELL_VMARGIN);
|
||||
this.containerHeight = this.panel.gridPos.h * CELL_HEIGHT + ((this.panel.gridPos.h-1) * CELL_VMARGIN);
|
||||
}
|
||||
|
||||
this.height = this.containerHeight - (PANEL_BORDER + PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
|
||||
}
|
||||
|
||||
render(payload?) {
|
||||
// ignore if other panel is in fullscreen mode
|
||||
if (this.otherPanelInFullscreenMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.calculatePanelHeight();
|
||||
this.timing.renderStart = new Date().getTime();
|
||||
this.events.emit('render', payload);
|
||||
}
|
||||
|
||||
private onSizeChanged() {
|
||||
this.calculatePanelHeight();
|
||||
this.$timeout(() => {
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
|
||||
duplicate() {
|
||||
this.dashboard.duplicatePanel(this.panel);
|
||||
this.$timeout(() => {
|
||||
|
@ -98,6 +98,7 @@ module.directive('grafanaPanel', function($rootScope, $document) {
|
||||
}
|
||||
|
||||
ctrl.events.on('render', () => {
|
||||
console.log('panelDirective::render!');
|
||||
if (lastHeight !== ctrl.containerHeight) {
|
||||
panelContainer.css({minHeight: ctrl.containerHeight});
|
||||
lastHeight = ctrl.containerHeight;
|
||||
|
@ -88,7 +88,7 @@ function panelHeader($compile) {
|
||||
let menuScope;
|
||||
|
||||
elem.click(function(evt) {
|
||||
const targetClass = evt.target.className;
|
||||
//const targetClass = evt.target.className;
|
||||
|
||||
// remove existing scope
|
||||
if (menuScope) {
|
||||
@ -100,10 +100,10 @@ function panelHeader($compile) {
|
||||
menuElem.html(menuHtml);
|
||||
$compile(menuElem)(menuScope);
|
||||
|
||||
if (targetClass === 'panel-title-text' || targetClass === 'panel-title') {
|
||||
evt.stopPropagation();
|
||||
elem.find('[data-toggle=dropdown]').dropdown('toggle');
|
||||
}
|
||||
// if (targetClass === 'panel-title-text' || targetClass === 'panel-title') {
|
||||
// evt.stopPropagation();
|
||||
// elem.find('[data-toggle=dropdown]').dropdown('toggle');
|
||||
// }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -54,6 +54,7 @@ function graphDirective($rootScope, timeSrv, popoverSrv, contextSrv) {
|
||||
});
|
||||
|
||||
ctrl.events.on('render', function(renderData) {
|
||||
console.log('graph render');
|
||||
data = renderData || data;
|
||||
if (!data) {
|
||||
return;
|
||||
|
@ -13,7 +13,6 @@
|
||||
{
|
||||
"content": "<div class=\"text-center dashboard-header\">\n <span>Home Dashboard</span>\n</div>",
|
||||
"editable": true,
|
||||
"height": 2,
|
||||
"id": 1,
|
||||
"links": [],
|
||||
"mode": "html",
|
||||
@ -21,14 +20,16 @@
|
||||
"title": "",
|
||||
"transparent": true,
|
||||
"type": "text",
|
||||
"width": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
"gridPos": {
|
||||
"w": 12,
|
||||
"h": 2,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"folderId": 0,
|
||||
"headings": true,
|
||||
"height": 17,
|
||||
"id": 3,
|
||||
"limit": 4,
|
||||
"links": [],
|
||||
@ -40,22 +41,27 @@
|
||||
"title": "",
|
||||
"transparent": false,
|
||||
"type": "dashlist",
|
||||
"width": 7,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
"gridPos": {
|
||||
"w": 7,
|
||||
"h": 17,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"height": 17,
|
||||
"id": 4,
|
||||
"links": [],
|
||||
"title": "",
|
||||
"transparent": false,
|
||||
"type": "pluginlist",
|
||||
"width": 5,
|
||||
"x": 7,
|
||||
"y": 6
|
||||
"gridPos": {
|
||||
"w": 5,
|
||||
"h": 17,
|
||||
"x": 7,
|
||||
"y": 6
|
||||
}
|
||||
}
|
||||
],
|
||||
"rows": [],
|
||||
|
Loading…
Reference in New Issue
Block a user