瀏覽代碼

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

Torkel Ödegaard 10 年之前
父節點
當前提交
9c6698e87b

+ 4 - 3
public/app/features/dashboard/viewStateSrv.js

@@ -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() {

+ 53 - 7
public/app/features/panel/metrics_panel_ctrl.ts

@@ -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};
+    });
   }
 }
 

+ 1 - 1
public/app/features/panel/panel.ts

@@ -29,7 +29,7 @@ class PanelDirective {
     };
   }
 
-  link(scope) {
+  link(scope, elem) {
     return null;
   }
 }

+ 6 - 1
public/app/features/panel/panel_ctrl.ts

@@ -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;
+  }
 }

+ 1 - 1
public/app/features/panel/panel_editor_tab.ts

@@ -9,7 +9,7 @@ var directiveModule = angular.module('grafana.directives');
 function panelEditorTab(dynamicDirectiveSrv) {
   return dynamicDirectiveSrv.create({
     scope: {
-      panelCtrl: "=",
+      ctrl: "=",
       editorTab: "=",
     },
     directive: scope => {

+ 2 - 2
public/app/features/panel/partials/panel.html

@@ -1,4 +1,4 @@
-<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 - 5
public/app/features/panel/query_editor.ts

@@ -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,

+ 3 - 3
public/app/partials/dashboard.html

@@ -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>

+ 8 - 8
public/app/partials/metrics.html

@@ -1,25 +1,25 @@
 <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 - 7
public/app/partials/panelgeneral.html

@@ -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>
 
 

+ 4 - 1
public/app/plugins/datasource/graphite/module.js

@@ -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() {

+ 2 - 2
public/app/plugins/datasource/graphite/partials/query.editor.html

@@ -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">

+ 5 - 4
public/app/plugins/datasource/graphite/query_ctrl.js

@@ -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();
         }
       }
     };

+ 12 - 3
public/app/plugins/panel/test/module.ts

@@ -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}

+ 5 - 5
public/app/plugins/panel/text/editor.html

@@ -1,17 +1,17 @@
 <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>