From b01fd24e153c1ada17d9644d984538bfa0d4c3b2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 29 Sep 2021 10:45:00 +0100 Subject: [PATCH] Add link-call node and add return mode for link-out node --- .../editor-client/src/js/ui/editor.js | 2 +- .../src/js/ui/editors/panes/appearance.js | 17 +-- .../editor-client/src/js/ui/view-tools.js | 6 +- .../@node-red/editor-client/src/js/ui/view.js | 8 +- .../src/sass/ui/common/treeList.scss | 3 +- .../@node-red/nodes/core/common/60-link.html | 110 +++++++++++++++--- .../@node-red/nodes/core/common/60-link.js | 63 +++++++++- .../@node-red/nodes/icons/link-call.svg | 5 + .../@node-red/nodes/icons/link-return.svg | 5 + .../nodes/locales/en-US/messages.json | 8 +- 10 files changed, 192 insertions(+), 35 deletions(-) create mode 100644 packages/node_modules/@node-red/nodes/icons/link-call.svg create mode 100644 packages/node_modules/@node-red/nodes/icons/link-return.svg diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js index b6c11e5f3..8dd0ee0d5 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js @@ -151,7 +151,7 @@ RED.editor = (function() { valid = definition[property].hasOwnProperty("required") && !definition[property].required; } else { var configNode = RED.nodes.node(value); - valid = (configNode !== null && (configNode.valid == null || configNode.valid)); + valid = (configNode && (configNode.valid == null || configNode.valid)); } } return valid; diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js index e910ede04..046141b52 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/appearance.js @@ -93,17 +93,20 @@ } + var showLabel = node._def.hasOwnProperty("showLabel")?node._def.showLabel:true; + if (!$("#node-input-show-label").prop('checked')) { // Not checked - hide label - if (!/^link (in|out)$/.test(node.type)) { - // Not a link node - default state is true + + if (showLabel) { + // Default to show label if (node.l !== false) { editState.changes.l = node.l editState.changed = true; } node.l = false; } else { - // A link node - default state is false + // Node has showLabel:false (eg link nodes) if (node.hasOwnProperty('l') && node.l) { editState.changes.l = node.l editState.changed = true; @@ -112,8 +115,8 @@ } } else { // Checked - show label - if (!/^link (in|out)$/.test(node.type)) { - // Not a link node - default state is true + if (showLabel) { + // Default to show label if (node.hasOwnProperty('l') && !node.l) { editState.changes.l = node.l editState.changed = true; @@ -204,8 +207,8 @@ }) if (!node.hasOwnProperty("l")) { - // Show label if type not link - node.l = !/^link (in|out)$/.test(node._def.type); + // Show label unless def.showLabel set to false + node.l = node._def.hasOwnProperty("showLabel")?node._def.showLabel:true; } $("#node-input-show-label").prop("checked",node.l).trigger("change"); diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js index 2fba37e88..9b3977448 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js @@ -159,15 +159,15 @@ RED.view.tools = (function() { nodes.forEach(function(n) { var modified = false; var oldValue = n.l === undefined?true:n.l; - var isLink = /^link (in|out)$/.test(n._def.type); + var showLabel = n._def.hasOwnProperty("showLabel")?n._def.showLabel:true; if (labelShown) { - if (n.l === false || (isLink && !n.hasOwnProperty('l'))) { + if (n.l === false || (!showLabel && !n.hasOwnProperty('l'))) { n.l = true; modified = true; } } else { - if ((!isLink && (!n.hasOwnProperty('l') || n.l === true)) || (isLink && n.l === true) ) { + if ((showLabel && (!n.hasOwnProperty('l') || n.l === true)) || (!showLabel && n.l === true) ) { n.l = false; modified = true; } diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index 8ccbf6fe4..42455055b 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -413,7 +413,7 @@ RED.view = (function() { var nn = result.node; var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label"); - if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) { + if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) { nn.l = showLabel; } @@ -1088,7 +1088,7 @@ RED.view = (function() { nn.x = point[0]; nn.y = point[1]; var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label"); - if (showLabel !== undefined && !/^link (in|out)$/.test(nn._def.type) && !nn._def.defaults.hasOwnProperty("l")) { + if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) { nn.l = showLabel; } if (quickAddLink) { @@ -1991,7 +1991,7 @@ RED.view = (function() { activeLinkNodes = {}; for (var i=0;i + + diff --git a/packages/node_modules/@node-red/nodes/core/common/60-link.js b/packages/node_modules/@node-red/nodes/core/common/60-link.js index 5470ed434..939191fbf 100644 --- a/packages/node_modules/@node-red/nodes/core/common/60-link.js +++ b/packages/node_modules/@node-red/nodes/core/common/60-link.js @@ -17,6 +17,8 @@ module.exports = function(RED) { "use strict"; + const crypto = require("crypto"); + function LinkInNode(n) { RED.nodes.createNode(this,n); var node = this; @@ -40,13 +42,70 @@ module.exports = function(RED) { function LinkOutNode(n) { RED.nodes.createNode(this,n); var node = this; + var mode = n.mode || "link"; + var event = "node:"+n.id; this.on("input", function(msg, send, done) { msg._event = event; RED.events.emit(event,msg) - send(msg); - done(); + + if (mode === "return") { + if (Array.isArray(msg._linkSource) && msg._linkSource.length > 0) { + var messageEvent = msg._linkSource.pop(); + var returnNode = RED.nodes.getNode(messageEvent.node); + if (returnNode && returnNode.returnLinkMessage) { + returnNode.returnLinkMessage(messageEvent.id, msg); + } else { + node.warn("Return target not a link-call node") + } + } else { + node.warn("No call return target") + } + done(); + } else if (mode === "link") { + send(msg); + done(); + } }); } RED.nodes.registerType("link out",LinkOutNode); + + + function LinkCallNode(n) { + RED.nodes.createNode(this,n); + const node = this; + const target = n.links[0]; + const messageEvents = {}; + + this.on("input", function(msg, send, done) { + msg._linkSource = msg._linkSource || []; + const messageEvent = { + id: crypto.randomBytes(14).toString('hex'), + node: node.id, + } + messageEvents[messageEvent.id] = { send, done }; + msg._linkSource.push(messageEvent); + var targetNode = RED.nodes.getNode(target); + if (targetNode) { + targetNode.receive(msg); + } + }); + + this.returnLinkMessage = function(eventId, msg) { + if (Array.isArray(msg._linkSource) && msg._linkSource.length === 0) { + delete msg._linkSource; + } + const messageEvent = messageEvents[eventId]; + if (messageEvent) { + delete messageEvents[eventId]; + messageEvent.send(msg); + messageEvent.done(); + } else { + node.warn("Unrecognised message returned") + } + } + } + RED.nodes.registerType("link call",LinkCallNode); + + } diff --git a/packages/node_modules/@node-red/nodes/icons/link-call.svg b/packages/node_modules/@node-red/nodes/icons/link-call.svg new file mode 100644 index 000000000..a3dcbdd22 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/icons/link-call.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/node_modules/@node-red/nodes/icons/link-return.svg b/packages/node_modules/@node-red/nodes/icons/link-return.svg new file mode 100644 index 000000000..e82ee92f6 --- /dev/null +++ b/packages/node_modules/@node-red/nodes/icons/link-return.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index a2e63a046..d9d94ef59 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -159,7 +159,13 @@ }, "link": { "linkIn": "link in", - "linkOut": "link out" + "linkOut": "link out", + "linkCall": "link call", + "linkOutReturn": "link return", + "outMode": "Mode", + "sendToAll": "Send to all connected link nodes", + "returnToCaller": "Return to calling link node" + }, "tls": { "tls": "TLS configuration",