Commit 12f487e2 by Torkel Ödegaard

feat(plugin-editors): more work on plugin editor loading

parent 30a8a434
...@@ -16,6 +16,8 @@ import "./directives/password_strenght"; ...@@ -16,6 +16,8 @@ import "./directives/password_strenght";
import "./directives/spectrum_picker"; import "./directives/spectrum_picker";
import "./directives/tags"; import "./directives/tags";
import "./directives/value_select_dropdown"; import "./directives/value_select_dropdown";
import "./directives/plugin_directive_loader";
import "./directives/rebuild_on_change";
import "./directives/give_focus"; import "./directives/give_focus";
import './jquery_extended'; import './jquery_extended';
import './partials'; import './partials';
......
///<reference path="../../headers/common.d.ts" />
import angular from 'angular';
import _ from 'lodash';
import coreModule from '../core_module';
function pluginDirectiveLoader($compile, datasourceSrv) {
function getPluginComponentDirective(options) {
return function() {
return {
templateUrl: options.Component.templateUrl,
restrict: 'E',
controller: options.Component,
controllerAs: 'ctrl',
bindToController: true,
scope: options.bindings,
link: (scope, elem, attrs, ctrl) => {
if (ctrl.link) {
ctrl.link(scope, elem, attrs, ctrl);
}
}
};
};
}
function getModule(scope, attrs) {
switch (attrs.type) {
case "metrics-query-editor":
let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
return datasourceSrv.get(datasource).then(ds => {
if (!scope.target.refId) {
scope.target.refId = 'A';
}
return System.import(ds.meta.module).then(dsModule => {
return {
name: 'metrics-query-editor-' + ds.meta.id,
bindings: {target: "=", panelCtrl: "="},
attrs: {"target": "target", "panel-ctrl": "ctrl"},
Component: dsModule.MetricsQueryEditor
};
});
});
case 'datasource-config-view':
return System.import(scope.datasourceMeta.module).then(function(dsModule) {
return {
name: 'ds-config-' + scope.datasourceMeta.id,
bindings: {meta: "=", current: "="},
attrs: {meta: "datasourceMeta", current: "current"},
Component: dsModule.ConfigView,
};
});
}
}
function appendAndCompile(scope, elem, componentInfo) {
console.log('compile', elem, componentInfo);
var child = angular.element(document.createElement(componentInfo.name));
_.each(componentInfo.attrs, (value, key) => {
child.attr(key, value);
});
$compile(child)(scope);
elem.empty();
elem.append(child);
}
function registerPluginComponent(scope, elem, attrs, componentInfo) {
if (!componentInfo.Component.registered) {
var directiveName = attrs.$normalize(componentInfo.name);
var directiveFn = getPluginComponentDirective(componentInfo);
coreModule.directive(directiveName, directiveFn);
componentInfo.Component.registered = true;
}
appendAndCompile(scope, elem, componentInfo);
}
return {
restrict: 'E',
link: function(scope, elem, attrs) {
getModule(scope, attrs).then(function (componentInfo) {
registerPluginComponent(scope, elem, attrs, componentInfo);
});
}
};
}
coreModule.directive('pluginDirectiveLoader', pluginDirectiveLoader);
///<reference path="../../headers/common.d.ts" />
import angular from 'angular';
import _ from 'lodash';
import $ from 'jquery';
import coreModule from '../core_module';
function getBlockNodes(nodes) {
var node = nodes[0];
var endNode = nodes[nodes.length - 1];
var blockNodes;
for (var i = 1; node !== endNode && (node = node.nextSibling); i++) {
if (blockNodes || nodes[i] !== node) {
if (!blockNodes) {
blockNodes = $([].slice.call(nodes, 0, i));
}
blockNodes.push(node);
}
}
return blockNodes || nodes;
}
function rebuildOnChange($compile) {
return {
transclude: true,
priority: 600,
restrict: 'A',
link: function(scope, elem, attrs, ctrl, transclude) {
var childScope, previousElements;
var uncompiledHtml;
scope.$watch(attrs.rebuildOnChange, function rebuildOnChangeAction(value) {
if (childScope) {
childScope.$destroy();
childScope = null;
elem.empty();
}
if (value) {
if (!childScope) {
transclude(function(clone, newScope) {
childScope = newScope;
elem.append($compile(clone)(childScope));
});
}
}
});
}
};
}
coreModule.directive('rebuildOnChange', rebuildOnChange);
...@@ -41,7 +41,12 @@ ...@@ -41,7 +41,12 @@
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<ds-config-view ng-if="datasourceMeta.id" ds-meta="datasourceMeta" current="current"></ds-config-view> <div rebuild-on-change="datasourceMeta.id">
<plugin-directive-loader type="datasource-config-view">
</plugin-directive-loader>
</div>
<!-- <ds&#45;config&#45;view ds&#45;meta="datasourceMeta" current="current"></ds&#45;config&#45;view> -->
<div ng-if="testing" style="margin-top: 25px"> <div ng-if="testing" style="margin-top: 25px">
<h5 ng-show="!testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5> <h5 ng-show="!testing.done">Testing.... <i class="fa fa-spiner fa-spin"></i></h5>
......
...@@ -50,7 +50,7 @@ var module = angular.module('grafana.directives'); ...@@ -50,7 +50,7 @@ var module = angular.module('grafana.directives');
module.directive('grafanaPanel', function() { module.directive('grafanaPanel', function() {
return { return {
restrict: 'E', restrict: 'E',
templateUrl: 'app/features/panel/partials/panel.html', templateUrl: 'public/app/features/panel/partials/panel.html',
transclude: true, transclude: true,
scope: { ctrl: "=" }, scope: { ctrl: "=" },
link: function(scope, elem) { link: function(scope, elem) {
......
...@@ -5,105 +5,6 @@ import _ from 'lodash'; ...@@ -5,105 +5,6 @@ import _ from 'lodash';
var directivesModule = angular.module('grafana.directives'); var directivesModule = angular.module('grafana.directives');
function pluginDirectiveLoader($compile, datasourceSrv) {
function getPluginComponentDirective(options) {
return function() {
return {
templateUrl: options.Component.templateUrl,
restrict: 'E',
controller: options.Component,
controllerAs: 'ctrl',
bindToController: true,
scope: options.bindings,
link: (scope, elem, attrs, ctrl) => {
if (ctrl.link) {
ctrl.link(scope, elem, attrs, ctrl);
}
}
};
};
}
function getModule(scope, attrs) {
switch (attrs.type) {
case "metrics-query-editor": {
let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
return datasourceSrv.get(datasource).then(ds => {
if (!scope.target.refId) {
scope.target.refId = 'A';
}
return System.import(ds.meta.module).then(dsModule => {
return {
name: 'metrics-query-editor-' + ds.meta.id,
bindings: {target: "=", panelCtrl: "="},
attrs: {"target": "target", "panel-ctrl": "ctrl"},
Component: dsModule.MetricsQueryEditor
};
});
});
}
}
}
function appendAndCompile(scope, elem, componentInfo) {
var child = angular.element(document.createElement(componentInfo.name));
_.each(componentInfo.attrs, (value, key) => {
child.attr(key, value);
});
$compile(child)(scope);
elem.empty();
elem.append(child);
}
function registerPluginComponent(scope, elem, attrs, componentInfo) {
if (!componentInfo.Component.registered) {
var directiveName = attrs.$normalize(componentInfo.name);
var directiveFn = getPluginComponentDirective(componentInfo);
directivesModule.directive(directiveName, directiveFn);
componentInfo.Component.registered = true;
}
appendAndCompile(scope, elem, componentInfo);
}
return {
restrict: 'E',
link: function(scope, elem, attrs) {
getModule(scope, attrs).then(function (componentInfo) {
registerPluginComponent(scope, elem, attrs, componentInfo);
});
}
};
}
/** @ngInject */
function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
return dynamicDirectiveSrv.create({
watchPath: "ctrl.panel.datasource",
directive: scope => {
let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
return datasourceSrv.get(datasource).then(ds => {
scope.datasource = ds;
if (!scope.target.refId) {
scope.target.refId = 'A';
}
return System.import(ds.meta.module).then(dsModule => {
return {
name: 'metrics-query-editor-' + ds.meta.id,
fn: dsModule.metricsQueryEditor,
};
});
});
}
});
}
/** @ngInject */ /** @ngInject */
function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) { function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
return dynamicDirectiveSrv.create({ return dynamicDirectiveSrv.create({
...@@ -121,6 +22,4 @@ function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) { ...@@ -121,6 +22,4 @@ function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
}); });
} }
directivesModule.directive('pluginDirectiveLoader', pluginDirectiveLoader);
directivesModule.directive('metricsQueryEditor', metricsQueryEditor);
directivesModule.directive('metricsQueryOptions', metricsQueryOptions); directivesModule.directive('metricsQueryOptions', metricsQueryOptions);
...@@ -23,11 +23,16 @@ function (GraphiteDatasource) { ...@@ -23,11 +23,16 @@ function (GraphiteDatasource) {
return {templateUrl: 'public/app/plugins/datasource/graphite/partials/config.html'}; return {templateUrl: 'public/app/plugins/datasource/graphite/partials/config.html'};
} }
function ConfigView() {
}
ConfigView.templateUrl = 'public/app/plugins/datasource/graphite/partials/config.html';
return { return {
Datasource: GraphiteDatasource, Datasource: GraphiteDatasource,
configView: configView, configView: configView,
annotationsQueryEditor: annotationsQueryEditor, annotationsQueryEditor: annotationsQueryEditor,
metricsQueryEditor: metricsQueryEditor, metricsQueryEditor: metricsQueryEditor,
metricsQueryOptions: metricsQueryOptions, metricsQueryOptions: metricsQueryOptions,
ConfigView: ConfigView
}; };
}); });
declare var Datasource: any;
export default Datasource;
define([ ///<reference path="../../../headers/common.d.ts" />
'angular',
'lodash', import angular from 'angular';
'moment', import _ from 'lodash';
'app/core/utils/datemath', import moment from 'moment';
'./query_ctrl',
], import * as dateMath from 'app/core/utils/datemath';
function (angular, _, moment, dateMath) {
'use strict'; var durationSplitRegexp = /(\d+)(ms|s|m|h|d|w|M|y)/;
var durationSplitRegexp = /(\d+)(ms|s|m|h|d|w|M|y)/; /** @ngInject */
function PrometheusDatasource(instanceSettings, $q, backendSrv, templateSrv) {
/** @ngInject */
function PrometheusDatasource(instanceSettings, $q, backendSrv, templateSrv) {
this.type = 'prometheus'; this.type = 'prometheus';
this.editorSrc = 'app/features/prometheus/partials/query.editor.html'; this.editorSrc = 'app/features/prometheus/partials/query.editor.html';
this.name = instanceSettings.name; this.name = instanceSettings.name;
...@@ -23,7 +21,7 @@ function (angular, _, moment, dateMath) { ...@@ -23,7 +21,7 @@ function (angular, _, moment, dateMath) {
this.lastErrors = {}; this.lastErrors = {};
this._request = function(method, url) { this._request = function(method, url) {
var options = { var options: any = {
url: this.url + url, url: this.url + url,
method: method method: method
}; };
...@@ -52,7 +50,7 @@ function (angular, _, moment, dateMath) { ...@@ -52,7 +50,7 @@ function (angular, _, moment, dateMath) {
return; return;
} }
var query = {}; var query: any = {};
query.expr = templateSrv.replace(target.expr, options.scopedVars); query.expr = templateSrv.replace(target.expr, options.scopedVars);
var interval = target.interval || options.interval; var interval = target.interval || options.interval;
...@@ -121,8 +119,7 @@ function (angular, _, moment, dateMath) { ...@@ -121,8 +119,7 @@ function (angular, _, moment, dateMath) {
var interpolated; var interpolated;
try { try {
interpolated = templateSrv.replace(query); interpolated = templateSrv.replace(query);
} } catch (err) {
catch (err) {
return $q.reject(err); return $q.reject(err);
} }
...@@ -270,13 +267,12 @@ function (angular, _, moment, dateMath) { ...@@ -270,13 +267,12 @@ function (angular, _, moment, dateMath) {
return metricName + '{' + labelPart + '}'; return metricName + '{' + labelPart + '}';
} }
function getPrometheusTime(date, roundUp) { function getPrometheusTime(date, roundUp): number {
if (_.isString(date)) { if (_.isString(date)) {
date = dateMath.parse(date, roundUp); date = dateMath.parse(date, roundUp);
} }
return (date.valueOf() / 1000).toFixed(0); return Math.floor(date.valueOf() / 1000);
}
} }
}
return PrometheusDatasource; export {PrometheusDatasource};
});
define([
'./datasource',
],
function (PromDatasource) {
'use strict';
function metricsQueryEditor() {
return {controller: 'PrometheusQueryCtrl', templateUrl: 'public/app/plugins/datasource/prometheus/partials/query.editor.html'};
}
function configView() {
return {templateUrl: 'public/app/plugins/datasource/prometheus/partials/config.html'};
}
return {
Datasource: PromDatasource,
metricsQueryEditor: metricsQueryEditor,
configView: configView,
};
});
import {PrometheusDatasource} from './datasource';
import {PrometheusQueryCtrl} from './query_ctrl';
// function metricsQueryEditor() {
// return {controller: 'PrometheusQueryCtrl', templateUrl: 'public/app/plugins/datasource/prometheus/partials/query.editor.html'};
// }
//
// function configView() {
// return {templateUrl: ''};
// }
class PrometheusConfigViewCtrl {
static templateUrl = 'public/app/plugins/datasource/prometheus/partials/config.html';
}
export {
PrometheusDatasource as Datasource,
PrometheusQueryCtrl as MetricsQueryEditor,
PrometheusConfigViewCtrl as ConfigView
};
define([ ///<reference path="../../../headers/common.d.ts" />
'angular',
'lodash',
],
function (angular, _) {
'use strict';
var module = angular.module('grafana.controllers'); import angular from 'angular';
import _ from 'lodash';
import moment from 'moment';
module.controller('PrometheusQueryCtrl', function($scope, templateSrv) { import * as dateMath from 'app/core/utils/datemath';
function PrometheusQueryCtrl($scope, templateSrv) {
$scope.panelCtrl = $scope.ctrl; $scope.panelCtrl = $scope.ctrl;
$scope.panel = $scope.panelCtrl.panel; $scope.panel = $scope.panelCtrl.panel;
...@@ -62,6 +61,6 @@ function (angular, _) { ...@@ -62,6 +61,6 @@ function (angular, _) {
}; };
$scope.init(); $scope.init();
}); }
}); export {PrometheusQueryCtrl};
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
<script src="[[.AppSubUrl]]/public/vendor/npm/es5-shim/es5-shim.js"></script> <script src="[[.AppSubUrl]]/public/vendor/npm/es5-shim/es5-shim.js"></script>
<script src="[[.AppSubUrl]]/public/vendor/npm/es6-shim/es6-shim.js"></script> <script src="[[.AppSubUrl]]/public/vendor/npm/es6-shim/es6-shim.js"></script>
<script src="[[.AppSubUrl]]/public/vendor/npm/es6-promise/dist/es6-promise.js"></script> <script src="[[.AppSubUrl]]/public/vendor/npm/es6-promise/dist/es6-promise.js"></script>
<script src="[[.AppSubUrl]]/public/vendor/npm/systemjs/dist/system-polyfills.js"></script>
<script src="[[.AppSubUrl]]/public/vendor/npm/systemjs/dist/system.src.js"></script> <script src="[[.AppSubUrl]]/public/vendor/npm/systemjs/dist/system.src.js"></script>
<script src="[[.AppSubUrl]]/public/app/system.conf.js"></script> <script src="[[.AppSubUrl]]/public/app/system.conf.js"></script>
<script src="[[.AppSubUrl]]/public/app/boot.js"></script> <script src="[[.AppSubUrl]]/public/app/boot.js"></script>
......
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