DOCS+FE: cleanup, adding Source fields to workflows

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2026-01-27 07:31:35 +11:00
parent 46bbc6e335
commit 31530fb46e
3 changed files with 133 additions and 130 deletions

View File

@@ -4,10 +4,11 @@
[![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/NczTUTWyRr) [![Discord](https://img.shields.io/discord/1274490466481602755?color=0aa8d2&logoColor=fff&logo=Discord&style=for-the-badge)](https://discord.gg/NczTUTWyRr)
[![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons)
# NetAlertX - Network scanner & notification framework # NetAlertX - Network Visibility & Asset Intelligence Framework
| [📑 Docker guide](https://docs.netalertx.com/DOCKER_INSTALLATION) | [🚀 Releases](https://github.com/jokob-sk/NetAlertX/releases) | [📚 Docs](https://docs.netalertx.com/) | [🔌 Plugins](https://docs.netalertx.com/PLUGINS) | [🤖 Ask AI](https://gurubase.io/g/netalertx) ---
|----------------------| ----------------------| ----------------------| ----------------------| ----------------------| ### || [Docker guide](https://docs.netalertx.com/DOCKER_INSTALLATION) || [Releases](https://github.com/netalertx/NetAlertX/releases) || [Docs](https://docs.netalertx.com/) || [Plugins](https://docs.netalertx.com/PLUGINS) || [Website](https://netalertx.com)
---
<a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank"> <a href="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" target="_blank">
<img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" /> <img src="https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/docs/img/GENERAL/github_social_image.jpg" width="1000px" />

View File

@@ -6,7 +6,7 @@ hide:
# NetAlertX Documentation # NetAlertX Documentation
Welcome to the official NetAlertX documentation! NetAlertX is a powerful tool designed to simplify the management and monitoring of your network. Below, you will find guides and resources to help you set up, configure, and troubleshoot your NetAlertX instance. Find guides and resources to help you set up, configure, and troubleshoot your NetAlertX instance.
![Preview](./img/devices_split.png) ![Preview](./img/devices_split.png)
@@ -15,7 +15,7 @@ Welcome to the official NetAlertX documentation! NetAlertX is a powerful tool de
NetAlertX provides contextual help within the application: NetAlertX provides contextual help within the application:
- **Hover over settings, fields, or labels** to see additional tooltips and guidance. - **Hover over settings, fields, or labels** to see additional tooltips and guidance.
- **Click (question-mark) icons** next to various elements to view detailed information. - **Click ? (question-mark) icons** next to various elements to view detailed information.
--- ---

View File

@@ -12,7 +12,7 @@
<section class="content workflows col-sm-12 col-xs-12"> <section class="content workflows col-sm-12 col-xs-12">
<div id="workflowContainerWrap" class="bg-grey-dark color-palette col-sm-12 col-xs-12 box-default box-info "> <div id="workflowContainerWrap" class="bg-grey-dark color-palette col-sm-12 col-xs-12 box-default box-info ">
<div id="workflowContainer"></div> <div id="workflowContainer"></div>
</div> </div>
<div id="buttons" class="bottom-buttons col-sm-12 col-xs-12"> <div id="buttons" class="bottom-buttons col-sm-12 col-xs-12">
<div class="add-workflow col-sm-4 col-xs-12"> <div class="add-workflow col-sm-4 col-xs-12">
@@ -48,10 +48,12 @@ let fieldOptions = [
"devLastIP", "devStaticIP", "devScan", "devLogEvents", "devAlertEvents", "devLastIP", "devStaticIP", "devScan", "devLogEvents", "devAlertEvents",
"devAlertDown", "devSkipRepeated", "devLastNotification", "devPresentLastScan", "devAlertDown", "devSkipRepeated", "devLastNotification", "devPresentLastScan",
"devIsNew", "devLocation", "devIsArchived", "devParentMAC", "devParentPort", "devIsNew", "devLocation", "devIsArchived", "devParentMAC", "devParentPort",
"devIcon", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin", "devFQDN", "devIcon", "devSite", "devSSID", "devSyncHubNode", "devSourcePlugin", "devFQDN",
"devParentRelType", "devReqNicsOnline" "devParentRelType", "devReqNicsOnline", "devNameSource", "devVendorSource" ,
"devSSIDSource", "devParentMACSource" , "devParentPortSource" , "devParentRelTypeSource",
"devVlanSource"
]; ];
let triggerTypes = [ let triggerTypes = [
"Devices" "Devices"
]; ];
@@ -79,7 +81,7 @@ let emptyWorkflow = {
}, },
"conditions": [ "conditions": [
], ],
"actions": [ "actions": [
] ]
}; };
@@ -131,25 +133,25 @@ function renderWorkflows() {
// Generate UI for a single workflow // Generate UI for a single workflow
function generateWorkflowUI(wf, wfIndex) { function generateWorkflowUI(wf, wfIndex) {
let wfEnabled = (wf?.enabled ?? "No") == "Yes"; let wfEnabled = (wf?.enabled ?? "No") == "Yes";
let $wfContainer = $("<div>", { let $wfContainer = $("<div>", {
class: "workflow-card panel col-sm-12 col-sx-12", class: "workflow-card panel col-sm-12 col-sx-12",
id: `wf-${wfIndex}-container` id: `wf-${wfIndex}-container`
}); });
// Workflow Name // Workflow Name
let $wfLinkWrap = $("<div>", let $wfLinkWrap = $("<div>",
{ {
class: " ", class: " ",
id: `wf-${wfIndex}-header` id: `wf-${wfIndex}-header`
} }
) )
let $wfEnabledIcon = $("<i>", { let $wfEnabledIcon = $("<i>", {
class: `alignRight fa ${wfEnabled ? "fa-dot-circle" : "fa-circle" }` class: `alignRight fa ${wfEnabled ? "fa-dot-circle" : "fa-circle" }`
}); });
let $wfHeaderLink = $("<a>", let $wfHeaderLink = $("<a>",
{ {
@@ -163,7 +165,7 @@ function generateWorkflowUI(wf, wfIndex) {
let $wfHeaderHeading = $("<h4>", let $wfHeaderHeading = $("<h4>",
{ {
class: "panel-title" class: "panel-title"
} }
).text(wf.name) ).text(wf.name)
@@ -176,34 +178,34 @@ function generateWorkflowUI(wf, wfIndex) {
let isOpen = panelState === "true"; // Convert stored string to boolean let isOpen = panelState === "true"; // Convert stored string to boolean
console.log(`panel isOpen: ${isOpen}` ); console.log(`panel isOpen: ${isOpen}` );
let $wfCollapsiblePanel = $("<div>", {
class: ` panel-collapse collapse ${isOpen ? 'in' : ''}`, let $wfCollapsiblePanel = $("<div>", {
id: `wf-${wfIndex}-collapsible-panel` class: ` panel-collapse collapse ${isOpen ? 'in' : ''}`,
id: `wf-${wfIndex}-collapsible-panel`
}); });
let $wfEnabled = createEditableDropdown( let $wfEnabled = createEditableDropdown(
`[${wfIndex}].enabled`, `[${wfIndex}].enabled`,
getString("WF_Enabled"), getString("WF_Enabled"),
wfEnabledOptions, wfEnabledOptions,
wfEnabled ? "Yes" :"No", wfEnabled ? "Yes" :"No",
`wf-${wfIndex}-enabled` `wf-${wfIndex}-enabled`
); );
$wfCollapsiblePanel.append($wfEnabled) $wfCollapsiblePanel.append($wfEnabled)
let $wfNameInput = createEditableInput( let $wfNameInput = createEditableInput(
`[${wfIndex}].name`, `[${wfIndex}].name`,
getString("WF_Name"), getString("WF_Name"),
wf.name, wf.name,
`wf-${wfIndex}-name`, `wf-${wfIndex}-name`,
"workflow-name-input" "workflow-name-input"
); );
$wfCollapsiblePanel.append($wfNameInput) $wfCollapsiblePanel.append($wfNameInput)
let $triggersIcon = $("<i>", { let $triggersIcon = $("<i>", {
class: "fa-solid fa-bolt" class: "fa-solid fa-bolt"
}); });
@@ -221,34 +223,34 @@ function generateWorkflowUI(wf, wfIndex) {
).append($triggerTitle); ).append($triggerTitle);
let $triggerTypeDropdown = createEditableDropdown( let $triggerTypeDropdown = createEditableDropdown(
`[${wfIndex}].trigger.object_type`, `[${wfIndex}].trigger.object_type`,
getString("WF_Trigger_type"), getString("WF_Trigger_type"),
triggerTypes, triggerTypes,
wf.trigger.object_type, wf.trigger.object_type,
`wf-${wfIndex}-trigger-object-type` `wf-${wfIndex}-trigger-object-type`
); );
let $eventTypeDropdown = createEditableDropdown( let $eventTypeDropdown = createEditableDropdown(
`[${wfIndex}].trigger.event_type`, `[${wfIndex}].trigger.event_type`,
getString("WF_Trigger_event_type"), getString("WF_Trigger_event_type"),
triggerEvents, triggerEvents,
wf.trigger.event_type, wf.trigger.event_type,
`wf-${wfIndex}-trigger-event-type` `wf-${wfIndex}-trigger-event-type`
); );
let $triggerIcon = $("<i>", { let $triggerIcon = $("<i>", {
class: "fa-solid fa-bolt bckg-icon-2-line" class: "fa-solid fa-bolt bckg-icon-2-line"
}); });
$triggerSection.append($triggerIcon); $triggerSection.append($triggerIcon);
$triggerSection.append($triggerTypeDropdown); $triggerSection.append($triggerTypeDropdown);
$triggerSection.append($eventTypeDropdown); $triggerSection.append($eventTypeDropdown);
$wfCollapsiblePanel.append($triggerSection); $wfCollapsiblePanel.append($triggerSection);
// Conditions // Conditions
let $conditionsIcon = $("<i>", { let $conditionsIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270" class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270"
}); });
@@ -262,10 +264,10 @@ function generateWorkflowUI(wf, wfIndex) {
$conditionsContainer.append(renderConditions(wfIndex, `[${wfIndex}]`, 0, wf.conditions)); $conditionsContainer.append(renderConditions(wfIndex, `[${wfIndex}]`, 0, wf.conditions));
$wfCollapsiblePanel.append($conditionsContainer); $wfCollapsiblePanel.append($conditionsContainer);
let $actionsIcon = $("<i>", { let $actionsIcon = $("<i>", {
class: "fa-solid fa-person-running fa-flip-horizontal" class: "fa-solid fa-person-running fa-flip-horizontal"
}); });
@@ -295,10 +297,10 @@ function generateWorkflowUI(wf, wfIndex) {
// Dropdown for action.type // Dropdown for action.type
let $actionDropdown= createEditableDropdown( let $actionDropdown= createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].type`, `[${wfIndex}].actions[${actionIndex}].type`,
getString("WF_Action_type"), getString("WF_Action_type"),
actionTypes, actionTypes,
action.type, action.type,
`wf-${wfIndex}-actionIndex-${actionIndex}-type` `wf-${wfIndex}-actionIndex-${actionIndex}-type`
); );
@@ -314,23 +316,23 @@ function generateWorkflowUI(wf, wfIndex) {
// Dropdown for action.field // Dropdown for action.field
let $fieldDropdown = createEditableDropdown( let $fieldDropdown = createEditableDropdown(
`[${wfIndex}].actions[${actionIndex}].field`, `[${wfIndex}].actions[${actionIndex}].field`,
getString("WF_Action_field"), getString("WF_Action_field"),
fieldOptions, fieldOptions,
action.field, action.field,
`wf-${wfIndex}-actionIndex-${actionIndex}-field` `wf-${wfIndex}-actionIndex-${actionIndex}-field`
); );
// Textbox for action.value // Textbox for action.value
let $actionValueInput = createEditableInput( let $actionValueInput = createEditableInput(
`[${wfIndex}].actions[${actionIndex}].value`, `[${wfIndex}].actions[${actionIndex}].value`,
getString("WF_Action_value"), getString("WF_Action_value"),
action.value, action.value,
`wf-${wfIndex}-actionIndex-${actionIndex}-value`, `wf-${wfIndex}-actionIndex-${actionIndex}-value`,
"action-value-input" "action-value-input"
); );
$actionEl.append($fieldDropdown); $actionEl.append($fieldDropdown);
$actionEl.append($actionValueInput); $actionEl.append($actionValueInput);
@@ -340,7 +342,7 @@ function generateWorkflowUI(wf, wfIndex) {
let $actionRemoveButtonWrap = $("<div>", { class: "button-container col-sm-1 col-sx-12" }); let $actionRemoveButtonWrap = $("<div>", { class: "button-container col-sm-1 col-sx-12" });
let $actionRemoveIcon = $("<i>", { let $actionRemoveIcon = $("<i>", {
class: "fa-solid fa-trash" class: "fa-solid fa-trash"
}); });
@@ -353,14 +355,14 @@ function generateWorkflowUI(wf, wfIndex) {
$actionRemoveButtonWrap.append($actionRemoveButton); $actionRemoveButtonWrap.append($actionRemoveButton);
let $actionIcon = $("<i>", { let $actionIcon = $("<i>", {
class: `fa-solid fa-person-running fa-flip-horizontal bckg-icon-${numberOfLines}-line ` class: `fa-solid fa-person-running fa-flip-horizontal bckg-icon-${numberOfLines}-line `
}); });
$actionEl.prepend($actionIcon) $actionEl.prepend($actionIcon)
$actionElWrap.append($actionEl) $actionElWrap.append($actionEl)
$actionElWrap.append($actionRemoveButtonWrap) $actionElWrap.append($actionRemoveButtonWrap)
$actionsContainer.append($actionElWrap); $actionsContainer.append($actionElWrap);
@@ -370,7 +372,7 @@ function generateWorkflowUI(wf, wfIndex) {
// add action button // add action button
let $actionAddButtonWrap = $("<div>", { class: "button-container col-sm-12 col-sx-12" }); let $actionAddButtonWrap = $("<div>", { class: "button-container col-sm-12 col-sx-12" });
let $actionAddIcon = $("<i>", { let $actionAddIcon = $("<i>", {
class: "fa-solid fa-plus" class: "fa-solid fa-plus"
}); });
let $actionAddButton = $("<div>", { let $actionAddButton = $("<div>", {
@@ -382,10 +384,10 @@ function generateWorkflowUI(wf, wfIndex) {
$actionAddButtonWrap.append($actionAddButton) $actionAddButtonWrap.append($actionAddButton)
$actionsContainer.append($actionAddButtonWrap) $actionsContainer.append($actionAddButtonWrap)
let $wfRemoveButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" }); let $wfRemoveButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfRemoveIcon = $("<i>", { let $wfRemoveIcon = $("<i>", {
class: "fa-solid fa-trash" class: "fa-solid fa-trash"
}); });
@@ -399,7 +401,7 @@ function generateWorkflowUI(wf, wfIndex) {
let $wfDuplicateButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" }); let $wfDuplicateButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfDuplicateIcon = $("<i>", { let $wfDuplicateIcon = $("<i>", {
class: "fa-solid fa-copy" class: "fa-solid fa-copy"
}); });
@@ -412,7 +414,7 @@ function generateWorkflowUI(wf, wfIndex) {
let $wfExportButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" }); let $wfExportButtonWrap = $("<div>", { class: "button-container col-sm-4 col-sx-12" });
let $wfExportIcon = $("<i>", { let $wfExportIcon = $("<i>", {
class: "fa-solid fa-file-export" class: "fa-solid fa-file-export"
}); });
@@ -422,13 +424,13 @@ function generateWorkflowUI(wf, wfIndex) {
}) })
.append($wfExportIcon) // Add icon .append($wfExportIcon) // Add icon
.append(` ${getString("WF_Export")}`); // Add text .append(` ${getString("WF_Export")}`); // Add text
$wfCollapsiblePanel.append($actionsContainer); $wfCollapsiblePanel.append($actionsContainer);
$wfCollapsiblePanel.append($wfDuplicateButtonWrap.append($wfDuplicateButton)) $wfCollapsiblePanel.append($wfDuplicateButtonWrap.append($wfDuplicateButton))
$wfCollapsiblePanel.append($wfExportButtonWrap.append($wfExportButton)) $wfCollapsiblePanel.append($wfExportButtonWrap.append($wfExportButton))
$wfCollapsiblePanel.append($wfRemoveButtonWrap.append($wfRemoveButton)) $wfCollapsiblePanel.append($wfRemoveButtonWrap.append($wfRemoveButton))
$wfContainer.append($wfCollapsiblePanel) $wfContainer.append($wfCollapsiblePanel)
@@ -439,24 +441,24 @@ function generateWorkflowUI(wf, wfIndex) {
// -------------------------------------- // --------------------------------------
// Render conditions recursively // Render conditions recursively
function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, conditions) { function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, conditions) {
let $conditionList = $("<div>", { let $conditionList = $("<div>", {
class: "condition-list panel col-sm-12 col-sx-12", class: "condition-list panel col-sm-12 col-sx-12",
parentIndexPath: parentIndexPath parentIndexPath: parentIndexPath
}); });
lastConditionIndex = 0 lastConditionIndex = 0
let $conditionListWrap = $("<div>", { let $conditionListWrap = $("<div>", {
class: `condition-list-wrap ${conditionGroupsIndex==0?"col-sm-12":"col-sm-11"} col-sx-12`, class: `condition-list-wrap ${conditionGroupsIndex==0?"col-sm-12":"col-sm-11"} col-sx-12`,
conditionGroupsIndex: conditionGroupsIndex conditionGroupsIndex: conditionGroupsIndex
}); });
let $deleteConditionGroupWrap = $("<div>", { let $deleteConditionGroupWrap = $("<div>", {
class: "condition-group-wrap-del col-sm-1 col-sx-12" class: "condition-group-wrap-del col-sm-1 col-sx-12"
}); });
$.each(conditions, function (conditionIndex, condition) { $.each(conditions, function (conditionIndex, condition) {
let currentPath = `${parentIndexPath}.conditions[${conditionIndex}]`; let currentPath = `${parentIndexPath}.conditions[${conditionIndex}]`;
if (condition.logic) { if (condition.logic) {
@@ -467,16 +469,16 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
); );
let $logicDropdown = createEditableDropdown( let $logicDropdown = createEditableDropdown(
`${currentPath}.logic`, `${currentPath}.logic`,
getString("WF_Conditions_logic_rules"), getString("WF_Conditions_logic_rules"),
["AND", "OR"], ["AND", "OR"],
condition.logic, condition.logic,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-logic` // id `wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-logic` // id
); );
$nestedCondition.append($logicDropdown); $nestedCondition.append($logicDropdown);
$conditionListNested = renderConditions(wfIndex, currentPath, conditionGroupsIndex+1, condition.conditions) $conditionListNested = renderConditions(wfIndex, currentPath, conditionGroupsIndex+1, condition.conditions)
$nestedCondition.append($conditionListNested); // Recursive call for nested conditions $nestedCondition.append($conditionListNested); // Recursive call for nested conditions
@@ -484,7 +486,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
} else { } else {
// INDIVIDUAL CONDITIONS // INDIVIDUAL CONDITIONS
let $conditionIcon = $("<i>", { let $conditionIcon = $("<i>", {
class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270 bckg-icon-3-line " class: "fa-solid fa-arrows-split-up-and-left fa-rotate-270 bckg-icon-3-line "
}); });
@@ -505,27 +507,27 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Create dropdown for condition field // Create dropdown for condition field
let $fieldDropdown = createEditableDropdown( let $fieldDropdown = createEditableDropdown(
`${currentPath}.field`, `${currentPath}.field`,
getString("WF_Condition_field"), getString("WF_Condition_field"),
fieldOptions, fieldOptions,
condition.field, condition.field,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-field` `wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-field`
); );
// Create dropdown for operator // Create dropdown for operator
let $operatorDropdown = createEditableDropdown( let $operatorDropdown = createEditableDropdown(
`${currentPath}.operator`, `${currentPath}.operator`,
getString("WF_Condition_operator"), getString("WF_Condition_operator"),
operatorTypes, operatorTypes,
condition.operator, condition.operator,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-operator` `wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-operator`
); );
// Editable input for condition value // Editable input for condition value
let $editableInput = createEditableInput( let $editableInput = createEditableInput(
`${currentPath}.value`, `${currentPath}.value`,
getString("WF_Condition_value"), getString("WF_Condition_value"),
condition.value, condition.value,
`wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-value`, `wf-${wfIndex}-${currentPath.replace(/\./g, "-")}-value`,
"condition-value-input" "condition-value-input"
); );
@@ -535,7 +537,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
$conditionItemsWrap.append($editableInput); // Append editable input for condition value $conditionItemsWrap.append($editableInput); // Append editable input for condition value
let $conditionRemoveButtonWrap = $("<div>", { class: "button-container col-sm-1 col-sx-12" }); let $conditionRemoveButtonWrap = $("<div>", { class: "button-container col-sm-1 col-sx-12" });
let $conditionRemoveButtonIcon = $("<i>", { let $conditionRemoveButtonIcon = $("<i>", {
class: "fa-solid fa-trash" class: "fa-solid fa-trash"
}); });
let $conditionRemoveButton = $("<div>", { let $conditionRemoveButton = $("<div>", {
@@ -549,7 +551,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
$conditionItem.append($conditionItemsWrap); $conditionItem.append($conditionItemsWrap);
$conditionItem.append($conditionRemoveButtonWrap); $conditionItem.append($conditionRemoveButtonWrap);
$conditionList.append($conditionItem); $conditionList.append($conditionItem);
} }
lastConditionIndex = conditionIndex lastConditionIndex = conditionIndex
@@ -562,7 +564,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
if (conditionGroupsIndex != 0) { if (conditionGroupsIndex != 0) {
// Add Condition button // Add Condition button
let $conditionAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" }); let $conditionAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" });
let $conditionAddIcon = $("<i>", { let $conditionAddIcon = $("<i>", {
class: "fa-solid fa-plus" class: "fa-solid fa-plus"
}); });
let $conditionAddButton = $("<div>", { let $conditionAddButton = $("<div>", {
@@ -574,7 +576,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Remove Condition Group button // Remove Condition Group button
let $conditionGroupRemoveWrap = $("<div>", { class: "button-container col-sx-12" }); let $conditionGroupRemoveWrap = $("<div>", { class: "button-container col-sx-12" });
let $conditionGroupRemoveIcon = $("<i>", { let $conditionGroupRemoveIcon = $("<i>", {
class: "fa-solid fa-trash" class: "fa-solid fa-trash"
}); });
let $conditionGroupRemoveButton = $("<div>", { let $conditionGroupRemoveButton = $("<div>", {
@@ -592,7 +594,7 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
// Add Condition Group button // Add Condition Group button
let $conditionsGroupAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" }); let $conditionsGroupAddWrap = $("<div>", { class: "button-container col-sm-6 col-sx-12" });
let $conditionsGroupAddIcon = $("<i>", { let $conditionsGroupAddIcon = $("<i>", {
class: "fa-solid fa-plus" class: "fa-solid fa-plus"
}); });
let $conditionsGroupAddButton = $("<div>", { let $conditionsGroupAddButton = $("<div>", {
@@ -606,9 +608,9 @@ function renderConditions(wfIndex, parentIndexPath, conditionGroupsIndex, condit
$conditionList.append($addButtonWrap); $conditionList.append($addButtonWrap);
$conditionListWrap.append($conditionList) $conditionListWrap.append($conditionList)
let $res = $("<div>", { let $res = $("<div>", {
class: "condition-list-res col-sm-12 col-sx-12" class: "condition-list-res col-sm-12 col-sx-12"
}); });
@@ -627,8 +629,8 @@ function createEditableDropdown(jsonPath, labelText, options, selectedValue, id)
class: "form-group col-sm-12 col-sx-12" class: "form-group col-sm-12 col-sx-12"
}); });
let $label = $("<label>", { let $label = $("<label>", {
for: id, for: id,
class: "col-sm-4 col-xs-12 control-label " class: "col-sm-4 col-xs-12 control-label "
}).text(labelText); }).text(labelText);
@@ -643,7 +645,7 @@ function createEditableDropdown(jsonPath, labelText, options, selectedValue, id)
jsonPath: jsonPath, jsonPath: jsonPath,
class: "form-control col-sm-8 col-xs-12" class: "form-control col-sm-8 col-xs-12"
}); });
// Add options to the select dropdown // Add options to the select dropdown
$.each(options, function (_, option) { $.each(options, function (_, option) {
@@ -659,7 +661,7 @@ function createEditableDropdown(jsonPath, labelText, options, selectedValue, id)
let newValue = $select.val(); let newValue = $select.val();
console.log(`Selected new value: ${newValue}`); console.log(`Selected new value: ${newValue}`);
console.log(`Selected new jsonPath: ${$select.attr("jsonPath")}`); console.log(`Selected new jsonPath: ${$select.attr("jsonPath")}`);
updateWorkflowObject(newValue, $select.attr("jsonPath")); // Call the onSave callback with the new value updateWorkflowObject(newValue, $select.attr("jsonPath")); // Call the onSave callback with the new value
}); });
@@ -678,8 +680,8 @@ function createEditableInput(jsonPath, labelText, value, id, className = "") {
class: "form-group col-sm-12 col-xs-12" class: "form-group col-sm-12 col-xs-12"
}); });
let $label = $("<label>", { let $label = $("<label>", {
for: id, for: id,
class: "col-sm-4 col-xs-12 control-label " class: "col-sm-4 col-xs-12 control-label "
}).text(labelText); }).text(labelText);
@@ -689,7 +691,7 @@ function createEditableInput(jsonPath, labelText, value, id, className = "") {
}); });
// console.log(jsonPath); // console.log(jsonPath);
let $input = $("<input>", { let $input = $("<input>", {
type: "text", type: "text",
jsonPath: jsonPath, jsonPath: jsonPath,
@@ -706,11 +708,11 @@ function createEditableInput(jsonPath, labelText, value, id, className = "") {
// Trigger onSave when the user presses Enter or the input loses focus // Trigger onSave when the user presses Enter or the input loses focus
$input.on("blur keyup", function (e) { $input.on("blur keyup", function (e) {
if (e.type === "blur" || e.key === "Enter") { if (e.type === "blur" || e.key === "Enter") {
let newValue = $input.val(); let newValue = $input.val();
console.log(`Selected new value: ${newValue}`); console.log(`Selected new value: ${newValue}`);
updateWorkflowObject(newValue, $input.attr("jsonPath")); // Call the onSave callback with the new value updateWorkflowObject(newValue, $input.attr("jsonPath")); // Call the onSave callback with the new value
} }
}); });
@@ -763,15 +765,15 @@ function recursiveUpdate(current, tokens, newValue) {
current[key] = newValue; current[key] = newValue;
return; return;
} }
const token = tokens[0]; const token = tokens[0];
// If the next level does not exist, optionally create it. // If the next level does not exist, optionally create it.
if (current[token] === undefined) { if (current[token] === undefined) {
// Determine if the next token is an array index or a property. // Determine if the next token is an array index or a property.
current[token] = typeof tokens[1] === 'number' ? [] : {}; current[token] = typeof tokens[1] === 'number' ? [] : {};
} }
// Recursively update the next level. // Recursively update the next level.
recursiveUpdate(current[token], tokens.slice(1), newValue); recursiveUpdate(current[token], tokens.slice(1), newValue);
} }
@@ -817,7 +819,7 @@ function addWorkflow(workflows) {
// --------------------------------------------------- // ---------------------------------------------------
// Function to remove a Workflow // Function to remove a Workflow
function removeWorkflow(workflows, wfIndex) { function removeWorkflow(workflows, wfIndex) {
showModalWarning ('<?= lang('WF_Remove');?>', '<?= lang('WF_Remove_Copy');?>', showModalWarning ('<?= lang('WF_Remove');?>', '<?= lang('WF_Remove_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', `executeRemoveWorkflow`, wfIndex); '<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Delete');?>', `executeRemoveWorkflow`, wfIndex);
} }
@@ -825,7 +827,7 @@ function removeWorkflow(workflows, wfIndex) {
// --------------------------------------------------- // ---------------------------------------------------
// Function to execute the remove of a Workflow // Function to execute the remove of a Workflow
function executeRemoveWorkflow() { function executeRemoveWorkflow() {
workflows = getWorkflowsJson() workflows = getWorkflowsJson()
workflows.splice($('#modal-warning').attr("data-myparam-triggered-by"), 1); workflows.splice($('#modal-warning').attr("data-myparam-triggered-by"), 1);
@@ -839,7 +841,7 @@ function executeRemoveWorkflow() {
// --------------------------------------------------- // ---------------------------------------------------
// Function to duplicate a Workflow // Function to duplicate a Workflow
function duplicateWorkflow(workflows, wfIndex) { function duplicateWorkflow(workflows, wfIndex) {
workflows.push(workflows[wfIndex]) workflows.push(workflows[wfIndex])
updateWorkflowsJson(workflows) updateWorkflowsJson(workflows)
@@ -852,7 +854,7 @@ function duplicateWorkflow(workflows, wfIndex) {
// Function to export a Workflow // Function to export a Workflow
function exportWorkflow(workflows, wfIndex) { function exportWorkflow(workflows, wfIndex) {
// Add new icon as base64 string // Add new icon as base64 string
showModalInput ('<i class="fa fa-file-export pointer"></i> <?= lang('WF_Export');?>', '<?= lang('WF_Export_Copy');?>', showModalInput ('<i class="fa fa-file-export pointer"></i> <?= lang('WF_Export');?>', '<?= lang('WF_Export_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', null, null, JSON.stringify(workflows[wfIndex], null, 2)); '<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', null, null, JSON.stringify(workflows[wfIndex], null, 2));
} }
@@ -861,18 +863,18 @@ showModalInput ('<i class="fa fa-file-export pointer"></i> <?= lang('WF_Export'
// Function to import a Workflow // Function to import a Workflow
function importWorkflow(workflows, wfIndex) { function importWorkflow(workflows, wfIndex) {
// Add new icon as base64 string // Add new icon as base64 string
showModalInput ('<i class="fa fa-file-import pointer"></i> <?= lang('WF_Import');?>', '<?= lang('WF_Import_Copy');?>', showModalInput ('<i class="fa fa-file-import pointer"></i> <?= lang('WF_Import');?>', '<?= lang('WF_Import_Copy');?>',
'<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'importWorkflowExecute', null, "" ); '<?= lang('Gen_Cancel');?>', '<?= lang('Gen_Okay');?>', 'importWorkflowExecute', null, "" );
} }
function importWorkflowExecute() function importWorkflowExecute()
{ {
var json = JSON.parse($('#modal-input-textarea').val()); var json = JSON.parse($('#modal-input-textarea').val());
workflows = getWorkflowsJson() workflows = getWorkflowsJson()
workflows.push(json); workflows.push(json);
updateWorkflowsJson(workflows) updateWorkflowsJson(workflows)
@@ -998,7 +1000,7 @@ function removeAction(workflows, wfIndex, actionIndex) {
} }
console.log(actionIndex); console.log(actionIndex);
// Remove the specified condition // Remove the specified condition
target.actions.splice(actionIndex, 1); target.actions.splice(actionIndex, 1);
@@ -1016,15 +1018,15 @@ function removeConditionGroup(workflows, wfIndex, parentIndexPath) {
// Split the path by dots // Split the path by dots
const parts = parentIndexPath.split('.'); const parts = parentIndexPath.split('.');
// Extract the last part (index) // Extract the last part (index)
const lastIndex = parts.pop().replace(/\D/g, ''); // Remove any non-numeric characters const lastIndex = parts.pop().replace(/\D/g, ''); // Remove any non-numeric characters
// Rebuild the path without the last part // Rebuild the path without the last part
const newPath = parts.join('.'); const newPath = parts.join('.');
console.log(parentIndexPath); console.log(parentIndexPath);
console.log(newPath); console.log(newPath);
// Navigate to the target nested object // Navigate to the target nested object
let target = getNestedObject(workflows, newPath); let target = getNestedObject(workflows, newPath);
@@ -1074,22 +1076,22 @@ function getNestedObject(obj, path) {
function getWorkflowsJson() function getWorkflowsJson()
{ {
return workflows = JSON.parse(getCache('workflows')) || getEmptyWorkflowJson(); return workflows = JSON.parse(getCache('workflows')) || getEmptyWorkflowJson();
} }
// --------------------------------------------------- // ---------------------------------------------------
// Get workflows JSON // Get workflows JSON
function updateWorkflowsJson(workflows) function updateWorkflowsJson(workflows)
{ {
// Store the updated workflows object back into cache // Store the updated workflows object back into cache
setCache('workflows', JSON.stringify(workflows)); setCache('workflows', JSON.stringify(workflows));
} }
// --------------------------------------------------- // ---------------------------------------------------
// Get empty workflow JSON // Get empty workflow JSON
function getEmptyWorkflowJson() function getEmptyWorkflowJson()
{ {
return emptyWorkflow; return emptyWorkflow;
} }
// --------------------------------------------------- // ---------------------------------------------------
// Save workflows JSON // Save workflows JSON
@@ -1100,11 +1102,11 @@ function saveWorkflows()
// import // import
$.post('php/server/query_replace_config.php', { base64data: appConfBase64, fileName: "workflows.json" }, function(msg) { $.post('php/server/query_replace_config.php', { base64data: appConfBase64, fileName: "workflows.json" }, function(msg) {
console.log(msg); console.log(msg);
// showMessage(msg); // showMessage(msg);
write_notification(`[WF]: ${msg}`, 'interrupt'); write_notification(`[WF]: ${msg}`, 'interrupt');
}); });
} }
// --------------------------------------------------- // ---------------------------------------------------
// Event listeners // Event listeners
@@ -1154,7 +1156,7 @@ $(document).on("click", ".remove-condition", function () {
let wfIndex = $(this).attr("wfindex"); let wfIndex = $(this).attr("wfindex");
let parentIndexPath = $(this).attr("parentIndexPath"); let parentIndexPath = $(this).attr("parentIndexPath");
let conditionIndex = parseInt($(this).attr("conditionIndex"), 10); let conditionIndex = parseInt($(this).attr("conditionIndex"), 10);
removeCondition(getWorkflowsJson(), wfIndex, parentIndexPath, conditionIndex); removeCondition(getWorkflowsJson(), wfIndex, parentIndexPath, conditionIndex);
}); });
@@ -1162,7 +1164,7 @@ $(document).on("click", ".remove-condition", function () {
$(document).on("click", ".remove-action", function () { $(document).on("click", ".remove-action", function () {
let wfIndex = $(this).attr("wfindex"); let wfIndex = $(this).attr("wfindex");
let actionIndex = $(this).attr("actionIndex"); let actionIndex = $(this).attr("actionIndex");
removeAction(getWorkflowsJson(), wfIndex, actionIndex); removeAction(getWorkflowsJson(), wfIndex, actionIndex);
}); });