diff --git a/red/runtime/nodes/flows/index.js b/red/runtime/nodes/flows/index.js index a625641b6..2e6d274f0 100644 --- a/red/runtime/nodes/flows/index.js +++ b/red/runtime/nodes/flows/index.js @@ -387,9 +387,10 @@ function updateMissingTypes() { } function addFlow(flow) { - var i,node; - + if (!flow.hasOwnProperty('nodes')) { + throw new Error('missing nodes property'); + } flow.id = redUtil.generateId(); var nodes = [{ @@ -449,6 +450,9 @@ function getFlow(id) { if (flow.label) { result.label = flow.label; } + if (id !== 'global') { + result.nodes = []; + } if (flow.nodes) { var nodeIds = Object.keys(flow.nodes); if (nodeIds.length > 0) { @@ -462,6 +466,9 @@ function getFlow(id) { result.configs = configIds.map(function(configId) { return clone(flow.configs[configId]); }) + if (result.configs.length === 0) { + delete result.configs; + } } if (flow.subflows) { var subflowIds = Object.keys(flow.subflows); @@ -480,40 +487,63 @@ function getFlow(id) { delete subflow.instances; return subflow; }); + if (result.subflows.length === 0) { + delete result.subflows; + } } return result; } function updateFlow(id,newFlow) { - if (id === 'global') { - // TODO: handle global update - throw new Error('not allowed to update global'); - } - - var flow = activeFlowConfig.flows[id]; - if (!flow) { - var e = new Error(); - e.code = 404; - throw e; + var label = id; + if (id !== 'global') { + if (!activeFlowConfig.flows[id]) { + var e = new Error(); + e.code = 404; + throw e; + } + label = activeFlowConfig.flows[id].label; } var newConfig = clone(activeConfig); - newConfig = newConfig.filter(function(node) { - return node.z !== id && node.id !== id; - }); + var nodes; - var tabNode = { - type:'tab', - label:newFlow.label, - id:id + if (id === 'global') { + // Remove all nodes whose z is not a known flow + // When subflows can be owned by a flow, this logic will have to take + // that into account + newConfig = newConfig.filter(function(node) { + return node.type === 'tab' || (node.hasOwnProperty('z') && activeFlowConfig.flows.hasOwnProperty(node.z)); + }) + + // Add in the new config nodes + nodes = newFlow.configs||[]; + if (newFlow.subflows) { + // Add in the new subflows + newFlow.subflows.forEach(function(sf) { + nodes = nodes.concat(sf.nodes||[]).concat(sf.configs||[]); + delete sf.nodes; + delete sf.configs; + nodes.push(sf); + }); + } + } else { + newConfig = newConfig.filter(function(node) { + return node.z !== id && node.id !== id; + }); + var tabNode = { + type:'tab', + label:newFlow.label, + id:id + } + nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]); + nodes.forEach(function(n) { + n.z = id; + }); } - var nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]); - nodes.forEach(function(n) { - n.z = id; - }); - newConfig = newConfig.concat(nodes); + newConfig = newConfig.concat(nodes); return setConfig(newConfig,'flows',true).then(function() { - log.info(log._("nodes.flows.updated-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"})); + log.info(log._("nodes.flows.updated-flow",{label:(label?label+" ":"")+"["+id+"]"})); }) }