| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- define([
- 'angular',
- 'lodash',
- 'jquery',
- 'rst2html',
- ],
- function (angular, _, $, rst2html) {
- 'use strict';
- angular
- .module('grafana.directives')
- .directive('graphiteFuncEditor', function($compile, templateSrv) {
- var funcSpanTemplate = '<a ng-click="">{{func.def.name}}</a><span>(</span>';
- var paramTemplate = '<input type="text" style="display:none"' +
- ' class="input-small tight-form-func-param"></input>';
- var funcControlsTemplate =
- '<div class="tight-form-func-controls">' +
- '<span class="pointer fa fa-arrow-left"></span>' +
- '<span class="pointer fa fa-question-circle"></span>' +
- '<span class="pointer fa fa-remove" ></span>' +
- '<span class="pointer fa fa-arrow-right"></span>' +
- '</div>';
- return {
- restrict: 'A',
- link: function postLink($scope, elem) {
- var $funcLink = $(funcSpanTemplate);
- var $funcControls = $(funcControlsTemplate);
- var ctrl = $scope.ctrl;
- var func = $scope.func;
- var scheduledRelink = false;
- var paramCountAtLink = 0;
- function clickFuncParam(paramIndex) {
- /*jshint validthis:true */
- var $link = $(this);
- var $comma = $link.prev('.comma');
- var $input = $link.next();
- $input.val(func.params[paramIndex]);
- $comma.removeClass('last');
- $link.hide();
- $input.show();
- $input.focus();
- $input.select();
- var typeahead = $input.data('typeahead');
- if (typeahead) {
- $input.val('');
- typeahead.lookup();
- }
- }
- function scheduledRelinkIfNeeded() {
- if (paramCountAtLink === func.params.length) {
- return;
- }
- if (!scheduledRelink) {
- scheduledRelink = true;
- setTimeout(function() {
- relink();
- scheduledRelink = false;
- }, 200);
- }
- }
- function paramDef(index) {
- if (index < func.def.params.length) {
- return func.def.params[index];
- }
- if (_.last(func.def.params).multiple) {
- return _.assign({}, _.last(func.def.params), {optional: true});
- }
- return {};
- }
- function inputBlur(paramIndex) {
- /*jshint validthis:true */
- var $input = $(this);
- if ($input.data('typeahead') && $input.data('typeahead').shown) {
- return;
- }
- var $link = $input.prev();
- var $comma = $link.prev('.comma');
- var newValue = $input.val();
- if (newValue !== '' || paramDef(paramIndex).optional) {
- $link.html(templateSrv.highlightVariablesAsHtml(newValue));
- func.updateParam(newValue, paramIndex);
- scheduledRelinkIfNeeded();
- $scope.$apply(function() {
- ctrl.targetChanged();
- });
- if ($link.hasClass('last') && newValue === '') {
- $comma.addClass('last');
- } else {
- $link.removeClass('last');
- }
- $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 = paramDef(paramIndex).options;
- if (paramDef(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;
- }
- });
- var typeahead = $input.data('typeahead');
- typeahead.lookup = function () {
- this.query = this.$element.val() || '';
- return this.process(this.source);
- };
- }
- function toggleFuncControls() {
- var targetDiv = elem.closest('.tight-form');
- 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');
- $funcControls.show();
- }
- function addElementsAndCompile() {
- $funcControls.appendTo(elem);
- $funcLink.appendTo(elem);
- var defParams = _.clone(func.def.params);
- var lastParam = _.last(func.def.params);
- while (func.params.length >= defParams.length && lastParam && lastParam.multiple) {
- defParams.push(_.assign({}, lastParam, {optional: true}));
- }
- _.each(defParams, function(param, index) {
- if (param.optional && func.params.length < index) {
- return false;
- }
- var paramValue = templateSrv.highlightVariablesAsHtml(func.params[index]);
- var last = (index >= func.params.length - 1) && param.optional && !paramValue;
- if (last && param.multiple) {
- paramValue = '+';
- }
- if (index > 0) {
- $('<span class="comma' + (last ? ' last' : '') + '">, </span>').appendTo(elem);
- }
- var $paramLink = $(
- '<a ng-click="" class="graphite-func-param-link' + (last ? ' last' : '') + '">'
- + (paramValue || ' ') + '</a>');
- var $input = $(paramTemplate);
- $input.attr('placeholder', param.name);
- paramCountAtLink++;
- $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 (param.options) {
- addTypeahead($input, index);
- }
- });
- $('<span>)</span>').appendTo(elem);
- $compile(elem.contents())($scope);
- }
- function ifJustAddedFocusFirstParam() {
- 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('fa-remove')) {
- toggleFuncControls();
- $scope.$apply(function() {
- ctrl.removeFunction($scope.func);
- });
- return;
- }
- if ($target.hasClass('fa-arrow-left')) {
- $scope.$apply(function() {
- _.move(ctrl.queryModel.functions, $scope.$index, $scope.$index - 1);
- ctrl.targetChanged();
- });
- return;
- }
- if ($target.hasClass('fa-arrow-right')) {
- $scope.$apply(function() {
- _.move(ctrl.queryModel.functions, $scope.$index, $scope.$index + 1);
- ctrl.targetChanged();
- });
- return;
- }
- if ($target.hasClass('fa-question-circle')) {
- if (func.def.description) {
- alert(rst2html(func.def.description));
- } else {
- window.open(
- "http://graphite.readthedocs.org/en/latest/functions.html#graphite.render.functions." + func.def.name,'_blank');
- }
- return;
- }
- });
- }
- function relink() {
- elem.children().remove();
- addElementsAndCompile();
- ifJustAddedFocusFirstParam();
- registerFuncControlsToggle();
- registerFuncControlsActions();
- }
- relink();
- }
- };
- });
- });
|