mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(ux): dashboard edit mode progress
This commit is contained in:
parent
29e834e74b
commit
01627b3a68
@ -26,7 +26,6 @@ export class DashboardCtrl {
|
||||
$timeout) {
|
||||
|
||||
$scope.editor = { index: 0 };
|
||||
$scope.panels = config.panels;
|
||||
|
||||
var resizeEventTimeout;
|
||||
|
||||
@ -107,22 +106,12 @@ export class DashboardCtrl {
|
||||
$rootScope.$broadcast('refresh');
|
||||
};
|
||||
|
||||
$scope.addRow = function(dash, row) {
|
||||
dash.rows.push(row);
|
||||
};
|
||||
|
||||
$scope.addRowDefault = function() {
|
||||
$scope.resetRow();
|
||||
$scope.row.title = 'New row';
|
||||
$scope.addRow($scope.dashboard, $scope.row);
|
||||
};
|
||||
|
||||
$scope.resetRow = function() {
|
||||
$scope.row = {
|
||||
title: '',
|
||||
$scope.dashboard.rows.push({
|
||||
title: 'New row',
|
||||
panels: [],
|
||||
height: '250px',
|
||||
editable: true,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
$scope.showJsonEditor = function(evt, options) {
|
||||
@ -132,24 +121,6 @@ export class DashboardCtrl {
|
||||
$scope.appEvent('show-dash-editor', { src: 'public/app/partials/edit_json.html', scope: editScope });
|
||||
};
|
||||
|
||||
$scope.onDrop = function(panelId, row, dropTarget) {
|
||||
var info = $scope.dashboard.getPanelInfoById(panelId);
|
||||
if (dropTarget) {
|
||||
var dropInfo = $scope.dashboard.getPanelInfoById(dropTarget.id);
|
||||
dropInfo.row.panels[dropInfo.index] = info.panel;
|
||||
info.row.panels[info.index] = dropTarget;
|
||||
var dragSpan = info.panel.span;
|
||||
info.panel.span = dropTarget.span;
|
||||
dropTarget.span = dragSpan;
|
||||
} else {
|
||||
info.row.panels.splice(info.index, 1);
|
||||
info.panel.span = 12 - $scope.dashboard.rowSpan(row);
|
||||
row.panels.push(info.panel);
|
||||
}
|
||||
|
||||
$rootScope.$broadcast('render');
|
||||
};
|
||||
|
||||
$scope.registerWindowResizeEvent = function() {
|
||||
angular.element(window).bind('resize', function() {
|
||||
$timeout.cancel(resizeEventTimeout);
|
||||
@ -166,7 +137,6 @@ export class DashboardCtrl {
|
||||
}
|
||||
|
||||
init(dashboard) {
|
||||
this.$scope.resetRow();
|
||||
this.$scope.registerWindowResizeEvent();
|
||||
this.$scope.onAppEvent('show-json-editor', this.$scope.showJsonEditor);
|
||||
this.$scope.onAppEvent('template-variable-value-updated', this.$scope.templateVariableUpdated);
|
||||
|
@ -11,18 +11,15 @@
|
||||
<div class="dash-row-header pointer" ng-if="ctrl.dashboard.editMode">
|
||||
<div class="dash-row-header-title" ng-bind="ctrl.row.title | interpolateTemplateVars:this"></div>
|
||||
<div class="dash-row-header-settings dropdown">
|
||||
<!-- <a class="pointer dropdown-toggle" data-toggle="dropdown"> -->
|
||||
<!-- <i class="fa fa-cog"></i> -->
|
||||
<!-- </a> -->
|
||||
<a class="pointer dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-plus-circle"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="drop1">
|
||||
<li>
|
||||
<a ng-click="toggleRow(row)">Collapse row</a>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a href="javascript:void(0);">Add Panel</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li bindonce ng-repeat="(key, value) in panels">
|
||||
<a ng-click="addPanelDefault(key)" bo-text="value.name"></a>
|
||||
<li bindonce ng-repeat="(key, value) in ctrl.panelPlugins">
|
||||
<a ng-click="ctrl.addPanelDefault(key)" bo-text="value.name"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -42,20 +39,20 @@
|
||||
<li><a ng-click="setHeight('700px')">700 px</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown-submenu">
|
||||
<a href="javascript:void(0);">Move</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a ng-click="moveRow('up')">Up</a></li>
|
||||
<li><a ng-click="moveRow('down')">Down</a></li>
|
||||
<li><a ng-click="moveRow('top')">To top</a></li>
|
||||
<li><a ng-click="moveRow('bottom')">To Bottom</a></li>
|
||||
</ul>
|
||||
<!-- <li class="dropdown-submenu"> -->
|
||||
<!-- <a href="javascript:void(0);">Move</a> -->
|
||||
<!-- <ul class="dropdown-menu"> -->
|
||||
<!-- <li><a ng-click="moveRow('up')">Up</a></li> -->
|
||||
<!-- <li><a ng-click="moveRow('down')">Down</a></li> -->
|
||||
<!-- <li><a ng-click="moveRow('top')">To top</a></li> -->
|
||||
<!-- <li><a ng-click="moveRow('bottom')">To Bottom</a></li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- </li> -->
|
||||
<li>
|
||||
<a ng-click="ctrl.editRow()">Row options</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="editRow()">Row editor</a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="deleteRow()">Delete row</a>
|
||||
<a ng-click="ctrl.deleteRow()">Delete row</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -68,12 +65,12 @@
|
||||
</div>
|
||||
|
||||
<div class="panels-wrapper" ng-if="!ctrl.row.collapse">
|
||||
<div ng-repeat="panel in ctrl.row.panels track by panel.id" class="panel" ui-draggable="!ctrl.dashboard.meta.fullscreen" drag="panel.id" ui-on-drop="onDrop($data, row, panel)" drag-handle-class="drag-handle" panel-width>
|
||||
<div ng-repeat="panel in ctrl.row.panels track by panel.id" class="panel" ui-draggable="!ctrl.dashboard.meta.fullscreen" drag="panel.id" ui-on-drop="ctrl.onDrop($data, panel)" drag-handle-class="drag-handle" panel-width>
|
||||
<plugin-component type="panel" class="panel-margin">
|
||||
</plugin-component>
|
||||
</div>
|
||||
|
||||
<div panel-drop-zone class="panel panel-drop-zone" ui-on-drop="onDrop($data, row)" data-drop="true">
|
||||
<div panel-drop-zone class="panel panel-drop-zone" ui-on-drop="ctrl.onDrop($data)" data-drop="true">
|
||||
<div class="panel-container" style="background: transparent">
|
||||
<div style="text-align: center">
|
||||
<em>Drop here</em>
|
||||
|
@ -1,21 +1,83 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import _ from 'lodash';
|
||||
import coreModule from 'app/core/core_module';
|
||||
import config from 'app/core/config';
|
||||
import {coreModule, appEvents} from 'app/core/core';
|
||||
|
||||
export class DashRowCtrl {
|
||||
showTitle: boolean;
|
||||
dashboard: any;
|
||||
row: any;
|
||||
panelPlugins;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope) {
|
||||
this.showTitle = true;
|
||||
this.-
|
||||
this.panelPlugins = config.panels;
|
||||
}
|
||||
|
||||
onDrop(panelId, dropTarget) {
|
||||
var info = this.dashboard.getPanelInfoById(panelId);
|
||||
if (dropTarget) {
|
||||
var dropInfo = this.dashboard.getPanelInfoById(dropTarget.id);
|
||||
dropInfo.row.panels[dropInfo.index] = info.panel;
|
||||
info.row.panels[info.index] = dropTarget;
|
||||
var dragSpan = info.panel.span;
|
||||
info.panel.span = dropTarget.span;
|
||||
dropTarget.span = dragSpan;
|
||||
} else {
|
||||
info.row.panels.splice(info.index, 1);
|
||||
info.panel.span = 12 - this.dashboard.rowSpan(this.row);
|
||||
this.row.panels.push(info.panel);
|
||||
}
|
||||
|
||||
this.$rootScope.$broadcast('render');
|
||||
}
|
||||
|
||||
addPanel(panel) {
|
||||
this.dashboard.addPanel(panel, this.row);
|
||||
}
|
||||
|
||||
editRow() {
|
||||
// this.appEvent('show-dash-editor', {
|
||||
// src: 'public/app/partials/roweditor.html',
|
||||
// scope: this.$scope.$new()
|
||||
// });
|
||||
}
|
||||
|
||||
addPanelDefault(type) {
|
||||
var defaultSpan = 12;
|
||||
var _as = 12 - this.dashboard.rowSpan(this.row);
|
||||
|
||||
var panel = {
|
||||
title: config.new_panel_title,
|
||||
error: false,
|
||||
span: _as < defaultSpan && _as > 0 ? _as : defaultSpan,
|
||||
editable: true,
|
||||
type: type,
|
||||
isNew: true,
|
||||
};
|
||||
|
||||
this.addPanel(panel);
|
||||
}
|
||||
|
||||
deleteRow() {
|
||||
if (!this.row.panels.length) {
|
||||
this.dashboard.rows = _.without(this.dashboard.rows, this.row);
|
||||
return;
|
||||
}
|
||||
|
||||
appEvents.emit('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to delete this row?',
|
||||
icon: 'fa-trash',
|
||||
yesText: 'Delete',
|
||||
onConfirm: () => {
|
||||
this.dashboard.rows = _.without(this.dashboard.rows, this.row);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function rowDirective() {
|
||||
export function rowDirective($rootScope) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'public/app/features/dashboard/row/row.html',
|
||||
@ -25,6 +87,22 @@ export function rowDirective() {
|
||||
scope: {
|
||||
dashboard: "=",
|
||||
row: "=",
|
||||
},
|
||||
link: function(scope, element) {
|
||||
scope.$watchGroup(['ctrl.row.collapse', 'ctrl.row.height'], function() {
|
||||
element.css({minHeight: scope.ctrl.row.collapse ? '5px' : scope.ctrl.row.height});
|
||||
});
|
||||
|
||||
$rootScope.onAppEvent('panel-fullscreen-enter', function(evt, info) {
|
||||
var hasPanel = _.find(scope.ctrl.row.panels, {id: info.panelId});
|
||||
if (!hasPanel) {
|
||||
element.hide();
|
||||
}
|
||||
}, scope);
|
||||
|
||||
$rootScope.onAppEvent('panel-fullscreen-exit', function() {
|
||||
element.show();
|
||||
}, scope);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -63,7 +141,7 @@ coreModule.directive('panelWidth', function($rootScope) {
|
||||
updateWidth();
|
||||
}, scope);
|
||||
|
||||
scope.$watch('ctrl.panel.span', updateWidth);
|
||||
scope.$watch('panel.span', updateWidth);
|
||||
|
||||
if (fullscreen) {
|
||||
element.hide();
|
||||
@ -71,3 +149,23 @@ coreModule.directive('panelWidth', function($rootScope) {
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
coreModule.directive('panelDropZone', function($timeout) {
|
||||
return function(scope, element) {
|
||||
scope.$on("ANGULAR_DRAG_START", function() {
|
||||
$timeout(function() {
|
||||
var dropZoneSpan = 12 - scope.ctrl.dashboard.rowSpan(scope.ctrl.row);
|
||||
|
||||
if (dropZoneSpan > 0) {
|
||||
element.find('.panel-container').css('height', scope.ctrl.row.height);
|
||||
element[0].style.width = ((dropZoneSpan / 1.2) * 10) + '%';
|
||||
element.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
scope.$on("ANGULAR_DRAG_END", function() {
|
||||
element.hide();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
@ -1,167 +1,51 @@
|
||||
define([
|
||||
'angular',
|
||||
'lodash',
|
||||
'app/core/config'
|
||||
],
|
||||
function (angular, _, config) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('RowCtrl', function($scope, $rootScope, $timeout) {
|
||||
var _d = {
|
||||
title: "Row",
|
||||
height: "150px",
|
||||
collapse: false,
|
||||
editable: true,
|
||||
panels: [],
|
||||
};
|
||||
|
||||
_.defaults($scope.row,_d);
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.editor = {index: 0};
|
||||
};
|
||||
|
||||
$scope.togglePanelMenu = function(posX) {
|
||||
$scope.showPanelMenu = !$scope.showPanelMenu;
|
||||
$scope.panelMenuPos = posX;
|
||||
};
|
||||
|
||||
$scope.toggleRow = function(row) {
|
||||
row.collapse = row.collapse ? false : true;
|
||||
};
|
||||
|
||||
$scope.settingsHover = function(row) {
|
||||
// Shows/hides the settings button on hover
|
||||
return row.hoverSettings = ! row.hoverSettings;
|
||||
};
|
||||
|
||||
$scope.addPanel = function(panel) {
|
||||
$scope.dashboard.addPanel(panel, $scope.row);
|
||||
};
|
||||
|
||||
$scope.deleteRow = function() {
|
||||
function delete_row() {
|
||||
$scope.dashboard.rows = _.without($scope.dashboard.rows, $scope.row);
|
||||
}
|
||||
|
||||
if (!$scope.row.panels.length) {
|
||||
delete_row();
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.appEvent('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to delete this row?',
|
||||
icon: 'fa-trash',
|
||||
yesText: 'Delete',
|
||||
onConfirm: function() {
|
||||
delete_row();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editRow = function() {
|
||||
$scope.appEvent('show-dash-editor', {
|
||||
src: 'public/app/partials/roweditor.html',
|
||||
scope: $scope.$new()
|
||||
});
|
||||
};
|
||||
|
||||
$scope.moveRow = function(direction) {
|
||||
var rowsList = $scope.dashboard.rows;
|
||||
var rowIndex = _.indexOf(rowsList, $scope.row);
|
||||
var newIndex = rowIndex;
|
||||
switch(direction) {
|
||||
case 'up': {
|
||||
newIndex = rowIndex - 1;
|
||||
break;
|
||||
}
|
||||
case 'down': {
|
||||
newIndex = rowIndex + 1;
|
||||
break;
|
||||
}
|
||||
case 'top': {
|
||||
newIndex = 0;
|
||||
break;
|
||||
}
|
||||
case 'bottom': {
|
||||
newIndex = rowsList.length - 1;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newIndex = rowIndex;
|
||||
}
|
||||
}
|
||||
if (newIndex >= 0 && newIndex <= (rowsList.length - 1)) {
|
||||
_.move(rowsList, rowIndex, newIndex);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.addPanelDefault = function(type) {
|
||||
var defaultSpan = 12;
|
||||
var _as = 12 - $scope.dashboard.rowSpan($scope.row);
|
||||
|
||||
var panel = {
|
||||
title: config.new_panel_title,
|
||||
error: false,
|
||||
span: _as < defaultSpan && _as > 0 ? _as : defaultSpan,
|
||||
editable: true,
|
||||
type: type,
|
||||
isNew: true,
|
||||
};
|
||||
|
||||
$scope.addPanel(panel);
|
||||
|
||||
$timeout(function() {
|
||||
$scope.dashboardViewState.update({fullscreen: true, edit: true, panelId: panel.id });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setHeight = function(height) {
|
||||
$scope.row.height = height;
|
||||
$scope.$broadcast('render');
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
});
|
||||
|
||||
module.directive('rowHeight', function() {
|
||||
return function(scope, element) {
|
||||
scope.$watchGroup(['row.collapse', 'row.height'], function() {
|
||||
element.css({ minHeight: scope.row.collapse ? '5px' : scope.row.height });
|
||||
});
|
||||
|
||||
scope.onAppEvent('panel-fullscreen-enter', function(evt, info) {
|
||||
var hasPanel = _.find(scope.row.panels, {id: info.panelId});
|
||||
if (!hasPanel) {
|
||||
element.hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.onAppEvent('panel-fullscreen-exit', function() {
|
||||
element.show();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('panelDropZone', function() {
|
||||
return function(scope, element) {
|
||||
scope.$on("ANGULAR_DRAG_START", function() {
|
||||
var dropZoneSpan = 12 - scope.dashboard.rowSpan(scope.row);
|
||||
|
||||
if (dropZoneSpan > 0) {
|
||||
element.find('.panel-container').css('height', scope.row.height);
|
||||
element[0].style.width = ((dropZoneSpan / 1.2) * 10) + '%';
|
||||
element.show();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("ANGULAR_DRAG_END", function() {
|
||||
element.hide();
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
});
|
||||
// define([
|
||||
// 'angular',
|
||||
// 'lodash',
|
||||
// 'app/core/config'
|
||||
// ],
|
||||
// function (angular, _, config) {
|
||||
// 'use strict';
|
||||
//
|
||||
// var module = angular.module('grafana.controllers');
|
||||
//
|
||||
// module.controller('RowCtrl', function($scope, $rootScope, $timeout) {
|
||||
//
|
||||
// $scope.moveRow = function(direction) {
|
||||
// var rowsList = $scope.dashboard.rows;
|
||||
// var rowIndex = _.indexOf(rowsList, $scope.row);
|
||||
// var newIndex = rowIndex;
|
||||
// switch(direction) {
|
||||
// case 'up': {
|
||||
// newIndex = rowIndex - 1;
|
||||
// break;
|
||||
// }
|
||||
// case 'down': {
|
||||
// newIndex = rowIndex + 1;
|
||||
// break;
|
||||
// }
|
||||
// case 'top': {
|
||||
// newIndex = 0;
|
||||
// break;
|
||||
// }
|
||||
// case 'bottom': {
|
||||
// newIndex = rowsList.length - 1;
|
||||
// break;
|
||||
// }
|
||||
// default: {
|
||||
// newIndex = rowIndex;
|
||||
// }
|
||||
// }
|
||||
// if (newIndex >= 0 && newIndex <= (rowsList.length - 1)) {
|
||||
// _.move(rowsList, rowIndex, newIndex);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// $scope.setHeight = function(height) {
|
||||
// $scope.row.height = height;
|
||||
// $scope.$broadcast('render');
|
||||
// };
|
||||
//
|
||||
// $scope.init();
|
||||
// });
|
||||
//
|
||||
// });
|
||||
|
@ -149,6 +149,7 @@ function (angular, _, $) {
|
||||
|
||||
ctrl.editMode = false;
|
||||
ctrl.fullscreen = false;
|
||||
ctrl.dashboard.editMode = this.oldDashboardEditMode;
|
||||
|
||||
this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
|
||||
|
||||
@ -170,8 +171,10 @@ function (angular, _, $) {
|
||||
ctrl.editMode = this.state.edit && this.dashboard.meta.canEdit;
|
||||
ctrl.fullscreen = true;
|
||||
|
||||
this.oldDashboardEditMode = this.dashboard.editMode;
|
||||
this.oldTimeRange = ctrl.range;
|
||||
this.fullscreenPanel = panelScope;
|
||||
this.dashboard.editMode = false;
|
||||
|
||||
$(window).scrollTop(0);
|
||||
|
||||
|
@ -384,7 +384,6 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
|
||||
if (!annotations || annotations.length === 0) {
|
||||
return;
|
||||
}
|
||||
console.log(annotations);
|
||||
|
||||
var types = {};
|
||||
types['$__alerting'] = {
|
||||
|
@ -80,7 +80,7 @@ $enable-flex: false;
|
||||
// Typography
|
||||
// -------------------------
|
||||
|
||||
$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
$font-family-sans-serif: "Open Sans", Helvetica, Arial, sans-serif;
|
||||
$font-family-serif: Georgia, "Times New Roman", Times, serif;
|
||||
$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||
$font-family-base: $font-family-sans-serif !default;
|
||||
|
@ -211,7 +211,7 @@ div.flot-text {
|
||||
|
||||
.dash-row-handle-column {
|
||||
width: 2rem;
|
||||
background: $page-bg;
|
||||
background: $input-label-bg;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@ -235,7 +235,7 @@ div.flot-text {
|
||||
flex-direction: row;
|
||||
text-align: left;
|
||||
align-items: center;
|
||||
background: $page-bg;
|
||||
background: $input-label-bg;
|
||||
margin-right: $panel-margin;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user