mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(panel plugin): improving panel plugin model
This commit is contained in:
@@ -123,6 +123,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
|
|||||||
panels[panel.Id] = map[string]interface{}{
|
panels[panel.Id] = map[string]interface{}{
|
||||||
"module": panel.Module,
|
"module": panel.Module,
|
||||||
"name": panel.Name,
|
"name": panel.Name,
|
||||||
|
"info": panel.Info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,11 +59,14 @@ coreModule.filter('noXml', function() {
|
|||||||
|
|
||||||
coreModule.filter('interpolateTemplateVars', function (templateSrv) {
|
coreModule.filter('interpolateTemplateVars', function (templateSrv) {
|
||||||
var filterFunc: any = function(text, scope) {
|
var filterFunc: any = function(text, scope) {
|
||||||
if (scope.panel) {
|
var scopedVars;
|
||||||
return templateSrv.replaceWithText(text, scope.panel.scopedVars);
|
if (scope.ctrl && scope.ctrl.panel) {
|
||||||
|
scopedVars = scope.ctrl.panel.scopedVars;
|
||||||
} else {
|
} else {
|
||||||
return templateSrv.replaceWithText(text, scope.row.scopedVars);
|
scopedVars = scope.row.scopedVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return templateSrv.replaceWithText(text, scopedVars);
|
||||||
};
|
};
|
||||||
|
|
||||||
filterFunc.$stateful = true;
|
filterFunc.$stateful = true;
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ define([
|
|||||||
'./solo_panel_ctrl',
|
'./solo_panel_ctrl',
|
||||||
'./panel_loader',
|
'./panel_loader',
|
||||||
'./query_editor',
|
'./query_editor',
|
||||||
|
'./panel_editor_tab',
|
||||||
], function () {});
|
], function () {});
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
///<reference path="../../headers/common.d.ts" />
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
import PanelMeta from './panel_meta2';
|
import PanelMeta from './panel_meta3';
|
||||||
|
|
||||||
export class PanelCtrl {
|
export class PanelCtrl {
|
||||||
meta: any;
|
meta: any;
|
||||||
panel: any;
|
panel: any;
|
||||||
row: any;
|
row: any;
|
||||||
dashboard: any;
|
dashboard: any;
|
||||||
|
tabIndex: number;
|
||||||
|
|
||||||
constructor(private scope) {
|
constructor(private scope) {
|
||||||
this.meta = new PanelMeta(this.panel);
|
this.meta = new PanelMeta(this.panel);
|
||||||
|
this.tabIndex = 0;
|
||||||
this.publishAppEvent('panel-instantiated', {scope: scope});
|
this.publishAppEvent('panel-instantiated', {scope: scope});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,4 +38,28 @@ export class PanelCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class PanelDirective {
|
||||||
|
template: string;
|
||||||
|
templateUrl: string;
|
||||||
|
bindToController: boolean;
|
||||||
|
scope: any;
|
||||||
|
controller: any;
|
||||||
|
controllerAs: string;
|
||||||
|
|
||||||
|
getDirective() {
|
||||||
|
return {
|
||||||
|
template: this.template,
|
||||||
|
templateUrl: this.templateUrl,
|
||||||
|
controller: this.controller,
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
bindToController: true,
|
||||||
|
scope: {dashboard: "=", panel: "=", row: "="},
|
||||||
|
link: this.link
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
link(scope) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
24
public/app/features/panel/panel_editor_tab.ts
Normal file
24
public/app/features/panel/panel_editor_tab.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import angular from 'angular';
|
||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
|
var directiveModule = angular.module('grafana.directives');
|
||||||
|
|
||||||
|
/** @ngInject */
|
||||||
|
function panelEditorTab(dynamicDirectiveSrv) {
|
||||||
|
return dynamicDirectiveSrv.create({
|
||||||
|
scope: {
|
||||||
|
panelCtrl: "=",
|
||||||
|
editorTab: "=",
|
||||||
|
},
|
||||||
|
directive: scope => {
|
||||||
|
return Promise.resolve({
|
||||||
|
name: 'panel-editor-tab-' + scope.editorTab.title,
|
||||||
|
fn: scope.editorTab.directiveFn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
directiveModule.directive('panelEditorTab', panelEditorTab);
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
import angular from 'angular';
|
import angular from 'angular';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
|
|
||||||
import {unknownPanelDirective} from '../../plugins/panel/unknown/module';
|
import {UnknownPanel} from '../../plugins/panel/unknown/module';
|
||||||
|
|
||||||
var directiveModule = angular.module('grafana.directives');
|
var directiveModule = angular.module('grafana.directives');
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
function panelLoader($compile, dynamicDirectiveSrv, $http, $q) {
|
function panelLoader($compile, dynamicDirectiveSrv, $http, $q, $injector) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
@@ -18,11 +18,11 @@ function panelLoader($compile, dynamicDirectiveSrv, $http, $q) {
|
|||||||
},
|
},
|
||||||
link: function(scope, elem, attrs) {
|
link: function(scope, elem, attrs) {
|
||||||
|
|
||||||
function getTemplate(component) {
|
function getTemplate(directive) {
|
||||||
if (component.template) {
|
if (directive.template) {
|
||||||
return $q.when(component.template);
|
return $q.when(directive.template);
|
||||||
}
|
}
|
||||||
return $http.get(component.templateUrl).then(res => {
|
return $http.get(directive.templateUrl).then(res => {
|
||||||
return res.data;
|
return res.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -38,37 +38,42 @@ function panelLoader($compile, dynamicDirectiveSrv, $http, $q) {
|
|||||||
elem.append(child);
|
elem.append(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPanel(name, directive) {
|
function addPanel(name, Panel) {
|
||||||
if (!directive.registered) {
|
if (Panel.registered) {
|
||||||
getTemplate(directive).then(template => {
|
addPanelAndCompile(name);
|
||||||
directive.templateUrl = null;
|
}
|
||||||
directive.template = `<grafana-panel ctrl="ctrl">${template}</grafana-panel>`;
|
|
||||||
directive.controllerAs = 'ctrl';
|
|
||||||
directive.bindToController = true;
|
|
||||||
directive.scope = {
|
|
||||||
dashboard: "=",
|
|
||||||
panel: "=",
|
|
||||||
row: "="
|
|
||||||
};
|
|
||||||
|
|
||||||
directiveModule.directive(attrs.$normalize(name), function() {
|
if (Panel.promise) {
|
||||||
return directive;
|
Panel.promise.then(() => {
|
||||||
});
|
|
||||||
directive.registered = true;
|
|
||||||
addPanelAndCompile(name);
|
addPanelAndCompile(name);
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
addPanelAndCompile(name);
|
|
||||||
|
var panelInstance = $injector.instantiate(Panel);
|
||||||
|
var directive = panelInstance.getDirective();
|
||||||
|
|
||||||
|
Panel.promise = getTemplate(directive).then(template => {
|
||||||
|
directive.templateUrl = null;
|
||||||
|
directive.template = `<grafana-panel ctrl="ctrl">${template}</grafana-panel>`;
|
||||||
|
directiveModule.directive(attrs.$normalize(name), function() {
|
||||||
|
return directive;
|
||||||
|
});
|
||||||
|
Panel.registered = true;
|
||||||
|
addPanelAndCompile(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var panelElemName = 'panel-directive-' + scope.panel.type;
|
var panelElemName = 'panel-directive-' + scope.panel.type;
|
||||||
let panelInfo = config.panels[scope.panel.type];
|
let panelInfo = config.panels[scope.panel.type];
|
||||||
if (!panelInfo) {
|
if (!panelInfo) {
|
||||||
addPanel(panelElemName, unknownPanelDirective);
|
addPanel(panelElemName, UnknownPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.import(panelInfo.module).then(function(panelModule) {
|
System.import(panelInfo.module).then(function(panelModule) {
|
||||||
addPanel(panelElemName, panelModule.panel);
|
addPanel(panelElemName, panelModule.Panel);
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log('Panel err: ', err);
|
console.log('Panel err: ', err);
|
||||||
});
|
});
|
||||||
@@ -76,4 +81,4 @@ function panelLoader($compile, dynamicDirectiveSrv, $http, $q) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
angular.module('grafana.directives').directive('panelLoader', panelLoader);
|
directiveModule.directive('panelLoader', panelLoader);
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ function (angular, $, _) {
|
|||||||
.directive('panelMenu', function($compile, linkSrv) {
|
.directive('panelMenu', function($compile, linkSrv) {
|
||||||
var linkTemplate =
|
var linkTemplate =
|
||||||
'<span class="panel-title drag-handle pointer">' +
|
'<span class="panel-title drag-handle pointer">' +
|
||||||
'<span class="panel-title-text drag-handle">{{ctrl.panel.title}}</span>' +
|
'<span class="panel-title-text drag-handle">{{ctrl.panel.title | interpolateTemplateVars:this}}</span>' +
|
||||||
'<span class="panel-links-btn"><i class="fa fa-external-link"></i></span>' +
|
'<span class="panel-links-btn"><i class="fa fa-external-link"></i></span>' +
|
||||||
'<span class="panel-time-info" ng-show="ctrl.panelMeta.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.panelMeta.timeInfo}}</span>' +
|
'<span class="panel-time-info" ng-show="ctrl.meta.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.panelMeta.timeInfo}}</span>' +
|
||||||
'</span>';
|
'</span>';
|
||||||
|
|
||||||
function createExternalLinkMenu(ctrl) {
|
function createExternalLinkMenu(ctrl) {
|
||||||
@@ -44,7 +44,7 @@ function (angular, $, _) {
|
|||||||
template += '<div class="panel-menu-row">';
|
template += '<div class="panel-menu-row">';
|
||||||
template += '<a class="panel-menu-link" gf-dropdown="extendedMenu"><i class="fa fa-bars"></i></a>';
|
template += '<a class="panel-menu-link" gf-dropdown="extendedMenu"><i class="fa fa-bars"></i></a>';
|
||||||
|
|
||||||
_.each(ctrl.panelMeta.menu, function(item) {
|
_.each(ctrl.meta.menu, function(item) {
|
||||||
// skip edit actions if not editor
|
// skip edit actions if not editor
|
||||||
if (item.role === 'Editor' && !ctrl.dashboard.meta.canEdit) {
|
if (item.role === 'Editor' && !ctrl.dashboard.meta.canEdit) {
|
||||||
return;
|
return;
|
||||||
@@ -64,7 +64,7 @@ function (angular, $, _) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getExtendedMenu(ctrl) {
|
function getExtendedMenu(ctrl) {
|
||||||
return angular.copy(ctrl.panelMeta.extendedMenu);
|
return angular.copy(ctrl.meta.extendedMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -80,7 +80,7 @@ function (angular, $, _) {
|
|||||||
|
|
||||||
elem.append($link);
|
elem.append($link);
|
||||||
|
|
||||||
$scope.$watchCollection('panel.links', function(newValue) {
|
$scope.$watchCollection('ctrl.panel.links', function(newValue) {
|
||||||
var showIcon = (newValue ? newValue.length > 0 : false) && ctrl.panel.title !== '';
|
var showIcon = (newValue ? newValue.length > 0 : false) && ctrl.panel.title !== '';
|
||||||
$panelLinksBtn.toggle(showIcon);
|
$panelLinksBtn.toggle(showIcon);
|
||||||
});
|
});
|
||||||
|
|||||||
56
public/app/features/panel/panel_meta3.ts
Normal file
56
public/app/features/panel/panel_meta3.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
///<reference path="../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
|
function panelOptionsTab() {
|
||||||
|
return {templateUrl: 'app/partials/panelgeneral.html'};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class PanelMeta {
|
||||||
|
description: any;
|
||||||
|
icon: any;
|
||||||
|
name: any;
|
||||||
|
menu: any;
|
||||||
|
editorTabs: any;
|
||||||
|
extendedMenu: any;
|
||||||
|
|
||||||
|
constructor(panel) {
|
||||||
|
let panelInfo = config.panels[panel.type];
|
||||||
|
console.log(panelInfo);
|
||||||
|
|
||||||
|
this.icon = panelInfo.icon;
|
||||||
|
this.name = panelInfo.name;
|
||||||
|
this.menu = [];
|
||||||
|
this.editorTabs = [];
|
||||||
|
this.extendedMenu = [];
|
||||||
|
|
||||||
|
if (panelInfo.fullscreen) {
|
||||||
|
this.addMenuItem('View', 'icon-eye-open', 'ctrl.viewPanel(); dismiss();');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addMenuItem('Edit', 'icon-cog', 'ctrl.editPanel(); dismiss();', 'Editor');
|
||||||
|
this.addMenuItem('Duplicate', 'icon-copy', 'ctrl.duplicate()', 'Editor');
|
||||||
|
this.addMenuItem('Share', 'icon-share', 'ctrl.share(); dismiss();');
|
||||||
|
|
||||||
|
this.addEditorTab('General', panelOptionsTab);
|
||||||
|
|
||||||
|
if (panelInfo.metricsEditor) {
|
||||||
|
this.addEditorTab('Metrics', 'app/partials/metrics.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addExtendedMenuItem('Panel JSON', '', 'ctrl.editPanelJson(); dismiss();');
|
||||||
|
}
|
||||||
|
|
||||||
|
addMenuItem (text, icon, click, role?) {
|
||||||
|
this.menu.push({text: text, icon: icon, click: click, role: role});
|
||||||
|
}
|
||||||
|
|
||||||
|
addExtendedMenuItem (text, icon, click, role?) {
|
||||||
|
this.extendedMenu.push({text: text, icon: icon, click: click, role: role});
|
||||||
|
}
|
||||||
|
|
||||||
|
addEditorTab(title, directiveFn) {
|
||||||
|
this.editorTabs.push({title: title, directiveFn: directiveFn});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
<div class="gf-box">
|
<div class="gf-box">
|
||||||
<div class="gf-box-header">
|
<div class="gf-box-header">
|
||||||
<div class="gf-box-title">
|
<div class="gf-box-title">
|
||||||
<i ng-class="panelMeta.editIcon"></i>
|
<i ng-class="ctrl.meta.icon"></i>
|
||||||
{{ctrl.panelMeta.panelName}}
|
{{ctrl.meta.name}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-model="editor.index" bs-tabs>
|
<div ng-model="ctrl.tabIndex" bs-tabs>
|
||||||
<div ng-repeat="tab in panelMeta.editorTabs" data-title="{{tab.title}}">
|
<div ng-repeat="tab in ctrl.meta.editorTabs" data-title="{{tab.title}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-box-body">
|
<div class="gf-box-body">
|
||||||
<div ng-repeat="tab in panelMeta.editorTabs" ng-if="editor.index === $index">
|
<div ng-repeat="tab in ctrl.meta.editorTabs" ng-if="ctrl.tabIndex === $index">
|
||||||
<div ng-include src="tab.src"></div>
|
<panel-editor-tab editor-tab="tab" panel-ctrl="ctrl"></panel-editor-tab>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,23 +7,23 @@
|
|||||||
Title
|
Title
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="text" class="input-xlarge tight-form-input" ng-model='panel.title'></input>
|
<input type="text" class="input-xlarge tight-form-input" ng-model='panelCtrl.panel.title'></input>
|
||||||
</li>
|
</li>
|
||||||
<li class="tight-form-item">
|
<li class="tight-form-item">
|
||||||
Span
|
Span
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<select class="input-mini tight-form-input" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
|
<select class="input-mini tight-form-input" ng-model="panelCtrl.panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
|
||||||
</li>
|
</li>
|
||||||
<li class="tight-form-item">
|
<li class="tight-form-item">
|
||||||
Height
|
Height
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input type="text" class="input-small tight-form-input" ng-model='panel.height'></input>
|
<input type="text" class="input-small tight-form-input" ng-model='panelCtrl.panel.height'></input>
|
||||||
</li>
|
</li>
|
||||||
<li class="tight-form-item">
|
<li class="tight-form-item">
|
||||||
<label class="checkbox-label" for="panel.transparent">Transparent</label>
|
<label class="checkbox-label" for="panel.transparent">Transparent</label>
|
||||||
<input class="cr1" id="panel.transparent" type="checkbox" ng-model="panel.transparent" ng-checked="panel.transparent">
|
<input class="cr1" id="panel.transparent" type="checkbox" ng-model="panelCtrl.panel.transparent" ng-checked="panelCtrl.panel.transparent">
|
||||||
<label for="panel.transparent" class="cr1"></label>
|
<label for="panel.transparent" class="cr1"></label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
Repeat Panel
|
Repeat Panel
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<select class="input-small tight-form-input last" ng-model="panel.repeat" ng-options="f.name as f.name for f in dashboard.templating.list">
|
<select class="input-small tight-form-input last" ng-model="panelCtrl.panel.repeat" ng-options="f.name as f.name for f in panelCtrl.dashboard.templating.list">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
Min span
|
Min span
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<select class="input-small tight-form-input last" ng-model="panel.minSpan" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12]">
|
<select class="input-small tight-form-input last" ng-model="panelCtrl.panel.minSpan" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12]">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
@@ -56,6 +56,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<panel-links-editor panel="panel"></panel-links-editor>
|
<panel-links-editor panel="panelCtrl.panel"></panel-links-editor>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
///<reference path="../../../headers/common.d.ts" />
|
///<reference path="../../../headers/common.d.ts" />
|
||||||
|
|
||||||
import {PanelCtrl} from '../../../features/panel/panel_ctrl';
|
import {PanelDirective, PanelCtrl} from '../../../features/panel/panel';
|
||||||
|
|
||||||
class TestPanelCtrl extends PanelCtrl {
|
class TestPanelCtrl extends PanelCtrl {
|
||||||
constructor($scope) {
|
constructor($scope) {
|
||||||
@@ -8,15 +8,23 @@ class TestPanelCtrl extends PanelCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var panel = {
|
|
||||||
templateUrl: `app/plugins/panel/test/module.html`,
|
class TestPanel extends PanelDirective {
|
||||||
controller: TestPanelCtrl,
|
templateUrl = `app/plugins/panel/test/module.html`;
|
||||||
link: function(scope, elem) {
|
controller = TestPanelCtrl;
|
||||||
console.log('panel link');
|
|
||||||
|
constructor($http) {
|
||||||
|
super();
|
||||||
|
console.log('panel ctor: ', $http);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
link(scope) {
|
||||||
|
console.log('panel link: ', scope.ctrl.panel.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
TestPanelCtrl,
|
TestPanelCtrl,
|
||||||
panel,
|
// testPanelDirective as panel,
|
||||||
|
TestPanel as Panel,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
{
|
{
|
||||||
"type": "panel",
|
"type": "panel",
|
||||||
"name": "Test",
|
"name": "Test",
|
||||||
"id": "test"
|
"id": "test",
|
||||||
|
|
||||||
|
"info": {
|
||||||
|
"description": "Test panel",
|
||||||
|
"author": {
|
||||||
|
"name": "Core Grafana Team.",
|
||||||
|
"url": "http://grafana.org"
|
||||||
|
},
|
||||||
|
"logos": {
|
||||||
|
"icon": "fa fa-fw th-large",
|
||||||
|
"small": "img/logo_small.png",
|
||||||
|
"large": "img/logo_large.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
///<reference path="../../../headers/common.d.ts" />
|
///<reference path="../../../headers/common.d.ts" />
|
||||||
|
|
||||||
export function unknownPanelDirective() {
|
import {PanelDirective} from '../../../features/panel/panel';
|
||||||
return {
|
|
||||||
restrict: 'E',
|
export class UnknownPanel extends PanelDirective {
|
||||||
template: `
|
template = `<div class="text-center" style="padding-top: 2rem">
|
||||||
<grafana-panel>
|
Unknown panel type: <strong>{{ctrl.panel.type}}</strong>
|
||||||
<div class="text-center" style="padding-top: 2rem">
|
</div>`;
|
||||||
Unknown panel type: <strong>{{panel.type}}</strong>
|
|
||||||
</div>
|
|
||||||
</grafana-panel>
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user