Просмотр исходного кода

Reworking variable value dropdown, take3

Torkel Ödegaard 10 лет назад
Родитель
Сommit
483ef20527

+ 1 - 1
public/app/directives/metric.segment.js

@@ -68,7 +68,7 @@ function (angular, app, _, $) {
             else {
               // need to have long delay because the blur
               // happens long before the click event on the typeahead options
-              cancelBlur = setTimeout($scope.switchToLink, 350);
+              cancelBlur = setTimeout($scope.switchToLink, 50);
             }
           };
 

+ 64 - 32
public/app/directives/variableValueSelect.js

@@ -10,23 +10,72 @@ function (angular, app, _) {
   angular
     .module('grafana.directives')
     .directive('variableValueSelect', function($compile, $window, $timeout) {
+
+      function openDropdown(inputEl, linkEl) {
+        inputEl.css('width', (linkEl.width() + 16) + 'px');
+
+        linkEl.hide();
+        inputEl.show();
+        inputEl.focus();
+      };
+
       return {
         scope: {
           variable: "=",
           onUpdated: "&"
         },
+
         templateUrl: 'app/features/dashboard/partials/variableValueSelect.html',
+
         link: function(scope, elem) {
           var bodyEl = angular.element($window.document.body);
+          var linkEl = elem.find('.variable-value-link');
+          var inputEl = elem.find('input');
           var variable = scope.variable;
+          var cancelBlur = null;
 
-          scope.show = function() {
-            if (scope.selectorOpen) {
-              return;
+          scope.openDropdown = function() {
+            inputEl.show();
+            linkEl.hide();
+            scope.dropdownVisible = true;
+
+            inputEl.css('width', (linkEl.width() + 16) + 'px');
+
+            linkEl.hide();
+            inputEl.show();
+            inputEl.focus();
+
+            $timeout(function() { bodyEl.on('click', scope.bodyOnClick); }, 0, false);
+          };
+
+          scope.switchToLink = function(now) {
+            if (now === true || cancelBlur) {
+              clearTimeout(cancelBlur);
+              cancelBlur = null;
+              inputEl.hide();
+              linkEl.show();
+              scope.dropdownVisible = false;
+              scope.$digest();
+
+              scope.updateLinkText();
+              scope.onUpdated();
+            }
+            else {
+              // need to have long delay because the blur
+              // happens long before the click event on the typeahead options
+              cancelBlur = setTimeout(scope.switchToLink, 50);
             }
 
-            scope.selectorOpen = true;
-            scope.giveFocus = 1;
+            bodyEl.off('click', scope.bodyOnClick);
+          };
+
+          scope.bodyOnClick = function(e) {
+            if (elem.has(e.target).length === 0) {
+              scope.switchToLink();
+            }
+          };
+
+          scope.show = function() {
             scope.oldCurrentText = variable.current.text;
             scope.highlightIndex = -1;
 
@@ -45,9 +94,7 @@ function (angular, app, _) {
 
             scope.search = {query: '', options: scope.options};
 
-            $timeout(function() {
-              bodyEl.on('click', scope.bodyOnClick);
-            }, 0, false);
+            scope.openDropdown();
           };
 
           scope.queryChanged = function() {
@@ -79,7 +126,7 @@ function (angular, app, _) {
           scope.optionSelected = function(option, event) {
             option.selected = !option.selected;
 
-            var hideAfter = true;
+            var hideAfter = false;
             var setAllExceptCurrentTo = function(newValue) {
               _.each(scope.options, function(other) {
                 if (option !== other) { other.selected = newValue; }
@@ -91,13 +138,10 @@ function (angular, app, _) {
             }
             else if (!variable.multi) {
               setAllExceptCurrentTo(false);
-            } else {
-              if (event.ctrlKey || event.metaKey || event.shiftKey) {
-                hideAfter = false;
-              }
-              else {
-                setAllExceptCurrentTo(false);
-              }
+              hideAfter = true;
+            } else if (event.ctrlKey || event.metaKey || event.shiftKey) {
+              hideAfter = true;
+              setAllExceptCurrentTo(false);
             }
 
             var selected = _.filter(scope.options, {selected: true});
@@ -124,23 +168,8 @@ function (angular, app, _) {
               variable.current.value = selected[0].value;
             }
 
-            scope.updateLinkText();
-            scope.onUpdated();
-
             if (hideAfter) {
-              scope.hide();
-            }
-          };
-
-          scope.hide = function() {
-            scope.selectorOpen = false;
-            bodyEl.off('click', scope.bodyOnClick);
-          };
-
-          scope.bodyOnClick = function(e) {
-            var dropdown = elem.find('.variable-value-dropdown');
-            if (dropdown.has(e.target).length === 0) {
-              scope.$apply(scope.hide);
+              scope.switchToLink();
             }
           };
 
@@ -152,6 +181,9 @@ function (angular, app, _) {
           scope.$watchGroup(['variable.hideLabel', 'variable.name', 'variable.label', 'variable.current.text'], function() {
             scope.updateLinkText();
           });
+
+          linkEl.click(scope.openDropdown);
+          //inputEl.blur(scope.switchToLink);
         },
       };
     });

+ 16 - 23
public/app/features/dashboard/partials/variableValueSelect.html

@@ -1,35 +1,28 @@
-<span class="template-variable" ng-show="!variable.hideLabel" style="padding-right: 5px">
+<span class="template-variable tight-form-item" ng-show="!variable.hideLabel" style="padding-right: 5px">
 	{{labelText}}:
 </span>
 
 <div style="position: relative; display: inline-block">
-	<a ng-click="show()" class="variable-value-link">
+	<a ng-click="show()" class="variable-value-link tight-form-item">
 		{{linkText}}
 		<i class="fa fa-caret-down"></i>
 	</a>
+	<input type="text" class="tight-form-clear-input input-small" style="display: none" ng-keydown="keyDown($event)" ng-model="search.query" ng-change="queryChanged()" ></input>
 
-	<div ng-if="selectorOpen" class="variable-value-dropdown">
-		<div class="variable-search-wrapper">
-			<span style="position: relative;">
-				<input type="text" placeholder="Search values..." ng-keydown="keyDown($event)" give-focus="giveFocus" tabindex="1" ng-model="search.query" spellcheck='false' ng-change="queryChanged()" />
-			</span>
+	<div class="variable-value-dropdown" ng-if="dropdownVisible">
+		<div class="variable-options-column">
+			<!-- <div class="variable&#45;options&#45;column&#45;header">Selected</div> -->
+			<a class="variable-option pointer" bindonce ng-repeat="option in search.options" ng-class="{'selected': option.selected, 'highlighted': $index === highlightIndex}" ng-click="optionSelected(option, $event)">
+				<span class="fa fa-fw variable-option-icon"></span>
+				<span>{{option.text}}</span>
+			</a>
 		</div>
-
-		<div class="variable-options-wrapper">
-			<div class="variable-options-column">
-				<a class="variable-option pointer" bindonce ng-repeat="option in search.options"
-					ng-class="{'selected': option.selected, 'highlighted': $index === highlightIndex}" ng-click="optionSelected(option, $event)">
-					<span>{{option.text}}</span>
-					<span class="fa fa-fw variable-option-icon"></span>
-				</a>
-			</div>
-			<div class="variable-options-column" ng-if="variable.tags">
-				<!-- <div class="variable&#45;options&#45;column&#45;header">Tags</div> -->
-				<a class="variable-option-tag pointer" ng-repeat="tag in variable.tags" ng-click="selectTag(option, $event)">
-					<span class="label-tag" tag-color-from-name="tag">{{tag}}</span>
-					<span class="fa fa-fw variable-option-icon"></span>
-				</a>
-			</div>
+		<div class="variable-options-column" ng-if="variable.tags">
+			<!-- <div class="variable&#45;options&#45;column&#45;header">Tags</div> -->
+			<a class="variable-option-tag pointer" ng-repeat="tag in variable.tags" ng-click="selectTag(option, $event)">
+				<span class="fa fa-fw variable-option-icon"></span>
+				<span class="label-tag" tag-color-from-name="tag">{{tag}}&nbsp;&nbsp;<i class="fa fa-tag"></i>&nbsp;</span>
+			</a>
 		</div>
 	</div>
 </div>

+ 35 - 35
public/app/features/templating/partials/editor.html

@@ -226,41 +226,41 @@
 				</div>
 			</div>
 
-			<!-- <div class="editor&#45;row" ng&#45;if="current.type === 'query'"> -->
-			<!-- 	<div class="tight&#45;form&#45;section"> -->
-			<!-- 		<h5>Value Groups/Tags</h5> -->
-			<!-- 		<div class="tight&#45;form" ng&#45;if="current.useTags"> -->
-			<!-- 			<ul class="tight&#45;form&#45;list"> -->
-			<!-- 				<li class="tight&#45;form&#45;item" style="width: 115px"> -->
-			<!-- 					Tags query -->
-			<!-- 				</li> -->
-			<!-- 				<li> -->
-			<!-- 					<input type="text" style="width: 588px" class="input&#45;xxlarge tight&#45;form&#45;input last" ng&#45;model='current.tagsQuery' placeholder="metric name or tags query" ng&#45;model&#45;onblur ng&#45;change="runQuery()"></input> -->
-			<!-- 				</li> -->
-			<!-- 			</ul> -->
-			<!-- 			<div class="clearfix"></div> -->
-			<!-- 		</div> -->
-			<!-- 		<div class="tight&#45;form" ng&#45;if="current.useTags"> -->
-			<!-- 			<ul class="tight&#45;form&#45;list"> -->
-			<!-- 				<li class="tight&#45;form&#45;item" style="width: 115px;"> -->
-			<!-- 					Tags values query -->
-			<!-- 				</li> -->
-			<!-- 				<li> -->
-			<!-- 					<input type="text" style="width: 588px" class="input tight&#45;form&#45;input last" ng&#45;model='current.tagValuesQuery' placeholder="apps.$__tag.*" ng&#45;model&#45;onblur ng&#45;change="runQuery()"></input> -->
-			<!-- 				</li> -->
-			<!-- 			</ul> -->
-			<!-- 			<div class="clearfix"></div> -->
-			<!-- 		</div> -->
-			<!-- 		<div class="tight&#45;form"> -->
-			<!-- 			<ul class="tight&#45;form&#45;list"> -->
-			<!-- 				<li class="tight&#45;form&#45;item last"> -->
-			<!-- 					<editor&#45;checkbox text="Enable" model="current.useTags" change="runQuery()"></editor&#45;checkbox> -->
-			<!-- 				</li> -->
-			<!-- 			</ul> -->
-			<!-- 			<div class="clearfix"></div> -->
-			<!-- 		</div> -->
-			<!-- 	</div> -->
-			<!-- </div> -->
+			<div class="editor-row" ng-if="current.type === 'query'">
+				<div class="tight-form-section">
+					<h5>value groups/tags</h5>
+					<div class="tight-form" ng-if="current.usetags">
+						<ul class="tight-form-list">
+							<li class="tight-form-item" style="width: 115px">
+								tags query
+							</li>
+							<li>
+								<input type="text" style="width: 588px" class="input-xxlarge tight-form-input last" ng-model='current.tagsquery' placeholder="metric name or tags query" ng-model-onblur ng-change="runquery()"></input>
+							</li>
+						</ul>
+						<div class="clearfix"></div>
+					</div>
+					<div class="tight-form" ng-if="current.usetags">
+						<ul class="tight-form-list">
+							<li class="tight-form-item" style="width: 115px;">
+								tags values query
+							</li>
+							<li>
+								<input type="text" style="width: 588px" class="input tight-form-input last" ng-model='current.tagvaluesquery' placeholder="apps.$__tag.*" ng-model-onblur ng-change="runquery()"></input>
+							</li>
+						</ul>
+						<div class="clearfix"></div>
+					</div>
+					<div class="tight-form">
+						<ul class="tight-form-list">
+							<li class="tight-form-item last">
+								<editor-checkbox text="enable" model="current.usetags" change="runquery()"></editor-checkbox>
+							</li>
+						</ul>
+						<div class="clearfix"></div>
+					</div>
+				</div>
+			</div>
 
 			<div class="editor-row">
 				<div class="tight-form-section">

+ 16 - 15
public/css/less/submenu.less

@@ -20,7 +20,7 @@
 }
 
 .submenu-item {
-  padding: 8px 7px;
+//  padding: 8px 7px;
   margin-right: 20px;
   display: inline-block;
   border-radius: 3px;
@@ -43,10 +43,10 @@
 
 .variable-value-dropdown {
   position: absolute;
-  top: 27px;
+  top: 47px;
   min-width: 150px;
   max-height: 400px;
-  background: @grafanaPanelBackground;
+  background: @dropdownBackground;
   box-shadow: 0px 0px 55px 0px black;
   border: 1px solid @grafanaTargetFuncBackground;
   z-index: 1000;
@@ -74,22 +74,23 @@
 .variable-option,
 .variable-options-column-header {
   display: block;
-  padding: 0 27px 0 8px;
+  padding: 2px 27px 0 8px;
   position: relative;
+  white-space: nowrap;
+  min-width: 115px;
 
- .variable-option-icon { display: none }
+ .variable-option-icon {
+   display: inline-block;
+   width: 24px;
+   height: 18px;
+   position: relative;
+   top: 4px;
+   background: url(@checkboxImageUrl) left top no-repeat;
+ }
 
   &.selected {
-    .variable-option-icon:before {
-      content: "\f00c";
-    }
-    .variable-option-icon {
-      display: block;
-      padding-left: 4px;
-      line-height: 26px;
-      position: absolute;
-      right: 0;
-      top: 0;
+    .variable-option-icon{
+      background: url(@checkboxImageUrl) 0px -18px no-repeat;
     }
   }
 }

+ 1 - 2
public/css/less/tightform.less

@@ -23,7 +23,7 @@
 .tight-form-container-no-item-borders {
   border: 1px solid @grafanaTargetBorder;
 
-  .tight-form, .tight-form-item, [type=text].tight-form-input {
+  .tight-form, .tight-form-item, [type=text].tight-form-input, [type=text].tight-form-clear-input  {
     border: none;
   }
 }
@@ -132,7 +132,6 @@ input[type=text].tight-form-clear-input {
   border: none;
   margin: 0px;
   background: transparent;
-  float: left;
   color: @grafanaTargetColor;
   border-radius: 0;
   border-right: 1px solid @grafanaTargetSegmentBorder;