You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
9.4 KiB
331 lines
9.4 KiB
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
/**
|
|
* JQuery class that creates an override UI control - button that shows menu with available override options and pill
|
|
* buttons on which user can change selected option. Used in graph widget configuration window.
|
|
*/
|
|
jQuery(function ($) {
|
|
"use strict";
|
|
|
|
function createOverrideElement($override, option, value) {
|
|
var close = $('<button>', {'type': 'button'})
|
|
.on('click', function(e) {
|
|
$override.overrides('removeOverride', $override, option);
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
})
|
|
.addClass([ZBX_STYLE_BTN_ICON, ZBX_ICON_REMOVE_SMALLER, 'js-remove']),
|
|
opt = $override.data('options'),
|
|
field_name = opt.makeName(option, opt.getId($override));
|
|
|
|
if (option === 'color') {
|
|
const id = field_name.replace(/\]/g, '_').replace(/\[/g, '_');
|
|
const input = $('<input>', {'name': field_name, 'type': 'hidden', 'id': id}).val(value);
|
|
|
|
return $('<div>')
|
|
.addClass('color-picker')
|
|
.append(input)
|
|
.append(close);
|
|
}
|
|
else if (option === 'timeshift') {
|
|
return $('<div>')
|
|
.append($('<input>', {
|
|
'name': field_name,
|
|
'maxlength': 10,
|
|
'type': 'text',
|
|
'placeholder': t('S_TIME_SHIFT')
|
|
})
|
|
.val(value)
|
|
)
|
|
.append(close);
|
|
}
|
|
else {
|
|
var visible_name = option,
|
|
visible_value = value;
|
|
|
|
if (typeof opt.captions[option] !== 'undefined') {
|
|
visible_name = opt.captions[option];
|
|
}
|
|
if (typeof opt.captions[option + value] !== 'undefined') {
|
|
visible_value = opt.captions[option + value];
|
|
}
|
|
|
|
var content = [
|
|
$('<span>', {'data-option': option}).text(visible_name + ': ' + visible_value),
|
|
$('<input>').attr({'name': field_name, 'type': 'hidden'}).val(value)
|
|
];
|
|
|
|
return $('<div>')
|
|
.append(content)
|
|
.append(close);
|
|
}
|
|
}
|
|
|
|
function getMenu($obj, options, option_to_edit, trigger_elmnt) {
|
|
var sections = [],
|
|
menu = [],
|
|
option_to_edit = option_to_edit || null;
|
|
|
|
var appendMenuItem = function(menu, name, items, opt) {
|
|
if (items.length > 0) {
|
|
var item = items.shift();
|
|
|
|
if (typeof menu[item] === 'undefined') {
|
|
menu[item] = {items: {}};
|
|
}
|
|
|
|
appendMenuItem(menu[item].items, name, items, opt);
|
|
}
|
|
else {
|
|
menu[name] = {
|
|
data: opt,
|
|
items: {}
|
|
};
|
|
}
|
|
};
|
|
|
|
var getMenuPopupItems = function($obj, tree, trigger_elmnt) {
|
|
var items = [],
|
|
data,
|
|
item;
|
|
|
|
if (objectSize(tree) > 0) {
|
|
for (var name in tree) {
|
|
data = tree[name];
|
|
|
|
if (typeof data === 'object') {
|
|
item = {label: name};
|
|
|
|
if (typeof data.items !== 'undefined' && objectSize(data.items) > 0) {
|
|
item.items = getMenuPopupItems($obj, data.items, trigger_elmnt);
|
|
}
|
|
|
|
if (typeof data.data !== 'undefined') {
|
|
item.data = data.data;
|
|
|
|
item.clickCallback = function(e) {
|
|
var args = [$obj];
|
|
$(this).data('args').forEach(function(a) {args.push(a)});
|
|
methods[$(this).data('callback')].apply($obj, args);
|
|
|
|
// Remove menu only after .data() has been read from <a>.
|
|
$(this).closest('.menu-popup-top').menuPopup('close', null, true);
|
|
|
|
cancelEvent(e);
|
|
};
|
|
}
|
|
|
|
items[items.length] = item;
|
|
}
|
|
}
|
|
}
|
|
|
|
return items;
|
|
};
|
|
|
|
$(options.sections).each(function(i, section) {
|
|
menu = [];
|
|
$(section['options']).each(function(i, opt) {
|
|
if (option_to_edit === null || option_to_edit === opt.args[0]) {
|
|
var items = splitPath(opt.name),
|
|
name = (items.length > 0) ? items.pop() : opt.name;
|
|
|
|
appendMenuItem(menu, name, items, opt);
|
|
}
|
|
});
|
|
|
|
if (option_to_edit) {
|
|
var key = Object.keys(menu)[0];
|
|
sections.push({
|
|
label: key,
|
|
items: getMenuPopupItems($obj, menu[key].items, trigger_elmnt)
|
|
});
|
|
}
|
|
else {
|
|
sections.push({
|
|
label: section['name'],
|
|
items: getMenuPopupItems($obj, menu, trigger_elmnt)
|
|
});
|
|
}
|
|
});
|
|
|
|
return sections;
|
|
}
|
|
|
|
var methods = {
|
|
/**
|
|
* Create control for override option configuration.
|
|
*
|
|
* Supported options:
|
|
* - add - UI element to click on to open override options menu.
|
|
* - override - selector for single override set. Mandatory if getId() uses it.
|
|
* - overridesList - selector for overrides list. Mandatory if getId() uses it.
|
|
* - options - selector of UI elements for already specified overrides.
|
|
* - menu - JSon for override options that appears in context menu.
|
|
* - getId - Function returns unique identifier of override used for override option name.
|
|
* - makeName - Function creates pattern matching name for input field that stores value of override option.
|
|
* - makeOption - Function extracts given string and returns override option from it.
|
|
* - onUpdate - Function called when override values changes.
|
|
*
|
|
* @param options
|
|
*/
|
|
init: function(options) {
|
|
options = $.extend({}, {
|
|
options: 'input[type=hidden]',
|
|
add: null,
|
|
menu: {},
|
|
// Argument row_id is needed even if it is not used. Function is assumed to be overwritten.
|
|
makeName: function(option, row_id) {
|
|
return option;
|
|
},
|
|
makeOption: function(name) {
|
|
return name;
|
|
},
|
|
onUpdate: function() {
|
|
return true;
|
|
},
|
|
getId: function($override) {
|
|
var opt = $override.data('options');
|
|
return $(opt.overridesList + ' ' + opt.override).index($override.closest(opt.override));
|
|
}
|
|
}, options);
|
|
|
|
this.each(function() {
|
|
var $override = $(this);
|
|
if (typeof $override.data('options') !== 'undefined') {
|
|
return;
|
|
}
|
|
|
|
$override.data('options', $.extend({}, options));
|
|
|
|
$(options.options, $override).each(function() {
|
|
var opt = options.makeOption($(this).attr('name')),
|
|
elmnt = createOverrideElement($override, opt, $(this).val());
|
|
|
|
$(elmnt).insertBefore($(this));
|
|
$(this).remove();
|
|
|
|
if (opt === 'color') {
|
|
$(elmnt).find('input').colorpicker();
|
|
}
|
|
});
|
|
|
|
$override.on('click', '[data-option]', function(e) {
|
|
var obj = $(this);
|
|
obj.menuPopup(getMenu($override, options['menu'], obj.data('option'), obj), e);
|
|
return false;
|
|
});
|
|
|
|
$(options['add'], $override).on('click keydown', function(e) {
|
|
var obj = $(this);
|
|
|
|
if (e.type === 'keydown') {
|
|
if (e.which != 13) {
|
|
return;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.target = this;
|
|
}
|
|
|
|
obj.menuPopup(getMenu($override, options['menu'], null, obj), e);
|
|
return false;
|
|
});
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Method:
|
|
* - adds new override option (UI element) of type {option} and value {value} for given $override;
|
|
* - changes if specified option of type {option} is already set for given $override.
|
|
*
|
|
* @param object $override Object of current override.
|
|
* @param string option String of override option to set (e.g. color, type etc).
|
|
* @param string value Value of option. Can be NULL for options 'color' and 'timeshift'.
|
|
*/
|
|
addOverride: function($override, option, value) {
|
|
var opt = $override.data('options');
|
|
if ($('[name="' + opt['makeName'](option, opt.getId($override)) + '"]', $override).length > 0) {
|
|
methods.updateOverride($override, option, value);
|
|
}
|
|
else {
|
|
var elmnt = createOverrideElement($override, option, value);
|
|
$('<li>')
|
|
.append(elmnt)
|
|
.insertBefore($('li:last', $override));
|
|
|
|
if (option === 'color') {
|
|
$(elmnt).find('input').colorpicker();
|
|
}
|
|
}
|
|
|
|
// Call on-select callback.
|
|
opt['onUpdate']();
|
|
},
|
|
|
|
/**
|
|
* Update existing override option in given $override.
|
|
*
|
|
* See methods.addOverride for argument description.
|
|
*/
|
|
updateOverride: function($override, option, value) {
|
|
var opt = $override.data('options'),
|
|
field_name = opt['makeName'](option, opt.getId($override));
|
|
$('[name="' + field_name + '"]', $override).val(value);
|
|
|
|
switch (option) {
|
|
case 'timeshift':
|
|
case 'color':
|
|
break;
|
|
|
|
default:
|
|
var visible_name = (typeof opt.captions[option] !== 'undefined') ? opt.captions[option] : option,
|
|
visible_value = (typeof opt.captions[option + value] !== 'undefined')
|
|
? opt.captions[option + value]
|
|
: value;
|
|
$('span', $('[name="' + field_name + '"]', $override).parent())
|
|
.text(visible_name + ': ' + visible_value);
|
|
break;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Removes existing override option from given $override.
|
|
*
|
|
* @param object $override Object of current override.
|
|
* @param string option Override option that need to be removed.
|
|
*/
|
|
removeOverride: function($override, option) {
|
|
var opt = $override.data('options');
|
|
$('[name="'+opt['makeName'](option, opt.getId($override))+'"]', $(this)).closest('li').remove();
|
|
opt['onUpdate']();
|
|
}
|
|
};
|
|
|
|
$.fn.overrides = function(method) {
|
|
if (methods[method]) {
|
|
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
|
}
|
|
|
|
return methods.init.apply(this, arguments);
|
|
};
|
|
});
|