mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
added func controls
This commit is contained in:
parent
e3e6f511e7
commit
feb20243e5
@ -10,7 +10,7 @@ function (angular, _, config, gfunc, Parser) {
|
||||
|
||||
var module = angular.module('kibana.controllers');
|
||||
|
||||
module.controller('GraphiteTargetCtrl', function($scope, $http, filterSrv, $timeout) {
|
||||
module.controller('GraphiteTargetCtrl', function($scope, $http, filterSrv) {
|
||||
|
||||
$scope.init = function() {
|
||||
parseTarget();
|
||||
|
@ -14,120 +14,201 @@ function (angular, _, $) {
|
||||
var paramTemplate = '<input type="text" style="display:none"' +
|
||||
' class="input-mini grafana-function-param-input"></input>';
|
||||
|
||||
var clickFuncParam = function(func, paramIndex) {
|
||||
var $link = $(this);
|
||||
var $input = $link.next();
|
||||
|
||||
$input.val(func.params[paramIndex]);
|
||||
$input.css('width', ($link.width() + 16) + 'px');
|
||||
|
||||
$link.hide();
|
||||
$input.show();
|
||||
$input.focus();
|
||||
$input.select();
|
||||
|
||||
var typeahead = $input.data('typeahead');
|
||||
if (typeahead) {
|
||||
$input.val('');
|
||||
typeahead.lookup();
|
||||
}
|
||||
};
|
||||
|
||||
var inputBlur = function(scope, func, paramIndex) {
|
||||
var $input = $(this);
|
||||
var $link = $input.prev();
|
||||
|
||||
if ($input.val() !== '') {
|
||||
$link.text($input.val());
|
||||
|
||||
if (func.updateParam($input.val(), paramIndex)) {
|
||||
scope.$apply(function() {
|
||||
scope.targetChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$input.hide();
|
||||
$link.show();
|
||||
};
|
||||
|
||||
var inputKeyPress = function(scope, func, paramIndex, e) {
|
||||
if(e.which === 13) {
|
||||
inputBlur.call(this, scope, func, paramIndex);
|
||||
}
|
||||
};
|
||||
|
||||
var inputKeyDown = function() {
|
||||
this.style.width = (3 + this.value.length) * 8 + 'px';
|
||||
};
|
||||
|
||||
var addTypeahead = function($input, scope, func, paramIndex) {
|
||||
$input.attr('data-provide', 'typeahead');
|
||||
|
||||
var options = func.def.params[paramIndex].options;
|
||||
if (func.def.params[paramIndex].type === 'int') {
|
||||
options = _.map(options, function(val) { return val.toString(); } );
|
||||
}
|
||||
|
||||
$input.typeahead({
|
||||
source: options,
|
||||
minLength: 0,
|
||||
items: 20,
|
||||
updater: function (value) {
|
||||
setTimeout(function() {
|
||||
inputBlur.call($input[0], scope, func, paramIndex);
|
||||
}, 0);
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
var typeahead = $input.data('typeahead');
|
||||
typeahead.lookup = function () {
|
||||
this.query = this.$element.val() || '';
|
||||
return this.process(this.source);
|
||||
};
|
||||
|
||||
};
|
||||
var funcControlsTemplate =
|
||||
'<span class="graphite-func-controls">' +
|
||||
'<span class="pointer icon-arrow-left"></span>' +
|
||||
'<span class="pointer icon-info-sign"></span>' +
|
||||
'<span class="pointer icon-remove" ></span>' +
|
||||
'<span class="pointer icon-arrow-right"></span>' +
|
||||
'</span>';
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function postLink($scope, elem) {
|
||||
var $funcLink = $(funcSpanTemplate);
|
||||
var $funcControls = $(funcControlsTemplate);
|
||||
var func = $scope.func;
|
||||
var funcDef = func.def;
|
||||
|
||||
$funcLink.appendTo(elem);
|
||||
function clickFuncParam(paramIndex) {
|
||||
/*jshint validthis:true */
|
||||
|
||||
_.each($scope.func.def.params, function(param, index) {
|
||||
var $paramLink = $('<a ng-click="">' + $scope.func.params[index] + '</a>');
|
||||
var $input = $(paramTemplate);
|
||||
var $link = $(this);
|
||||
var $input = $link.next();
|
||||
|
||||
$paramLink.appendTo(elem);
|
||||
$input.appendTo(elem);
|
||||
$input.val(func.params[paramIndex]);
|
||||
$input.css('width', ($link.width() + 16) + 'px');
|
||||
|
||||
$input.blur(_.partial(inputBlur, $scope, $scope.func, index));
|
||||
$input.keyup(inputKeyDown);
|
||||
$input.keypress(_.partial(inputKeyPress, $scope, $scope.func, index));
|
||||
$paramLink.click(_.partial(clickFuncParam, $scope.func, index));
|
||||
$link.hide();
|
||||
$input.show();
|
||||
$input.focus();
|
||||
$input.select();
|
||||
|
||||
if (index !== $scope.func.def.params.length - 1) {
|
||||
$('<span>, </span>').appendTo(elem);
|
||||
var typeahead = $input.data('typeahead');
|
||||
if (typeahead) {
|
||||
$input.val('');
|
||||
typeahead.lookup();
|
||||
}
|
||||
}
|
||||
|
||||
function inputBlur(paramIndex) {
|
||||
/*jshint validthis:true */
|
||||
|
||||
var $input = $(this);
|
||||
var $link = $input.prev();
|
||||
|
||||
if ($input.val() !== '') {
|
||||
$link.text($input.val());
|
||||
|
||||
if (func.updateParam($input.val(), paramIndex)) {
|
||||
$scope.$apply(function() {
|
||||
$scope.targetChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($scope.func.def.params[index].options) {
|
||||
addTypeahead($input, $scope, $scope.func, index);
|
||||
$input.hide();
|
||||
$link.show();
|
||||
}
|
||||
|
||||
function inputKeyPress(paramIndex, e) {
|
||||
/*jshint validthis:true */
|
||||
|
||||
if(e.which === 13) {
|
||||
inputBlur.call(this, paramIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function inputKeyDown() {
|
||||
/*jshint validthis:true */
|
||||
this.style.width = (3 + this.value.length) * 8 + 'px';
|
||||
}
|
||||
|
||||
function addTypeahead($input, paramIndex) {
|
||||
$input.attr('data-provide', 'typeahead');
|
||||
|
||||
var options = funcDef.params[paramIndex].options;
|
||||
if (funcDef.params[paramIndex].type === 'int') {
|
||||
options = _.map(options, function(val) { return val.toString(); } );
|
||||
}
|
||||
|
||||
});
|
||||
$input.typeahead({
|
||||
source: options,
|
||||
minLength: 0,
|
||||
items: 20,
|
||||
updater: function (value) {
|
||||
setTimeout(function() {
|
||||
inputBlur.call($input[0], paramIndex);
|
||||
}, 0);
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
$('<span>)</span>').appendTo(elem);
|
||||
var typeahead = $input.data('typeahead');
|
||||
typeahead.lookup = function () {
|
||||
this.query = this.$element.val() || '';
|
||||
return this.process(this.source);
|
||||
};
|
||||
}
|
||||
|
||||
$compile(elem.contents())($scope);
|
||||
function getPosition() {
|
||||
var el = elem[0];
|
||||
var pos = {};
|
||||
if (typeof el.getBoundingClientRect === 'function') {
|
||||
pos = el.getBoundingClientRect();
|
||||
}
|
||||
else {
|
||||
pos = { width: el.offsetWidth, height: el.offsetHeight };
|
||||
}
|
||||
|
||||
return $.extend(pos, elem.offset());
|
||||
}
|
||||
|
||||
function toggleFuncControls() {
|
||||
var targetDiv = elem.closest('.grafana-target-inner');
|
||||
|
||||
if (elem.hasClass('show-function-controls')) {
|
||||
elem.removeClass('show-function-controls');
|
||||
targetDiv.removeClass('has-open-function');
|
||||
$funcControls.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
elem.addClass('show-function-controls');
|
||||
targetDiv.addClass('has-open-function');
|
||||
|
||||
if ($scope.func.added) {
|
||||
$scope.func.added = false;
|
||||
setTimeout(function() {
|
||||
elem.find('a').click();
|
||||
var pos = getPosition();
|
||||
$funcControls.css('position', 'absolute');
|
||||
$funcControls.css('top', (pos.top - 78) + 'px');
|
||||
$funcControls.css('left', pos.left + 'px');
|
||||
$funcControls.css('width', pos.width + 'px');
|
||||
console.log(pos);
|
||||
$funcControls.show();
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function addElementsAndCompile() {
|
||||
$funcLink.appendTo(elem);
|
||||
|
||||
_.each(funcDef.params, function(param, index) {
|
||||
var $paramLink = $('<a ng-click="" class="graphite-func-param-link">' + func.params[index] + '</a>');
|
||||
var $input = $(paramTemplate);
|
||||
|
||||
$paramLink.appendTo(elem);
|
||||
$input.appendTo(elem);
|
||||
|
||||
$input.blur(_.partial(inputBlur, index));
|
||||
$input.keyup(inputKeyDown);
|
||||
$input.keypress(_.partial(inputKeyPress, index));
|
||||
$paramLink.click(_.partial(clickFuncParam, index));
|
||||
|
||||
if (index !== funcDef.params.length - 1) {
|
||||
$('<span>, </span>').appendTo(elem);
|
||||
}
|
||||
|
||||
if (funcDef.params[index].options) {
|
||||
addTypeahead($input, index);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('<span>)</span>').appendTo(elem);
|
||||
|
||||
elem.append($funcControls);
|
||||
|
||||
$compile(elem.contents())($scope);
|
||||
}
|
||||
|
||||
function ifJustAddedFocusFistParam() {
|
||||
if ($scope.func.added) {
|
||||
$scope.func.added = false;
|
||||
setTimeout(function() {
|
||||
elem.find('.graphite-func-param-link').first().click();
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function registerFuncControlsToggle() {
|
||||
$funcLink.click(toggleFuncControls);
|
||||
}
|
||||
|
||||
function registerFuncControlsActions() {
|
||||
$funcControls.click(function(e) {
|
||||
var $target = $(e.target);
|
||||
if ($target.hasClass('icon-remove')) {
|
||||
toggleFuncControls();
|
||||
$scope.$apply(function() {
|
||||
$scope.removeFunction($scope.func);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addElementsAndCompile();
|
||||
ifJustAddedFocusFistParam();
|
||||
registerFuncControlsToggle();
|
||||
registerFuncControlsActions();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -7,99 +7,97 @@
|
||||
ng-controller="GraphiteTargetCtrl"
|
||||
ng-init="init()">
|
||||
|
||||
<div class="grafana-target-inner-wrapper">
|
||||
<div class="grafana-target-inner">
|
||||
<ul class="grafana-target-controls">
|
||||
<li ng-show="parserError">
|
||||
<a bs-tooltip="parserError" style="color: rgb(229, 189, 28)" role="menuitem">
|
||||
<i class="icon-warning-sign"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" tabindex="1" ng-click="showTextEditor = !showTextEditor">
|
||||
<i class="icon-pencil"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="pointer dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
tabindex="1">
|
||||
<i class="icon-cog"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li role="menuitem">
|
||||
<a tabindex="1"
|
||||
ng-click="duplicate()">
|
||||
Duplicate
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" tabindex="1" ng-click="removeTarget(target)">
|
||||
<i class="icon-remove"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="grafana-target-inner">
|
||||
<ul class="grafana-target-controls">
|
||||
<li ng-show="parserError">
|
||||
<a bs-tooltip="parserError" style="color: rgb(229, 189, 28)" role="menuitem">
|
||||
<i class="icon-warning-sign"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" tabindex="1" ng-click="showTextEditor = !showTextEditor">
|
||||
<i class="icon-pencil"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a class="pointer dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
tabindex="1">
|
||||
<i class="icon-cog"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li role="menuitem">
|
||||
<a tabindex="1"
|
||||
ng-click="duplicate()">
|
||||
Duplicate
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" tabindex="1" ng-click="removeTarget(target)">
|
||||
<i class="icon-remove"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="grafana-target-controls-left">
|
||||
<li>
|
||||
<a class="grafana-target-segment"
|
||||
ng-click="target.hide = !target.hide; get_data();"
|
||||
role="menuitem">
|
||||
<i class="icon-eye-open"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="grafana-target-controls-left">
|
||||
<li>
|
||||
<a class="grafana-target-segment"
|
||||
ng-click="target.hide = !target.hide; get_data();"
|
||||
role="menuitem">
|
||||
<i class="icon-eye-open"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<input type="text"
|
||||
class="grafana-target-text-input span10"
|
||||
ng-model="target.target"
|
||||
focus-me="showTextEditor"
|
||||
spellcheck='false'
|
||||
ng-model-onblur ng-change="targetTextChanged()"
|
||||
ng-show="showTextEditor" />
|
||||
<input type="text"
|
||||
class="grafana-target-text-input span10"
|
||||
ng-model="target.target"
|
||||
focus-me="showTextEditor"
|
||||
spellcheck='false'
|
||||
ng-model-onblur ng-change="targetTextChanged()"
|
||||
ng-show="showTextEditor" />
|
||||
|
||||
<ul class="grafana-segment-list" role="menu" ng-hide="showTextEditor">
|
||||
<li class="dropdown" ng-repeat="segment in segments" role="menuitem">
|
||||
<a tabindex="1"
|
||||
class="grafana-target-segment dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
ng-click="getAltSegments($index)"
|
||||
focus-me="segment.focus"
|
||||
ng-bind-html-unsafe="segment.html">
|
||||
</a>
|
||||
<ul class="dropdown-menu scrollable grafana-segment-dropdown-menu" role="menu">
|
||||
<li ng-repeat="altSegment in altSegments" role="menuitem">
|
||||
<a href="javascript:void(0)" tabindex="1" ng-click="setSegment($index, $parent.$index)" ng-bind-html-unsafe="altSegment.html"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li ng-repeat="func in functions">
|
||||
<span graphite-func-editor class="grafana-target-segment grafana-target-function">
|
||||
</span>
|
||||
<!-- <a class="grafana-target-segment grafana-target-function dropdown-toggle"
|
||||
bs-popover="'app/partials/graphite/funcEditor.html'"
|
||||
data-placement="bottom">
|
||||
{{func.def.name}}
|
||||
</a> -->
|
||||
<!-- <span class="grafana-target-segment grafana-target-function">
|
||||
<span>{{func.def.name}}(</span><span ng-repeat="param in func.def.params">
|
||||
<input type="text"
|
||||
class="input-mini grafana-function-param-input"
|
||||
dynamic-width
|
||||
ng-model="func.params[$index]"></input>
|
||||
</span><span>)</span>
|
||||
</span> -->
|
||||
</li>
|
||||
<li class="dropdown" graphite-add-func>
|
||||
<ul class="grafana-segment-list" role="menu" ng-hide="showTextEditor">
|
||||
<li class="dropdown" ng-repeat="segment in segments" role="menuitem">
|
||||
<a tabindex="1"
|
||||
class="grafana-target-segment dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
ng-click="getAltSegments($index)"
|
||||
focus-me="segment.focus"
|
||||
ng-bind-html-unsafe="segment.html">
|
||||
</a>
|
||||
<ul class="dropdown-menu scrollable grafana-segment-dropdown-menu" role="menu">
|
||||
<li ng-repeat="altSegment in altSegments" role="menuitem">
|
||||
<a href="javascript:void(0)" tabindex="1" ng-click="setSegment($index, $parent.$index)" ng-bind-html-unsafe="altSegment.html"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li ng-repeat="func in functions">
|
||||
<span graphite-func-editor class="grafana-target-segment grafana-target-function">
|
||||
</span>
|
||||
<!-- <a class="grafana-target-segment grafana-target-function dropdown-toggle"
|
||||
bs-popover="'app/partials/graphite/funcEditor.html'"
|
||||
data-placement="bottom">
|
||||
{{func.def.name}}
|
||||
</a> -->
|
||||
<!-- <span class="grafana-target-segment grafana-target-function">
|
||||
<span>{{func.def.name}}(</span><span ng-repeat="param in func.def.params">
|
||||
<input type="text"
|
||||
class="input-mini grafana-function-param-input"
|
||||
dynamic-width
|
||||
ng-model="func.params[$index]"></input>
|
||||
</span><span>)</span>
|
||||
</span> -->
|
||||
</li>
|
||||
<li class="dropdown" graphite-add-func>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
2
src/css/bootstrap.dark.min.css
vendored
2
src/css/bootstrap.dark.min.css
vendored
File diff suppressed because one or more lines are too long
2
src/css/bootstrap.light.min.css
vendored
2
src/css/bootstrap.light.min.css
vendored
File diff suppressed because one or more lines are too long
@ -221,16 +221,16 @@
|
||||
border-bottom: 1px solid @grafanaTargetBorder;
|
||||
}
|
||||
|
||||
.grafana-target-inner-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grafana-target-inner {
|
||||
border-top: 1px solid @grafanaTargetBorder;
|
||||
border-left: 1px solid @grafanaTargetBorder;
|
||||
border-right: 1px solid @grafanaTargetBorder;
|
||||
background: @grafanaTargetBackground;
|
||||
width: 100%;
|
||||
|
||||
&.has-open-function {
|
||||
margin-top: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.grafana-target-onoff {
|
||||
@ -282,6 +282,11 @@
|
||||
> a:hover {
|
||||
color: @linkColor;
|
||||
}
|
||||
|
||||
&.show-function-controls {
|
||||
min-width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=text].grafana-function-param-input {
|
||||
@ -358,6 +363,25 @@ select.grafana-target-segment-input {
|
||||
padding: 0; margin: 0;
|
||||
}
|
||||
|
||||
.graphite-func-controls {
|
||||
display: none;
|
||||
text-align: center;
|
||||
|
||||
.icon-arrow-left {
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.icon-arrow-right {
|
||||
float: right;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.icon-remove {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=text].func-param {
|
||||
border: none;
|
||||
background: inherit;
|
||||
|
Loading…
Reference in New Issue
Block a user