From 3d9bc265dde7a21f0e6aad83b89af967b10302cc Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:58:11 +0100 Subject: [PATCH 1/4] Handle users of env config nodes when adding/removing subflow node --- .../@node-red/editor-client/src/js/nodes.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js index 12e0a6ef1..ace560f4a 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js +++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -809,6 +809,20 @@ RED.nodes = (function() { if (sf) { sf.instances.splice(sf.instances.indexOf(node),1); } + + node.env?.forEach((prop) => { + if (prop.type === "conf-type" && prop.value) { + // Remove the node from the config node users + const configNode = getNode(prop.value); + if (configNode) { + if (configNode.users.indexOf(node) !== -1) { + configNode.users.splice(configNode.users.indexOf(node), 1); + RED.events.emit('nodes:change', configNode); + updatedConfigNode = true; + } + } + } + }); } if (updatedConfigNode) { @@ -2684,6 +2698,22 @@ RED.nodes = (function() { } } } + + // Subflows can have config node env + if (n.type.indexOf("subflow:") === 0) { + n.env?.forEach((prop) => { + if (prop.type === "conf-type" && prop.value) { + // Add the node to the config node users + const configNode = getNode(prop.value); + if (configNode) { + if (configNode.users.indexOf(n) === -1) { + configNode.users.push(n); + RED.events.emit('nodes:change', configNode); + } + } + } + }); + } } function flowVersion(version) { From f2d72b1050874f0d049d1bafef015bf13fd82d94 Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Thu, 7 Nov 2024 21:59:14 +0100 Subject: [PATCH 2/4] Handle users of env config nodes when saving subflow node config --- .../js/ui/editors/panes/envVarProperties.js | 31 ++++++++++++++++++- .../src/js/ui/editors/panes/properties.js | 1 + .../editor-client/src/js/ui/subflow.js | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/envVarProperties.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/envVarProperties.js index b004662be..0c7694126 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/envVarProperties.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/envVarProperties.js @@ -20,10 +20,31 @@ apply: function(editState) { var old_env = node.env; var new_env = []; + if (/^subflow:/.test(node.type)) { + // Get the list of environment variables from the node properties new_env = RED.subflow.exportSubflowInstanceEnv(node); } + if (old_env && old_env.length) { + old_env.forEach(function (prop) { + if (prop.type === "conf-type" && prop.value) { + const stillInUse = new_env?.some((p) => p.type === "conf-type" && p.name === prop.name && p.value === prop.value); + if (!stillInUse) { + // Remove the node from the config node users + // Only for empty value or modified + const configNode = RED.nodes.node(prop.value); + if (configNode) { + if (configNode.users.indexOf(node) !== -1) { + configNode.users.splice(configNode.users.indexOf(node), 1); + RED.events.emit('nodes:change', configNode) + } + } + } + } + }); + } + // Get the values from the Properties table tab var items = this.list.editableList('items'); items.each(function (i,el) { @@ -41,7 +62,6 @@ } }); - if (new_env && new_env.length > 0) { new_env.forEach(function(prop) { if (prop.type === "cred") { @@ -52,6 +72,15 @@ editState.changed = true; } delete prop.value; + } else if (prop.type === "conf-type" && prop.value) { + const configNode = RED.nodes.node(prop.value); + if (configNode) { + if (configNode.users.indexOf(node) === -1) { + // Add the node to the config node users + configNode.users.push(node); + RED.events.emit('nodes:change', configNode); + } + } } }); } diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js index cfa72be10..3f35d98a8 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/properties.js @@ -44,6 +44,7 @@ apply: function(editState) { var newValue; var d; + // If the node is a subflow, the node's properties (exepts name) are saved by `envProperties` if (node._def.defaults) { for (d in node._def.defaults) { if (node._def.defaults.hasOwnProperty(d)) { diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js index 751bf9cfb..3e1b9a410 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js @@ -1362,7 +1362,7 @@ RED.subflow = (function() { item.value = ""+input.prop("checked"); break; case "conf-types": - item.value = input.val() + item.value = input.val() === "_ADD_" ? "" : input.val(); item.type = "conf-type" } if (ui.type === "cred" || item.type !== data.parent.type || item.value !== data.parent.value) { From deccfdf654982fcb2127cb061978d2d36939a2fd Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:00:36 +0100 Subject: [PATCH 3/4] Handle users of env config nodes when undo subflow node changes --- .../@node-red/editor-client/src/js/history.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/history.js b/packages/node_modules/@node-red/editor-client/src/js/history.js index 2fa4e4427..60e71c391 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/history.js +++ b/packages/node_modules/@node-red/editor-client/src/js/history.js @@ -453,10 +453,48 @@ RED.history = (function() { RED.events.emit("nodes:change",newConfigNode); } }); + } else if (i === "env" && ev.node.type.indexOf("subflow:") === 0) { + // Subflow can have config node in node.env + let nodeList = ev.node.env || []; + nodeList = nodeList.reduce((list, prop) => { + if (prop.type === "conf-type" && prop.value) { + list.push(prop.value); + } + return list; + }, []); + + nodeList.forEach(function(id) { + const configNode = RED.nodes.node(id); + if (configNode) { + if (configNode.users.indexOf(ev.node) !== -1) { + configNode.users.splice(configNode.users.indexOf(ev.node), 1); + RED.events.emit("nodes:change", configNode); + } + } + }); + + nodeList = ev.changes.env || []; + nodeList = nodeList.reduce((list, prop) => { + if (prop.type === "conf-type" && prop.value) { + list.push(prop.value); + } + return list; + }, []); + + nodeList.forEach(function(id) { + const configNode = RED.nodes.node(id); + if (configNode) { + if (configNode.users.indexOf(ev.node) === -1) { + configNode.users.push(ev.node); + RED.events.emit("nodes:change", configNode); + } + } + }); } ev.node[i] = ev.changes[i]; } } + ev.node.dirty = true; ev.node.changed = ev.changed; From c8a02d53e89efe39605f859f29acc96f1884b1fe Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Thu, 7 Nov 2024 22:06:45 +0100 Subject: [PATCH 4/4] Ensure the node added to config node users is the proxy object --- packages/node_modules/@node-red/editor-client/src/js/nodes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js index ace560f4a..b62f54b27 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js +++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -702,11 +702,11 @@ RED.nodes = (function() { n["_"] = RED._; } if (n._def.category == "config") { - configNodes[n.id] = n; + configNodes[n.id] = newNode; } else { if (n.wires && (n.wires.length > n.outputs)) { n.outputs = n.wires.length; } n.dirty = true; - updateConfigNodeUsers(n); + updateConfigNodeUsers(newNode); if (n._def.category == "subflows" && typeof n.i === "undefined") { var nextId = 0; RED.nodes.eachNode(function(node) {