Commit eaaf9246 by Torkel Ödegaard

feat(plugins): more work on refining datasource editors

parent 0583ec0f
......@@ -16,7 +16,7 @@ import "./directives/password_strenght";
import "./directives/spectrum_picker";
import "./directives/tags";
import "./directives/value_select_dropdown";
import "./directives/plugin_directive_loader";
import "./directives/plugin_component";
import "./directives/rebuild_on_change";
import "./directives/give_focus";
import './jquery_extended';
......
///<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 => {
scope.datasource = ds;
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) {
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('pluginComponent', pluginDirectiveLoader);
......@@ -5,7 +5,8 @@ import _ from 'lodash';
import coreModule from '../core_module';
function pluginDirectiveLoader($compile, datasourceSrv) {
/** @ngInject */
function pluginComponentLoader($compile, datasourceSrv) {
function getPluginComponentDirective(options) {
return function() {
......@@ -88,4 +89,4 @@ function pluginDirectiveLoader($compile, datasourceSrv) {
};
}
coreModule.directive('pluginDirectiveLoader', pluginDirectiveLoader);
coreModule.directive('pluginComponent', pluginComponentLoader);
......@@ -177,42 +177,6 @@ function (angular, $, _, moment) {
return newPanel;
};
p.getNextQueryLetter = function(panel) {
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return _.find(letters, function(refId) {
return _.every(panel.targets, function(other) {
return other.refId !== refId;
});
});
};
p.addDataQueryTo = function(panel, datasource) {
var target = {
refId: this.getNextQueryLetter(panel)
};
if (datasource) {
target.datasource = datasource.name;
}
panel.targets.push(target);
};
p.removeDataQuery = function (panel, query) {
panel.targets = _.without(panel.targets, query);
};
p.duplicateDataQuery = function(panel, query) {
var clone = angular.copy(query);
clone.refId = this.getNextQueryLetter(panel);
panel.targets.push(clone);
};
p.moveDataQuery = function(panel, fromIndex, toIndex) {
_.move(panel.targets, fromIndex, toIndex);
};
p.formatDate = function(date, format) {
date = moment.isMoment(date) ? date : moment(date);
format = format || 'YYYY-MM-DD HH:mm:ss';
......
......@@ -193,23 +193,6 @@ class MetricsPanelCtrl extends PanelCtrl {
});
}
addDataQuery(datasource) {
this.dashboard.addDataQueryTo(this.panel, datasource);
}
removeDataQuery(query) {
this.dashboard.removeDataQuery(this.panel, query);
this.refresh();
};
duplicateDataQuery(query) {
this.dashboard.duplicateDataQuery(this.panel, query);
}
moveDataQuery(fromIndex, toIndex) {
this.dashboard.moveDataQuery(this.panel, fromIndex, toIndex);
}
setDatasource(datasource) {
// switching to mixed
if (datasource.meta.mixed) {
......@@ -229,6 +212,13 @@ class MetricsPanelCtrl extends PanelCtrl {
this.datasource = null;
this.refresh();
}
addDataQuery(datasource) {
var target = {
datasource: datasource ? datasource.name : undefined
};
this.panel.targets.push(target);
}
}
export {MetricsPanelCtrl};
......@@ -5,9 +5,11 @@ import config from 'app/core/config';
import {PanelCtrl} from './panel_ctrl';
import {MetricsPanelCtrl} from './metrics_panel_ctrl';
import {PanelDirective} from './panel_directive';
import {QueryEditorCtrl} from './query_editor';
export {
PanelCtrl,
MetricsPanelCtrl,
PanelDirective,
QueryEditorCtrl,
}
......@@ -3,23 +3,70 @@
import angular from 'angular';
import _ from 'lodash';
var directivesModule = angular.module('grafana.directives');
/** @ngInject */
function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
return dynamicDirectiveSrv.create({
watchPath: "ctrl.panel.datasource",
directive: scope => {
return datasourceSrv.get(scope.ctrl.panel.datasource).then(ds => {
return System.import(ds.meta.module).then(dsModule => {
return {
name: 'metrics-query-options-' + ds.meta.id,
fn: dsModule.metricsQueryOptions
};
});
});
export class QueryEditorCtrl {
target: any;
datasource: any;
panelCtrl: any;
panel: any;
constructor(private $scope, private $injector) {
this.panel = this.panelCtrl.panel;
this.datasource = $scope.datasource;
if (!this.target.refId) {
this.target.refId = this.getNextQueryLetter();
}
});
}
getNextQueryLetter() {
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
return _.find(letters, refId => {
return _.every(this.panel.targets, function(other) {
return other.refId !== refId;
});
});
}
removeDataQuery(query) {
this.panel.targets = _.without(this.panel.targets, query);
this.panelCtrl.refresh();
};
duplicateDataQuery(query) {
var clone = angular.copy(query);
clone.refId = this.getNextQueryLetter();
this.panel.targets.push(clone);
}
moveDataQuery(direction) {
var index = _.indexOf(this.panel.targets, this.target);
_.move(this.panel.targets, index, index + direction);
}
toggleHideQuery(target) {
target.hide = !target.hide;
this.panelCtrl.refresh();
}
}
directivesModule.directive('metricsQueryOptions', metricsQueryOptions);
// var directivesModule = angular.module('grafana.directives');
//
// /** @ngInject */
// function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
// return dynamicDirectiveSrv.create({
// watchPath: "ctrl.panel.datasource",
// directive: scope => {
// return datasourceSrv.get(scope.ctrl.panel.datasource).then(ds => {
// return System.import(ds.meta.module).then(dsModule => {
// return {
// name: 'metrics-query-options-' + ds.meta.id,
// fn: dsModule.metricsQueryOptions
// };
// });
// });
// }
// });
// }
//
// directivesModule.directive('metricsQueryOptions', metricsQueryOptions);
<div class="editor-row">
<div class="tight-form-container">
<plugin-directive-loader type="metrics-query-editor" ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
</plugin-directive-loader>
<plugin-component type="metrics-query-editor" ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
</plugin-component>
</div>
<div style="margin: 20px 0 0 0">
......
......@@ -4,7 +4,6 @@ define([
'app/core/utils/datemath',
'./influx_series',
'./influx_query',
'./query_ctrl',
],
function (angular, _, dateMath, InfluxSeries, InfluxQuery) {
'use strict';
......
<div class="tight-form">
<ul class="tight-form-list pull-right">
<li class="tight-form-item small" ng-show="target.datasource">
<em>{{target.datasource}}</em>
<em>{{ctrl.target.datasource}}</em>
</li>
<li class="tight-form-item">
<div class="dropdown">
......@@ -9,14 +9,14 @@
<i class="fa fa-bars"></i>
</a>
<ul class="dropdown-menu pull-right" role="menu">
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
<li role="menuitem"><a tabindex="1" ng-click="ctrl.duplicateDataQuery(target)">Duplicate</a></li>
<li role="menuitem"><a tabindex="1" ng-click="ctrl.moveDataQuery(-1)">Move up</a></li>
<li role="menuitem"><a tabindex="1" ng-click="ctrl.moveDataQuery(1)">Move down</a></li>
</ul>
</div>
</li>
<li class="tight-form-item last">
<a class="pointer" tabindex="1" ng-click="panelCtr.removeDataQuery(target)">
<a class="pointer" tabindex="1" ng-click="ctrl.removeDataQuery(ctrl.target)">
<i class="fa fa-remove"></i>
</a>
</li>
......@@ -24,12 +24,10 @@
<ul class="tight-form-list">
<li class="tight-form-item" style="min-width: 15px; text-align: center">
{{target.refId}}
{{ctrl.target.refId}}
</li>
<li>
<a class="tight-form-item"
ng-click="target.hide = !target.hide; panelCtrl.refresh();"
role="menuitem">
<a class="tight-form-item" ng-click="ctrl.toggleHideQuery(ctrl.target);" role="menuitem">
<i class="fa fa-eye"></i>
</a>
</li>
......
......@@ -5,62 +5,64 @@ import _ from 'lodash';
import moment from 'moment';
import * as dateMath from 'app/core/utils/datemath';
import {QueryEditorCtrl} from 'app/features/panel/panel';
function PrometheusQueryCtrl($scope, templateSrv) {
$scope.panelCtrl = $scope.ctrl;
$scope.panel = $scope.panelCtrl.panel;
/** @ngInject */
class PrometheusQueryCtrl extends QueryEditorCtrl {
static templateUrl = 'public/app/plugins/datasource/prometheus/partials/query.editor.html';
metric: any;
resolutions: any;
oldTarget: any;
$scope.init = function() {
var target = $scope.target;
constructor($scope, $injector, private templateSrv) {
super($scope, $injector);
var target = this.target;
target.expr = target.expr || '';
target.intervalFactor = target.intervalFactor || 2;
$scope.metric = '';
$scope.resolutions = _.map([1,2,3,4,5,10], function(f) {
this.metric = '';
this.resolutions = _.map([1,2,3,4,5,10], function(f) {
return {factor: f, label: '1/' + f};
});
$scope.$on('typeahead-updated', function() {
$scope.$apply($scope.inputMetric);
$scope.refreshMetricData();
$scope.$on('typeahead-updated', () => {
$scope.$apply(this.inputMetric);
this.refreshMetricData();
});
};
}
$scope.refreshMetricData = function() {
if (!_.isEqual($scope.oldTarget, $scope.target)) {
$scope.oldTarget = angular.copy($scope.target);
$scope.paneCtrl.refresh();
refreshMetricData() {
if (!_.isEqual(this.oldTarget, this.target)) {
this.oldTarget = angular.copy(this.target);
this.panelCtrl.refresh();
}
};
}
$scope.inputMetric = function() {
$scope.target.expr += $scope.target.metric;
$scope.metric = '';
};
inputMetric() {
this.target.expr += this.target.metric;
this.metric = '';
}
$scope.suggestMetrics = function(query, callback) {
$scope.datasource
.performSuggestQuery(query)
.then(callback);
};
suggestMetrics(query, callback) {
this.datasource.performSuggestQuery(query).then(callback);
}
$scope.linkToPrometheus = function() {
var range = Math.ceil(($scope.range.to.valueOf() - $scope.range.from.valueOf()) / 1000);
var endTime = $scope.range.to.utc().format('YYYY-MM-DD HH:mm');
linkToPrometheus() {
var range = this.panelCtrl.range;
var rangeDiff = Math.ceil((range.to.valueOf() - range.from.valueOf()) / 1000);
var endTime = range.to.utc().format('YYYY-MM-DD HH:mm');
var expr = {
expr: templateSrv.replace($scope.target.expr, $scope.panel.scopedVars),
range_input: range + 's',
expr: this.templateSrv.replace(this.target.expr, this.panelCtrl.panel.scopedVars),
range_input: rangeDiff + 's',
end_input: endTime,
step_input: '',
stacked: $scope.panel.stack,
stacked: this.panelCtrl.panel.stack,
tab: 0
};
var hash = encodeURIComponent(JSON.stringify([expr]));
return $scope.datasource.directUrl + '/graph#' + hash;
return this.datasource.directUrl + '/graph#' + hash;
};
$scope.init();
}
export {PrometheusQueryCtrl};
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