mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-05 19:15:03 +00:00
* config and scripts templates #3159 * fixed bug for config rename, clone operations * add reload for config and script list * fixed timeout
This commit is contained in:
parent
eb0a6e5310
commit
90c4865789
11 changed files with 1167 additions and 1139 deletions
457
httpdocs/templates/script_list.html
Normal file
457
httpdocs/templates/script_list.html
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
{% if script_list.confset_id == nil or script_list.confset_id == "" then %}
|
||||
<div class='alert alert-danger'>
|
||||
<b>Attention!</b>
|
||||
The page was not found!
|
||||
<a class='text-danger' href='#' onclick='history.back()'>Click here to return to the previous page!</a>
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
<div class='container-fluid mt-3'>
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item" aria-current="page">
|
||||
<a href='/lua/config_list.lua'>{{ i18n("config_scripts.config_list", {}) }}</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item" aria-current="page">
|
||||
<a href='/lua/config_list.lua?subdir={{ script_list.script_subdir }}'>
|
||||
{{ script_list.hooks_localizated[script_list.script_subdir] }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
{{ i18n("scripts_list.config", {}) }} <b>{{ script_list.confset_name }}</b>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<div class='row'>
|
||||
<div class='col-md-12 col-lg-12 mt-3'>
|
||||
<table id='hostsScripts' class="table w-100 table-striped table-hover table-bordered mt-3">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ i18n("name", {}) }}</th>
|
||||
<th>{{ i18n("description", {}) }}</th>
|
||||
<th>{{ i18n("enabled", {}) }}</th>
|
||||
<th>{{ i18n("action", {})}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# include modals for script_list.lua #}
|
||||
{* script_list.template_utils.gen("script_list_components/edit_config_modal.html") *}
|
||||
|
||||
{# add css, js files #}
|
||||
<link href="{{ ntop.getHttpPrefix() }}/datatables/datatables.min.css" rel="stylesheet">
|
||||
<script type='text/javascript'>
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
const $script_table = $("#hostsScripts").DataTable({
|
||||
dom: "Bfrtip",
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
lengthChange: false,
|
||||
ajax: {
|
||||
'url': '{{ ntop.getHttpPrefix() }}/lua/get_user_scripts.lua?confset_id={{ script_list.confset_id }}&script_subdir={{ script_list.script_subdir }}',
|
||||
'type': 'GET',
|
||||
dataSrc: ''
|
||||
},
|
||||
stateSave: true,
|
||||
initComplete: function(settings, json) {
|
||||
// select the correct tab
|
||||
(() => {
|
||||
|
||||
// get hash from url
|
||||
const hash = window.location.hash;
|
||||
|
||||
// redirect to correct tab
|
||||
if (hash == undefined || hash == null || hash == "" || hash == "#enabled") {
|
||||
$(`#enabled-scripts`).addClass("active").trigger("click");
|
||||
}
|
||||
else if (hash == "#disabled") {
|
||||
$(`#disabled-scripts`).addClass("active").trigger("click");
|
||||
}
|
||||
else {
|
||||
$(`#all-scripts`).addClass("active").trigger("click");
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
// clean searchbox
|
||||
$(".dataTables_filter").find("input[type='search']").val('').trigger('keyup');
|
||||
|
||||
// counts scripts inside table
|
||||
count_scripts();
|
||||
},
|
||||
order: [ [0, "asc"] ],
|
||||
buttons: [
|
||||
{
|
||||
extend: "filterScripts",
|
||||
attr: {
|
||||
id: "all-scripts",
|
||||
},
|
||||
text: "All"
|
||||
},
|
||||
{
|
||||
extend: "filterScripts",
|
||||
attr: {
|
||||
id: "enabled-scripts"
|
||||
},
|
||||
text: "Enabled"
|
||||
},
|
||||
{
|
||||
extend: "filterScripts",
|
||||
attr: {
|
||||
id: "disabled-scripts"
|
||||
},
|
||||
text: "Disabled"
|
||||
}
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
data: 'title',
|
||||
render: function (data, type, row) {
|
||||
|
||||
if (type == 'display') {
|
||||
return `<b>${data}</b>`
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ data: 'description' },
|
||||
{
|
||||
data: 'enabled_hooks',
|
||||
sortable: false,
|
||||
className: 'text-center',
|
||||
render: function (data, type, row) {
|
||||
|
||||
if (data.length <= 0 && type != "display") {
|
||||
return false;
|
||||
}
|
||||
if (data.length > 0 && type != "display") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data.length >= 0 && type == "display" && row.all_hooks.length > 0 && row.input_handler == undefined) {
|
||||
|
||||
$('#hostsScripts').on('click', `input[name='${row.key}-check']`, function(e) {
|
||||
|
||||
const $this = $(this);
|
||||
const value = $this.val();
|
||||
const hooks = row.all_hooks;
|
||||
const data = {};
|
||||
|
||||
hooks.forEach(d => {
|
||||
data[d] = {
|
||||
enabled: (value == "true")
|
||||
}
|
||||
})
|
||||
|
||||
$.when(
|
||||
$.post('{{ ntop.getHttpPrefix() }}/lua/edit_user_script_config.lua', {
|
||||
script_subdir: '{{ script_list.script_subdir }}',
|
||||
script_key: row.key,
|
||||
csrf: '{{ ntop.getRandomCSRFValue() }}',
|
||||
JSON: JSON.stringify(data),
|
||||
confset_id: '{{ script_list.confset_id }}'
|
||||
})
|
||||
)
|
||||
.then((d, status, xhr) => {
|
||||
location.reload();
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
return `
|
||||
<form type='post'>
|
||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-sm btn-secondary ${row.is_enabled ? "active" : ""}">
|
||||
<input value='true' type="radio" name="${row.key}-check" ${row.is_enabled ? "checked" : ""}> On
|
||||
</label>
|
||||
<label class="btn btn-sm btn-secondary ${!row.is_enabled ? "active" : ""}">
|
||||
<input value='false' type="radio" name="${row.key}-check" ${row.is_enabled ? "checked" : ""}> Off
|
||||
</label>
|
||||
</div>
|
||||
</form>`;
|
||||
|
||||
}
|
||||
|
||||
return data.join(', ')
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: -1,
|
||||
data: null,
|
||||
className: 'text-center',
|
||||
render: function (data, type, row) {
|
||||
return `
|
||||
<div class='btn-group'>
|
||||
<button ${row.input_handler == undefined ? "disabled" : ""}
|
||||
data-toggle="modal"
|
||||
title='Edit Script'
|
||||
data-target="#modal-script"
|
||||
class="btn btn-square btn-sm btn-primary">
|
||||
|
||||
<i class='fas fa-edit'></i>
|
||||
|
||||
</button>
|
||||
<a
|
||||
href='${data.edit_url}'
|
||||
title='View Source Script'
|
||||
class='btn btn-square btn-sm btn-secondary'>
|
||||
<i class='fas fa-scroll'></i>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
sortable: false
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// initialize are you sure
|
||||
$("#edit-form").areYouSure({
|
||||
'message':'{{ i18n("scripts_list.are_you_sure", {}) }}'
|
||||
});
|
||||
|
||||
// handle modal-script close event
|
||||
$("#modal-script").on("hide.bs.modal", function(e) {
|
||||
|
||||
// if the forms is dirty then ask to the user
|
||||
// if he wants save edits
|
||||
if ($('#edit-form').hasClass('dirty')) {
|
||||
|
||||
// ask to user if he REALLY wants close modal
|
||||
const result = confirm("The changes will not be saved. Are you sure?");
|
||||
if (!result) e.preventDefault();
|
||||
|
||||
// remove dirty class from form
|
||||
$('#edit-form').removeClass('dirty');
|
||||
}
|
||||
});
|
||||
|
||||
// load templates for the script
|
||||
$('#hostsScripts').on('click', 'button[data-target="#modal-script"]', function(e) {
|
||||
|
||||
// get script key and script name
|
||||
const row_data = $script_table.row($(this).parent().parent()).data();
|
||||
const script_key = row_data.key;
|
||||
const script_title = row_data.title;
|
||||
|
||||
// change title to modal
|
||||
$("#script-name").html(`<b>${script_title}</b>`);
|
||||
|
||||
$("#modal-script form").off('submit');
|
||||
|
||||
$("#modal-script").on("submit", "form", function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
$('#edit-form').trigger('reinitialize.areYouSure');
|
||||
|
||||
$('#edit-form').removeClass('dirty');
|
||||
$("#btn-apply").trigger("click");
|
||||
});
|
||||
|
||||
$.when(
|
||||
$.get('{{ ntop.getHttpPrefix() }}/lua/get_user_script_config.lua', {
|
||||
script_subdir: '{{ script_list.script_subdir }}',
|
||||
confset_id: '{{ script_list.confset_id }}',
|
||||
script_key: script_key
|
||||
}
|
||||
)
|
||||
)
|
||||
.then((data, status, x) => {
|
||||
|
||||
// clean table editor
|
||||
const $table_editor = $("#script-config-editor > tbody");
|
||||
$table_editor.empty();
|
||||
|
||||
// destructure gui and hooks from data
|
||||
const {gui, hooks} = data;
|
||||
|
||||
// create build_gui()
|
||||
{* script_list.template_utils.gen("script_list_components/build_gui.html") *}
|
||||
|
||||
// append gui on the edit modal
|
||||
build_gui(gui, hooks);
|
||||
|
||||
// bind event to modal_button
|
||||
const on_apply = (e) => {
|
||||
|
||||
const $button = $(this);
|
||||
// prepare request to save config
|
||||
const data = {}
|
||||
// variable for checking errors
|
||||
let error = false;
|
||||
|
||||
// iterate over granularities
|
||||
$table_editor.children("tr").each(function (index) {
|
||||
|
||||
const id = $(this).attr("id");
|
||||
|
||||
const enabled = $(this).find("input[type='checkbox']").is(":checked");
|
||||
const $template = $(this).find(".template");
|
||||
|
||||
const operator = $template.find("select").val();
|
||||
const threshold = $template.find("input").val();
|
||||
|
||||
// hide before errors
|
||||
$template.find(`.invalid-feedback`).hide();
|
||||
|
||||
// if operator is empty then alert the user
|
||||
if (enabled && (operator == "" || operator == undefined || operator == null)) {
|
||||
|
||||
$template.find(`.invalid-feedback`).text("Please select an operator!").show();
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the value is empty then alert the user (only for checked granularities)
|
||||
if (enabled && (threshold == null || threshold == undefined || threshold == "")) {
|
||||
$template.find(`.invalid-feedback`).text("Please fill the input box!").show();
|
||||
error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// save data into dictonary
|
||||
data[id] = {
|
||||
'enabled': enabled,
|
||||
'script_conf': {
|
||||
'operator': operator,
|
||||
'threshold': threshold
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// check if there are any errors on input values
|
||||
if (error) return;
|
||||
// remove dirty class from form
|
||||
$('#edit-form').removeClass('dirty')
|
||||
// disable button
|
||||
$button.attr("disabled", "");
|
||||
|
||||
// make post request
|
||||
$.when(
|
||||
$.post('{{ ntop.getHttpPrefix() }}/lua/edit_user_script_config.lua', {
|
||||
script_subdir: '{{ script_list.script_subdir }}',
|
||||
script_key: script_key,
|
||||
csrf: '{{ ntop.getRandomCSRFValue() }}',
|
||||
JSON: JSON.stringify(data),
|
||||
confset_id: '{{ script_list.confset_id }}'
|
||||
})
|
||||
)
|
||||
.then((d, status, xhr) => {
|
||||
location.reload();
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
// bind event on reset defaults button
|
||||
const on_reset = (e) => {
|
||||
|
||||
// get default values for config
|
||||
$.when(
|
||||
$.get('{{ ntop.getHttpPrefix() }}/lua/get_user_script_config.lua', {
|
||||
script_subdir: '{{ script_list.script_subdir }}',
|
||||
script_key: script_key
|
||||
})
|
||||
)
|
||||
.then((data, status, xhr) => {
|
||||
|
||||
const {hooks} = data;
|
||||
|
||||
// reset default values
|
||||
for (key in hooks) {
|
||||
|
||||
const granularity = hooks[key];
|
||||
|
||||
$(`input[name='${key}-check']`).prop('checked', granularity.enabled);
|
||||
|
||||
if (granularity.script_conf.threshold === undefined) {
|
||||
$(`input[name='${key}-input']`).val('');
|
||||
}
|
||||
else {
|
||||
$(`input[name='${key}-input']`).val(granularity.script_conf.threshold);
|
||||
}
|
||||
|
||||
if (granularity.enabled) {
|
||||
$(`select[name='${key}-select']`).removeAttr("disabled");
|
||||
$(`input[name='${key}-input']`).removeAttr("readonly");
|
||||
}
|
||||
else {
|
||||
$(`input[name='${key}-input']`).attr("readonly", "");
|
||||
$(`select[name='${key}-select']`).attr("disabled", "");
|
||||
}
|
||||
|
||||
$(`select[name='${key}-select']`).val(granularity.script_conf.operator);
|
||||
|
||||
}
|
||||
|
||||
// remove dirty class from form
|
||||
$('#edit-form').removeClass('dirty')
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// bind click event to btn-apply
|
||||
$("#btn-apply").off("click").click(on_apply);
|
||||
|
||||
// bind reset default click event
|
||||
$("#btn-reset").off("click").click(on_reset);
|
||||
|
||||
// bind are you sure to form
|
||||
$('#edit-form').trigger('rescan.areYouSure');
|
||||
$('#edit-form').trigger('reinitialize.areYouSure');
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Count the scripts that are enabled, disabled inside the script table
|
||||
*/
|
||||
const count_scripts = () => {
|
||||
|
||||
// count scripts
|
||||
const $disabled_button = $(`#disabled-scripts`);
|
||||
const $all_button = $("#all-scripts");
|
||||
const $enabled_button = $(`#enabled-scripts`);
|
||||
|
||||
let enabled_count = 0;
|
||||
let disabled_count = 0;
|
||||
|
||||
$script_table.data().each(d => {
|
||||
|
||||
if (d.is_enabled) {
|
||||
enabled_count++;
|
||||
}
|
||||
else {
|
||||
disabled_count++;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$all_button.html(`{{ i18n("all", {}) }} (${enabled_count + disabled_count})`)
|
||||
$enabled_button.html(`{{ i18n("enabled", {}) }} (${enabled_count})`);
|
||||
$disabled_button.html(`{{ i18n("disabled", {}) }} (${disabled_count})`);
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
setTimeout(() => {
|
||||
document.location.reload()
|
||||
}, {{ script_list.timeout_csrf }});
|
||||
</script>
|
||||
|
||||
{% end %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue