Commit 9c6698e8 by Torkel Ödegaard

feat(panels): progress on new panel infrastructure, base classes

parent 73af4df9
......@@ -17,6 +17,7 @@ function (angular, _, $) {
self.state = {};
self.panelScopes = [];
self.$scope = $scope;
self.dashboard = $scope.dashboard;
$scope.exitFullscreen = function() {
if (self.state.fullscreen) {
......@@ -74,7 +75,7 @@ function (angular, _, $) {
DashboardViewState.prototype.update = function(state, skipUrlSync) {
_.extend(this.state, state);
this.fullscreen = this.state.fullscreen;
this.dashboard.meta.fullscreen = this.state.fullscreen;
if (!this.state.fullscreen) {
this.state.panelId = null;
......@@ -92,7 +93,7 @@ function (angular, _, $) {
DashboardViewState.prototype.syncState = function() {
if (this.panelScopes.length === 0) { return; }
if (this.fullscreen) {
if (this.dashboard.meta.fullscreen) {
if (this.fullscreenPanel) {
this.leaveFullscreen(false);
}
......@@ -148,13 +149,13 @@ function (angular, _, $) {
ctrl.editMode = this.state.edit && this.$scope.dashboardMeta.canEdit;
ctrl.height = ctrl.editMode ? editHeight : fullscreenHeight;
ctrl.fullscreen = true;
this.oldTimeRange = ctrl.range;
this.fullscreenPanel = panelScope;
$(window).scrollTop(0);
panelScope.fullscreen = true;
this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id});
$timeout(function() {
......
......@@ -3,18 +3,64 @@
import config from 'app/core/config';
import {PanelCtrl} from './panel_ctrl';
function metricsEditorTab() {
return {templateUrl: 'public/app/partials/metrics.html'};
}
class MetricsPanelCtrl extends PanelCtrl {
constructor($scope) {
error: boolean;
loading: boolean;
datasource: any;
constructor($scope, private $q, private datasourceSrv) {
super($scope);
this.editorTabIndex = 1;
if (!this.panel.targets) {
this.panel.targets = [{}];
}
}
initEditorTabs() {
super.initEditorTabs();
this.editorTabs.push({title: 'Metrics', directiveFn: metricsEditorTab});
this.addEditorTab('Metrics', () => {
return { templateUrl: 'public/app/partials/metrics.html' };
});
}
refresh() {
this.getData();
}
refreshData(data) {
// null op
return data;
}
loadSnapshot(data) {
// null op
return data;
}
getData() {
if (this.otherPanelInFullscreenMode()) { return; }
if (this.panel.snapshotData) {
if (this.loadSnapshot) {
this.loadSnapshot(this.panel.snapshotData);
}
return;
}
delete this.error;
this.loading = true;
this.datasourceSrv.get(this.panel.datasource).then(datasource => {
this.datasource = datasource;
return this.refreshData(this.datasource) || this.$q.when({});
}).then(() => {
this.loading = false;
}, err => {
console.log('Panel data error:', err);
this.loading = false;
this.error = err.message || "Timeseries data request error";
this.inspector = {error: err};
});
}
}
......
......@@ -29,7 +29,7 @@ class PanelDirective {
};
}
link(scope) {
link(scope, elem) {
return null;
}
}
......
......@@ -15,7 +15,8 @@ export class PanelCtrl {
icon: string;
editorTabs: any;
$scope: any;
isMetricsPanel: boolean;
fullscreen: boolean;
inspector: any;
constructor($scope) {
var plugin = config.panels[this.panel.type];
......@@ -77,4 +78,8 @@ export class PanelCtrl {
menu.push({text: 'Share', click: 'ctrl.share(); dismiss();'});
return menu;
}
otherPanelInFullscreenMode() {
return this.dashboard.meta.fullscreen && !this.fullscreen;
}
}
......@@ -9,7 +9,7 @@ var directiveModule = angular.module('grafana.directives');
function panelEditorTab(dynamicDirectiveSrv) {
return dynamicDirectiveSrv.create({
scope: {
panelCtrl: "=",
ctrl: "=",
editorTab: "=",
},
directive: scope => {
......
<div class="panel-container" ng-class="{'panel-transparent': panel.transparent}">
<div class="panel-container" ng-class="{'panel-transparent': ctrl.panel.transparent}">
<div class="panel-header">
<span class="alert-error panel-error small pointer" config-modal="app/partials/inspector.html" ng-if="ctrl.error">
<span data-placement="top" bs-tooltip="ctrl.error">
......@@ -39,7 +39,7 @@
<div class="gf-box-body">
<div ng-repeat="tab in ctrl.editorTabs" ng-if="ctrl.editorTabIndex === $index">
<panel-editor-tab editor-tab="tab" panel-ctrl="ctrl"></panel-editor-tab>
<panel-editor-tab editor-tab="tab" ctrl="ctrl"></panel-editor-tab>
</div>
</div>
</div>
......
......@@ -5,11 +5,11 @@ import angular from 'angular';
/** @ngInject */
function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
return dynamicDirectiveSrv.create({
watchPath: "panel.datasource",
watchPath: "ctrl.panel.datasource",
directive: scope => {
let datasource = scope.target.datasource || scope.panel.datasource;
let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
return datasourceSrv.get(datasource).then(ds => {
scope.datasource = ds;
scope.ctrl.datasource = ds;
if (!scope.target.refId) {
scope.target.refId = 'A';
......@@ -29,9 +29,9 @@ function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
/** @ngInject */
function metricsQueryOptions(dynamicDirectiveSrv, datasourceSrv) {
return dynamicDirectiveSrv.create({
watchPath: "panel.datasource",
watchPath: "ctrl.panel.datasource",
directive: scope => {
return datasourceSrv.get(scope.panel.datasource).then(ds => {
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,
......
......@@ -23,7 +23,7 @@
<div class="row-text pointer" ng-click="toggleRow(row)" ng-bind="row.title | interpolateTemplateVars:this"></div>
</div>
<div class="row-open" ng-show="!row.collapse">
<div class='row-tab bgSuccess dropdown' ng-show="dashboardMeta.canEdit" ng-hide="dashboardViewState.fullscreen">
<div class='row-tab bgSuccess dropdown' ng-show="dashboardMeta.canEdit" ng-hide="dashboard.meta.fullscreen">
<span class="row-tab-button dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-bars"></i>
</span>
......@@ -79,7 +79,7 @@
<div class="row-text pointer" ng-click="toggleRow(row)" ng-if="row.showTitle" ng-bind="row.title | interpolateTemplateVars:this">
</div>
<div ng-repeat="panel in row.panels track by panel.id" class="panel" ui-draggable="!dashboardViewState.fullscreen" drag="panel.id"
<div ng-repeat="panel in row.panels track by panel.id" class="panel" ui-draggable="!dashboard.meta.fullscreen" drag="panel.id"
ui-on-drop="onDrop($data, row, panel)" drag-handle-class="drag-handle" panel-width>
<panel-loader class="panel-margin" dashboard="dashboard" row="row" panel="panel">
</panel-loader>
......@@ -98,7 +98,7 @@
</div>
</div>
<div ng-show='dashboardMeta.canEdit' class="row-fluid add-row-panel-hint" ng-hide="dashboardViewState.fullscreen">
<div ng-show='dashboardMeta.canEdit' class="row-fluid add-row-panel-hint" ng-hide="dashboard.meta.fullscreen">
<div class="span12" style="text-align:right;">
<span style="margin-right: 10px;" ng-click="addRowDefault()" class="pointer btn btn-info btn-small">
<span><i class="fa fa-plus"></i> ADD ROW</span>
......
<div class="editor-row">
<div class="tight-form-container">
<metrics-query-editor ng-repeat="target in panel.targets" ng-class="{'tight-form-disabled': target.hide}" >
<metrics-query-editor ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}" >
</metrics-query-editor>
</div>
<div style="margin: 20px 0 0 0">
<button class="btn btn-inverse" ng-click="addDataQuery()" ng-hide="datasource.meta.mixed">
<button class="btn btn-inverse" ng-click="ctrl.addDataQuery()" ng-hide="ctrl.datasource.meta.mixed">
<i class="fa fa-plus"></i>&nbsp;
Query
</button>
<div class="dropdown" ng-if="datasource.meta.mixed">
<div class="dropdown" ng-if="ctrl.datasource.meta.mixed">
<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-plus"></i>&nbsp;
Query &nbsp; <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="datasource in datasources" role="menuitem" ng-hide="datasource.meta.builtIn">
<a ng-click="addDataQuery(datasource);">{{datasource.name}}</a>
<li ng-repeat="datasource in ctrl.getMetricSources()" role="menuitem" ng-hide="ctrl.datasource.meta.builtIn">
<a ng-click="ctrl.addDataQuery(datasource);">{{datasource.name}}</a>
</li>
</ul>
</div>
......@@ -34,12 +34,12 @@
<div class="pull-right dropdown" style="margin-right: 10px;">
<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown" bs-tooltip="'Datasource'">
<i class="fa fa-database"></i>&nbsp;
{{datasource.name}} &nbsp; <span class="caret"></span>
{{ctrl.datasource.name}} &nbsp; <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="datasource in datasources" role="menuitem">
<a ng-click="setDatasource(datasource);">{{datasource.name}}</a>
<li ng-repeat="datasource in ctrl.getMetricSources()" role="menuitem">
<a ng-click="ctrl.setDatasource(datasource);">{{datasource.name}}</a>
</li>
</ul>
</div>
......
......@@ -7,23 +7,23 @@
Title
</li>
<li>
<input type="text" class="input-xlarge tight-form-input" ng-model='panelCtrl.panel.title'></input>
<input type="text" class="input-xlarge tight-form-input" ng-model='ctrl.panel.title'></input>
</li>
<li class="tight-form-item">
Span
</li>
<li>
<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>
<select class="input-mini tight-form-input" ng-model="ctrl.panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
</li>
<li class="tight-form-item">
Height
</li>
<li>
<input type="text" class="input-small tight-form-input" ng-model='panelCtrl.panel.height'></input>
<input type="text" class="input-small tight-form-input" ng-model='ctrl.panel.height'></input>
</li>
<li class="tight-form-item">
<label class="checkbox-label" for="panel.transparent">Transparent</label>
<input class="cr1" id="panel.transparent" type="checkbox" ng-model="panelCtrl.panel.transparent" ng-checked="panelCtrl.panel.transparent">
<input class="cr1" id="panel.transparent" type="checkbox" ng-model="ctrl.panel.transparent" ng-checked="ctrl.panel.transparent">
<label for="panel.transparent" class="cr1"></label>
</li>
</ul>
......@@ -38,7 +38,7 @@
Repeat Panel
</li>
<li>
<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">
<select class="input-small tight-form-input last" ng-model="ctrl.panel.repeat" ng-options="f.name as f.name for f in ctrl.dashboard.templating.list">
<option value=""></option>
</select>
</li>
......@@ -46,7 +46,7 @@
Min span
</li>
<li>
<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]">
<select class="input-small tight-form-input last" ng-model="ctrl.panel.minSpan" ng-options="f for f in [1,2,3,4,5,6,7,8,9,10,11,12]">
<option value=""></option>
</select>
</li>
......@@ -56,6 +56,6 @@
</div>
</div>
<panel-links-editor panel="panelCtrl.panel"></panel-links-editor>
<panel-links-editor panel="ctrl.panel"></panel-links-editor>
......@@ -5,7 +5,10 @@ function (GraphiteDatasource) {
'use strict';
function metricsQueryEditor() {
return {controller: 'GraphiteQueryCtrl', templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html'};
return {
controller: 'GraphiteQueryCtrl',
templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html'
};
}
function metricsQueryOptions() {
......
......@@ -48,14 +48,14 @@
{{target.refId}}
</li>
<li>
<a class="tight-form-item" ng-click="target.hide = !target.hide; get_data();" role="menuitem">
<a class="tight-form-item" ng-click="target.hide = !target.hide; panelCtrl.getData();" role="menuitem">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
<span style="display: block; overflow: hidden;">
<input type="text" class="tight-form-clear-input" style="width: 100%;" ng-model="target.target" give-focus="target.textEditor" spellcheck='false' ng-model-onblur ng-change="get_data()" ng-show="target.textEditor"></input>
<input type="text" class="tight-form-clear-input" style="width: 100%;" ng-model="target.target" give-focus="target.textEditor" spellcheck='false' ng-model-onblur ng-change="panelCtrl.getData()" ng-show="target.textEditor"></input>
</span>
<ul class="tight-form-list" role="menu" ng-hide="target.textEditor">
......
......@@ -11,6 +11,7 @@ function (angular, _, config, gfunc, Parser) {
var module = angular.module('grafana.controllers');
module.controller('GraphiteQueryCtrl', function($scope, uiSegmentSrv, templateSrv) {
var panelCtrl = $scope.panelCtrl = $scope.ctrl;
$scope.init = function() {
if ($scope.target) {
......@@ -125,7 +126,7 @@ function (angular, _, config, gfunc, Parser) {
}
var path = getSegmentPathUpTo(fromIndex + 1);
return $scope.datasource.metricFindQuery(path)
return panelCtrl.datasource.metricFindQuery(path)
.then(function(segments) {
if (segments.length === 0) {
if (path !== '') {
......@@ -159,7 +160,7 @@ function (angular, _, config, gfunc, Parser) {
$scope.getAltSegments = function (index) {
var query = index === 0 ? '*' : getSegmentPathUpTo(index) + '.*';
return $scope.datasource.metricFindQuery(query).then(function(segments) {
return panelCtrl.datasource.metricFindQuery(query).then(function(segments) {
var altSegments = _.map(segments, function(segment) {
return uiSegmentSrv.newSegment({ value: segment.text, expandable: segment.expandable });
});
......@@ -208,7 +209,7 @@ function (angular, _, config, gfunc, Parser) {
$scope.targetTextChanged = function() {
parseTarget();
$scope.get_data();
$scope.ctrl.getData();
};
$scope.targetChanged = function() {
......@@ -222,7 +223,7 @@ function (angular, _, config, gfunc, Parser) {
if ($scope.target.target !== oldTarget) {
if ($scope.segments[$scope.segments.length - 1].value !== 'select metric') {
$scope.$parent.get_data();
$scope.ctrl.getData();
}
}
};
......
......@@ -7,19 +7,28 @@ function optionsTab() {
}
export class TestPanelCtrl extends MetricsPanelCtrl {
constructor($scope) {
super($scope);
data: any;
constructor($scope, $q, datasourceSrv) {
super($scope, $q, datasourceSrv);
}
initEditorTabs() {
super.initEditorTabs();
this.editorTabs.push({title: 'Options', directiveFn: optionsTab});
}
refreshData(data) {
console.log('refreshData: ', data);
}
}
class TestPanel extends PanelDirective {
templateUrl = `app/plugins/panel/test/module.html`;
controller = TestPanelCtrl;
link(scope, elem) {
console.log('test panel linking:', scope);
}
}
export {TestPanel as Panel}
<div>
<div class="row-fluid">
<div class="span4">
<label class="small">Mode</label> <select class="input-medium" ng-model="panelCtrl.panel.mode" ng-options="f for f in ['html','markdown','text']"></select>
<label class="small">Mode</label> <select class="input-medium" ng-model="ctrl.panel.mode" ng-options="f for f in ['html','markdown','text']"></select>
</div>
<div class="span2" ng-show="panelCtrl.panel.mode == 'text'">
<label class="small">Font Size</label> <select class="input-mini" ng-model="panelCtrl.panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
<div class="span2" ng-show="ctrl.panel.mode == 'text'">
<label class="small">Font Size</label> <select class="input-mini" ng-model="ctrl.panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
</div>
</div>
<label class=small>Content
<span ng-show="panelCtrl.panel.mode == 'markdown'">(This area uses <a target="_blank" href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>. HTML is not supported)</span>
<span ng-show="ctrl.panel.mode == 'markdown'">(This area uses <a target="_blank" href="http://en.wikipedia.org/wiki/Markdown">Markdown</a>. HTML is not supported)</span>
</label>
<textarea ng-model="panelCtrl.panel.content" rows="20" style="width:95%" ng-change="panelCtrl.render()" ng-model-onblur>
<textarea ng-model="ctrl.panel.content" rows="20" style="width:95%" ng-change="ctrl.render()" ng-model-onblur>
</textarea>
</div>
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