mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Big refactoring of the way panels are loaded and how they are built using directives, this way feel cleaner and allowed for placing the panel edit box outside the panel-container
This commit is contained in:
parent
b67f4dc390
commit
04ec222462
@ -6,6 +6,8 @@ function () {
|
||||
function PanelMeta(options) {
|
||||
this.description = options.description;
|
||||
this.fullscreen = options.fullscreen;
|
||||
this.editIcon = options.editIcon;
|
||||
this.panelName = options.panelName;
|
||||
this.menu = [];
|
||||
this.editorTabs = [];
|
||||
this.extendedMenu = [];
|
||||
|
@ -18,7 +18,7 @@ function (_, crypto) {
|
||||
panels : {
|
||||
'graph': { path: 'panels/graph' },
|
||||
'singlestat': { path: 'panels/singlestat' },
|
||||
'text': { path: 'panels/text' }
|
||||
'text': { path: 'panels/text' },
|
||||
},
|
||||
plugins : {},
|
||||
default_route : '/dashboard/file/default.json',
|
||||
|
@ -143,7 +143,6 @@ function (angular, _, config, $) {
|
||||
};
|
||||
|
||||
$scope.newDashboard = function() {
|
||||
//$location.path('/dashboard/file/empty.json');
|
||||
$location.url('dashboard/new');
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
define([
|
||||
'./arrayJoin',
|
||||
'./dashUpload',
|
||||
'./grafanaPanel',
|
||||
'./grafanaSimplePanel',
|
||||
'./ngBlur',
|
||||
'./dashEditLink',
|
||||
|
@ -1,80 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'jquery',
|
||||
'config',
|
||||
'./panelMenu',
|
||||
],
|
||||
function (angular, $, config) {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('grafana.directives')
|
||||
.directive('grafanaPanel', function($compile, $parse) {
|
||||
|
||||
var container = '<div class="panel-container"></div>';
|
||||
var content = '<div class="panel-content"></div>';
|
||||
|
||||
var panelHeader =
|
||||
'<div class="panel-header">'+
|
||||
'<span class="alert-error panel-error small pointer"' +
|
||||
'config-modal="app/partials/inspector.html" ng-if="panelMeta.error">' +
|
||||
'<span data-placement="top" bs-tooltip="panelMeta.error">' +
|
||||
'<i class="fa fa-exclamation"></i><span class="panel-error-arrow"></span>' +
|
||||
'</span>' +
|
||||
'</span>' +
|
||||
|
||||
'<span class="panel-loading" ng-show="panelMeta.loading">' +
|
||||
'<i class="fa fa-spinner fa-spin"></i>' +
|
||||
'</span>' +
|
||||
|
||||
'<div class="panel-title-container drag-handle" panel-menu></div>' +
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, elem, attr) {
|
||||
var getter = $parse(attr.type), panelType = getter($scope);
|
||||
var newScope = $scope.$new();
|
||||
|
||||
// compile the module and uncloack. We're done
|
||||
function loadModule($module) {
|
||||
$module.appendTo(elem);
|
||||
elem.wrap(container);
|
||||
|
||||
$compile(elem.contents())(newScope);
|
||||
elem.removeClass("ng-cloak");
|
||||
|
||||
var panelCtrlElem = $(elem.children()[0]);
|
||||
var panelCtrlScope = panelCtrlElem.data().$scope;
|
||||
|
||||
panelCtrlScope.$watchGroup(['fullscreen', 'panel.height', 'row.height'], function() {
|
||||
panelCtrlElem.css({ minHeight: panelCtrlScope.panel.height || panelCtrlScope.row.height });
|
||||
panelCtrlElem.toggleClass('panel-fullscreen', panelCtrlScope.fullscreen ? true : false);
|
||||
});
|
||||
}
|
||||
|
||||
newScope.$on('$destroy',function() {
|
||||
elem.unbind();
|
||||
elem.remove();
|
||||
});
|
||||
|
||||
elem.addClass('ng-cloak');
|
||||
|
||||
var panelPath = config.panels[panelType].path;
|
||||
|
||||
$scope.require([
|
||||
'jquery',
|
||||
'text!'+panelPath+'/module.html',
|
||||
panelPath + "/module",
|
||||
], function ($, moduleTemplate) {
|
||||
var $module = $(moduleTemplate);
|
||||
$module.prepend(panelHeader);
|
||||
$module.first().find('.panel-header').nextAll().wrapAll(content);
|
||||
loadModule($module);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
});
|
@ -1,18 +1,4 @@
|
||||
<topnav toggle="toggleSideMenu()" icon="fa fa-shield" section="Account" show-menu-btn="!grafana.sidemenu">
|
||||
<!-- <ul class="nav"> -->
|
||||
<!-- <li> -->
|
||||
<!-- <a href="asd">Details</a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li> -->
|
||||
<!-- <a href="asd">Data Sources</a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li> -->
|
||||
<!-- <a href="asd">Users</a> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li> -->
|
||||
<!-- <a href="asd">API Keys</a> -->
|
||||
<!-- </li> -->
|
||||
<!-- </ul> -->
|
||||
</topnav>
|
||||
|
||||
<div class="gf-box" style="min-height: 500px">
|
||||
@ -34,6 +20,10 @@
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<panel-loader type="'test'"></panel-loader>
|
||||
|
||||
<br>
|
||||
<button type="submit" class="pull-right btn btn-success" ng-click="update()">Update</button>
|
||||
</form>
|
||||
|
@ -7,6 +7,7 @@ define([
|
||||
'./opentsdb/datasource',
|
||||
'./elasticsearch/datasource',
|
||||
'./dashboard/all',
|
||||
'./panel/all',
|
||||
'./profile/profileCtrl',
|
||||
'./account/accountUsersCtrl',
|
||||
'./account/datasourcesCtrl',
|
||||
|
@ -9,7 +9,6 @@ define([
|
||||
'./keybindings',
|
||||
'./viewStateSrv',
|
||||
'./playlistSrv',
|
||||
'./panelSrv',
|
||||
'./soloPanelCtrl',
|
||||
'./timeSrv',
|
||||
'./unsavedChangesSrv',
|
||||
|
@ -118,7 +118,7 @@ function (angular, _, $) {
|
||||
self.$scope.dashboard.emit_refresh();
|
||||
}
|
||||
else {
|
||||
self.fullscreenPanel.$emit('render');
|
||||
self.fullscreenPanel.$broadcast('render');
|
||||
}
|
||||
delete self.fullscreenPanel;
|
||||
});
|
||||
@ -139,7 +139,7 @@ function (angular, _, $) {
|
||||
panelScope.fullscreen = true;
|
||||
|
||||
$timeout(function() {
|
||||
panelScope.$emit('render');
|
||||
panelScope.$broadcast('render');
|
||||
});
|
||||
};
|
||||
|
||||
|
5
src/app/features/panel/all.js
Normal file
5
src/app/features/panel/all.js
Normal file
@ -0,0 +1,5 @@
|
||||
define([
|
||||
'./panelMenu',
|
||||
'./panelDirective',
|
||||
'./panelSrv',
|
||||
], function () {});
|
40
src/app/features/panel/panelDirective.js
Normal file
40
src/app/features/panel/panelDirective.js
Normal file
@ -0,0 +1,40 @@
|
||||
define([
|
||||
'angular',
|
||||
'jquery',
|
||||
'config',
|
||||
],
|
||||
function (angular, $, config) {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('grafana.directives')
|
||||
.directive('panelLoader', function($compile, $parse) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, elem, attr) {
|
||||
var getter = $parse(attr.type), panelType = getter(scope);
|
||||
var panelPath = config.panels[panelType].path;
|
||||
|
||||
scope.require([panelPath + "/module"], function () {
|
||||
var panelEl = angular.element(document.createElement('grafana-panel-' + panelType));
|
||||
elem.append(panelEl);
|
||||
$compile(panelEl)(scope);
|
||||
});
|
||||
}
|
||||
};
|
||||
}).directive('grafanaPanel', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: '/app/features/panel/partials/panel.html',
|
||||
transclude: true,
|
||||
link: function(scope, elem) {
|
||||
var panelContainer = elem.find('.panel-container');
|
||||
|
||||
scope.$watchGroup(['fullscreen', 'panel.height', 'row.height'], function() {
|
||||
panelContainer.css({ minHeight: scope.panel.height || scope.row.height, display: 'block' });
|
||||
elem.toggleClass('panel-fullscreen', scope.fullscreen ? true : false);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
42
src/app/features/panel/partials/panel.html
Normal file
42
src/app/features/panel/partials/panel.html
Normal file
@ -0,0 +1,42 @@
|
||||
<div class="panel-container">
|
||||
<div class="panel-header">
|
||||
<span class="alert-error panel-error small pointer" config-modal="app/partials/inspector.html" ng-if="panelMeta.error">
|
||||
<span data-placement="top" bs-tooltip="panelMeta.error">
|
||||
<i class="fa fa-exclamation"></i><span class="panel-error-arrow"></span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span class="panel-loading" ng-show="panelMeta.loading">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</span>
|
||||
|
||||
<div class="panel-title-container drag-handle" panel-menu></div>
|
||||
</div>
|
||||
|
||||
<div class="panel-content">
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-full-edit" ng-if="editMode">
|
||||
<div class="gf-box">
|
||||
<div class="gf-box-header">
|
||||
<div class="gf-box-title">
|
||||
<i ng-class="panelMeta.editIcon"></i>
|
||||
{{panelMeta.panelName}}
|
||||
</div>
|
||||
|
||||
<div ng-model="editor.index" bs-tabs>
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-box-body">
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
|
||||
<div ng-include src="tab.src"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div ng-controller='GraphCtrl'>
|
||||
<grafana-panel>
|
||||
|
||||
<div class="graph-wrapper" ng-class="{'graph-legend-rightside': panel.legend.rightSide}">
|
||||
<div class="graph-canvas-wrapper">
|
||||
@ -24,23 +24,6 @@
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-box gf-box-full-edit" ng-if="editMode">
|
||||
<div class="gf-box-header">
|
||||
<div class="gf-box-title">
|
||||
<i class="fa fa-bar-chart"></i>
|
||||
Graph
|
||||
</div>
|
||||
</grafana-panel>
|
||||
|
||||
<div ng-model="editor.index" bs-tabs>
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-box-body">
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
|
||||
<div ng-include src="tab.src"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -16,10 +16,18 @@ function (angular, app, $, _, kbn, moment, TimeSeries, PanelMeta) {
|
||||
|
||||
var module = angular.module('grafana.panels.graph');
|
||||
|
||||
module.directive('grafanaPanelGraph', function() {
|
||||
return {
|
||||
controller: 'GraphCtrl',
|
||||
templateUrl: '/app/panels/graph/module.html',
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, timeSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
description: 'Graph panel',
|
||||
panelName: 'Graph',
|
||||
editIcon: "fa fa-bar-chart",
|
||||
fullscreen: true,
|
||||
metricsEditor: true
|
||||
});
|
||||
|
@ -1,26 +1,4 @@
|
||||
<div ng-controller='SingleStatCtrl'>
|
||||
|
||||
<grafana-panel>
|
||||
<div class="singlestat-panel" singlestat-panel></div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-box gf-box-full-edit" ng-if="editMode">
|
||||
<div class="gf-box-header">
|
||||
<div class="gf-box-title">
|
||||
<i class="fa fa-dashboard"></i>
|
||||
Singlestat
|
||||
</div>
|
||||
|
||||
<div ng-model="editor.index" bs-tabs>
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-box-body">
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
|
||||
<div ng-include src="tab.src"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</grafana-panel>
|
||||
|
@ -13,10 +13,18 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
|
||||
var module = angular.module('grafana.panels.singlestat');
|
||||
app.useModule(module);
|
||||
|
||||
module.directive('grafanaPanelSinglestat', function() {
|
||||
return {
|
||||
controller: 'SingleStatCtrl',
|
||||
templateUrl: '/app/panels/singlestat/module.html',
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('SingleStatCtrl', function($scope, panelSrv, timeSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
description: 'Singlestat panel',
|
||||
panelName: 'Singlestat',
|
||||
editIcon: "fa fa-dashboard",
|
||||
fullscreen: true,
|
||||
metricsEditor: true
|
||||
});
|
||||
@ -192,7 +200,7 @@ function (angular, app, _, TimeSeries, kbn, PanelMeta) {
|
||||
data.colorMap = $scope.panel.colors;
|
||||
|
||||
$scope.data = data;
|
||||
$scope.$emit('render');
|
||||
$scope.$broadcast('render');
|
||||
};
|
||||
|
||||
$scope.getFormatedValue = function(mainValue) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
<div ng-controller='text'>
|
||||
<p ng-bind-html="content" ng-show="content">
|
||||
</p>
|
||||
</div>
|
||||
<grafana-panel>
|
||||
<p ng-bind-html="content" ng-show="content"></p>
|
||||
</grafana-panel>
|
||||
|
@ -8,15 +8,24 @@ define([
|
||||
function (angular, app, _, require, PanelMeta) {
|
||||
'use strict';
|
||||
|
||||
var converter;
|
||||
|
||||
var module = angular.module('grafana.panels.text', []);
|
||||
app.useModule(module);
|
||||
|
||||
var converter;
|
||||
module.directive('grafanaPanelText', function() {
|
||||
return {
|
||||
controller: 'TextPanelCtrl',
|
||||
templateUrl: '/app/panels/text/module.html',
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('text', function($scope, templateSrv, $sce, panelSrv) {
|
||||
module.controller('TextPanelCtrl', function($scope, templateSrv, $sce, panelSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
description : "A static text panel that can use plain text, markdown, or (sanitized) HTML"
|
||||
panelName: 'Text',
|
||||
editIcon: "fa fa-text-width",
|
||||
fullscreen: true,
|
||||
});
|
||||
|
||||
$scope.panelMeta.addEditorTab('Edit text', 'app/panels/text/editor.html');
|
||||
|
@ -79,12 +79,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Panels, draggable needs to be disabled in fullscreen because Firefox bug -->
|
||||
<div ng-repeat="(name, panel) in row.panels"
|
||||
class="panel"
|
||||
<div ng-repeat="(name, panel) in row.panels" class="panel"
|
||||
ui-draggable="{{!dashboardViewState.fullscreen}}" drag="panel.id"
|
||||
ui-on-Drop="onDrop($data, row, panel)"
|
||||
drag-handle-class="drag-handle" panel-width ng-model="panel">
|
||||
<grafana-panel type="panel.type" ng-cloak></grafana-panel>
|
||||
drag-handle-class="drag-handle" panel-width>
|
||||
<panel-loader type="panel.type" class="panel-margin"></panel-loader>
|
||||
</div>
|
||||
|
||||
<div panel-drop-zone class="panel panel-drop-zone"
|
||||
|
@ -1,22 +0,0 @@
|
||||
<div bindonce class="gf-box-header">
|
||||
<div class="gf-box-title">
|
||||
<i class="fa fa-text-width"></i>
|
||||
<span bo-text="panel.type+' settings'"></span>
|
||||
</div>
|
||||
|
||||
<div ng-model="editor.index" bs-tabs style="text-transform:capitalize;">
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="gf-box-header-close-btn" ng-click="dismiss();">
|
||||
<i class="fa fa-remove"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gf-box-body">
|
||||
<div ng-repeat="tab in panelMeta.editorTabs" ng-show="editor.index == $index">
|
||||
<div ng-include src="tab.src"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -58,7 +58,7 @@ function (angular, store) {
|
||||
$location.path('');
|
||||
return;
|
||||
}
|
||||
$scope.initDashboard(window.grafanaImportDashboard, $scope);
|
||||
$scope.initDashboard({ meta: {}, model: window.grafanaImportDashboard }, $scope);
|
||||
});
|
||||
|
||||
module.controller('NewDashboardCtrl', function($scope) {
|
||||
|
@ -5,10 +5,6 @@
|
||||
border: 1px solid @grafanaTargetFuncBackground;
|
||||
}
|
||||
|
||||
.gf-box-full-edit {
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
.gf-box-no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -5,10 +5,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
padding: 0px 0px 0px 0px;
|
||||
background: @grafanaPanelBackground;
|
||||
.panel-margin {
|
||||
margin: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
background: @grafanaPanelBackground;
|
||||
position: relative;
|
||||
&:hover {
|
||||
.panel-actions {
|
||||
@ -91,17 +94,17 @@
|
||||
top: 60px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
background: @grafanaPanelBackground;
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
|
||||
.panel-content {
|
||||
padding-bottom: 130px;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
margin-bottom: 70px;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
.panel-menu {
|
||||
top: 0px;
|
||||
}
|
||||
@ -110,6 +113,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.panel-full-edit {
|
||||
margin-top: 30px;
|
||||
padding-bottom: 130px;
|
||||
}
|
||||
|
||||
.panel-menu {
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
|
@ -1,6 +1,6 @@
|
||||
define([
|
||||
'helpers',
|
||||
'features/dashboard/panelSrv',
|
||||
'features/panel/panelSrv',
|
||||
'panels/graph/module'
|
||||
], function(helpers) {
|
||||
'use strict';
|
||||
|
Loading…
Reference in New Issue
Block a user