Commit dbafc8c9 by Torkel Ödegaard

feat(plugins): work on plugin directive loading

parent 6c6c3a50
...@@ -4,4 +4,5 @@ define([ ...@@ -4,4 +4,5 @@ define([
'./panel_srv', './panel_srv',
'./panel_helper', './panel_helper',
'./solo_panel_ctrl', './solo_panel_ctrl',
'./panel_loader',
], function () {}); ], function () {});
define([ define([
'angular', 'angular',
'jquery', 'jquery',
'app/core/config',
], ],
function (angular, $, config) { function (angular, $) {
'use strict'; 'use strict';
var module = angular.module('grafana.directives'); var module = angular.module('grafana.directives');
module.directive('panelLoader', function($compile, $parse) {
return {
restrict: 'E',
link: function(scope, elem, attr) {
var getter = $parse(attr.type), panelType = getter(scope);
var module = config.panels[panelType].module;
System.import(module).then(function() {
var panelEl = angular.element(document.createElement('grafana-panel-' + panelType));
elem.append(panelEl);
$compile(panelEl)(scope);
}).catch(function(err) {
console.log('Failed to load panel:', err);
scope.appEvent('alert-error', ['Panel Load Error', 'Failed to load panel ' + panelType + ', ' + err]);
});
}
};
});
module.directive('grafanaPanel', function() { module.directive('grafanaPanel', function() {
return { return {
restrict: 'E', restrict: 'E',
......
///<reference path="../../headers/common.d.ts" />
import angular from 'angular';
import config from 'app/core/config';
/** @ngInject */
function panelLoader($parse, dynamicDirectiveSrv) {
return dynamicDirectiveSrv.create({
directive: scope => {
let modulePath = config.panels[scope.panel.type].module;
return System.import(modulePath).then(function(panelModule) {
return {
name: 'panel-directive-' + scope.panel.type,
fn: panelModule.panel,
};
});
},
});
}
angular.module('grafana.directives').directive('panelLoader', panelLoader);
<div class="editor-row" style="margin-bottom: 20px;">
<span style="float: right; font-size: 12px;"><i>Last updated by Grafana October 4, 2015 12:15:04 by $username</i></span>
<div class="section">
<h5>General Alerting Options</h5>
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item">
Alert Title
</li>
<li>
<input type="text" class="input-xlarge tight-form-input"></input>
</li>
<li class="tight-form-item">
Alerting Backend
</li>
<li>
<select class="input-medium tight-form-input">
<option>Grafana Alerting</option>
</select>
</li>
<li class="tight-form-item last">
<label class="checkbox-label" for="alerting-enabled">Enabled</label>
<input class="cr1" id="alerting-enabled" type="checkbox">
<label for="alerting-enabled" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="editor-row" style="margin-bottom: 20px;">
<h5>Choose your query:</h5>
<p>Select an exising query to alert on:</p>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item">None</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
<li class="tight-form-item">apps</li>
<li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
<li class="tight-form-item">fakesite</li>
<li class="tight-form-item">counters</li>
<li class="tight-form-item">requests</li>
<li class="tight-form-item">count</li>
<li class="tight-form-item">scaleToSeconds(1)</li>
<li class="tight-form-item last">aliasByNode(2)</li>
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item" style="min-width: 15px; text-align: center">B</li>
<li class="tight-form-item last"><span class="query-keyword">Metric:</span> us-west-2 AWS/EC2 CPUUtilization <span class="query-keyword">Stats:</span> Minimum Maximum <span class="query-keyword">Dimensions</span> InstanceIS <span class="query-segment-operator">=</span> i-b0e8a447 <span class="query-keyword">Alias</span> {{stat}} <span class="query-keyword">Period</span> 60</li>
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item" style="min-width: 15px; text-align: center">C</li>
<li class="tight-form-item last"><span class="query-keyword">Query:</span> avg(counters_logins) by(server) <span class="query-keyword">Legend Format:</span> {{app}} - {{server}} <span class="query-keyword">Step:</span> 1s <span class="query-keyword">Resolution:</span> 1/2</li>
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item" style="min-width: 15px; text-align: center">D</li>
<li class="tight-form-item last"><span class="query-keyword">SELECT</span> mean(value) <span class="query-keyword">FROM</span> logins.count <span class="query-keyword">WHERE</span> hostname <span class="query-segment-operator">=</span> /$Hostname$/ <span class="query-keyword">GROUP BY</span> time($internal) hostname</li>
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" checked /></li>
<li class="tight-form-item" style="min-width: 15px; text-align: center">E</li>
<li class="tight-form-item last"><span class="query-keyword">Metric:</span> apps.backend.backend_01.counters.requests.count <span class="query-keyword">Alias:</span> Bristow <span class="query-keyword">Aggregator:</span> Sum <span class="query-keyword">Downsample:</span> 1m <span class="query-keyword">Aggregator</span> Sum <span class="query-keyword">Tags</span> host = test</li>
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
</ul>
<div class="clearfix"></div>
</div>
</div>
<div class="editor-row" style="margin-bottom: 20px;">
<p>Or write a new custom alerting query:</p>
<div class="section">
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
<li class="tight-form-item">
<a class="pointer">
<i class="fa fa-pencil"></i>
</a>
</li>
<li class="tight-form-item">
select metric
</li>
<li>
<a class="tight-form-item tight-form-func last dropdown-toggle"><i class="fa fa-plus"></i></a>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="editor-row" style="margin-bottom: 10px;">
<div class="section">
<h5>Define Your States</h5>
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item">
by
</li>
<li>
<select class="input-medium tight-form-input">
<option>Averaging</option>
</select>
</li>
<li class="tight-form-item">
the values in the query over the last
</li>
<li>
<input type="text" class="input-mini tight-form-input last"></input>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="editor-row" style="margin-bottom: 20px;">
<div class="section">
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
<span class="alert-state alert-state-warning">Warn</span>
</li>
<li>
<input type="text" class="input-mini tight-form-input" value=">" style="text-align: center;"></input>
</li>
<li>
<input type="text" class="input-mini tight-form-input" value="#B" style="text-align: center;"></input>
</li>
<li class="tight-form-item">
.notify
</li>
<li class="alert-notify-emails">
<bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
</li>
<li class="tight-form-item last">
<label class="checkbox-label" for="state-enabled">Enabled</label>
<input class="cr1" id="state-enabled" type="checkbox">
<label for="state-enabled" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
<span class="alert-state alert-state-critical">Critical</span>
</li>
<li>
<input type="text" class="input-mini tight-form-input"></input>
</li>
<li>
<input type="text" class="input-mini tight-form-input"></input>
</li>
<li class="tight-form-item">
.notify
</li>
<li class="alert-notify-emails">
<bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
</li>
<li class="tight-form-item last">
<label class="checkbox-label" for="state-enabled2">Enabled</label>
<input class="cr1" id="state-enabled2" type="checkbox">
<label for="state-enabled2" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
<div class="editor-row">
<div class="section">
<h5>What to Say <span style="float: right; font-size: 12px; font-weight: normal;"><a href="#">Variables</a> | <a href="#">Preview</a></span></h5>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
Summary
</li>
<li>
<input type="text" class="input-xxlarge tight-form-input last"></input>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form last">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 100px;">
Description
</li>
<li>
<textarea class="tight-form-textarea input-xxlarge last"></textarea>
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
<div ng-repeat="(name, panel) in row.panels track by panel.id" class="panel" ui-draggable="!dashboardViewState.fullscreen" drag="panel.id" <div ng-repeat="(name, panel) in row.panels track by panel.id" class="panel" ui-draggable="!dashboardViewState.fullscreen" drag="panel.id"
ui-on-Drop="onDrop($data, row, panel)" drag-handle-class="drag-handle" panel-width> ui-on-Drop="onDrop($data, row, panel)" drag-handle-class="drag-handle" panel-width>
<panel-loader type="panel.type" class="panel-margin"></panel-loader> <panel-loader class="panel-margin"></panel-loader>
</div> </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="onDrop($data, row)" data-drop="true">
......
...@@ -11,14 +11,8 @@ function (angular, app, _, config, PanelMeta) { ...@@ -11,14 +11,8 @@ function (angular, app, _, config, PanelMeta) {
var module = angular.module('grafana.panels.dashlist', []); var module = angular.module('grafana.panels.dashlist', []);
app.useModule(module); app.useModule(module);
module.directive('grafanaPanelDashlist', function() { /** @ngInject */
return { function DashListPanelCtrl($scope, panelSrv, backendSrv) {
controller: 'DashListPanelCtrl',
templateUrl: 'app/plugins/panel/dashlist/module.html',
};
});
module.controller('DashListPanelCtrl', function($scope, panelSrv, backendSrv) {
$scope.panelMeta = new PanelMeta({ $scope.panelMeta = new PanelMeta({
panelName: 'Dashboard list', panelName: 'Dashboard list',
...@@ -73,5 +67,16 @@ function (angular, app, _, config, PanelMeta) { ...@@ -73,5 +67,16 @@ function (angular, app, _, config, PanelMeta) {
}; };
$scope.init(); $scope.init();
}); }
function dashListPanelDirective() {
return {
controller: DashListPanelCtrl,
templateUrl: 'app/plugins/panel/dashlist/module.html',
};
}
return {
panel: dashListPanelDirective
};
}); });
...@@ -4,7 +4,7 @@ define([ ...@@ -4,7 +4,7 @@ define([
'moment', 'moment',
'lodash', 'lodash',
'app/core/utils/kbn', 'app/core/utils/kbn',
'./graph.tooltip', './graph_tooltip',
'jquery.flot', 'jquery.flot',
'jquery.flot.events', 'jquery.flot.events',
'jquery.flot.selection', 'jquery.flot.selection',
......
declare var GraphTooltip: any;
export default GraphTooltip;
declare var panel: any;
declare var GraphCtrl: any;
export {panel, GraphCtrl};
...@@ -12,16 +12,8 @@ define([ ...@@ -12,16 +12,8 @@ define([
function (angular, _, moment, kbn, TimeSeries, PanelMeta) { function (angular, _, moment, kbn, TimeSeries, PanelMeta) {
'use strict'; 'use strict';
var module = angular.module('grafana.panels.graph'); /** @ngInject */
function GraphCtrl($scope, $rootScope, panelSrv, annotationsSrv, panelHelper) {
module.directive('grafanaPanelGraph', function() {
return {
controller: 'GraphCtrl',
templateUrl: 'app/plugins/panel/graph/module.html',
};
});
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, panelHelper) {
$scope.panelMeta = new PanelMeta({ $scope.panelMeta = new PanelMeta({
panelName: 'Graph', panelName: 'Graph',
...@@ -294,7 +286,17 @@ function (angular, _, moment, kbn, TimeSeries, PanelMeta) { ...@@ -294,7 +286,17 @@ function (angular, _, moment, kbn, TimeSeries, PanelMeta) {
}; };
panelSrv.init($scope); panelSrv.init($scope);
}
}); function graphPanelDirective() {
return {
controller: GraphCtrl,
templateUrl: 'app/plugins/panel/graph/module.html',
};
}
return {
GraphCtrl: GraphCtrl,
panel: graphPanelDirective,
};
}); });
define([ ///<reference path="../../../../headers/common.d.ts" />
'./helpers',
'app/features/panel/panel_srv', import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
'app/features/panel/panel_helper',
'app/plugins/panel/graph/module' import 'app/features/panel/panel_srv';
], function(helpers) { import 'app/features/panel/panel_helper';
'use strict';
import angular from 'angular';
describe('GraphCtrl', function() { import {GraphCtrl} from '../module';
import helpers from '../../../../../test/specs/helpers';
angular.module('grafana.controllers').controller('GraphCtrl', GraphCtrl);
describe('GraphCtrl', function() {
var ctx = new helpers.ControllerTestContext(); var ctx = new helpers.ControllerTestContext();
beforeEach(module('grafana.services')); beforeEach(angularMocks.module('grafana.services'));
beforeEach(module('grafana.panels.graph')); beforeEach(angularMocks.module('grafana.controllers'));
beforeEach(ctx.providePhase()); beforeEach(ctx.providePhase());
beforeEach(ctx.createControllerPhase('GraphCtrl')); beforeEach(ctx.createControllerPhase('GraphCtrl'));
...@@ -45,7 +50,4 @@ define([ ...@@ -45,7 +50,4 @@ define([
}); });
});
}); });
define([ ///<reference path="../../../../headers/common.d.ts" />
'./helpers',
'angular',
'jquery',
'app/core/time_series',
'app/plugins/panel/graph/graph'
], function(helpers, angular, $, TimeSeries) {
'use strict';
describe('grafanaGraph', function() { import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
beforeEach(module('grafana.directives')); import '../module';
import angular from 'angular';
import $ from 'jquery';
import helpers from '../../../../../test/specs/helpers';
import TimeSeries from '../../../../core/time_series2';
describe('grafanaGraph', function() {
beforeEach(angularMocks.module('grafana.directives'));
function graphScenario(desc, func) { function graphScenario(desc, func) {
describe(desc, function() { describe(desc, function() {
var ctx = {}; var ctx: any = {};
ctx.setup = function (setupFunc) { ctx.setup = function(setupFunc) {
beforeEach(module(function($provide) { beforeEach(angularMocks.module(function($provide) {
$provide.value("timeSrv", new helpers.TimeSrvStub()); $provide.value("timeSrv", new helpers.TimeSrvStub());
})); }));
beforeEach(inject(function($rootScope, $compile) { beforeEach(angularMocks.inject(function($rootScope, $compile) {
var scope = $rootScope.$new(); var scope = $rootScope.$new();
var element = angular.element("<div style='width:500px' grafana-graph><div>"); var element = angular.element("<div style='width:500px' grafana-graph><div>");
...@@ -226,6 +227,4 @@ define([ ...@@ -226,6 +227,4 @@ define([
expect(axis.tickFormatter(100, axis)).to.be("100%"); expect(axis.tickFormatter(100, axis)).to.be("100%");
}); });
}); });
});
}); });
define([ ///<reference path="../../../../headers/common.d.ts" />
'jquery',
'app/plugins/panel/graph/graph.tooltip'
], function($, GraphTooltip) {
'use strict';
var scope = { import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
import $ from 'jquery';
import GraphTooltip from '../graph_tooltip';
var scope = {
appEvent: sinon.spy(), appEvent: sinon.spy(),
onAppEvent: sinon.spy(), onAppEvent: sinon.spy(),
}; };
var elem = $('<div></div>'); var elem = $('<div></div>');
var dashboard = { }; var dashboard = { };
function describeSharedTooltip(desc, fn) { function describeSharedTooltip(desc, fn) {
var ctx = {}; var ctx: any = {};
ctx.scope = scope; ctx.scope = scope;
ctx.scope.panel = { ctx.scope.panel = {
tooltip: { tooltip: {
...@@ -36,9 +37,9 @@ define([ ...@@ -36,9 +37,9 @@ define([
fn(ctx); fn(ctx);
}); });
} }
describeSharedTooltip("steppedLine false, stack false", function(ctx) { describeSharedTooltip("steppedLine false, stack false", function(ctx) {
ctx.setup(function() { ctx.setup(function() {
ctx.data = [ ctx.data = [
{ data: [[10, 15], [12, 20]], lines: {} }, { data: [[10, 15], [12, 20]], lines: {} },
...@@ -58,9 +59,9 @@ define([ ...@@ -58,9 +59,9 @@ define([
expect(ctx.results[1].value).to.be(2); expect(ctx.results[1].value).to.be(2);
expect(ctx.results[0].hoverIndex).to.be(0); expect(ctx.results[0].hoverIndex).to.be(0);
}); });
}); });
describeSharedTooltip("one series is hidden", function(ctx) { describeSharedTooltip("one series is hidden", function(ctx) {
ctx.setup(function() { ctx.setup(function() {
ctx.data = [ ctx.data = [
{ data: [[10, 15], [12, 20]], }, { data: [[10, 15], [12, 20]], },
...@@ -68,9 +69,9 @@ define([ ...@@ -68,9 +69,9 @@ define([
]; ];
ctx.pos = { x: 11 }; ctx.pos = { x: 11 };
}); });
}); });
describeSharedTooltip("steppedLine false, stack true, individual false", function(ctx) { describeSharedTooltip("steppedLine false, stack true, individual false", function(ctx) {
ctx.setup(function() { ctx.setup(function() {
ctx.data = [ ctx.data = [
{ {
...@@ -99,9 +100,9 @@ define([ ...@@ -99,9 +100,9 @@ define([
it('should show stacked value', function() { it('should show stacked value', function() {
expect(ctx.results[1].value).to.be(17); expect(ctx.results[1].value).to.be(17);
}); });
}); });
describeSharedTooltip("steppedLine false, stack true, individual false, series stack false", function(ctx) { describeSharedTooltip("steppedLine false, stack true, individual false, series stack false", function(ctx) {
ctx.setup(function() { ctx.setup(function() {
ctx.data = [ ctx.data = [
{ {
...@@ -131,9 +132,9 @@ define([ ...@@ -131,9 +132,9 @@ define([
expect(ctx.results[1].value).to.be(2); expect(ctx.results[1].value).to.be(2);
}); });
}); });
describeSharedTooltip("steppedLine false, stack true, individual true", function(ctx) { describeSharedTooltip("steppedLine false, stack true, individual true", function(ctx) {
ctx.setup(function() { ctx.setup(function() {
ctx.data = [ ctx.data = [
{ {
...@@ -164,8 +165,7 @@ define([ ...@@ -164,8 +165,7 @@ define([
expect(ctx.results[1].value).to.be(2); expect(ctx.results[1].value).to.be(2);
}); });
});
}); });
declare module "test/specs/helpers" { declare let helpers: any;
let helpers: any; export default helpers;
export default helpers;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment