mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Add Status Node to Subflow to allow subflow-specific status
Closes #597
This commit is contained in:
@@ -265,7 +265,6 @@ class Flow {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the flow definition. This doesn't change anything that is running.
|
||||
* This should be called after `stop` and before `start`.
|
||||
|
@@ -17,6 +17,8 @@
|
||||
const clone = require("clone");
|
||||
const Flow = require('./Flow').Flow;
|
||||
|
||||
const util = require("util");
|
||||
|
||||
const redUtil = require("@node-red/util").util;
|
||||
const flowUtil = require("./util");
|
||||
|
||||
@@ -104,6 +106,40 @@ class Subflow extends Flow {
|
||||
var self = this;
|
||||
// Create a subflow node to accept inbound messages and route appropriately
|
||||
var Node = require("../Node");
|
||||
|
||||
if (this.subflowDef.status) {
|
||||
var subflowStatusConfig = {
|
||||
id: this.subflowInstance.id+":status",
|
||||
type: "subflow-status",
|
||||
z: this.subflowInstance.id,
|
||||
_flow: this.parent
|
||||
}
|
||||
this.statusNode = new Node(subflowStatusConfig);
|
||||
this.statusNode.on("input", function(msg) {
|
||||
if (msg.payload !== undefined) {
|
||||
if (typeof msg.payload === "string") {
|
||||
// if msg.payload is a String, use it as status text
|
||||
self.node.status({text:msg.payload})
|
||||
return;
|
||||
} else if (Object.prototype.toString.call(msg.payload) === "[object Object]") {
|
||||
if (msg.payload.hasOwnProperty('text') || msg.payload.hasOwnProperty('fill') || msg.payload.hasOwnProperty('shape') || Object.keys(msg.payload).length === 0) {
|
||||
// msg.payload is an object that looks like a status object
|
||||
self.node.status(msg.payload);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Anything else - inspect it and use as status text
|
||||
var text = util.inspect(msg.payload);
|
||||
if (text.length > 32) { text = text.substr(0,32) + "..."; }
|
||||
self.node.status({text:text});
|
||||
} else if (msg.status !== undefined) {
|
||||
// if msg.status exists
|
||||
self.node.status(msg.status)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
var subflowInstanceConfig = {
|
||||
id: this.subflowInstance.id,
|
||||
type: this.subflowInstance.type,
|
||||
@@ -168,7 +204,6 @@ class Subflow extends Flow {
|
||||
|
||||
// Wire the subflow outputs
|
||||
if (this.subflowDef.out) {
|
||||
var modifiedNodes = {};
|
||||
for (var i=0;i<this.subflowDef.out.length;i++) {
|
||||
// i: the output index
|
||||
// This is what this Output is wired to
|
||||
@@ -180,7 +215,6 @@ class Subflow extends Flow {
|
||||
this.node._updateWires(subflowInstanceConfig.wires);
|
||||
} else {
|
||||
var node = self.node_map[wires[j].id];
|
||||
modifiedNodes[node.id] = node;
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
}
|
||||
@@ -189,9 +223,47 @@ class Subflow extends Flow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.subflowDef.status) {
|
||||
var subflowStatusId = this.statusNode.id;
|
||||
wires = this.subflowDef.status.wires;
|
||||
for (var j=0;j<wires.length;j++) {
|
||||
if (wires[j].id === this.subflowDef.id) {
|
||||
// A subflow input wired straight to a subflow output
|
||||
subflowInstanceConfig.wires[wires[j].port].push(subflowStatusId);
|
||||
this.node._updateWires(subflowInstanceConfig.wires);
|
||||
} else {
|
||||
var node = self.node_map[wires[j].id];
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
}
|
||||
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]);
|
||||
node.wires[wires[j].port].push(subflowStatusId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.start(diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a node instance from this subflow.
|
||||
* If the subflow has a status node, check for that, otherwise use
|
||||
* the super-class function
|
||||
* @param {String} id [description]
|
||||
* @param {Boolean} cancelBubble if true, prevents the flow from passing the request to the parent
|
||||
* This stops infinite loops when the parent asked this Flow for the
|
||||
* node to begin with.
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
getNode(id, cancelBubble) {
|
||||
if (this.statusNode && this.statusNode.id === id) {
|
||||
return this.statusNode;
|
||||
}
|
||||
return super.getNode(id,cancelBubble);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a status event from a node within this flow.
|
||||
* @param {Node} node The original node that triggered the event
|
||||
@@ -205,10 +277,14 @@ class Subflow extends Flow {
|
||||
handleStatus(node,statusMessage,reportingNode,muteStatus) {
|
||||
let handled = super.handleStatus(node,statusMessage,reportingNode,muteStatus);
|
||||
if (!handled) {
|
||||
// No status node on this subflow caught the status message.
|
||||
// Pass up to the parent with this subflow's instance as the
|
||||
// reporting node
|
||||
handled = this.parent.handleStatus(node,statusMessage,this.node,true);
|
||||
if (!this.statusNode || node === this.node) {
|
||||
// No status node on this subflow caught the status message.
|
||||
// AND there is no Subflow Status node - so the user isn't
|
||||
// wanting to manage status messages themselves
|
||||
// Pass up to the parent with this subflow's instance as the
|
||||
// reporting node
|
||||
handled = this.parent.handleStatus(node,statusMessage,this.node,true);
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
|
||||
|
Reference in New Issue
Block a user