mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #4797 from GogoVega/config-node-history
Add config node to `RED.history` and handle `changed` prop
This commit is contained in:
		| @@ -808,6 +808,17 @@ RED.editor = (function() { | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             const oldCreds = {}; | ||||
|             if (editing_node._def.credentials) { | ||||
|                 for (const prop in editing_node._def.credentials) { | ||||
|                     if (Object.prototype.hasOwnProperty.call(editing_node._def.credentials, prop)) { | ||||
|                         if (prop in editing_node.credentials) { | ||||
|                             oldCreds[prop] = editing_node.credentials[prop]; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 const rc = editing_node._def.oneditsave.call(editing_node); | ||||
|                 if (rc === true) { | ||||
| @@ -839,6 +850,21 @@ RED.editor = (function() { | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (editing_node._def.credentials) { | ||||
|                 for (const prop in editing_node._def.credentials) { | ||||
|                     if (Object.prototype.hasOwnProperty.call(editing_node._def.credentials, prop)) { | ||||
|                         if (oldCreds[prop] !== editing_node.credentials[prop]) { | ||||
|                             if (editing_node.credentials[prop] === '__PWRD__') { | ||||
|                                 continue; | ||||
|                             } | ||||
|                             editState.changes.credentials = editState.changes.credentials || {}; | ||||
|                             editState.changes.credentials[prop] = oldCreds[prop]; | ||||
|                             editState.changed = true; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -1481,134 +1507,181 @@ RED.editor = (function() { | ||||
|             }, | ||||
|             { | ||||
|                 id: "node-config-dialog-ok", | ||||
|                 text: adding?RED._("editor.configAdd"):RED._("editor.configUpdate"), | ||||
|                 text: adding ? RED._("editor.configAdd") : RED._("editor.configUpdate"), | ||||
|                 class: "primary", | ||||
|                 click: function() { | ||||
|                     var editState = { | ||||
|                     // TODO: Already defined | ||||
|                     const configProperty = name; | ||||
|                     const configType = type; | ||||
|                     const configTypeDef = RED.nodes.getType(configType); | ||||
|  | ||||
|                     const wasChanged = editing_config_node.changed; | ||||
|                     const editState = { | ||||
|                         changes: {}, | ||||
|                         changed: false, | ||||
|                         outputMap: null | ||||
|                     }; | ||||
|                     var configProperty = name; | ||||
|                     var configId = editing_config_node.id; | ||||
|                     var configType = type; | ||||
|                     var configAdding = adding; | ||||
|                     var configTypeDef = RED.nodes.getType(configType); | ||||
|                     var d; | ||||
|                     var input; | ||||
|                      | ||||
|                     // Call `oneditsave` and search for changes | ||||
|                     handleEditSave(editing_config_node, editState); | ||||
|  | ||||
|                     if (configTypeDef.oneditsave) { | ||||
|                         try { | ||||
|                             configTypeDef.oneditsave.call(editing_config_node); | ||||
|                         } catch(err) { | ||||
|                             console.warn("oneditsave",editing_config_node.id,editing_config_node.type,err.toString()); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     for (d in configTypeDef.defaults) { | ||||
|                         if (configTypeDef.defaults.hasOwnProperty(d)) { | ||||
|                             var newValue; | ||||
|                             input = $("#node-config-input-"+d); | ||||
|                             if (input.attr('type') === "checkbox") { | ||||
|                                 newValue = input.prop('checked'); | ||||
|                             } else if ("format" in configTypeDef.defaults[d] && configTypeDef.defaults[d].format !== "" && input[0].nodeName === "DIV") { | ||||
|                                 newValue = input.text(); | ||||
|                             } else { | ||||
|                                 newValue = input.val(); | ||||
|                             } | ||||
|                             if (newValue != null && newValue !== editing_config_node[d]) { | ||||
|                                 if (editing_config_node._def.defaults[d].type) { | ||||
|                                     if (newValue == "_ADD_") { | ||||
|                                         newValue = ""; | ||||
|                                     } | ||||
|                                     // Change to a related config node | ||||
|                                     var configNode = RED.nodes.node(editing_config_node[d]); | ||||
|                                     if (configNode) { | ||||
|                                         var users = configNode.users; | ||||
|                                         users.splice(users.indexOf(editing_config_node),1); | ||||
|                                         RED.events.emit("nodes:change",configNode); | ||||
|                                     } | ||||
|                                     configNode = RED.nodes.node(newValue); | ||||
|                                     if (configNode) { | ||||
|                                         configNode.users.push(editing_config_node); | ||||
|                                         RED.events.emit("nodes:change",configNode); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 editing_config_node[d] = newValue; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     activeEditPanes.forEach(function(pane) { | ||||
|                     // Search for changes in the edit box (panes) | ||||
|                     activeEditPanes.forEach(function (pane) { | ||||
|                         if (pane.apply) { | ||||
|                             pane.apply.call(pane, editState); | ||||
|                         } | ||||
|                     }) | ||||
|                     }); | ||||
|  | ||||
|                     editing_config_node.label = configTypeDef.label; | ||||
|  | ||||
|                     var scope = $("#red-ui-editor-config-scope").val(); | ||||
|                     editing_config_node.z = scope; | ||||
|                     // TODO: Why? | ||||
|                     editing_config_node.label = configTypeDef.label | ||||
|  | ||||
|                     // Check if disabled has changed | ||||
|                     if ($("#node-config-input-node-disabled").prop('checked')) { | ||||
|                         if (editing_config_node.d !== true) { | ||||
|                             editState.changes.d = editing_config_node.d; | ||||
|                             editState.changed = true; | ||||
|                             editing_config_node.d = true; | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (editing_config_node.d === true) { | ||||
|                             editState.changes.d = editing_config_node.d; | ||||
|                             editState.changed = true; | ||||
|                             delete editing_config_node.d; | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     // NOTE: must be undefined if no scope used | ||||
|                     const scope = $("#red-ui-editor-config-scope").val() || undefined; | ||||
|  | ||||
|                     // Check if the scope has changed | ||||
|                     if (editing_config_node.z !== scope) { | ||||
|                         editState.changes.z = editing_config_node.z; | ||||
|                         editState.changed = true; | ||||
|                         editing_config_node.z = scope; | ||||
|                     } | ||||
|  | ||||
|                     // Search for nodes that use this config node that are no longer | ||||
|                     // in scope, so must be removed | ||||
|                     const historyEvents = []; | ||||
|                     if (scope) { | ||||
|                         // Search for nodes that use this one that are no longer | ||||
|                         // in scope, so must be removed | ||||
|                         editing_config_node.users = editing_config_node.users.filter(function(n) { | ||||
|                             var keep = true; | ||||
|                             for (var d in n._def.defaults) { | ||||
|                                 if (n._def.defaults.hasOwnProperty(d)) { | ||||
|                                     if (n._def.defaults[d].type === editing_config_node.type && | ||||
|                                         n[d] === editing_config_node.id && | ||||
|                                         n.z !== scope) { | ||||
|                                             keep = false; | ||||
|                                             // Remove the reference to this node | ||||
|                                             // and revalidate | ||||
|                                             n[d] = null; | ||||
|                                             n.dirty = true; | ||||
|                                             n.changed = true; | ||||
|                                             validateNode(n); | ||||
|                         const newUsers = editing_config_node.users.filter(function (node) { | ||||
|                             let keepNode = false; | ||||
|                             let nodeModified = null; | ||||
|  | ||||
|                             for (const d in node._def.defaults) { | ||||
|                                 if (node._def.defaults.hasOwnProperty(d)) { | ||||
|                                     if (node._def.defaults[d].type === editing_config_node.type) { | ||||
|                                         if (node[d] === editing_config_node.id) { | ||||
|                                             if (node.z === editing_config_node.z) { | ||||
|                                                 // The node is kept only if at least one property uses | ||||
|                                                 // this config node in the correct scope. | ||||
|                                                 keepNode = true; | ||||
|                                             } else { | ||||
|                                                 if (!nodeModified) { | ||||
|                                                     nodeModified = { | ||||
|                                                         t: "edit", | ||||
|                                                         node: node, | ||||
|                                                         changes: { [d]: node[d] }, | ||||
|                                                         changed: node.changed, | ||||
|                                                         dirty: node.dirty | ||||
|                                                     }; | ||||
|                                                 } else { | ||||
|                                                     nodeModified.changes[d] = node[d]; | ||||
|                                                 } | ||||
|  | ||||
|                                                 // Remove the reference to the config node | ||||
|                                                 node[d] = ""; | ||||
|                                             } | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             return keep; | ||||
|                         }); | ||||
|                     } | ||||
|  | ||||
|                     if (configAdding) { | ||||
|                         RED.nodes.add(editing_config_node); | ||||
|                     } | ||||
|  | ||||
|                     validateNode(editing_config_node); | ||||
|                     var validatedNodes = {}; | ||||
|                     validatedNodes[editing_config_node.id] = true; | ||||
|  | ||||
|                     var userStack = editing_config_node.users.slice(); | ||||
|                     while(userStack.length > 0) { | ||||
|                         var user = userStack.pop(); | ||||
|                         if (!validatedNodes[user.id]) { | ||||
|                             validatedNodes[user.id] = true; | ||||
|                             if (user.users) { | ||||
|                                 userStack = userStack.concat(user.users); | ||||
|                             // Add the node modified to the history | ||||
|                             if (nodeModified) { | ||||
|                                 historyEvents.push(nodeModified); | ||||
|                             } | ||||
|                             validateNode(user); | ||||
|  | ||||
|                             // Mark as changed and revalidate this node | ||||
|                             if (!keepNode) { | ||||
|                                 node.changed = true; | ||||
|                                 node.dirty = true; | ||||
|                                 validateNode(node); | ||||
|                                 RED.events.emit("nodes:change", node); | ||||
|                             } | ||||
|  | ||||
|                             return keepNode; | ||||
|                         }); | ||||
|  | ||||
|                         // Check if users are changed | ||||
|                         if (editing_config_node.users.length !== newUsers.length) { | ||||
|                             editState.changes.users = editing_config_node.users; | ||||
|                             editState.changed = true; | ||||
|                             editing_config_node.users = newUsers; | ||||
|                         } | ||||
|                     } | ||||
|                     RED.nodes.dirty(true); | ||||
|                     RED.view.redraw(true); | ||||
|                     if (!configAdding) { | ||||
|                         RED.events.emit("editor:save",editing_config_node); | ||||
|                         RED.events.emit("nodes:change",editing_config_node); | ||||
|  | ||||
|                     if (editState.changed) { | ||||
|                         // Set the congig node as changed | ||||
|                         editing_config_node.changed = true; | ||||
|                     } | ||||
|  | ||||
|                     // Now, validate the config node | ||||
|                     validateNode(editing_config_node); | ||||
|  | ||||
|                     // And validate nodes using this config node too | ||||
|                     const validatedNodes = new Set(); | ||||
|                     const userStack = editing_config_node.users.slice(); | ||||
|  | ||||
|                     validatedNodes.add(editing_config_node.id); | ||||
|                     while (userStack.length) { | ||||
|                         const node = userStack.pop(); | ||||
|                         if (!validatedNodes.has(node.id)) { | ||||
|                             validatedNodes.add(node.id); | ||||
|                             if (node.users) { | ||||
|                                 userStack.push(...node.users); | ||||
|                             } | ||||
|                             validateNode(node); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     let historyEvent = { | ||||
|                         t: "edit", | ||||
|                         node: editing_config_node, | ||||
|                         changes: editState.changes, | ||||
|                         changed: wasChanged, | ||||
|                         dirty: RED.nodes.dirty() | ||||
|                     }; | ||||
|  | ||||
|                     if (historyEvents.length) { | ||||
|                         // Need a multi events | ||||
|                         historyEvent = { | ||||
|                             t: "multi", | ||||
|                             events: [historyEvent].concat(historyEvents), | ||||
|                             dirty: historyEvent.dirty | ||||
|                         }; | ||||
|                     } | ||||
|  | ||||
|                     if (!adding) { | ||||
|                         // This event is triggered when the edit box is saved, | ||||
|                         // regardless of whether there are any modifications. | ||||
|                         RED.events.emit("editor:save", editing_config_node); | ||||
|                     } | ||||
|  | ||||
|                     if (editState.changed) { | ||||
|                         if (adding) { | ||||
|                             RED.history.push({ t: "add", nodes: [editing_config_node.id], dirty: RED.nodes.dirty() }); | ||||
|                             // Add the new config node and trigger the `nodes:add` event | ||||
|                             RED.nodes.add(editing_config_node); | ||||
|                         } else { | ||||
|                             RED.history.push(historyEvent); | ||||
|                             RED.events.emit("nodes:change", editing_config_node); | ||||
|                         } | ||||
|  | ||||
|                         RED.nodes.dirty(true); | ||||
|                         RED.view.redraw(true); | ||||
|                     } | ||||
|  | ||||
|                     RED.tray.close(function() { | ||||
|                         var filter = null; | ||||
|                         // when editing a config via subflow edit panel, the `configProperty` will not | ||||
|   | ||||
		Reference in New Issue
	
	Block a user