浏览代码

ux(query editors): progress on new query editor styles

Torkel Ödegaard 9 年之前
父节点
当前提交
33f7b8479e

+ 0 - 5
public/app/core/components/info_popover.ts

@@ -11,11 +11,6 @@ export function infoPopover() {
     template: '<i class="fa fa-info-circle"></i>',
     transclude: true,
     link: function(scope, elem, attrs, ctrl, transclude) {
-      // var inputElem = elem.prev();
-      // if (inputElem.length === 0) {
-      //   console.log('Failed to find input element for popover');
-      //   return;
-      // }
 
       var offset = attrs.offset || '0 -10px';
       var position = attrs.position || 'right middle';

+ 1 - 0
public/app/features/panel/all.js

@@ -5,4 +5,5 @@ define([
   './query_ctrl',
   './panel_editor_tab',
   './query_editor_row',
+  './metrics_ds_selector',
 ], function () {});

+ 104 - 0
public/app/features/panel/metrics_ds_selector.ts

@@ -0,0 +1,104 @@
+///<reference path="../../headers/common.d.ts" />
+
+import angular from 'angular';
+import _ from 'lodash';
+
+var module = angular.module('grafana.directives');
+
+var template = `
+<div class="gf-form-group">
+  <div class="gf-form-inline">
+    <div class="gf-form">
+      <label class="gf-form-label">
+        <i class="icon-gf icon-gf-datasource"></i>
+      </label>
+      <label class="gf-form-label">
+        Data source
+      </label>
+
+      <metric-segment segment="ctrl.dsSegment"
+                      get-options="ctrl.getOptions()"
+                      on-change="ctrl.datasourceChanged()"></metric-segment>
+    </div>
+
+    <div class="gf-form gf-form--offset-1">
+      <button class="btn btn-inverse gf-form-btn" ng-click="ctrl.addDataQuery()" ng-hide="ctrl.current.meta.mixed">
+        <i class="fa fa-plus"></i>&nbsp;
+        Add query
+      </button>
+
+      <div class="dropdown" ng-if="ctrl.current.meta.mixed">
+        <button class="btn btn-inverse dropdown-toggle gf-form-btn" data-toggle="dropdown">
+          Add Query&nbsp;<span class="fa fa-caret-down"></span>
+        </button>
+
+        <ul class="dropdown-menu" role="menu">
+          <li ng-repeat="datasource in ctrl.datasources" role="menuitem" ng-hide="datasource.meta.builtIn">
+            <a ng-click="ctrl.addDataQuery(datasource);">{{datasource.name}}</a>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </div>
+</div>
+`;
+
+
+export class MetricsDsSelectorCtrl {
+  dsSegment: any;
+  dsName: string;
+  panelCtrl: any;
+  datasources: any[];
+  current: any;
+
+  /** @ngInject */
+  constructor(private uiSegmentSrv, datasourceSrv) {
+    this.datasources = datasourceSrv.getMetricSources();
+
+    for (let ds of this.datasources) {
+      if (ds.value === this.panelCtrl.panel.datasource) {
+        this.current = ds;
+      }
+    }
+
+    this.dsSegment = uiSegmentSrv.newSegment(this.current.name);
+  }
+
+  getOptions() {
+    return Promise.resolve(this.datasources.map(value => {
+      return this.uiSegmentSrv.newSegment(value.name);
+    }));
+  }
+
+  datasourceChanged() {
+    var ds = _.findWhere(this.datasources, {name: this.dsSegment.value});
+    if (ds) {
+      this.current = ds;
+      this.panelCtrl.setDatasource(ds);
+    }
+  }
+
+  addDataQuery(datasource) {
+    var target: any = {};
+
+    if (datasource) {
+      target.datasource = datasource.name;
+    }
+
+    this.panelCtrl.panel.targets.push(target);
+  }
+}
+
+module.directive('metricsDsSelector', function() {
+  return {
+    restrict: 'E',
+    template: template,
+    controller: MetricsDsSelectorCtrl,
+    bindToController: true,
+    controllerAs: 'ctrl',
+    transclude: true,
+    scope: {
+      panelCtrl: "="
+    }
+  };
+});

+ 0 - 12
public/app/features/panel/metrics_panel_ctrl.ts

@@ -27,7 +27,6 @@ class MetricsPanelCtrl extends PanelCtrl {
   resolution: any;
   timeInfo: any;
   skipDataOnInit: boolean;
-  datasources: any[];
   dataStream: any;
   dataSubscription: any;
 
@@ -52,7 +51,6 @@ class MetricsPanelCtrl extends PanelCtrl {
   private onInitMetricsPanelEditMode() {
     this.addEditorTab('Metrics', 'public/app/partials/metrics.html');
     this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html');
-    this.datasources = this.datasourceSrv.getMetricSources();
   }
 
   private onMetricsPanelRefresh() {
@@ -249,16 +247,6 @@ class MetricsPanelCtrl extends PanelCtrl {
     this.datasource = null;
     this.refresh();
   }
-
-  addDataQuery(datasource) {
-    var target: any = {};
-
-    if (datasource) {
-      target.datasource = datasource.name;
-    }
-
-    this.panel.targets.push(target);
-  }
 }
 
 export {MetricsPanelCtrl};

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

@@ -15,8 +15,9 @@
 
 	<div class="gf-form">
 		<label class="gf-form-label">
-			<a class="pointer" tabindex="1" ng-click="ctrl.toggleEditorMode()">
-				<i class="fa fa-pencil"></i>
+			<a class="pointer" tabindex="1" ng-click="ctrl.collapsed = !ctrl.collapsed">
+				<i class="fa fa-chevron-down" ng-hide="ctrl.collapsed"></i>
+				<i class="fa fa-chevron-left" ng-show="ctrl.collapsed"></i>
 			</a>
 		</label>
 		<label class="gf-form-label dropdown">
@@ -24,6 +25,9 @@
 				<i class="fa fa-bars"></i>
 			</a>
 			<ul class="dropdown-menu pull-right" role="menu">
+				<li role="menuitem">
+					<a tabindex="1" ng-click="ctrl.toggleEditorMode()">Toggle text editor</a>
+				</li>
 				<li role="menuitem">
 					<a tabindex="1" ng-click="ctrl.duplicateQuery()">Duplicate</a>
 				</li>
@@ -35,6 +39,11 @@
 				</li>
 			</ul>
 		</label>
+		<label class="gf-form-label">
+			<a class="pointer" tabindex="1" ng-click="ctrl.removeQuery(ctrl.target)">
+				<i class="fa fa-trash"></i>
+			</a>
+		</label>
 	</div>
 </div>
 

+ 2 - 0
public/app/features/panel/query_ctrl.ts

@@ -10,9 +10,11 @@ export class QueryCtrl {
   panel: any;
   hasRawMode: boolean;
   error: string;
+  collapsed: boolean;
 
   constructor(public $scope, private $injector) {
     this.panel = this.panelCtrl.panel;
+    this.collapsed = true;
 
     if (!this.target.refId) {
       this.target.refId = this.getNextQueryLetter();

+ 14 - 51
public/app/partials/metrics.html

@@ -1,56 +1,19 @@
-<div class="editor-row">
-
-	<div class="query-editor-rows">
-		<div ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
-			<rebuild-on-change property="ctrl.panel.datasource || target.datasource" show-null="true">
-				<plugin-component type="query-ctrl">
-				</plugin-component>
-			</rebuild-on-change>
-		</div>
-	</div>
-
-	<div style="margin: 20px 0 0 0">
-		<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="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 ctrl.datasources" role="menuitem" ng-hide="datasource.meta.builtIn">
-					<a ng-click="ctrl.addDataQuery(datasource);">{{datasource.name}}</a>
-				</li>
-			</ul>
-		</div>
-
-	</div>
-
-	<rebuild-on-change property="ctrl.panel.datasource" show-null="true">
-		<plugin-component type="query-options-ctrl">
-		</plugin-component>
-	</rebuild-on-change>
 
+<div class="query-editor-rows gf-form-group">
+  <div ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
+    <rebuild-on-change property="ctrl.panel.datasource || target.datasource" show-null="true">
+      <plugin-component type="query-ctrl">
+      </plugin-component>
+    </rebuild-on-change>
+  </div>
 </div>
 
-<div class="editor-row">
-
-	<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;
-			{{ctrl.datasource.name}} &nbsp; <span class="caret"></span>
-		</button>
+<metrics-ds-selector panel-ctrl="ctrl"></metrics-ds-selector>
 
-		<ul class="dropdown-menu" role="menu">
-			<li ng-repeat="datasource in ctrl.datasources" role="menuitem">
-				<a ng-click="ctrl.setDatasource(datasource);">{{datasource.name}}</a>
-			</li>
-		</ul>
-	</div>
-
-	<div class="clearfix"></div>
+<div class="gf-form-group">
+  <rebuild-on-change property="ctrl.panel.datasource" show-null="true">
+    <plugin-component type="query-options-ctrl">
+    </plugin-component>
+  </rebuild-on-change>
 </div>
+

+ 18 - 14
public/app/plugins/datasource/elasticsearch/partials/query.editor.html

@@ -1,17 +1,21 @@
-<query-editor-row ctrl="ctrl">
-	<li class="tight-form-item query-keyword" style="width: 75px">
-		Query
-	</li>
-	<li>
-		<input type="text" class="tight-form-input" style="width: 345px;" ng-model="ctrl.target.query" spellcheck='false' placeholder="Lucene query" ng-blur="ctrl.refresh()">
-	</li>
-	<li class="tight-form-item query-keyword">
-		Alias
-	</li>
-	<li>
-		<input type="text" class="tight-form-input" style="width: 200px;" ng-model="ctrl.target.alias" spellcheck='false' placeholder="alias patterns (empty = auto)" ng-blur="ctrl.refresh()">
-	</li>
-</query-editor-row>
+<query-editor-row ctrl="ctrl"></query-editor-row>
+
+<div class="tight-form">
+	<ul class="tight-form-list">
+		<li class="tight-form-item query-keyword" style="width: 75px">
+			Query
+		</li>
+		<li>
+			<input type="text" class="tight-form-input" style="width: 345px;" ng-model="ctrl.target.query" spellcheck='false' placeholder="Lucene query" ng-blur="ctrl.refresh()">
+		</li>
+		<li class="tight-form-item query-keyword">
+			Alias
+		</li>
+		<li>
+			<input type="text" class="tight-form-input" style="width: 200px;" ng-model="ctrl.target.alias" spellcheck='false' placeholder="alias patterns (empty = auto)" ng-blur="ctrl.refresh()">
+		</li>
+	</ul>
+</div>
 
 <div ng-repeat="agg in ctrl.target.metrics">
 	<elastic-metric-agg

+ 94 - 85
public/app/plugins/datasource/influxdb/partials/query.editor.html

@@ -1,89 +1,98 @@
 <query-editor-row ctrl="ctrl">
 
-	<div class="gf-form" ng-show="ctrl.target.rawQuery">
-		<input type="text" class="gf-form-input" ng-model="ctrl.target.query" spellcheck="false" ng-blur="ctrl.refresh()"></input>
-	</div>
-
-  <div ng-hide="ctrl.target.rawQuery">
-		<div class="gf-form-inline">
-			<div class="gf-form">
-				<label class="gf-form-label query-keyword width-7">FROM</label>
-
-				<metric-segment segment="ctrl.policySegment" get-options="ctrl.getPolicySegments()" on-change="ctrl.policyChanged()"></metric-segment>
-				<metric-segment segment="ctrl.measurementSegment" get-options="ctrl.getMeasurements()" on-change="ctrl.measurementChanged()"></metric-segment>
-			</div>
-
-			<div class="gf-form">
-				<label class="gf-form-label query-keyword">WHERE</label>
-
-				<div ng-repeat="segment in ctrl.tagSegments">
-					<metric-segment segment="segment" get-options="ctrl.getTagsOrValues(segment, $index)" on-change="ctrl.tagSegmentUpdated(segment, $index)"></metric-segment>
-				</div>
-			</div>
-
-			<div class="gf-form-filler"></div>
-		</div>
-
-		<div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
-			<div class="gf-form">
-				<label class="gf-form-label query-keyword width-7">
-					<span ng-show="$index === 0">SELECT</span>
-				</label>
-			</div>
-
-			<div class="gf-form" ng-repeat="part in selectParts">
-				<influx-query-part-editor
-						class="gf-form-label query-part"
-						part="part"
-						remove-action="ctrl.removeSelectPart(selectParts, part)"
-						part-updated="ctrl.selectPartUpdated(selectParts, part)"
-						get-options="ctrl.getPartOptions(part)">
-				</influx-query-part-editor>
-			</div>
-
-			<div class="gf-form">
-				<label class="dropdown"
-					dropdown-typeahead="ctrl.selectMenu"
-					dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
-				</label>
-			</div>
-
-			<div class="gf-form-filler"></div>
-		</div>
-
-		<div class="gf-form-inline">
-			<div class="gf-form">
-				<label class="gf-form-label query-keyword width-7">
-					<span>GROUP BY</span>
-				</label>
-
-				<influx-query-part-editor
-						ng-repeat="part in ctrl.queryModel.groupByParts"
-						part="part"
-						class="gf-form-label query-part"
-						remove-action="ctrl.removeGroupByPart(part, $index)" part-updated="ctrl.refresh();" get-options="ctrl.getPartOptions(part)">
-				</influx-query-part-editor>
-
-				<metric-segment segment="ctrl.groupBySegment" get-options="ctrl.getGroupByOptions()" on-change="ctrl.groupByAction(part, $index)"></metric-segment>
-			</div>
-
-			<div class="gf-form-filler"></div>
-		</div>
-
-	</div>
-
-	<div class="gf-form-inline">
-		<div class="gf-form max-width-30">
-			<label class="gf-form-label query-keyword width-7">ALIAS BY</label>
-			<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
-		</div>
-		<div class="gf-form">
-			<label class="gf-form-label">Format as</label>
-			<div class="gf-form-select-wrapper">
-				<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
-			</div>
-		</div>
-		<div class="gf-form-filler"></div>
-	</div>
+  <div class="gf-form" ng-if="ctrl.collapsed">
+    <label class="gf-form-label gf-form-filler pointer" ng-click="ctrl.collapsed = !ctrl.collapsed">
+      {{ctrl.target.query}}
+    </label>
+  </div>
+
+  <div ng-if="!ctrl.collapsed">
+
+    <div class="gf-form" ng-if="ctrl.target.rawQuery">
+      <input type="text" class="gf-form-input" ng-model="ctrl.target.query" spellcheck="false" ng-blur="ctrl.refresh()"></input>
+    </div>
+
+    <div ng-if="!ctrl.target.rawQuery">
+
+      <div class="gf-form-inline">
+        <div class="gf-form">
+          <label class="gf-form-label query-keyword width-7">FROM</label>
+
+          <metric-segment segment="ctrl.policySegment" get-options="ctrl.getPolicySegments()" on-change="ctrl.policyChanged()"></metric-segment>
+          <metric-segment segment="ctrl.measurementSegment" get-options="ctrl.getMeasurements()" on-change="ctrl.measurementChanged()"></metric-segment>
+        </div>
+
+        <div class="gf-form">
+          <label class="gf-form-label query-keyword">WHERE</label>
+
+          <div ng-repeat="segment in ctrl.tagSegments">
+            <metric-segment segment="segment" get-options="ctrl.getTagsOrValues(segment, $index)" on-change="ctrl.tagSegmentUpdated(segment, $index)"></metric-segment>
+          </div>
+        </div>
+
+        <div class="gf-form-filler"></div>
+      </div>
+
+      <div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
+        <div class="gf-form">
+          <label class="gf-form-label query-keyword width-7">
+            <span ng-show="$index === 0">SELECT</span>
+          </label>
+        </div>
+
+        <div class="gf-form" ng-repeat="part in selectParts">
+          <influx-query-part-editor
+                             class="gf-form-label query-part"
+                             part="part"
+                             remove-action="ctrl.removeSelectPart(selectParts, part)"
+                             part-updated="ctrl.selectPartUpdated(selectParts, part)"
+                             get-options="ctrl.getPartOptions(part)">
+          </influx-query-part-editor>
+        </div>
+
+        <div class="gf-form">
+          <label class="dropdown"
+                 dropdown-typeahead="ctrl.selectMenu"
+                 dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
+          </label>
+        </div>
+
+        <div class="gf-form-filler"></div>
+      </div>
+
+      <div class="gf-form-inline">
+        <div class="gf-form">
+          <label class="gf-form-label query-keyword width-7">
+            <span>GROUP BY</span>
+          </label>
+
+          <influx-query-part-editor
+                 ng-repeat="part in ctrl.queryModel.groupByParts"
+                 part="part"
+                 class="gf-form-label query-part"
+                 remove-action="ctrl.removeGroupByPart(part, $index)" part-updated="ctrl.refresh();" get-options="ctrl.getPartOptions(part)">
+          </influx-query-part-editor>
+
+          <metric-segment segment="ctrl.groupBySegment" get-options="ctrl.getGroupByOptions()" on-change="ctrl.groupByAction(part, $index)"></metric-segment>
+        </div>
+
+        <div class="gf-form-filler"></div>
+      </div>
+    </div>
+
+    <div class="gf-form-inline">
+      <div class="gf-form max-width-30">
+        <label class="gf-form-label query-keyword width-7">ALIAS BY</label>
+        <input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
+      </div>
+      <div class="gf-form">
+        <label class="gf-form-label">Format as</label>
+        <div class="gf-form-select-wrapper">
+          <select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
+        </div>
+      </div>
+      <div class="gf-form-filler"></div>
+    </div>
+  </div>
 
 </query-editor-row>

+ 1 - 1
public/app/plugins/datasource/influxdb/partials/query.options.html

@@ -38,7 +38,7 @@
 </section>
 
 <div class="editor-row">
-	<div class="pull-left" style="margin-top: 30px;">
+	<div class="pull-left">
 
 		<div class="grafana-info-box span6" ng-if="ctrl.panelCtrl.editorHelpIndex === 1">
 			<h5>Alias patterns</h5>

+ 5 - 3
public/sass/components/_gf-form.scss

@@ -8,8 +8,8 @@ $gf-form-margin: 0.25rem;
   text-align: left;
   position: relative;
 
-  .cr1 {
-    margin-left: 8px;
+  &--offset-1 {
+    margin-left: $spacer;
   }
 }
 
@@ -162,9 +162,11 @@ $gf-form-margin: 0.25rem;
 }
 
 .gf-form-btn {
-  margin-right: $gf-form-margin;
   padding: $input-padding-y $input-padding-x;
+  margin-right: $gf-form-margin;
   line-height: $input-line-height;
+  font-size: $font-size-sm;
+
   flex-shrink: 0;
   flex-grow: 0;
 }

+ 0 - 5
public/sass/components/_query_part.scss

@@ -9,8 +9,3 @@
   }
 }
 
-.query-part-name {
-}
-
-.query-part-parameters {
-}