Commit feb20243 by Torkel Ödegaard

added func controls

parent e3e6f511
......@@ -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 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>';
var inputBlur = function(scope, func, paramIndex) {
var $input = $(this);
var $link = $input.prev();
return {
restrict: 'A',
link: function postLink($scope, elem) {
var $funcLink = $(funcSpanTemplate);
var $funcControls = $(funcControlsTemplate);
var func = $scope.func;
var funcDef = func.def;
if ($input.val() !== '') {
$link.text($input.val());
function clickFuncParam(paramIndex) {
/*jshint validthis:true */
if (func.updateParam($input.val(), paramIndex)) {
scope.$apply(function() {
scope.targetChanged();
});
}
}
var $link = $(this);
var $input = $link.next();
$input.hide();
$link.show();
};
$input.val(func.params[paramIndex]);
$input.css('width', ($link.width() + 16) + 'px');
var inputKeyPress = function(scope, func, paramIndex, e) {
if(e.which === 13) {
inputBlur.call(this, scope, func, paramIndex);
}
};
$link.hide();
$input.show();
$input.focus();
$input.select();
var inputKeyDown = function() {
this.style.width = (3 + this.value.length) * 8 + 'px';
};
var typeahead = $input.data('typeahead');
if (typeahead) {
$input.val('');
typeahead.lookup();
}
}
var addTypeahead = function($input, scope, func, paramIndex) {
$input.attr('data-provide', 'typeahead');
function inputBlur(paramIndex) {
/*jshint validthis:true */
var options = func.def.params[paramIndex].options;
if (func.def.params[paramIndex].type === 'int') {
options = _.map(options, function(val) { return val.toString(); } );
}
var $input = $(this);
var $link = $input.prev();
$input.typeahead({
source: options,
minLength: 0,
items: 20,
updater: function (value) {
setTimeout(function() {
inputBlur.call($input[0], scope, func, paramIndex);
}, 0);
return value;
if ($input.val() !== '') {
$link.text($input.val());
if (func.updateParam($input.val(), paramIndex)) {
$scope.$apply(function() {
$scope.targetChanged();
});
}
}
$input.hide();
$link.show();
}
});
var typeahead = $input.data('typeahead');
typeahead.lookup = function () {
this.query = this.$element.val() || '';
return this.process(this.source);
};
function inputKeyPress(paramIndex, e) {
/*jshint validthis:true */
};
if(e.which === 13) {
inputBlur.call(this, paramIndex);
}
}
return {
restrict: 'A',
link: function postLink($scope, elem) {
var $funcLink = $(funcSpanTemplate);
function inputKeyDown() {
/*jshint validthis:true */
this.style.width = (3 + this.value.length) * 8 + 'px';
}
$funcLink.appendTo(elem);
function addTypeahead($input, paramIndex) {
$input.attr('data-provide', 'typeahead');
_.each($scope.func.def.params, function(param, index) {
var $paramLink = $('<a ng-click="">' + $scope.func.params[index] + '</a>');
var $input = $(paramTemplate);
var options = funcDef.params[paramIndex].options;
if (funcDef.params[paramIndex].type === 'int') {
options = _.map(options, function(val) { return val.toString(); } );
}
$paramLink.appendTo(elem);
$input.appendTo(elem);
$input.typeahead({
source: options,
minLength: 0,
items: 20,
updater: function (value) {
setTimeout(function() {
inputBlur.call($input[0], paramIndex);
}, 0);
return value;
}
});
$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));
var typeahead = $input.data('typeahead');
typeahead.lookup = function () {
this.query = this.$element.val() || '';
return this.process(this.source);
};
}
if (index !== $scope.func.def.params.length - 1) {
$('<span>, </span>').appendTo(elem);
function getPosition() {
var el = elem[0];
var pos = {};
if (typeof el.getBoundingClientRect === 'function') {
pos = el.getBoundingClientRect();
}
if ($scope.func.def.params[index].options) {
addTypeahead($input, $scope, $scope.func, index);
else {
pos = { width: el.offsetWidth, height: el.offsetHeight };
}
});
return $.extend(pos, elem.offset());
}
function toggleFuncControls() {
var targetDiv = elem.closest('.grafana-target-inner');
$('<span>)</span>').appendTo(elem);
if (elem.hasClass('show-function-controls')) {
elem.removeClass('show-function-controls');
targetDiv.removeClass('has-open-function');
$funcControls.hide();
return;
}
$compile(elem.contents())($scope);
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>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment