mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
poc(plugin editors): experimential test for plugin editors
This commit is contained in:
@@ -4,44 +4,7 @@ import config from 'app/core/config';
|
||||
|
||||
import {PanelCtrl} from './panel_ctrl';
|
||||
import {MetricsPanelCtrl} from './metrics_panel_ctrl';
|
||||
|
||||
export class DefaultPanelCtrl extends PanelCtrl {
|
||||
constructor($scope, $injector) {
|
||||
super($scope, $injector);
|
||||
}
|
||||
}
|
||||
|
||||
class PanelDirective {
|
||||
template: string;
|
||||
templateUrl: string;
|
||||
bindToController: boolean;
|
||||
scope: any;
|
||||
controller: any;
|
||||
controllerAs: string;
|
||||
|
||||
getDirective() {
|
||||
if (!this.controller) {
|
||||
this.controller = DefaultPanelCtrl;
|
||||
}
|
||||
|
||||
return {
|
||||
template: this.template,
|
||||
templateUrl: this.templateUrl,
|
||||
controller: this.controller,
|
||||
controllerAs: 'ctrl',
|
||||
bindToController: true,
|
||||
scope: {dashboard: "=", panel: "=", row: "="},
|
||||
link: (scope, elem, attrs, ctrl) => {
|
||||
ctrl.init();
|
||||
this.link(scope, elem, attrs, ctrl);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
link(scope, elem, attrs, ctrl) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
import {PanelDirective} from './panel_directive';
|
||||
|
||||
export {
|
||||
PanelCtrl,
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
define([
|
||||
'angular',
|
||||
'jquery',
|
||||
],
|
||||
function (angular, $) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
module.directive('grafanaPanel', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'app/features/panel/partials/panel.html',
|
||||
transclude: true,
|
||||
scope: { ctrl: "=" },
|
||||
link: function(scope, elem) {
|
||||
var panelContainer = elem.find('.panel-container');
|
||||
var ctrl = scope.ctrl;
|
||||
scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() {
|
||||
panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' });
|
||||
elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('panelResizer', function($rootScope) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<span class="resize-panel-handle"></span>',
|
||||
link: function(scope, elem) {
|
||||
var resizing = false;
|
||||
var lastPanel = false;
|
||||
var ctrl = scope.ctrl;
|
||||
var handleOffset;
|
||||
var originalHeight;
|
||||
var originalWidth;
|
||||
var maxWidth;
|
||||
|
||||
function dragStartHandler(e) {
|
||||
e.preventDefault();
|
||||
resizing = true;
|
||||
|
||||
handleOffset = $(e.target).offset();
|
||||
originalHeight = parseInt(ctrl.row.height);
|
||||
originalWidth = ctrl.panel.span;
|
||||
maxWidth = $(document).width();
|
||||
|
||||
lastPanel = ctrl.row.panels[ctrl.row.panels.length - 1];
|
||||
|
||||
$('body').on('mousemove', moveHandler);
|
||||
$('body').on('mouseup', dragEndHandler);
|
||||
}
|
||||
|
||||
function moveHandler(e) {
|
||||
ctrl.row.height = originalHeight + (e.pageY - handleOffset.top);
|
||||
ctrl.panel.span = originalWidth + (((e.pageX - handleOffset.left) / maxWidth) * 12);
|
||||
ctrl.panel.span = Math.min(Math.max(ctrl.panel.span, 1), 12);
|
||||
|
||||
var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
|
||||
|
||||
// auto adjust other panels
|
||||
if (Math.floor(rowSpan) < 14) {
|
||||
// last panel should not push row down
|
||||
if (lastPanel === ctrl.panel && rowSpan > 12) {
|
||||
lastPanel.span -= rowSpan - 12;
|
||||
}
|
||||
// reduce width of last panel so total in row is 12
|
||||
else if (lastPanel !== ctrl.panel) {
|
||||
lastPanel.span = lastPanel.span - (rowSpan - 12);
|
||||
lastPanel.span = Math.min(Math.max(lastPanel.span, 1), 12);
|
||||
}
|
||||
}
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.$broadcast('render');
|
||||
});
|
||||
}
|
||||
|
||||
function dragEndHandler() {
|
||||
// if close to 12
|
||||
var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
|
||||
if (rowSpan < 12 && rowSpan > 11) {
|
||||
lastPanel.span += 12 - rowSpan;
|
||||
}
|
||||
|
||||
scope.$apply(function() {
|
||||
$rootScope.$broadcast('render');
|
||||
});
|
||||
|
||||
$('body').off('mousemove', moveHandler);
|
||||
$('body').off('mouseup', dragEndHandler);
|
||||
}
|
||||
|
||||
elem.on('mousedown', dragStartHandler);
|
||||
|
||||
scope.$on("$destroy", function() {
|
||||
elem.off('mousedown', dragStartHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
});
|
||||
142
public/app/features/panel/panel_directive.ts
Normal file
142
public/app/features/panel/panel_directive.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import $ from 'jquery';
|
||||
|
||||
import {PanelCtrl} from './panel_ctrl';
|
||||
|
||||
export class DefaultPanelCtrl extends PanelCtrl {
|
||||
constructor($scope, $injector) {
|
||||
super($scope, $injector);
|
||||
}
|
||||
}
|
||||
|
||||
export class PanelDirective {
|
||||
template: string;
|
||||
templateUrl: string;
|
||||
bindToController: boolean;
|
||||
scope: any;
|
||||
controller: any;
|
||||
controllerAs: string;
|
||||
|
||||
getDirective() {
|
||||
if (!this.controller) {
|
||||
this.controller = DefaultPanelCtrl;
|
||||
}
|
||||
|
||||
return {
|
||||
template: this.template,
|
||||
templateUrl: this.templateUrl,
|
||||
controller: this.controller,
|
||||
controllerAs: 'ctrl',
|
||||
bindToController: true,
|
||||
scope: {dashboard: "=", panel: "=", row: "="},
|
||||
link: (scope, elem, attrs, ctrl) => {
|
||||
ctrl.init();
|
||||
this.link(scope, elem, attrs, ctrl);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
link(scope, elem, attrs, ctrl) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
module.directive('grafanaPanel', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'app/features/panel/partials/panel.html',
|
||||
transclude: true,
|
||||
scope: { ctrl: "=" },
|
||||
link: function(scope, elem) {
|
||||
var panelContainer = elem.find('.panel-container');
|
||||
var ctrl = scope.ctrl;
|
||||
scope.$watchGroup(['ctrl.fullscreen', 'ctrl.height', 'ctrl.panel.height', 'ctrl.row.height'], function() {
|
||||
panelContainer.css({ minHeight: ctrl.height || ctrl.panel.height || ctrl.row.height, display: 'block' });
|
||||
elem.toggleClass('panel-fullscreen', ctrl.fullscreen ? true : false);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('panelResizer', function($rootScope) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: '<span class="resize-panel-handle"></span>',
|
||||
link: function(scope, elem) {
|
||||
var resizing = false;
|
||||
var lastPanel;
|
||||
var ctrl = scope.ctrl;
|
||||
var handleOffset;
|
||||
var originalHeight;
|
||||
var originalWidth;
|
||||
var maxWidth;
|
||||
|
||||
function dragStartHandler(e) {
|
||||
e.preventDefault();
|
||||
resizing = true;
|
||||
|
||||
handleOffset = $(e.target).offset();
|
||||
originalHeight = parseInt(ctrl.row.height);
|
||||
originalWidth = ctrl.panel.span;
|
||||
maxWidth = $(document).width();
|
||||
|
||||
lastPanel = ctrl.row.panels[ctrl.row.panels.length - 1];
|
||||
|
||||
$('body').on('mousemove', moveHandler);
|
||||
$('body').on('mouseup', dragEndHandler);
|
||||
}
|
||||
|
||||
function moveHandler(e) {
|
||||
ctrl.row.height = originalHeight + (e.pageY - handleOffset.top);
|
||||
ctrl.panel.span = originalWidth + (((e.pageX - handleOffset.left) / maxWidth) * 12);
|
||||
ctrl.panel.span = Math.min(Math.max(ctrl.panel.span, 1), 12);
|
||||
|
||||
var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
|
||||
|
||||
// auto adjust other panels
|
||||
if (Math.floor(rowSpan) < 14) {
|
||||
// last panel should not push row down
|
||||
if (lastPanel === ctrl.panel && rowSpan > 12) {
|
||||
lastPanel.span -= rowSpan - 12;
|
||||
} else if (lastPanel !== ctrl.panel) {
|
||||
// reduce width of last panel so total in row is 12
|
||||
lastPanel.span = lastPanel.span - (rowSpan - 12);
|
||||
lastPanel.span = Math.min(Math.max(lastPanel.span, 1), 12);
|
||||
}
|
||||
}
|
||||
|
||||
scope.$apply(function() {
|
||||
scope.$broadcast('render');
|
||||
});
|
||||
}
|
||||
|
||||
function dragEndHandler() {
|
||||
// if close to 12
|
||||
var rowSpan = ctrl.dashboard.rowSpan(ctrl.row);
|
||||
if (rowSpan < 12 && rowSpan > 11) {
|
||||
lastPanel.span += 12 - rowSpan;
|
||||
}
|
||||
|
||||
scope.$apply(function() {
|
||||
$rootScope.$broadcast('render');
|
||||
});
|
||||
|
||||
$('body').off('mousemove', moveHandler);
|
||||
$('body').off('mouseup', dragEndHandler);
|
||||
}
|
||||
|
||||
elem.on('mousedown', dragStartHandler);
|
||||
|
||||
scope.$on("$destroy", function() {
|
||||
elem.off('mousedown', dragStartHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,80 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
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 => {
|
||||
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) {
|
||||
@@ -43,6 +117,6 @@ function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
|
||||
});
|
||||
}
|
||||
|
||||
angular.module('grafana.directives')
|
||||
.directive('metricsQueryEditor', metricsQueryEditor)
|
||||
.directive('metricsQueryOptions', metricsQueryOptions);
|
||||
directivesModule.directive('pluginDirectiveLoader', pluginDirectiveLoader);
|
||||
directivesModule.directive('metricsQueryEditor', metricsQueryEditor);
|
||||
directivesModule.directive('metricsQueryOptions', metricsQueryOptions);
|
||||
|
||||
Reference in New Issue
Block a user