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.
zabbix/ui/app/views/js/popup.action.edit.js.php

493 lines
15 KiB

<?php declare(strict_types = 0);
/*
** 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.
**/
?>
window.action_edit_popup = new class {
init({condition_operators, condition_types, conditions, actionid, eventsource}) {
this.overlay = overlays_stack.getById('action-edit');
this.dialogue = this.overlay.$dialogue[0];
this.form = this.overlay.$dialogue.$body[0].querySelector('form');
this.condition_operators = condition_operators;
this.condition_types = condition_types;
this.actionid = actionid;
this.eventsource = eventsource;
this._initActionButtons();
this._processTypeOfCalculation();
// Add existing conditions in action edit popup.
if (typeof(conditions) === 'object') {
conditions = Object.values(conditions);
}
for (const condition of conditions) {
this._createConditionsRow(condition);
}
// Reload operation table when esc_period is changed.
const esc_period = document.querySelector('#esc_period');
if (esc_period) {
esc_period.addEventListener('change', () => {
this.recovery = <?= ACTION_OPERATION ?>;
this._loadOperationTable();
});
}
}
_loadOperationTable(new_operation = {}) {
if (this.recovery == <?= ACTION_RECOVERY_OPERATION ?>) {
this.$operation_table = $('#recovery-operations-container');
}
else if (this.recovery == <?= ACTION_UPDATE_OPERATION ?>) {
this.$operation_table = $('#update-operations-container');
}
else {
this.$operation_table = $('#operations-container');
}
const fields = getFormFields(this.form);
const curl = new Curl('zabbix.php');
curl.setArgument('action', 'popup.action.operations.list');
curl.setArgument('type', <?= PAGE_TYPE_TEXT_RETURN_JSON ?>);
if (document.querySelector('#esc_period')) {
let esc_period = (document.querySelector('#esc_period').value).trim();
if (esc_period === '') {
esc_period = 0;
}
curl.setArgument('esc_period', esc_period);
}
this.loaderStart();
fetch(curl.getUrl(), {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'operations': fields.operations,
'recovery_operations': fields.recovery_operations,
'update_operations': fields.update_operations,
'new_operation': new_operation,
'eventsource': this.eventsource,
'actionid': this.actionid
})
})
.then((response) => response.json())
.then((response) => {
for (const element of this.form.parentNode.children) {
if (element.matches('.msg-good, .msg-bad, .msg-warning')) {
element.parentNode.removeChild(element);
}
}
if (typeof response === 'object' && 'error' in response) {
const message_box = makeMessageBox('bad', response.error.messages, response.error.title)[0];
this.form.parentNode.insertBefore(message_box, this.form);
}
else {
this.$operation_table.empty();
if (response.messages.length > 0) {
const message_box = makeMessageBox('bad', response.messages)[0];
this.form.parentNode.insertBefore(message_box, this.form);
}
this.$operation_table.append(response.body);
}
})
.catch((exception) => {
for (const element of this.form.parentNode.children) {
if (element.matches('.msg-good, .msg-bad, .msg-warning')) {
element.parentNode.removeChild(element);
}
}
let title, messages;
if (typeof exception === 'object' && 'error' in exception) {
title = exception.error.title;
messages = exception.error.messages;
}
else {
messages = [<?= json_encode(_('Unexpected server error.')) ?>];
}
const message_box = makeMessageBox('bad', messages, title)[0];
this.form.parentNode.insertBefore(message_box, this.form);
})
.finally(
this.$preloader.remove()
);
}
loaderStart() {
this.$preloader = $('<span>', {class: 'is-loading'});
this.$operation_table.append(this.$preloader);
}
_initActionButtons() {
this.dialogue.addEventListener('click', (e) => {
if (e.target.classList.contains('js-condition-create')) {
this._openConditionPopup();
}
else if (e.target.classList.contains('js-operation-details')) {
this._openOperationPopup(this.eventsource, <?= ACTION_OPERATION ?>, this.actionid);
}
else if (e.target.classList.contains('js-recovery-operations-create')) {
this._openOperationPopup(this.eventsource, <?= ACTION_RECOVERY_OPERATION ?>, this.actionid);
}
else if (e.target.classList.contains('js-update-operations-create')) {
this._openOperationPopup(this.eventsource, <?= ACTION_UPDATE_OPERATION ?>, this.actionid);
}
else if (e.target.classList.contains('js-edit-operation')) {
this._openEditOperationPopup(e, JSON.parse(e.target.dataset.operation));
}
else if (e.target.classList.contains('js-remove')) {
e.target.closest('tr').remove();
}
else if (e.target.classList.contains('js-remove-condition')) {
e.target.closest('tr').remove();
this._processTypeOfCalculation();
}
});
}
_openEditOperationPopup(e, operation_data) {
let row_index = 0;
if (operation_data !== null) {
row_index = parseInt(operation_data.operationid);
}
this.parameters = {
eventsource: this.eventsource,
recovery: operation_data.data.recovery,
actionid: this.actionid,
data: operation_data.data,
row_index: row_index
};
const overlay = PopUp('popup.action.operation.edit', this.parameters, {
dialogueid: 'operations',
dialogue_class: 'modal-popup-medium'
});
overlay.$dialogue[0].addEventListener('operation.submit', (e) => {
this.recovery = e.detail.operation.recovery;
this._loadOperationTable(e.detail);
});
}
_openOperationPopup(eventsource, recovery_phase, actionid) {
this.recovery = parseInt(recovery_phase);
const parameters = {
eventsource: eventsource,
recovery: recovery_phase,
actionid: actionid
};
const overlay = PopUp('popup.action.operation.edit', parameters, {
dialogueid: 'operations',
dialogue_class: 'modal-popup-medium'
});
overlay.$dialogue[0].addEventListener('operation.submit', (e) => {
this.recovery = e.detail.operation.recovery;
this._loadOperationTable(e.detail);
});
}
_openConditionPopup() {
this._processTypeOfCalculation();
let row_index = 0;
while (document.querySelector(`#conditionTable [data-row_index="${row_index}"]`) !== null) {
row_index++;
}
const parameters = {
type: <?= ZBX_POPUP_CONDITION_TYPE_ACTION ?>,
source: this.eventsource,
actionid: this.actionid,
row_index: row_index
};
const overlay = PopUp('popup.condition.edit', parameters, {
dialogueid: 'action-condition',
dialogue_class: 'modal-popup-medium'
});
overlay.$dialogue[0].addEventListener('condition.dialogue.submit', (e) => {
this._createConditionsRow(e.detail);
});
}
_createConditionsRow(input) {
let template;
if (is_array(input.value)) {
input.value.forEach((value, index) => {
const element = {...input, name: input.name[index], value: input.value[index]};
const has_row = this._checkConditionRow(element);
const result = [has_row.some(element => element === true)]
if (result[0] === true) {
return;
}
else {
element.condition_name = this.condition_types[element.conditiontype] + ' ' +
this.condition_operators[element.operator] + ' ';
element.data = element.name;
element.label = num2letter(element.row_index);
input.row_index++;
template = new Template(document.getElementById('condition-row-tmpl').innerHTML)
document
.querySelector('#conditionTable tbody')
.insertAdjacentHTML('beforeend', template.evaluate(element));
}
this._processTypeOfCalculation();
})
}
else {
const has_row = this._checkConditionRow(input);
const result = [has_row.some(element => element === true)];
if (result[0] === true) {
return;
}
else {
input.label = num2letter(input.row_index);
switch(parseInt(input.conditiontype)) {
case <?= CONDITION_TYPE_SUPPRESSED ?>:
input.condition_name = input.operator == <?= CONDITION_OPERATOR_YES ?>
? <?= json_encode(_('Problem is suppressed')) ?>
: <?= json_encode(_('Problem is not suppressed')) ?>;
template = new Template(document.getElementById('condition-suppressed-row-tmpl').innerHTML);
break;
case <?= CONDITION_TYPE_EVENT_TAG_VALUE ?>:
input.operator_name = this.condition_operators[input.operator];
template = new Template(document.getElementById('condition-tag-value-row-tmpl').innerHTML);
break;
default:
input.condition_name = this.condition_types[input.conditiontype] + ' ' +
this.condition_operators[input.operator] + ' ';
input.data = input.name;
template = new Template(document.getElementById('condition-row-tmpl').innerHTML);
}
document
.querySelector('#conditionTable tbody')
.insertAdjacentHTML('beforeend', template.evaluate(input));
}
this._processTypeOfCalculation();
}
}
/**
* Check if row with the same conditiontype and value already exists.
*/
_checkConditionRow(input) {
const result = [];
[...document.getElementById('conditionTable').getElementsByTagName('tr')].map(element => {
const table_row = element.getElementsByTagName('td')[2];
if (table_row !== undefined) {
const conditiontype = table_row.getElementsByTagName('input')[0].value;
const value = table_row.getElementsByTagName('input')[2].value;
const value2 = table_row.getElementsByTagName('input')[3].value
? table_row.getElementsByTagName('input')[3].value
: null;
if (conditiontype == <?= CONDITION_TYPE_SUPPRESSED ?>) {
result.push(input.conditiontype === conditiontype);
}
else {
if (input.value2 !== '') {
result.push(
input.conditiontype === conditiontype && input.value === value && input.value2 === value2
)
}
else {
result.push(input.conditiontype === conditiontype && input.value === value)
}
}
if (input.row_index == element.dataset.row_index) {
input.row_index++;
}
}
result.push(false);
});
return result;
}
submit() {
const fields = getFormFields(this.form);
fields.name = fields.name.trim();
if (fields.esc_period != null ) {
fields.esc_period = fields.esc_period.trim();
}
const curl = new Curl('zabbix.php');
curl.setArgument('action', this.actionid !== 0 ? 'action.update' : 'action.create');
this._post(curl.getUrl(), fields);
}
_post(url, data) {
fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
})
.then((response) => response.json())
.then((response) => {
if ('error' in response) {
throw {error: response.error};
}
overlayDialogueDestroy(this.overlay.dialogueid);
uncheckTableRows('action_' + this.eventsource, response.keepids ?? []);
this.dialogue.dispatchEvent(new CustomEvent('dialogue.submit', {detail: response.success}));
})
.catch((exception) => {
for (const element of this.form.parentNode.children) {
if (element.matches('.msg-good, .msg-bad, .msg-warning')) {
element.parentNode.removeChild(element);
}
}
let title, messages;
if (typeof exception === 'object' && 'error' in exception) {
title = exception.error.title;
messages = exception.error.messages;
}
else {
messages = [<?= json_encode(_('Unexpected server error.')) ?>];
}
const message_box = makeMessageBox('bad', messages, title)[0];
this.form.parentNode.insertBefore(message_box, this.form);
})
.finally(() => {
this.overlay.unsetLoading();
});
}
clone() {
this.actionid = 0;
const title = <?= json_encode(_('New action')) ?>;
const buttons = [
{
title: <?= json_encode(_('Add')) ?>,
class: '',
keepOpen: true,
isSubmit: true,
action: () => this.submit()
},
{
title: <?= json_encode(_('Cancel')) ?>,
class: 'btn-alt',
cancel: true,
action: () => ''
}
];
this.overlay.unsetLoading();
this.overlay.setProperties({title, buttons});
}
delete() {
const curl = new Curl('zabbix.php');
curl.setArgument('action', 'action.delete');
curl.setArgument('<?= CCsrfTokenHelper::CSRF_TOKEN_NAME ?>',
<?= json_encode(CCsrfTokenHelper::get('action')) ?>
);
this._post(curl.getUrl(), {actionids: [this.actionid]}, (response) => {
overlayDialogueDestroy(this.overlay.dialogueid);
this.dialogue.dispatchEvent(new CustomEvent('dialogue.submit', {detail: response.success}));
});
}
_processTypeOfCalculation() {
this.show_formula = document.querySelector('#evaltype').value == <?= CONDITION_EVAL_TYPE_EXPRESSION ?>;
const row_count = document.getElementById('conditionTable').rows.length - 2;
document.querySelector('#formula').style.display = this.show_formula ? '' : 'none';
document.querySelector('#formula').removeAttribute('readonly');
document.querySelector('#expression').style.display = this.show_formula ? 'none' : '';
document.querySelector('#label-evaltype').style.display = row_count > 1 ? '' : 'none';
document.querySelector('#evaltype-formfield').style.display = row_count > 1 ? '' : 'none';
const labels = document.querySelectorAll('#conditionTable .label');
const conditions = [];
[...labels].forEach(function (label) {
conditions.push({
id: label.dataset.formulaid,
type: label.dataset.conditiontype
});
});
document.getElementById('expression')
.innerHTML = getConditionFormula(conditions, + document.querySelector('#evaltype').value);
document.querySelector('#evaltype').onchange = function() {
this.show_formula = document.querySelector('#evaltype').value == <?= CONDITION_EVAL_TYPE_EXPRESSION ?>;
document.querySelector('#expression').style.display = this.show_formula ? 'none' : '';
document.querySelector('#formula').style.display = this.show_formula ? '' : 'none';
document.querySelector('#formula').removeAttribute('readonly');
const labels = document.querySelectorAll('#conditionTable .label');
const conditions = [];
[...labels].forEach(function (label) {
conditions.push({
id: label.dataset.formulaid,
type: label.dataset.conditiontype
});
});
document.getElementById('expression')
.innerHTML = getConditionFormula(conditions, + document.querySelector('#evaltype').value);
};
}
}