Files
grafana/public/app/plugins/datasource/graphite/add_graphite_func.ts

161 lines
4.1 KiB
TypeScript
Raw Normal View History

2018-03-20 11:07:31 +01:00
import _ from 'lodash';
import $ from 'jquery';
import rst2html from 'rst2html';
import Drop from 'tether-drop';
import coreModule from 'app/core/core_module';
2018-03-20 11:07:31 +01:00
2018-04-03 19:39:50 +02:00
/** @ngInject */
2018-03-20 11:07:31 +01:00
export function graphiteAddFunc($compile) {
2018-03-20 14:26:03 +01:00
const inputTemplate =
2018-03-20 11:07:31 +01:00
'<input type="text"' + ' class="gf-form-input"' + ' spellcheck="false" style="display:none"></input>';
2018-03-20 14:26:03 +01:00
const buttonTemplate =
2018-03-20 11:07:31 +01:00
'<a class="gf-form-label query-part dropdown-toggle"' +
' tabindex="1" gf-dropdown="functionMenu" data-toggle="dropdown">' +
'<i class="fa fa-plus"></i></a>';
return {
link: function($scope, elem) {
2018-08-29 14:26:50 +02:00
const ctrl = $scope.ctrl;
2018-03-20 11:07:31 +01:00
2018-08-29 14:26:50 +02:00
const $input = $(inputTemplate);
const $button = $(buttonTemplate);
2018-03-20 11:07:31 +01:00
$input.appendTo(elem);
$button.appendTo(elem);
ctrl.datasource.getFuncDefs().then(funcDefs => {
2018-08-29 14:26:50 +02:00
const allFunctions = _.map(funcDefs, 'name').sort();
2018-03-20 11:07:31 +01:00
$scope.functionMenu = createFunctionDropDownMenu(funcDefs);
$input.attr('data-provide', 'typeahead');
$input.typeahead({
source: allFunctions,
minLength: 1,
items: 10,
updater: value => {
let funcDef = ctrl.datasource.getFuncDef(value);
2018-03-20 11:07:31 +01:00
if (!funcDef) {
// try find close match
value = value.toLowerCase();
funcDef = _.find(allFunctions, funcName => {
2018-03-20 11:07:31 +01:00
return funcName.toLowerCase().indexOf(value) === 0;
});
if (!funcDef) {
return '';
}
}
$scope.$apply(() => {
2018-03-20 11:07:31 +01:00
ctrl.addFunction(funcDef);
});
$input.trigger('blur');
return '';
},
});
$button.click(() => {
2018-03-20 11:07:31 +01:00
$button.hide();
$input.show();
$input.focus();
});
$input.keyup(() => {
2018-03-20 11:07:31 +01:00
elem.toggleClass('open', $input.val() === '');
});
$input.blur(() => {
2018-04-13 19:48:37 +02:00
// clicking the function dropdown menu won't
2018-03-20 11:07:31 +01:00
// work if you remove class at once
setTimeout(() => {
2018-03-20 11:07:31 +01:00
$input.val('');
$input.hide();
$button.show();
elem.removeClass('open');
}, 200);
});
$compile(elem.contents())($scope);
});
let drop;
const cleanUpDrop = () => {
2018-03-20 11:07:31 +01:00
if (drop) {
drop.destroy();
drop = null;
}
};
$(elem)
.on('mouseenter', 'ul.dropdown-menu li', () => {
2018-03-20 11:07:31 +01:00
cleanUpDrop();
let funcDef;
2018-03-20 11:07:31 +01:00
try {
funcDef = ctrl.datasource.getFuncDef($('a', this).text());
} catch (e) {
// ignore
}
if (funcDef && funcDef.description) {
let shortDesc = funcDef.description;
2018-03-20 11:07:31 +01:00
if (shortDesc.length > 500) {
shortDesc = shortDesc.substring(0, 497) + '...';
}
2018-08-29 14:26:50 +02:00
const contentElement = document.createElement('div');
2018-03-20 11:07:31 +01:00
contentElement.innerHTML = '<h4>' + funcDef.name + '</h4>' + rst2html(shortDesc);
drop = new Drop({
target: this,
content: contentElement,
classes: 'drop-popover',
openOn: 'always',
tetherOptions: {
attachment: 'bottom left',
targetAttachment: 'bottom right',
},
});
}
})
.on('mouseout', 'ul.dropdown-menu li', () => {
2018-03-20 11:07:31 +01:00
cleanUpDrop();
});
$scope.$on('$destroy', cleanUpDrop);
},
};
}
coreModule.directive('graphiteAddFunc', graphiteAddFunc);
2018-03-20 11:07:31 +01:00
function createFunctionDropDownMenu(funcDefs) {
2018-08-29 14:26:50 +02:00
const categories = {};
2018-03-20 11:07:31 +01:00
_.forEach(funcDefs, funcDef => {
2018-03-20 11:07:31 +01:00
if (!funcDef.category) {
return;
}
if (!categories[funcDef.category]) {
categories[funcDef.category] = [];
}
categories[funcDef.category].push({
text: funcDef.name,
click: "ctrl.addFunction('" + funcDef.name + "')",
});
});
return _.sortBy(
_.map(categories, (submenu, category) => {
2018-03-20 11:07:31 +01:00
return {
text: category,
submenu: _.sortBy(submenu, 'text'),
};
}),
'text'
);
}