ntopng/httpdocs/templates/pages/edit_check.template
2024-02-22 11:22:52 +00:00

275 lines
10 KiB
Text

{#
(C) 2020 - ntop.org
#}
<div class="row">
<div class="col-md-12">
{* edit_check.breadcrumb *}
</div>
<div class="col-md-12">
<div class="alert border">
<div class="row">
<div class="col-12 col-sm-2 category">
<b>{{ i18n("edit_check.category") }}</b>
<br>
<i class='{{edit_check.script.category.icon}}'></i> {{ i18n(edit_check.script.category.i18n_title) }}
</div>
<div class="col-12 col-sm-8 description">
<b>{{ i18n("edit_check.description") }}</b>
<br>
{{ (i18n(edit_check.script.gui.i18n_description) or edit_check.script.gui.i18n_description) .. ternary(edit_check.script.gui.18n_url, "<a href='" .. i18n_url .. "'>here</a>", "") }}
</div>
<div class="col-12 col-sm-2 author">
<b>{{ i18n("edit_check.author") }}</b>
<br>
{{ edit_check.script.script.author }}
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link active" href="#params" data-bs-toggle='tab' role="tab">{{ i18n("edit_check.hooks_config") }}</a>
</li>
</ul>
</div>
<div class="card-body">
<div class="tab-content" id="tab-content">
<div class="tab-pane fade show active" id="params">
<form id="user-script-edits">
<div class="hooks">
{% for _, rendered_hook in ipairs(edit_check.rendered_hooks.templates) do %}
{%
local hook_name = rendered_hook.hook
local hook = edit_check.hooks_config[hook_name]
local severity = hook.script_conf.severity
if severity == nil then
severity = hook.script_conf.severity.severity_id
end
%}
<fieldset id="{{ hook_name }}">
<div class="card my-1">
<div class="card-header">
<b class="text-black-50">{{ (i18n("edit_check.hooks_name." .. hook_name) or hook_name) }}</b>
</div>
<div class="card-body">
<div class="rendered">
{* rendered_hook.template *}
</div>
{# Common fields shared across user scripts #}
<div class="commons">
</div>
</div>
</div>
</fieldset>
{% end %}
</div>
</form>
</div>
<div class="alert alert-danger mt-2" id="error-alert" style="display: none;">
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" id="reset-button" class="btn btn-danger">
{{ i18n("scripts_list.reset_default") }}
</button>
<button form="user-script-edits" id="submit-button" type="submit" class="btn btn-primary">
{{ i18n("save") }}
</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
const DEBUG = true;
// Object containing callbacks to be called when the user
// clicks the reset button.
const RESET_CALLBACKS = {
/*
[hookName] = pointerToTheCallback: (hookName, hookConfig, resetData) => ()
*/
};
/**
* Register a reset callback that it will be called when the user clicks the reset button.
*/
function registerResetCallback(hookName, callback) {
if (RESET_CALLBACKS[hookName] !== undefined) {
console.warn(`Overriding existing callback for the hook ${hookName}...`);
}
if (DEBUG) {
console.info(`Debug: Registered callback for [${hookName}].`);
}
RESET_CALLBACKS[hookName] = callback;
}
$(document).ready(function() {
function toggleFields($fieldset, enabled) {
$fieldset.find(`input[name!='enabled'],select,textarea,.btn,button`).each(function() {
if (!enabled) {
$(this).attr("disabled", true).addClass("disabled");
return;
}
$(this).removeAttr("disabled").removeClass("disabled");
});
}
const CSRF = "{{ ntop.getRandomCSRFValue() }}";
const RESET_ENDPOINT = "{{ ntop.getHttpPrefix() }}/lua/get_check_config.lua?check_subdir={{edit_check.check_subdir}}&script_key={{edit_check.script_key}}&factory=true"
const SAVE_ENDPOINT = "{{ ntop.getHttpPrefix() }}/lua/edit_check_config.lua";
const $errorAlert = $(`#error-alert`);
// Handle the enabled state of each input contained in a fieldset.
// For each 'Enabled' toggle...
$(`input[name='enabled']`).on('click', function() {
// ... disable or enable the fields inside the fieldset
const $fieldset = $(this).parents('fieldset');
const enabled = $(this).is(':checked');
toggleFields($fieldset, enabled);
})
// On Reset Button click...
$(`#reset-button`).on('click', async function() {
const request = $.get(RESET_ENDPOINT);
request.then(function(data) {
// for eache hook reset the default values
const {metadata, hooks} = data;
for (const [hookName, hook] of Object.entries(hooks)) {
const $fieldset = $(`fieldset[id='${hookName}']`);
const $enabled = $fieldset.find(`[name='enabled']`);
const $severitySelect = $fieldset.find(`[name='severity']`);
if (hook.enabled) {
$enabled.attr("checked", "checked");
}
else {
$enabled.removeAttr("checked");
}
// trigger the toggle click event to disable/enable fields
toggleFields($fieldset, hook.enabled);
// for each field inside the script conf
for (const [scriptField, value] of Object.entries(hook.script_conf)) {
// reset the severity select
if (scriptField === "severity") {
$severitySelect.val(value.severity_id);
continue;
}
// let's check if the field is contained inside the fieldset
// and then set it's previous value
const $field = $(`[name='${scriptField}']`);
if ($field.length > 0) {
$field.val(value);
}
}
// check if exists a reset callback for the hook and call it
if (RESET_CALLBACKS[hookName] !== undefined) RESET_CALLBACKS[hookName](hookName, hook, data);
}
});
});
// On form submitting...
$(`#user-script-edits`).on('submit', async function(e) {
e.preventDefault();
const $submitButton = $(`#submit-button`);
$submitButton.attr("disabled", "disabled");
// Object to send to the ajax endpoint.
// The object will contains a new field (named as the fieldset id)
// (which is the hook's name) containing the paramaters to configure
// for each fieldset inside the form '#user-script-edits'.
const serialized = {};
// For each fieldset inside the form
$(this).find('fieldset').each(function() {
// get the hook name and initialize an empty object
const hook = {enabled: true, script_conf: {}};
const $fieldset = $(this);
const hookName = $(this).attr('id');
// is the hook enabled?
hook.enabled = $fieldset.find(`[name='enabled']`).is(":checked");;
// load the script conf paramaters, use only the controls with a [name] attribute!
$fieldset.find("input[name],select[name],textarea[name]").each(function() {
const name = $(this).attr("name");
const ignore = $(this).hasClass("ignore");
if (name === 'enabled' || ignore) return;
const valueNumber = parseFloat($(this).val());
if (isNaN(valueNumber)) {
hook.script_conf[name] = $(this).val();
return;
}
hook.script_conf[name] = valueNumber;
});
serialized[hookName] = hook;
});
if (DEBUG) {
console.log(serialized)
}
// payload to send to the save endpoint
const payload = {
check_subdir: "{{ edit_check.check_subdir }}",
script_key: "{{ edit_check.script_key }}",
csrf: CSRF,
JSON: JSON.stringify(serialized),
};
const request = $.post(SAVE_ENDPOINT, payload);
request.then(function(data) {
const success = data.success;
if (!success) {
$errorAlert.text(data.error).show();
return;
}
// hide the previous errors
$errorAlert.hide();
// show a success message
ToastUtils.showToast({
title: "{{ i18n('success') }}",
body: "{* i18n('edit_check.success_message', {script_name = edit_check.script_title}) *}",
level: 'success',
delay: 3000,
id: `save-userscript`
});
});
request.fail(function() {
// TODO
});
request.always(function() {
$submitButton.removeAttr("disabled");
});
});
});
</script>