Reworking variable value dropdown, take3

This commit is contained in:
Torkel Ödegaard
2015-06-03 14:53:52 +02:00
parent c5d3eb53f0
commit 483ef20527
6 changed files with 133 additions and 108 deletions
+1 -1
View File
@@ -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
View File
@@ -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);
},
};
});
@@ -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>
@@ -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
View File
@@ -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
View File
@@ -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;