Reworking variable value dropdown, take3
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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-options-column-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-options-column-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-options-column-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}} <i class="fa fa-tag"></i> </span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -226,41 +226,41 @@
|
||||
</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" 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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user