. **/ use Widgets\SvgGraph\Includes\CWidgetFieldDataSet; ?> window.widget_form = new class extends CWidgetForm { /** * @type {Map} */ #single_items_sortable = new Map(); /** * @type {number} */ #dataset_row_unique_id = 0; init({form_tabs_id, color_palette, templateid}) { colorPalette.setThemeColors(color_palette); this._$overlay_body = jQuery('.overlay-dialogue-body'); this._form = this.getForm(); this._templateid = templateid; this._dataset_wrapper = document.getElementById('data_sets'); this._any_ds_aggregation_function_enabled = false; this.#dataset_row_unique_id = this._dataset_wrapper.querySelectorAll('.').length - 1; jQuery(`#${form_tabs_id}`) .on('change', 'input, z-color-picker, z-select, .multiselect', () => this.onGraphConfigChange()); this._dataset_wrapper.addEventListener('input', e => { if (e.target.matches('input[name$="[data_set_label]"]') || e.target.matches('input[name$="[timeshift]"]')) { this.registerUpdateEvent(); } }); this._datasetTabInit(); this._problemsTabInit(); this._updateForm(); this.ready(); } onGraphConfigChange() { this.registerUpdateEvent(); this._updateForm(); } updateVariableOrder(obj, row_selector, var_prefix) { for (const k of [10000, 0]) { jQuery(row_selector, obj).each(function(i) { if (var_prefix === 'ds') { jQuery(this).attr('data-set', i); jQuery('.single-item-table', this).attr('data-set', i); } jQuery('.multiselect[data-params]', this).each(function() { const name = jQuery(this).multiSelect('getOption', 'name'); if (name !== null) { jQuery(this).multiSelect('modify', { name: name.replace(/([a-z]+\[)\d+(]\[[a-z_]+])/, `$1${k + i}$2`) }); } }); ['name', 'color-field-name', 'palette-field-name'].forEach(attr => { jQuery(`[${attr}^="${var_prefix}["]`, this) .filter(function () { return jQuery(this).attr(attr).match(/[a-z]+\[\d+]\[[a-z_]+]/); }) .each(function () { const $this = jQuery(this); $this.attr(attr, $this.attr(attr).replace(/([a-z]+\[)\d+(]\[[a-z_]+])/, `$1${k + i}$2`)); }); }); }); } } _datasetTabInit() { this._updateDatasetsLabel(); // Initialize vertical accordion. const $data_sets = jQuery(this._dataset_wrapper); $data_sets .on('focus', '. input.input', function(e) { const list_item = e.target.closest('.'); if (list_item.classList.contains('')) { return; } $data_sets.zbx_vertical_accordion('expandNth', [...list_item.parentElement.children].indexOf(list_item) ); }) .on('click', '.', function(e) { const list_item = e.target.closest('.'); if (list_item.classList.contains('')) { return; } if (e.target.classList.contains('js-click-expand') || e.target.closest(`.${ZBX_STYLE_COLOR_PICKER}`) !== null) { $data_sets.zbx_vertical_accordion('expandNth', [...list_item.parentElement.children].indexOf(list_item) ); } }) .on('collapse', function(event, data) { jQuery('textarea, .multiselect', data.section).scrollTop(0); jQuery(window).trigger('resize'); const dataset = data.section[0]; if (dataset.dataset.type == '') { const message_block = dataset.querySelector('.no-items-message'); if (dataset.querySelectorAll('.single-item-table-row').length == 0) { message_block.style.display = 'block'; } } }) .on('expand', function(event, data) { jQuery(window).trigger('resize'); const dataset = data.section[0]; if (dataset.dataset.type == '') { const message_block = dataset.querySelector('.no-items-message'); if (dataset.querySelectorAll('.single-item-table-row').length == 0) { message_block.style.display = 'none'; } widget_form._initSingleItemSortable(dataset); } }) .zbx_vertical_accordion({handler: '.'}); // Initialize rangeControl UI elements. jQuery('.', jQuery(this._dataset_wrapper)).rangeControl(); this._dataset_wrapper.addEventListener('click', (e) => { if (e.target.classList.contains('js-add-item')) { this._selectItems(); } if (e.target.classList.contains('js-add-widget')) { this._selectWidget(); } if (e.target.matches('.single-item-table-row .table-col-name a')) { this._editItem(e.target); } if (e.target.classList.contains('js-remove-item')) { this._removeSingleItem(e.target); } if (e.target.classList.contains('js-remove')) { this._removeDataSet(e.target); } }); document .getElementById('dataset-add') .addEventListener('click', () => { this._addDataset(); }); document .getElementById('dataset-menu') .addEventListener('click', (e) => this._addDatasetMenu(e)); window.addPopupValues = (list) => { if (!isset('object', list) || list.object !== 'itemid') { return false; } for (let i = 0; i < list.values.length; i++) { this._addSingleItem({ itemid: list.values[i].itemid, name: list.values[i].name }); } this._initSingleItemSortable(this._getOpenedDataset()); } this._updateSingleItemsReferences(); this._initDataSetSortable(); this._initSingleItemSortable(this._getOpenedDataset()); } _problemsTabInit() { const widget = document.getElementById('problems'); document.getElementById('show_problems') .addEventListener('click', (e) => { jQuery('#graph_item_problems, #problem_name, #problemhosts_select').prop('disabled', !e.target.checked); jQuery('#problemhosts_').multiSelect(e.target.checked ? 'enable' : 'disable'); jQuery('[name^="severities["]', jQuery(widget)).prop('disabled', !e.target.checked); jQuery('[name="evaltype"]', jQuery(widget)).prop('disabled', !e.target.checked); jQuery('input, button, z-select', jQuery('#tags_table_tags', jQuery(widget))).prop('disabled', !e.target.checked ); }); } _updateDatasetsLabel() { for (const dataset of this._dataset_wrapper.querySelectorAll('.')) { this._updateDatasetLabel(dataset); } } _updateDatasetLabel(dataset) { const placeholder_text = + ` #${parseInt(dataset.dataset.set) + 1}`; const data_set_label = dataset.querySelector('.js-dataset-label'); const data_set_label_input = dataset.querySelector(`[name="ds[${dataset.dataset.set}][data_set_label]"]`); data_set_label.textContent = data_set_label_input.value !== '' ? data_set_label_input.value : placeholder_text; data_set_label_input.placeholder = placeholder_text; } _addDatasetMenu(e) { const menu = [ { items: [ { label: , clickCallback: () => { this._addDataset(); } }, { label: , clickCallback: () => { this._addDataset(); } } ] }, { items: [ { label: , disabled: this._getOpenedDataset() === null, clickCallback: () => { this._cloneDataset(); } } ] } ]; jQuery(e.target).menuPopup(menu, new jQuery.Event(e), { position: { of: e.target, my: 'left top', at: 'left bottom', within: 'body' } }); } _addDataset(type) { jQuery(this._dataset_wrapper).zbx_vertical_accordion('collapseAll'); const template = type == ? new Template(jQuery('#dataset-single-item-tmpl').html()) : new Template(jQuery('#dataset-pattern-item-tmpl').html()); const used_colors = []; for (const color_picker of this._form.querySelectorAll(`.${ZBX_STYLE_COLOR_PICKER}`)) { if (color_picker.color !== '') { used_colors.push(color_picker.color); } } const fragment = document.createRange().createContextualFragment(template.evaluate({ rowNum: ++this.#dataset_row_unique_id, color: type == ? '' : colorPalette.getNextColor(used_colors) })); this._dataset_wrapper.append(fragment); this.updateVariableOrder(this._dataset_wrapper, '.', 'ds'); this._updateDatasetsLabel(); const dataset = this._getOpenedDataset(); for (const range_control of dataset.querySelectorAll('.')) { jQuery(range_control).rangeControl(); } this._$overlay_body.scrollTop(Math.max(this._$overlay_body.scrollTop(), this._form.scrollHeight - this._$overlay_body.height() )); this._initDataSetSortable(); this._updateForm(); this.registerUpdateEvent(); } _cloneDataset() { const dataset = this._getOpenedDataset(); this._addDataset(dataset.dataset.type); const cloned_dataset = this._getOpenedDataset(); if (dataset.dataset.type == ) { for (const row of dataset.querySelectorAll('.single-item-table-row')) { this._addSingleItem({ itemid: row.querySelector(`[name$='[itemids][]`).value, reference: row.querySelector(`[name$='[references][]`).value, name: row.querySelector('.table-col-name a').textContent }); } this._initSingleItemSortable(cloned_dataset); } else { if (this._templateid === null) { jQuery('.js-hosts-multiselect', cloned_dataset).multiSelect('addData', jQuery('.js-hosts-multiselect', dataset).multiSelect('getData') ); } jQuery('.js-items-multiselect', cloned_dataset).multiSelect('addData', jQuery('.js-items-multiselect', dataset).multiSelect('getData') ); } for (const input of dataset.querySelectorAll('[name^=ds]')) { const cloned_name = input.name.replace(/([a-z]+\[)\d+(]\[[a-z_]+])/, `$1${cloned_dataset.getAttribute('data-set')}$2` ); if (input.tagName.toLowerCase() === 'z-select') { cloned_dataset.querySelector(`[name="${cloned_name}"]`).value = input.value; } else if (input.type === 'text') { cloned_dataset.querySelector(`[name="${cloned_name}"]`).value = input.value; if (input.classList.contains('')) { // Fire change event to redraw range input. cloned_dataset.querySelector(`[name="${cloned_name}"]`).dispatchEvent(new Event('change')); } } else if (input.type === 'checkbox' || input.type === 'radio') { // Click to fire events. cloned_dataset.querySelector(`[name="${cloned_name}"][value="${input.value}"]`).checked = input.checked; } } this._updateDatasetLabel(cloned_dataset); } _removeDataSet(obj) { const dataset_remove = obj.closest('.list-accordion-item'); dataset_remove.remove(); if (this.#single_items_sortable.has(dataset_remove)) { this.#single_items_sortable.get(dataset_remove).enable(false); this.#single_items_sortable.delete(dataset_remove); } this.updateVariableOrder(jQuery(this._dataset_wrapper), '.', 'ds'); this._updateDatasetsLabel(); const dataset = this._getOpenedDataset(); if (dataset !== null) { this._updateSingleItemsOrder(dataset); this._initSingleItemSortable(dataset); } this._initDataSetSortable(); this.onGraphConfigChange(); } _getOpenedDataset() { return this._dataset_wrapper.querySelector('.[data-set]'); } _initDataSetSortable() { if (this._sortable_data_set === undefined) { this._sortable_data_set = new CSortable(document.querySelector('#data_sets'), { selector_handle: '.js-main-drag-icon, .js-dataset-label' }); this._sortable_data_set.on(CSortable.EVENT_SORT, () => { this.updateVariableOrder(this._dataset_wrapper, '.', 'ds'); this._updateDatasetsLabel(); this.registerUpdateEvent(); }); } } _selectItems() { if (this._templateid === null) { PopUp('popup.generic', { srctbl: 'items', srcfld1: 'itemid', srcfld2: 'name', dstfrm: this._form.id, numeric: 1, writeonly: 1, multiselect: 1, with_webitems: 1, real_hosts: 1, resolve_macros: 1 }, {dialogue_class: 'modal-popup-generic'}); } else { PopUp('popup.generic', { srctbl: 'items', srcfld1: 'itemid', srcfld2: 'name', dstfrm: this._form.id, numeric: 1, writeonly: 1, multiselect: 1, with_webitems: 1, hostid: this._templateid, hide_host_filter: 1 }, {dialogue_class: 'modal-popup-generic'}); } } _editItem(target) { const dataset = this._getOpenedDataset(); const dataset_index = dataset.getAttribute('data-set'); const row = target.closest('.single-item-table-row'); const row_index = row.rowIndex; const itemid_input = row.querySelector('input[name$="[itemids][]"'); if (itemid_input.value !== '0') { const excludeids = []; for (const input of dataset.querySelectorAll('.single-item-table-row input[name$="[itemids][]"]')) { if (input.value !== '0') { excludeids.push(input.value); } } if (this._templateid === null) { PopUp('popup.generic', { srctbl: 'items', srcfld1: 'itemid', srcfld2: 'name', dstfrm: this._form.id, dstfld1: `items_${dataset_index}_${row_index}_itemid`, dstfld2: `items_${dataset_index}_${row_index}_name`, numeric: 1, writeonly: 1, with_webitems: 1, real_hosts: 1, resolve_macros: 1, excludeids }, {dialogue_class: 'modal-popup-generic'}); } else { PopUp('popup.generic', { srctbl: 'items', srcfld1: 'itemid', srcfld2: 'name', dstfrm: this._form.id, dstfld1: `items_${dataset_index}_${row_index}_itemid`, dstfld2: `items_${dataset_index}_${row_index}_name`, numeric: 1, writeonly: 1, with_webitems: 1, hostid: this._templateid, hide_host_filter: 1, excludeids }, {dialogue_class: 'modal-popup-generic'}); } } else { const exclude_typed_references = []; for (const input of dataset.querySelectorAll('.single-item-table-row input[name$="[references][]"]')) { if (input.value !== '') { exclude_typed_references.push(input.value); } } this._selectWidget(row, exclude_typed_references); } } _selectWidget(row = null, exclude_typed_references = []) { const widgets = ZABBIX.Dashboard.getReferableWidgets({ type: CWidgetsData.DATA_TYPE_ITEM_ID, widget_context: ZABBIX.Dashboard.getWidgetEditingContext() }); widgets.sort((a, b) => a.getHeaderName().localeCompare(b.getHeaderName())); const result = []; for (const widget of widgets) { const typed_reference = CWidgetBase.createTypedReference({ reference: widget.getFields().reference, type: CWidgetsData.DATA_TYPE_ITEM_ID }); if (exclude_typed_references.includes(typed_reference)) { continue; } result.push({ id: CWidgetBase.createTypedReference({ reference: widget.getFields().reference, type: CWidgetsData.DATA_TYPE_ITEM_ID }), name: widget.getHeaderName() }); } const popup = new CWidgetSelectPopup(result); popup.on('dialogue.submit', (e) => { if (row === null) { this._addSingleItem({ reference: e.detail.reference, name: e.detail.name }); } else { const name_col = row.querySelector('.table-col-name'); const name_col_link = name_col.querySelector('a'); const references_input = row.querySelector('input[name$="[references][]"'); name_col.classList.remove('unavailable-widget'); name_col_link.textContent = e.detail.name; references_input.value = e.detail.reference; } }); } _addSingleItem({itemid = '0', reference = '', name} = {}) { const dataset = this._getOpenedDataset(); const dataset_index = dataset.getAttribute('data-set'); const items_tbody = dataset.querySelector('.single-item-table tbody'); if (itemid !== '0') { if (items_tbody.querySelector(`input[name$="[itemids][]"][value="${itemid}"]`) !== null) { return; } } else { if (items_tbody.querySelector(`input[name$="[references][]"][value="${reference}"]`) !== null) { return; } } const items_new_index = items_tbody.rows.length + 1; const template = new Template(jQuery('#dataset-item-row-tmpl').html()); const row = template.evaluateToElement({ dsNum: dataset_index, rowNum: items_new_index, itemid, reference, name }); if (itemid === '0') { row.querySelector('.table-col-name .reference-hint').classList.remove(ZBX_STYLE_DISPLAY_NONE); } items_tbody.appendChild(row); const used_colors = []; for (const color_picker of this._form.querySelectorAll(`.${ZBX_STYLE_COLOR_PICKER}`)) { if (color_picker.color !== '') { used_colors.push(color_picker.color); } } row.querySelector(`.${ZBX_STYLE_COLOR_PICKER}`).color = colorPalette.getNextColor(used_colors); this.registerUpdateEvent(); } _removeSingleItem(element) { element.closest('.single-item-table-row').remove(); const dataset = this._getOpenedDataset(); this._updateSingleItemsOrder(dataset); this._initSingleItemSortable(dataset); this.registerUpdateEvent(); } _initSingleItemSortable(dataset) { const rows_container = dataset.querySelector('.single-item-table tbody'); if (rows_container === null) { return; } if (this.#single_items_sortable.has(dataset)) { return; } const sortable = new CSortable(rows_container, { selector_handle: '.table-col-handle' }); sortable.on(CSortable.EVENT_SORT, () => { this._updateSingleItemsOrder(dataset); this.registerUpdateEvent(); }); this.#single_items_sortable.set(dataset, sortable); } _updateSingleItemsReferences() { const widgets = ZABBIX.Dashboard .getReferableWidgets({ type: CWidgetsData.DATA_TYPE_ITEM_ID, widget_context: ZABBIX.Dashboard.getWidgetEditingContext() }) .reduce((map, widget) => map.set(widget.getFields().reference, widget.getHeaderName()), new Map()); for (const dataset of this._dataset_wrapper.querySelectorAll('.')) { for (const row of dataset.querySelectorAll('.single-item-table-row')) { const itemid_input = row.querySelector('input[name$="[itemids][]"'); const reference_input = row.querySelector('input[name$="[references][]"'); if (itemid_input.value !== '0') { continue; } const name_col = row.querySelector('.table-col-name'); const name_col_link = name_col.querySelector('a'); const name_col_hint = name_col.querySelector('.reference-hint'); const {reference} = CWidgetBase.parseTypedReference(reference_input.value); if (reference !== '') { name_col_link.textContent = widgets.get(reference); } else { name_col.classList.add('unavailable-widget'); name_col_link.textContent = ; } name_col_hint.classList.remove(ZBX_STYLE_DISPLAY_NONE); } } } _updateSingleItemsOrder(dataset) { const dataset_index = dataset.getAttribute('data-set'); for (const row of dataset.querySelectorAll('.single-item-table-row')) { const prefix = `items_${dataset_index}_${row.rowIndex}`; row.querySelector('.table-col-no span').textContent = `${row.rowIndex}:`; row.querySelector('.table-col-name a').id = `${prefix}_name`; row.querySelector('.table-col-action input[name$="[itemids][]"]').id = `${prefix}_itemid`; row.querySelector('.table-col-action input[name$="[references][]"]').id = `${prefix}_reference`; } } _updateForm() { const axes_used = {: 0, : 0}; for (const element of this._form.querySelectorAll('[type=radio], [type=hidden]')) { if (element.name.match(/ds\[\d+]\[axisy]/) && element.checked) { axes_used[element.value]++; } } for (const element of this._form.querySelectorAll('[type=hidden]')) { if (element.name.match(/or\[\d+]\[axisy]/)) { axes_used[element.value]++; } } const dataset = this._getOpenedDataset(); if (dataset !== null) { this._updateDatasetLabel(dataset); const dataset_index = dataset.getAttribute('data-set'); const draw_type = dataset.querySelector(`[name="ds[${dataset_index}][type]"]:checked`); const is_stacked = dataset.querySelector(`[type=checkbox][name="ds[${dataset_index}][stacked]"]`).checked; // Data set tab. const aggregate_function_select = dataset.querySelector(`[name="ds[${dataset_index}][aggregate_function]"]`); const approximation_select = dataset.querySelector(`[name="ds[${dataset_index}][approximation]"]`); let stacked_enabled = true; let width_enabled = true; let pointsize_enabled = true; let fill_enabled = true; let missingdata_enabled = true; let aggregate_none_enabled = true; let approximation_all_enabled = true; switch (draw_type.value) { case '': pointsize_enabled = false; if (is_stacked) { approximation_all_enabled = false; } break; case '': stacked_enabled = false; width_enabled = false; fill_enabled = false; missingdata_enabled = false; approximation_all_enabled = false; break; case '': pointsize_enabled = false; approximation_all_enabled = false; break; case '': width_enabled = false; pointsize_enabled = false; fill_enabled = false; missingdata_enabled = false; if (is_stacked) { aggregate_none_enabled = false; } approximation_all_enabled = false; break; } dataset.querySelector(`[type=checkbox][name="ds[${dataset_index}][stacked]"]`).disabled = !stacked_enabled; jQuery(`[name="ds[${dataset_index}][width]"]`, dataset).rangeControl(width_enabled ? 'enable' : 'disable'); jQuery(`[name="ds[${dataset_index}][pointsize]"]`, dataset).rangeControl( pointsize_enabled ? 'enable' : 'disable' ); jQuery(`[name="ds[${dataset_index}][fill]"]`, dataset).rangeControl(fill_enabled ? 'enable' : 'disable'); for (const element of dataset.querySelectorAll(`[name="ds[${dataset_index}][missingdatafunc]"]`)) { element.disabled = !missingdata_enabled; } aggregate_function_select.getOptionByValue().disabled = !aggregate_none_enabled; if (!aggregate_none_enabled && aggregate_function_select.value == ) { aggregate_function_select.value = ; } const aggregation_enabled = aggregate_function_select.value != ; dataset.querySelector(`[name="ds[${dataset_index}][aggregate_interval]"]`).disabled = !aggregation_enabled; for (const element of dataset.querySelectorAll(`[name="ds[${dataset_index}][aggregate_grouping]"]`)) { element.disabled = !aggregation_enabled; } approximation_select.getOptionByValue().disabled = !approximation_all_enabled; if (!approximation_all_enabled && approximation_select.value == ) { approximation_select.value = ; } } const all_datasets = this._dataset_wrapper.querySelectorAll('.'); this._any_ds_aggregation_function_enabled = false; for (const ds of all_datasets) { const ds_index = ds.getAttribute('data-set'); const aggregate_function_select = ds.querySelector(`[name="ds[${ds_index}][aggregate_function]"]`); if (aggregate_function_select.value != ) { this._any_ds_aggregation_function_enabled = true; break; } } // Displaying options tab. const percentile_left_checkbox = document.getElementById('percentile_left'); percentile_left_checkbox.disabled = !axes_used[]; document.getElementById('percentile_left_value').disabled = !percentile_left_checkbox.checked || !axes_used[]; const percentile_right_checkbox = document.getElementById('percentile_right'); percentile_right_checkbox.disabled = !axes_used[]; document.getElementById('percentile_right_value').disabled = !percentile_right_checkbox.checked || !axes_used[]; // Axes tab. const lefty_checkbox = document.getElementById('lefty'); lefty_checkbox.disabled = !axes_used[]; const lefty_on = !lefty_checkbox.disabled && lefty_checkbox.checked; if (lefty_checkbox.disabled) { lefty_checkbox.checked = true; } for (const element of document.querySelectorAll('#lefty_scale, #lefty_min, #lefty_max, #lefty_units')) { element.disabled = !lefty_on; } document.getElementById('lefty_static_units').disabled = !lefty_on || document.getElementById('lefty_units').value != ; const righty_checkbox = document.getElementById('righty'); righty_checkbox.disabled = !axes_used[]; const righty_on = !righty_checkbox.disabled && righty_checkbox.checked; if (righty_checkbox.disabled) { righty_checkbox.checked = true; } for (const element of document.querySelectorAll('#righty_scale, #righty_min, #righty_max, #righty_units')) { element.disabled = !righty_on; } document.getElementById('righty_static_units').disabled = !righty_on || document.getElementById('righty_units').value != ; // Legend tab. const show_legend = document.getElementById('legend').checked; const legend_statistic = document.getElementById('legend_statistic'); legend_statistic.disabled = !show_legend; document.getElementById('legend_aggregation').disabled = !show_legend || !this._any_ds_aggregation_function_enabled; for (const input of this._form.querySelectorAll('[name=legend_lines_mode]')) { input.disabled = !show_legend; } jQuery('#legend_lines').rangeControl(show_legend ? 'enable' : 'disable'); jQuery('#legend_columns').rangeControl(show_legend && !legend_statistic.checked ? 'enable' : 'disable'); document.querySelector('[for=legend_lines]') .textContent = document.querySelector('[name=legend_lines_mode]:checked').value === '1' ? : ; // Trigger event to update tab indicators. document.getElementById('tabs').dispatchEvent(new Event(TAB_INDICATOR_UPDATE_EVENT)); } };