mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
Initial commit on next_release branch
This commit is contained in:
21
front/appEvents.php
Executable file
21
front/appEvents.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
require 'php/templates/header.php';
|
||||
require 'php/templates/notification.php';
|
||||
?>
|
||||
<!-- ----------------------------------------------------------------------- -->
|
||||
|
||||
|
||||
<!-- Page ------------------------------------------------------------------ -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<?php
|
||||
require 'appEventsCore.php';
|
||||
?>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
require 'php/templates/footer.php';
|
||||
?>
|
||||
@@ -1,12 +1,12 @@
|
||||
<section class="content">
|
||||
<div class="nav-tabs-custom app-event-content" style="margin-bottom: 0px;">
|
||||
<ul id="tabs-location" class="nav nav-tabs col-sm-2">
|
||||
<li class="left-nav"><a class="col-sm-12" href="#" id="" data-toggle="tab">Events</a></li>
|
||||
</ul>
|
||||
<div id="tabs-content-location" class="tab-content col-sm-10">
|
||||
<table class="table table-striped" id="appevents-table" data-my-dbtable="AppEvents"></table>
|
||||
</div>
|
||||
<div class="nav-tabs-custom app-event-content" style="margin-bottom: 0px;">
|
||||
<ul id="tabs-location" class="nav nav-tabs col-sm-2 hidden">
|
||||
<li class="left-nav"><a class="col-sm-12" href="#" id="" data-toggle="tab">Events</a></li>
|
||||
</ul>
|
||||
<div id="tabs-content-location" class="tab-content col-sm-12">
|
||||
<table class="table table-striped" id="appevents-table" data-my-dbtable="AppEvents"></table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -18,75 +18,110 @@ showSpinner()
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
// Load JSON data from the provided URL
|
||||
$.getJSON('/php/server/query_json.php?file=table_appevents.json', function(data) {
|
||||
// Process the JSON data and generate UI dynamically
|
||||
processData(data)
|
||||
// Load JSON data from the provided URL
|
||||
$.getJSON('/php/server/query_json.php?file=table_appevents.json', function(data) {
|
||||
// Process the JSON data and generate UI dynamically
|
||||
processData(data)
|
||||
|
||||
// hide loading dialog
|
||||
hideSpinner()
|
||||
});
|
||||
// hide loading dialog
|
||||
hideSpinner()
|
||||
});
|
||||
});
|
||||
|
||||
function processData(data) {
|
||||
// Create an object to store unique ObjectType values as app event identifiers
|
||||
var appEventIdentifiers = {};
|
||||
// Create an object to store unique ObjectType values as app event identifiers
|
||||
var appEventIdentifiers = {};
|
||||
|
||||
// Array to accumulate data for DataTable
|
||||
var allData = [];
|
||||
// Array to accumulate data for DataTable
|
||||
var allData = [];
|
||||
|
||||
// Iterate through the data and generate tabs and content dynamically
|
||||
$.each(data.data, function(index, item) {
|
||||
|
||||
// Accumulate data for DataTable
|
||||
allData.push(item);
|
||||
|
||||
});
|
||||
|
||||
// Initialize DataTable for all app events
|
||||
// Iterate through the data and generate tabs and content dynamically
|
||||
$.each(data.data, function(index, item) {
|
||||
|
||||
$('#appevents-table').DataTable({
|
||||
data: allData,
|
||||
paging: true,
|
||||
lengthChange: true,
|
||||
lengthMenu: [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
||||
searching: true,
|
||||
ordering: true,
|
||||
info: true,
|
||||
autoWidth: false,
|
||||
pageLength: 25, // Set the default paging to 25
|
||||
columns: [
|
||||
{ data: 'DateTimeCreated', title: getString('AppEvents_DateTimeCreated') },
|
||||
{ data: 'AppEventType', title: getString('AppEvents_Type') },
|
||||
{ data: 'ObjectType', title: getString('AppEvents_ObjectType') },
|
||||
{ data: 'ObjectPrimaryID', title: getString('AppEvents_ObjectPrimaryID') },
|
||||
{ data: 'ObjectSecondaryID', title: getString('AppEvents_ObjectSecondaryID') },
|
||||
{ data: 'ObjectStatus', title: getString('AppEvents_ObjectStatus') },
|
||||
{ data: 'Extra', title: getString('AppEvents_Extra') },
|
||||
{ data: 'ObjectPlugin', title: getString('AppEvents_Plugin') },
|
||||
// Add other columns as needed
|
||||
],
|
||||
// Add column-specific configurations if needed
|
||||
columnDefs: [
|
||||
{ className: 'text-center', targets: [3] },
|
||||
{ width: '80px', targets: [6] },
|
||||
// ... Add other columnDefs as needed
|
||||
// Full MAC
|
||||
{targets: [3, 4],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (createDeviceLink(cellData));
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
]
|
||||
});
|
||||
// Accumulate data for DataTable
|
||||
allData.push(item);
|
||||
|
||||
});
|
||||
|
||||
console.log(allData);
|
||||
|
||||
|
||||
// Initialize DataTable for all app events
|
||||
|
||||
$('#appevents-table').DataTable({
|
||||
data: allData,
|
||||
paging: true,
|
||||
lengthChange: true,
|
||||
lengthMenu: [[10, 25, 50, 100, 500, -1], [10, 25, 50, 100, 500, 'All']],
|
||||
searching: true,
|
||||
ordering: true,
|
||||
info: true,
|
||||
autoWidth: false,
|
||||
pageLength: 25, // Set the default paging to 25
|
||||
columns: [
|
||||
{ data: 'DateTimeCreated', title: getString('AppEvents_DateTimeCreated') },
|
||||
{ data: 'AppEventProcessed', title: getString('AppEvents_AppEventProcessed') },
|
||||
{ data: 'AppEventType', title: getString('AppEvents_Type') },
|
||||
{ data: 'ObjectType', title: getString('AppEvents_ObjectType') },
|
||||
{ data: 'ObjectPrimaryID', title: getString('AppEvents_ObjectPrimaryID') },
|
||||
{ data: 'ObjectSecondaryID', title: getString('AppEvents_ObjectSecondaryID') },
|
||||
{ data: 'ObjectStatus', title: getString('AppEvents_ObjectStatus') },
|
||||
{ data: 'ObjectPlugin', title: getString('AppEvents_Plugin') },
|
||||
{ data: 'ObjectGUID', title: "GUID" },
|
||||
// Add other columns as needed
|
||||
],
|
||||
// Add column-specific configurations if needed
|
||||
columnDefs: [
|
||||
{ className: 'text-center', targets: [4] },
|
||||
{ width: '80px', targets: [7] },
|
||||
// ... Add other columnDefs as needed
|
||||
// Full MAC
|
||||
{targets: [4, 5],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
if (!emptyArr.includes(cellData)){
|
||||
$(td).html (createDeviceLink(cellData));
|
||||
} else {
|
||||
$(td).html ('');
|
||||
}
|
||||
} },
|
||||
// Processed
|
||||
{targets: [1],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
// console.log(cellData);
|
||||
$(td).html (cellData);
|
||||
}
|
||||
},
|
||||
// Datetime
|
||||
{targets: [0],
|
||||
'createdCell': function (td, cellData, rowData, row, col) {
|
||||
let timezone = $("#NAX_TZ").html(); // e.g., 'Europe/Berlin'
|
||||
let utcDate = new Date(cellData + ' UTC'); // Adding ' UTC' makes it interpreted as UTC time
|
||||
|
||||
// Format the date in the desired timezone
|
||||
let options = {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
hour12: false, // Use 24-hour format
|
||||
timeZone: timezone // Use the specified timezone
|
||||
};
|
||||
|
||||
let localDate = new Intl.DateTimeFormat('en-GB', options).format(utcDate);
|
||||
|
||||
// Update the table cell
|
||||
$(td).html(localDate);
|
||||
}
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
// Activate the first tab
|
||||
$('#tabs-location li:first-child').addClass('active');
|
||||
$('#tabs-content-location .tab-pane:first-child').addClass('active');
|
||||
// Activate the first tab
|
||||
$('#tabs-location li:first-child').addClass('active');
|
||||
$('#tabs-content-location .tab-pane:first-child').addClass('active');
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1840,6 +1840,47 @@ input[readonly] {
|
||||
height:50px;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Workflows
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
#workflowContainerWrap .panel-collapse
|
||||
{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.workflows .btn-secondary{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.workflows .condition-list button
|
||||
{
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.workflows button
|
||||
{
|
||||
/* width:100%; */
|
||||
}
|
||||
|
||||
#workflowContainerWrap
|
||||
{
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.workflow-card, .condition-list, .actions-list
|
||||
{
|
||||
display: grid;
|
||||
padding: 5px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.condition
|
||||
{
|
||||
padding: 5px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
Floating edit button
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
<!-- page script ----------------------------------------------------------- -->
|
||||
<script>
|
||||
var deviceStatus = 'all';
|
||||
var tableRows = getCache ("nax_parTableRows") == "" ? 10 : getCache ("nax_parTableRows") ;
|
||||
var tableRows = getCache ("nax_parTableRows") == "" ? 20 : getCache ("nax_parTableRows") ;
|
||||
var tableOrder = getCache ("nax_parTableOrder") == "" ? [[3,'desc'], [0,'asc']] : JSON.parse(getCache ("nax_parTableOrder")) ;
|
||||
|
||||
var tableColumnHide = [];
|
||||
@@ -737,7 +737,7 @@ function initializeDatatable (status) {
|
||||
},
|
||||
'paging' : true,
|
||||
'lengthChange' : true,
|
||||
'lengthMenu' : [[10, 25, 50, 100, 500, 100000], [10, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
|
||||
'lengthMenu' : [[10, 20, 25, 50, 100, 500, 100000], [10, 20, 25, 50, 100, 500, getString('Device_Tablelenght_all')]],
|
||||
'searching' : true,
|
||||
|
||||
'ordering' : true,
|
||||
|
||||
@@ -17,7 +17,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
// Check if file parameter is provided
|
||||
if ($file) {
|
||||
// Define the folder where files are located
|
||||
$filePath = "/app/api/" . basename($file);
|
||||
if ($file == "workflows.json")
|
||||
{
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
} else
|
||||
{
|
||||
$filePath = "/app/api/" . basename($file);
|
||||
}
|
||||
|
||||
// Check if the file exists
|
||||
if (file_exists($filePath)) {
|
||||
@@ -34,5 +40,38 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
http_response_code(400);
|
||||
echo json_encode(["error" => "Missing 'file' parameter"]);
|
||||
}
|
||||
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Read the input JSON data
|
||||
$inputData = file_get_contents("php://input");
|
||||
$decodedData = json_decode($inputData, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["error" => "Invalid JSON data"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check if file parameter is provided and is workflows.json
|
||||
if (!isset($_GET['file']) || $_GET['file'] !== "workflows.json") {
|
||||
http_response_code(400);
|
||||
echo json_encode(["error" => "Invalid or missing file parameter"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_GET['file'];
|
||||
$filePath = "/app/config/" . basename($file);
|
||||
|
||||
// Save new workflows.json (replace existing content)
|
||||
if (file_put_contents($filePath, json_encode($decodedData, JSON_PRETTY_PRINT))) {
|
||||
http_response_code(200);
|
||||
echo json_encode(["success" => "Workflows replaced successfully"]);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(["error" => "Failed to update workflows.json"]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
http_response_code(405);
|
||||
echo json_encode(["error" => "Method Not Allowed"]);
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -150,7 +150,8 @@
|
||||
let formattedDateTime = `${day}-${month}-${year} ${hour}:${minute}:${second}`;
|
||||
|
||||
if (document.getElementById) {
|
||||
document.getElementById("PIA_Servertime_place").innerHTML = '(' + formattedDateTime + ')';
|
||||
document.getElementById("NAX_Servertime_plc").innerHTML = '(' + formattedDateTime + ')';
|
||||
document.getElementById("NAX_TZ").innerHTML = timeZone;
|
||||
}
|
||||
|
||||
setTimeout(update_servertime, 1000); // Call recursively every second
|
||||
@@ -234,7 +235,13 @@
|
||||
<!-- Server Name -->
|
||||
<li>
|
||||
<div class="header-server-time small">
|
||||
<div><?php echo gethostname();?></div> <div><span id="PIA_Servertime_place"></span></div>
|
||||
<div>
|
||||
<?php echo gethostname();?>
|
||||
</div>
|
||||
<div>
|
||||
<span id="NAX_Servertime_plc"></span>
|
||||
<span id="NAX_TZ" class="hidden"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -414,18 +421,22 @@
|
||||
</li>
|
||||
|
||||
<!-- Integrations menu item -->
|
||||
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php' ) ) ){ echo 'active menu-open'; } ?>">
|
||||
<li class=" treeview <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php', 'appEvents.php' ) ) ){ echo 'active menu-open'; } ?>">
|
||||
<a href="#">
|
||||
<i class="fa fa-fw fa-plug"></i> <span><?= lang('Navigation_Integrations');?></span>
|
||||
<span class="pull-right-container">
|
||||
<i class="fa fa-angle-left pull-right"></i>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<ul class="treeview-menu " style="display: <?php if (in_array (basename($_SERVER['SCRIPT_NAME']), array('plugins.php', 'workflows.php', 'appEvents.php' ) ) ){ echo 'block'; } else {echo 'none';} ?>;">
|
||||
<li>
|
||||
<div class="info-icon-nav"> </div>
|
||||
<a href="workflows.php"><?= lang('Navigation_Workflows');?></a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="info-icon-nav"> </div>
|
||||
<a href="appEvents.php"><?= lang('Navigation_AppEvents');?></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="plugins.php"><?= lang("Navigation_Plugins");?> </a>
|
||||
</li>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "",
|
||||
"About_Exit": "",
|
||||
"About_Title": "",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "",
|
||||
"AppEvents_Extra": "",
|
||||
"AppEvents_GUID": "",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Dissenyat per:",
|
||||
"About_Exit": "Sortir",
|
||||
"About_Title": "Escàner de seguretat de xarxa i marc de notificacions",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Logged",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "GUID d'esdeveniments d'Aplicació",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Quins tipus de dispositius es poden utilitzar com a dispositius de xarxa a la vista \"xarxa\". El tipus de dispositiu ha de coincidir exactament amb la configuració <code>Tipus</code> dels detalls de dispositiu. Afegir-ho al dispositiu fent servir el botó <code>+</code>. No elimini els tipus existents, només afegir-ne nous.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Tipus de dispositiu de xarxa",
|
||||
"Navigation_About": "Sobre",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Dispositius",
|
||||
"Navigation_Donations": "Donacions",
|
||||
"Navigation_Events": "Esdeveniments",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Actualitza el valor sota. Sigues curós de seguir el format anterior. <b>No hi ha validació.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Deseu els canvis primer abans de comprovar la configuració."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "",
|
||||
"About_Exit": "",
|
||||
"About_Title": "",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "",
|
||||
"AppEvents_Extra": "",
|
||||
"AppEvents_GUID": "",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"About_Design": "Entworfen für:",
|
||||
"About_Exit": "Abmelden",
|
||||
"About_Title": "Netzwerksicherheitsscanner und Benachrichtigungsframework",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "protokolliert",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "Anwendungsereignis-GUID",
|
||||
@@ -500,6 +501,7 @@
|
||||
"NTFY_display_name": "NTFY",
|
||||
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
|
||||
"Navigation_About": "Über",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Geräte",
|
||||
"Navigation_Donations": "Spenden",
|
||||
"Navigation_Events": "Ereignisse",
|
||||
@@ -797,4 +799,4 @@
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": "Speichere die Änderungen, bevor Sie die Einstellungen testen."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Designed for:",
|
||||
"About_Exit": "Sign out",
|
||||
"About_Title": "Network security scanner & notification framework",
|
||||
"AppEvents_AppEventProcessed": "Processed",
|
||||
"AppEvents_DateTimeCreated": "Logged",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "Application Event GUID",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Which device types are allowed to be used as network devices in the Network view. The device type has to match exactly the <code>Type</code> setting on a specific device in Device details. Add it on the Device via the <code>+</code> button. Do not remove existing types, only add new ones.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Network device types",
|
||||
"Navigation_About": "About",
|
||||
"Navigation_AppEvents": "App Events",
|
||||
"Navigation_Devices": "Devices",
|
||||
"Navigation_Donations": "Donations",
|
||||
"Navigation_Events": "Events",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"About_Design": "Diseñado para:",
|
||||
"About_Exit": "Salir",
|
||||
"About_Title": "Escáner de seguridad de la red y marco de notificaciones",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Registrado",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "GUID del evento de aplicación",
|
||||
@@ -498,6 +499,7 @@
|
||||
"NTFY_display_name": "NTFY",
|
||||
"NTFY_icon": "<i class=\"fa fa-terminal\"></i>",
|
||||
"Navigation_About": "Acerca de",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Dispositivos",
|
||||
"Navigation_Donations": "Donaciones",
|
||||
"Navigation_Events": "Eventos",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Conçu pour :",
|
||||
"About_Exit": "Se déconnecter",
|
||||
"About_Title": "Analyse de la sécurité du réseau et cadre de notification",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Connecté",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "GUID d’événements de l'application",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Les types d'appareils autorisés à être utilisés comme appareils réseau dans la vue Réseau. Le type d'appareils doit être identique au paramètre <code>Type</code> d'un appareil dans le détail des appareils. Ajouter le sur l'appareil grâce au bouton <code>+</code>. Ne pas supprimer de valeurs, seulement en ajouter de nouvelles.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Type d'appareil réseau",
|
||||
"Navigation_About": "À propos",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Appareils",
|
||||
"Navigation_Donations": "Dons",
|
||||
"Navigation_Events": "Évènements",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Progettato per:",
|
||||
"About_Exit": "Esci",
|
||||
"About_Title": "Scanner di sicurezza di rete e framework di notifica",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Loggato",
|
||||
"AppEvents_Extra": "Extra",
|
||||
"AppEvents_GUID": "GUID evento applicazione",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Quali tipi di dispositivo possono essere utilizzati come dispositivi di rete nella vista Rete. Il tipo di dispositivo deve corrispondere esattamente all'impostazione <code>Tipo</code> su un dispositivo specifico nei Dettagli dispositivo. Aggiungilo sul Dispositivo tramite il pulsante <code>+</code>. Non rimuovere i tipi esistenti, aggiungine solo di nuovi.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Tipi di dispositivi di rete",
|
||||
"Navigation_About": "Informazioni su",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Dispositivi",
|
||||
"Navigation_Donations": "Donazioni",
|
||||
"Navigation_Events": "Eventi",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Designet for:",
|
||||
"About_Exit": "Logg ut",
|
||||
"About_Title": "Nettverkssikkerhetsskanner og varslingsrammeverk",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Logget",
|
||||
"AppEvents_Extra": "Ekstra",
|
||||
"AppEvents_GUID": "Applikasjon Hendelse GUID",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Hvilke enhetstyper som tillates å brukes som nettverksenheter i nettverksvisningen. Enhetstypen må samsvare med nøyaktig <code>Type</code> Innstillingen på en bestemt enhet i enhetsdetaljer. Ikke fjern eksisterende typer, legg bare til nye.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Nettverksenhetstyper",
|
||||
"Navigation_About": "Om",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Enheter",
|
||||
"Navigation_Donations": "Donasjoner",
|
||||
"Navigation_Events": "Hendelser",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Zaprojektowany dla:",
|
||||
"About_Exit": "Wyloguj",
|
||||
"About_Title": "Skaner bezpieczeństwa sieciowego i framwork powiadomień",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Zalogowany",
|
||||
"AppEvents_Extra": "Ekstra",
|
||||
"AppEvents_GUID": "Aplikacja GUID wydarzeń",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Które typy urządzeń mają zezwolenie na bycie użytym jako urządzenia sieciowe w Widoku Sieci. Typ urządzenia musi dokładnie odpowiadać ustawieniu <code>Typ</code> na konkretnym urządzeniu w Szczegółach urządzenia. Nie usuwaj istniejących typów, tylko dodawaj nowe.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Typy urządzeń sieciowych",
|
||||
"Navigation_About": "Informacje o",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Urządzenia",
|
||||
"Navigation_Donations": "Dotacje",
|
||||
"Navigation_Events": "Wydarzenia",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Zaktualizuj poniższą wartość. Zachowaj ostrożność i postępuj zgodnie z poprzednim formatem. <b>Walidacja nie jest wykonywana.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Zapisz zmiany zanim będziesz testować swoje ustawienia."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Desenvolvido por:",
|
||||
"About_Exit": "Sair",
|
||||
"About_Title": "Analisador de segurança de rede & framework de notificação",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Registrado em",
|
||||
"AppEvents_Extra": "Adicional",
|
||||
"AppEvents_GUID": "Evento de aplicação GUID",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "",
|
||||
"test_event_icon": "",
|
||||
"test_event_tooltip": ""
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Разработан:",
|
||||
"About_Exit": "Зарегистрироваться",
|
||||
"About_Title": "Сетевой сканер и система уведомлений",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Журнал",
|
||||
"AppEvents_Extra": "Дополнительно",
|
||||
"AppEvents_GUID": "GUID события приложения",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Какие типы устройств разрешено использовать в качестве сетевых устройств в представлении Сеть. Тип устройства должен точно соответствовать настройке <code>Type</code> для конкретного устройства в сведениях об устройстве. Добавьте его на устройство с помощью кнопки <code>+</code>. Не удаляйте существующие типы, а только добавляйте новые.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Типы сетевых устройств",
|
||||
"Navigation_About": "О NetAlertX",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Устройства",
|
||||
"Navigation_Donations": "Пожертвования",
|
||||
"Navigation_Events": "События",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Обновить значение ниже. Будьте осторожны, следуя предыдущему формату. <b>Проверка не выполняется.</b>",
|
||||
"test_event_icon": "fa-vial-circle-check",
|
||||
"test_event_tooltip": "Сначала сохраните изменения, прежде чем проверять настройки."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "",
|
||||
"About_Exit": "Oturum kapat",
|
||||
"About_Title": "",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "",
|
||||
"AppEvents_Extra": "Ekstra",
|
||||
"AppEvents_GUID": "",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "",
|
||||
"NETWORK_DEVICE_TYPES_name": "",
|
||||
"Navigation_About": "Hakkında",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Cihazlar",
|
||||
"Navigation_Donations": "",
|
||||
"Navigation_Events": "",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "Призначений для:",
|
||||
"About_Exit": "Вийти",
|
||||
"About_Title": "Сканер безпеки мережі та структура сповіщень",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "Зареєстровано",
|
||||
"AppEvents_Extra": "Екстра",
|
||||
"AppEvents_GUID": "GUID події програми",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "Які типи пристроїв дозволено використовувати як мережеві пристрої в поданні мережі. Тип пристрою має точно відповідати налаштуванню <code>Тип</code> на певному пристрої в Деталях пристрою. Додайте його на пристрій за допомогою кнопки <code>+</code>. Не видаляйте існуючі типи, лише додайте нові.",
|
||||
"NETWORK_DEVICE_TYPES_name": "Типи мережевих пристроїв",
|
||||
"Navigation_About": "про",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "Пристрої",
|
||||
"Navigation_Donations": "Пожертви",
|
||||
"Navigation_Events": "Події",
|
||||
@@ -716,4 +718,4 @@
|
||||
"settings_update_item_warning": "Оновіть значення нижче. Слідкуйте за попереднім форматом. <b>Перевірка не виконана.</b>",
|
||||
"test_event_icon": "fa-vial-circle- check",
|
||||
"test_event_tooltip": "Перш ніж перевіряти налаштування, збережіть зміни."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
"About_Design": "设计用于:",
|
||||
"About_Exit": "登出",
|
||||
"About_Title": "网络安全扫描器和通知框架",
|
||||
"AppEvents_AppEventProcessed": "",
|
||||
"AppEvents_DateTimeCreated": "已记录",
|
||||
"AppEvents_Extra": "额外的",
|
||||
"AppEvents_GUID": "应用程序事件 GUID",
|
||||
@@ -464,6 +465,7 @@
|
||||
"NETWORK_DEVICE_TYPES_description": "哪些设备类型允许在网络视图中用作网络设备。设备类型必须与设备详细信息中特定设备上的 <code>Type</code> 设置完全匹配。请勿删除现有类型,仅添加新类型。",
|
||||
"NETWORK_DEVICE_TYPES_name": "网络设备类型",
|
||||
"Navigation_About": "关于",
|
||||
"Navigation_AppEvents": "",
|
||||
"Navigation_Devices": "设备",
|
||||
"Navigation_Donations": "捐款",
|
||||
"Navigation_Events": "事件",
|
||||
|
||||
@@ -293,9 +293,6 @@ def create_sensor(mqtt_client, deviceId, deviceName, sensorType, sensorName, ico
|
||||
# check previous configs
|
||||
sensorConfig = sensor_config(deviceId, deviceName, sensorType, sensorName, icon, mac)
|
||||
|
||||
mylog('verbose', [f"[{pluginName}] Publishing sensor number {len(mqtt_sensors)}"])
|
||||
|
||||
|
||||
# send if new
|
||||
if sensorConfig.isNew:
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from const import pluginsPath, fullDbPath, logPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
@@ -53,8 +53,8 @@ def main():
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
# Retrieve devices
|
||||
unknown_devices = device_handler.getUnknown()
|
||||
|
||||
@@ -139,6 +139,7 @@ def cleanup_database (dbPath, DAYS_TO_KEEP_EVENTS, HRS_TO_KEEP_NEWDEV, HRS_TO_KE
|
||||
);"""
|
||||
|
||||
cursor.execute(delete_query)
|
||||
conn.commit()
|
||||
|
||||
|
||||
# -----------------------------------------------------
|
||||
|
||||
@@ -23,7 +23,7 @@ from logger import mylog, Logger, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
@@ -57,8 +57,8 @@ def main():
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
# Retrieve devices
|
||||
all_devices = device_handler.getAll()
|
||||
|
||||
@@ -18,7 +18,7 @@ from const import pluginsPath, fullDbPath, logPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
@@ -53,8 +53,8 @@ def main():
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
# Retrieve devices
|
||||
unknown_devices = device_handler.getUnknown()
|
||||
|
||||
@@ -24,7 +24,7 @@ from logger import mylog, Logger, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value, extract_between_strings, extract_ip_addresses, extract_mac_addresses
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ from logger import mylog, Logger, append_line_to_file
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from const import logPath, applicationPath, fullDbPath
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
from pytz import timezone
|
||||
|
||||
@@ -55,8 +55,8 @@ def main():
|
||||
# Initialize the Plugin obj output file
|
||||
plugin_objects = Plugin_Objects(RESULT_FILE)
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
# Retrieve devices
|
||||
unknown_devices = device_handler.getUnknown()
|
||||
|
||||
@@ -251,12 +251,12 @@ def main():
|
||||
|
||||
mylog("verbose", [f"[{pluginName}] starting execution"])
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
|
||||
db = DB() # instance of class DB
|
||||
db.open()
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
# Retrieve configuration settings
|
||||
# these should be self-explanatory
|
||||
omada_sites = []
|
||||
|
||||
@@ -19,7 +19,7 @@ from const import pluginsPath, fullDbPath, logPath
|
||||
from helper import timeNowTZ, get_setting_value
|
||||
from notification import write_notification
|
||||
from database import DB
|
||||
from device import Device_obj
|
||||
from models.device_instance import DeviceInstance
|
||||
import conf
|
||||
|
||||
# Make sure the TIMEZONE for logging is correct
|
||||
@@ -54,8 +54,8 @@ def main():
|
||||
db = DB() # instance of class DB
|
||||
db.open()
|
||||
|
||||
# Create a Device_obj instance
|
||||
device_handler = Device_obj(db)
|
||||
# Create a DeviceInstance instance
|
||||
device_handler = DeviceInstance(db)
|
||||
|
||||
# Retrieve devices
|
||||
if 'offline' in devices_to_wake:
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="content-wrapper">
|
||||
|
||||
<?php
|
||||
require 'appEventsCore.php';
|
||||
require 'workflowsCore.php';
|
||||
?>
|
||||
|
||||
|
||||
|
||||
385
front/workflowsCore.php
Executable file
385
front/workflowsCore.php
Executable file
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
//------------------------------------------------------------------------------
|
||||
// check if authenticated
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/security.php';
|
||||
?>
|
||||
|
||||
|
||||
<section class="content workflows">
|
||||
<div id="workflowContainerWrap" class="bg-grey-dark color-palette col-sm-12 box-default box-info ">
|
||||
<div id="workflowContainer"></div>
|
||||
|
||||
</div>
|
||||
<div id="buttons" class="buttons col-sm-12">
|
||||
<div class="add-workflow col-sm-6">
|
||||
<button type="button" class="btn btn-primary btn-default pa-btn bg-green" id="save" onclick="addWorkflow()">
|
||||
<?= lang('Gen_Add');?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="save-workflows col-sm-6">
|
||||
<button type="button" class="btn btn-primary btn-default pa-btn bg-green" id="save" onclick="saveWorkflows()">
|
||||
<?= lang('DevDetail_button_Save');?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
let workflows = [];
|
||||
|
||||
let fieldOptions = [
|
||||
"devMac", "devName", "devOwner", "devType", "devVendor", "devFavorite",
|
||||
"devGroup", "devComments", "devFirstConnection", "devLastConnection",
|
||||
"devLastIP", "devStaticIP", "devScan", "devLogEvents", "devAlertEvents",
|
||||
"devAlertDown", "devSkipRepeated", "devLastNotification", "devPresentLastScan",
|
||||
"devIsNew", "devLocation", "devIsArchived", "devParentMAC", "devParentPort",
|
||||
"devIcon", "devGUID", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin"
|
||||
];
|
||||
|
||||
let triggerTypes = [
|
||||
"Devices", "Plugins_Objects"
|
||||
];
|
||||
|
||||
let operatorTypes = [
|
||||
"equals", "contains" , "regex"
|
||||
];
|
||||
|
||||
let actionTypes = [
|
||||
"update_field", "run_plugin"
|
||||
];
|
||||
|
||||
// --------------------------------------
|
||||
// Retrieve and process the data
|
||||
function getData() {
|
||||
showSpinner();
|
||||
|
||||
getSetting()
|
||||
|
||||
$.get('php/server/query_json.php?file=workflows.json', function (res) {
|
||||
workflows = res;
|
||||
console.log(workflows);
|
||||
renderWorkflows();
|
||||
hideSpinner();
|
||||
});
|
||||
}
|
||||
|
||||
// --------------------------------------
|
||||
// Render all workflows
|
||||
function renderWorkflows() {
|
||||
let $container = $("#workflowContainer");
|
||||
$container.empty(); // Clear previous UI
|
||||
|
||||
$.each(workflows, function (index, wf) {
|
||||
let $wfElement = generateWorkflowUI(wf, index);
|
||||
$container.append($wfElement);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// Generate UI for a single workflow
|
||||
function generateWorkflowUI(wf, index) {
|
||||
|
||||
let $wfContainer = $("<div>", {
|
||||
class: "workflow-card box box-solid box-primary panel panel-default",
|
||||
id: `wf-${index}-container`
|
||||
});
|
||||
|
||||
// Workflow Name
|
||||
let $wfLinkWrap = $("<div>",
|
||||
{
|
||||
class: " ",
|
||||
id: `wf-${index}-header`
|
||||
}
|
||||
)
|
||||
|
||||
let $wfHeaderLink = $("<a>",
|
||||
{
|
||||
"class": "",
|
||||
"data-toggle": "collapse",
|
||||
"data-parent": "#workflowContainer",
|
||||
"aria-expanded": false,
|
||||
"href" : `#wf-${index}-collapsible-panel`
|
||||
}
|
||||
)
|
||||
|
||||
let $wfHeaderHeading = $("<h4>",
|
||||
{
|
||||
class: "panel-title"
|
||||
}
|
||||
).text(wf.name)
|
||||
|
||||
$wfContainer.append($wfHeaderLink.append($wfLinkWrap.append($wfHeaderHeading)));
|
||||
|
||||
// Collapsible panel start
|
||||
let $wfCollapsiblePanel = $("<div>", {
|
||||
class: "panel-collapse collapse ",
|
||||
id: `wf-${index}-collapsible-panel`
|
||||
});
|
||||
|
||||
let $wfNameInput = createEditableInput("Workflow name", wf.name, `wf-name-${index}`, "workflow-name-input", function(newValue) {
|
||||
console.log(`Saved new value: ${newValue}`);
|
||||
wf.name = newValue; // Update the workflow object with the new name
|
||||
});
|
||||
|
||||
$wfCollapsiblePanel.append($wfNameInput)
|
||||
|
||||
// Trigger Section with dropdowns
|
||||
let $triggerSection = $("<div>",
|
||||
{
|
||||
class: "condition-list box box-secondary"
|
||||
}
|
||||
).append("<strong>Trigger:</strong> ");
|
||||
|
||||
let $triggerTypeDropdown = createEditableDropdown("Trigger Type", triggerTypes, wf.trigger.object_type, `trigger-${index}-type`, function(newValue) {
|
||||
wf.trigger.object_type = newValue; // Update trigger's object_type
|
||||
});
|
||||
|
||||
let $eventTypeDropdown = createEditableDropdown("Event Type", ["update", "create", "delete"], wf.trigger.event_type, `event-${index}-type`, function(newValue) {
|
||||
wf.trigger.event_type = newValue; // Update trigger's event_type
|
||||
});
|
||||
|
||||
$triggerSection.append($triggerTypeDropdown);
|
||||
$triggerSection.append($eventTypeDropdown);
|
||||
$wfCollapsiblePanel.append($triggerSection);
|
||||
|
||||
// Conditions
|
||||
let $conditionsContainer = $("<div>").append("<strong>Conditions:</strong>");
|
||||
$conditionsContainer.append(renderConditions(wf.conditions));
|
||||
|
||||
$wfCollapsiblePanel.append($conditionsContainer);
|
||||
|
||||
|
||||
// Actions with action.field as dropdown
|
||||
let $actionsContainer = $("<div>",
|
||||
{
|
||||
class: "actions-list box box-secondary"
|
||||
}
|
||||
).append("<strong>Actions:</strong>");
|
||||
|
||||
$.each(wf.actions, function (_, action) {
|
||||
let $actionEl = $("<div>");
|
||||
|
||||
// Dropdown for action.field
|
||||
let $fieldDropdown = createEditableDropdown("Field", fieldOptions, action.field, `action-${index}-field`, function(newValue) {
|
||||
action.field = newValue; // Update action.field when a new value is selected
|
||||
});
|
||||
|
||||
|
||||
// Dropdown for action.type
|
||||
let $actionDropdown= createEditableDropdown("Action", actionTypes, action.field, `action-${index}-type`, function(newValue) {
|
||||
action.field = newValue; // Update action.field when a new value is selected
|
||||
});
|
||||
|
||||
|
||||
// Action Value Input (Editable)
|
||||
let $actionValueInput = createEditableInput("Value", action.value, `action-${index}-value`, "action-value-input", function(newValue) {
|
||||
action.value = newValue; // Update action.value when saved
|
||||
});
|
||||
|
||||
$actionEl.append($actionDropdown);
|
||||
$actionEl.append($fieldDropdown);
|
||||
$actionEl.append($actionValueInput);
|
||||
|
||||
$actionsContainer.append($actionEl);
|
||||
});
|
||||
|
||||
// add conditions group button
|
||||
let $actionAddButton = $("<button>", {
|
||||
class : "btn btn-secondary "
|
||||
}).text("Add Action")
|
||||
|
||||
$actionsContainer.append($actionAddButton)
|
||||
$wfCollapsiblePanel.append($actionsContainer);
|
||||
|
||||
$wfContainer.append($wfCollapsiblePanel)
|
||||
|
||||
return $wfContainer;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// Render conditions recursively
|
||||
function renderConditions(conditions) {
|
||||
let $conditionList = $("<div>", {
|
||||
class: "condition-list panel "
|
||||
});
|
||||
|
||||
$.each(conditions, function (index, condition) {
|
||||
if (condition.logic) {
|
||||
let $nestedCondition = $("<div>",
|
||||
{
|
||||
class : "condition box box-secondary"
|
||||
}
|
||||
);
|
||||
|
||||
let $logicDropdown = createEditableDropdown("Logic Rules", ["AND", "OR"], condition.logic, `logic-${condition.field}`, function(newValue) {
|
||||
condition.logic = newValue; // Update condition logic when a new value is selected
|
||||
});
|
||||
|
||||
$nestedCondition.append($logicDropdown);
|
||||
|
||||
$conditionListNested = renderConditions(condition.conditions)
|
||||
|
||||
|
||||
// add conditions group button
|
||||
let $conditionAddButton = $("<button>", {
|
||||
class : "btn btn-secondary "
|
||||
}).text("Add Condition")
|
||||
|
||||
$conditionListNested.append($conditionAddButton);
|
||||
$nestedCondition.append($conditionListNested); // Recursive call for nested conditions
|
||||
|
||||
$conditionList.append($nestedCondition);
|
||||
|
||||
} else {
|
||||
let $conditionItem = $("<div>",
|
||||
{
|
||||
class: "panel"
|
||||
});
|
||||
|
||||
// Create dropdown for condition field
|
||||
let $fieldDropdown = createEditableDropdown("Field", fieldOptions, condition.field, `condition-${index}-field-${condition.field}`, function(newValue) {
|
||||
condition.field = newValue; // Update condition field when a new value is selected
|
||||
});
|
||||
|
||||
// Create dropdown for operator
|
||||
let $operatorDropdown = createEditableDropdown("Operator", operatorTypes, condition.operator, `condition-${index}operator-${condition.field}`, function(newValue) {
|
||||
condition.operator = newValue; // Update operator when a new value is selected
|
||||
});
|
||||
|
||||
// Editable input for condition value
|
||||
let $editableInput = createEditableInput("Condition Value", condition.value, `condition-${index}-value-${condition.field}`, "condition-value-input", function(newValue) {
|
||||
condition.value = newValue; // Update condition value when saved
|
||||
});
|
||||
|
||||
$conditionItem.append($fieldDropdown); // Append field dropdown
|
||||
$conditionItem.append($operatorDropdown); // Append operator dropdown
|
||||
$conditionItem.append($editableInput); // Append editable input for condition value
|
||||
$conditionList.append($conditionItem);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// add conditions group button
|
||||
let $conditionsGroupAddButton = $("<button>", {
|
||||
class : "btn btn-secondary"
|
||||
}).text("Add Condition Group")
|
||||
|
||||
$conditionList.append($conditionsGroupAddButton);
|
||||
|
||||
|
||||
return $conditionList;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// Render SELECT Dropdown with Predefined Values
|
||||
function createEditableDropdown(labelText, options, selectedValue, id, onSave) {
|
||||
|
||||
let $wrapper = $("<div>", {
|
||||
class: "form-group col-xs-12"
|
||||
});
|
||||
|
||||
let $label = $("<label>", {
|
||||
for: id,
|
||||
class: "col-sm-4 col-xs-12 control-label "
|
||||
}).text(labelText);
|
||||
|
||||
// Create select wrapper
|
||||
let $selectWrapper = $("<div>", {
|
||||
class: "col-sm-8 col-xs-12"
|
||||
});
|
||||
|
||||
// Create select element
|
||||
let $select = $("<select>", {
|
||||
id: id,
|
||||
class: "form-control col-sm-8 col-xs-12"
|
||||
});
|
||||
|
||||
// Add options to the select dropdown
|
||||
$.each(options, function (_, option) {
|
||||
let $option = $("<option>", { value: option }).text(option);
|
||||
if (option === selectedValue) {
|
||||
$option.attr("selected", "selected"); // Set the default selection
|
||||
}
|
||||
$select.append($option);
|
||||
});
|
||||
|
||||
// Trigger onSave when the selection changes
|
||||
$select.on("change", function() {
|
||||
let newValue = $select.val();
|
||||
console.log(`Selected new value: ${newValue}`);
|
||||
if (onSave && typeof onSave === "function") {
|
||||
onSave(newValue); // Call onSave callback with the new value
|
||||
}
|
||||
});
|
||||
|
||||
$wrapper.append($label);
|
||||
$wrapper.append($selectWrapper.append($select));
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// Render INPUT HTML element
|
||||
function createEditableInput(labelText, value, id, className = "", onSave = null) {
|
||||
|
||||
// prepare wrapper
|
||||
$wrapper = $("<div>", {
|
||||
class: "form-group col-xs-12"
|
||||
});
|
||||
|
||||
let $label = $("<label>", {
|
||||
for: id,
|
||||
class: "col-sm-4 col-xs-12 control-label "
|
||||
}).text(labelText);
|
||||
|
||||
// Create input wrapper
|
||||
let $inputWrapper = $("<div>", {
|
||||
class: "col-sm-8 col-xs-12"
|
||||
});
|
||||
|
||||
|
||||
let $input = $("<input>", {
|
||||
type: "text",
|
||||
id: id,
|
||||
value: value,
|
||||
class: className + " col-sm-8 col-xs-12 form-control "
|
||||
});
|
||||
|
||||
// Optional: Add a change event listener to update the workflow name
|
||||
$input.on("change", function () {
|
||||
let newValue = $input.val();
|
||||
console.log(`Value changed to: ${newValue}`);
|
||||
});
|
||||
|
||||
// Trigger onSave when the user presses Enter or the input loses focus
|
||||
$input.on("blur keyup", function (e) {
|
||||
if (e.type === "blur" || e.key === "Enter") {
|
||||
if (onSave && typeof onSave === "function") {
|
||||
onSave($input.val()); // Call the onSave callback with the new value
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$wrapper.append($label)
|
||||
$wrapper.append($inputWrapper.append($input))
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// Initialize
|
||||
$(document).ready(function () {
|
||||
getData();
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user