mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Cleanup and remove old logic when importing identical subflows
This commit is contained in:
parent
507038947d
commit
4f20cd5c0a
@ -1386,7 +1386,7 @@ RED.nodes = (function() {
|
|||||||
var wires = links.filter(function(d) { return d.source === p });
|
var wires = links.filter(function(d) { return d.source === p });
|
||||||
for (var i=0;i<wires.length;i++) {
|
for (var i=0;i<wires.length;i++) {
|
||||||
var w = wires[i];
|
var w = wires[i];
|
||||||
if (w.target.type != "subflow") {
|
if (w?.target && w.target.type != "subflow") {
|
||||||
nIn.wires.push({id:w.target.id})
|
nIn.wires.push({id:w.target.id})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1716,7 +1716,7 @@ RED.nodes = (function() {
|
|||||||
// Remove the old subflow definition - but leave the instances in place
|
// Remove the old subflow definition - but leave the instances in place
|
||||||
var removalResult = RED.subflow.removeSubflow(n.id, true);
|
var removalResult = RED.subflow.removeSubflow(n.id, true);
|
||||||
// Create the list of nodes for the new subflow def
|
// Create the list of nodes for the new subflow def
|
||||||
var subflowNodes = [n].concat(zMap[n.id]);
|
var subflowNodes = [n].concat(zMap[n.id]).filter((s) => !!s);
|
||||||
// Import the new subflow - no clashes should occur as we've removed
|
// Import the new subflow - no clashes should occur as we've removed
|
||||||
// the old version
|
// the old version
|
||||||
var result = importNodes(subflowNodes);
|
var result = importNodes(subflowNodes);
|
||||||
@ -1801,6 +1801,30 @@ RED.nodes = (function() {
|
|||||||
return unknownTypes;
|
return unknownTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitExistingNodesNotification(existingNodes, importedNodes) {
|
||||||
|
const errorMessage = RED._("clipboard.importDuplicate", { count: existingNodes.length });
|
||||||
|
const maxItemCount = 5; // Max 5 items in the list
|
||||||
|
const nodeList = $("<ul>");
|
||||||
|
|
||||||
|
let itemCount = 0;
|
||||||
|
for (const { existing, imported } of existingNodes) {
|
||||||
|
if (itemCount >= maxItemCount) { break; }
|
||||||
|
const conflictType = (imported.type !== existing.type) ? " | " + imported.type : "";
|
||||||
|
$("<li>").text(existing.id + " [ " + existing.type + conflictType + " ]").appendTo(nodeList);
|
||||||
|
itemCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingNodes.length > maxItemCount) {
|
||||||
|
$("<li>").text(RED._("deploy.confirm.plusNMore", { count: (existingNodes.length - maxItemCount) })).appendTo(nodeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
const wrapper = $("<p>").append(nodeList);
|
||||||
|
const existingNodesError = new Error(errorMessage + wrapper.html());
|
||||||
|
existingNodesError.code = "import_conflict";
|
||||||
|
existingNodesError.importConfig = identifyImportConflicts(importedNodes);
|
||||||
|
throw existingNodesError;
|
||||||
|
}
|
||||||
|
|
||||||
function copyConfigNode(configNode, def, options = {}) {
|
function copyConfigNode(configNode, def, options = {}) {
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: configNode.id,
|
id: configNode.id,
|
||||||
@ -1906,8 +1930,8 @@ RED.nodes = (function() {
|
|||||||
newNode.h = 0;
|
newNode.h = 0;
|
||||||
} else if (node.type.substring(0, 7) === "subflow") {
|
} else if (node.type.substring(0, 7) === "subflow") {
|
||||||
newNode.name = node.name;
|
newNode.name = node.name;
|
||||||
newNode.inputs = node.inputs;
|
newNode.inputs = node.inputs ?? 0;
|
||||||
newNode.outputs = node.outputs;
|
newNode.outputs = node.outputs ?? 0;
|
||||||
newNode.env = node.env;
|
newNode.env = node.env;
|
||||||
} else {
|
} else {
|
||||||
newNode._config.x = node.x;
|
newNode._config.x = node.x;
|
||||||
@ -2029,44 +2053,27 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
// If some nodes already exists, ask the user for each node to choose
|
// If some nodes already exists, ask the user for each node to choose
|
||||||
// between copying it, replacing it or not importing it.
|
// between copying it, replacing it or not importing it.
|
||||||
|
// NOTE: Stops the import here - throws an error.
|
||||||
if (existingNodes.length) {
|
if (existingNodes.length) {
|
||||||
const errorMessage = RED._("clipboard.importDuplicate", { count: existingNodes.length });
|
emitExistingNodesNotification(existingNodes, originalNodes);
|
||||||
const maxItemCount = 5; // Max 5 items in the list
|
|
||||||
const nodeList = $("<ul>");
|
|
||||||
|
|
||||||
let itemCount = 0;
|
|
||||||
for (let { existing, imported } of existingNodes) {
|
|
||||||
if (itemCount >= maxItemCount) { break; }
|
|
||||||
const conflictType = (imported.type !== existing.type) ? " | " + imported.type : "";
|
|
||||||
$("<li>").text(existing.id + " [ " + existing.type + conflictType + " ]").appendTo(nodeList);
|
|
||||||
itemCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingNodes.length > maxItemCount) {
|
|
||||||
$("<li>").text(RED._("deploy.confirm.plusNMore", { count: (existingNodes.length - maxItemCount) })).appendTo(nodeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
const wrapper = $("<p>").append(nodeList);
|
|
||||||
const existingNodesError = new Error(errorMessage + wrapper.html());
|
|
||||||
existingNodesError.code = "import_conflict";
|
|
||||||
existingNodesError.importConfig = identifyImportConflicts(originalNodes);
|
|
||||||
throw existingNodesError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: activeWorkspace can be equal to 0 if it's the initial load
|
||||||
let activeWorkspace = RED.workspaces.active();
|
let activeWorkspace = RED.workspaces.active();
|
||||||
const activeSubflow = getSubflow(activeWorkspace);
|
const activeSubflow = getSubflow(activeWorkspace);
|
||||||
for (const node of originalNodes) {
|
if (activeSubflow) {
|
||||||
const group = /^subflow:(.+)$/.exec(node.type);
|
for (const node of originalNodes) {
|
||||||
if (group) {
|
const group = /^subflow:(.+)$/.exec(node.type);
|
||||||
const subflowId = group[1];
|
if (group) {
|
||||||
// NOTE: activeWorkspace can be equal to 0 if it's the initial load
|
const subflowId = group[1];
|
||||||
if (activeSubflow) {
|
|
||||||
let error;
|
let error;
|
||||||
|
|
||||||
if (subflowId === activeSubflow.id) {
|
if (subflowId === activeSubflow.id) {
|
||||||
error = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
error = new Error(RED._("notification.errors.cannotAddSubflowToItself"));
|
||||||
} else if (subflowContains(subflowId, activeSubflow.id)) {
|
} else if (subflowContains(subflowId, activeSubflow.id)) {
|
||||||
error = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
error = new Error(RED._("notification.errors.cannotAddCircularReference"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
// TODO: standardise error codes
|
// TODO: standardise error codes
|
||||||
error.code = "NODE_RED";
|
error.code = "NODE_RED";
|
||||||
@ -2089,53 +2096,13 @@ RED.nodes = (function() {
|
|||||||
initialLoad = JSON.parse(JSON.stringify(originalNodes));
|
initialLoad = JSON.parse(JSON.stringify(originalNodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Identifies unknown nodes and can emit a notification to warn the user.
|
||||||
const unknownTypes = identifyUnknowType(originalNodes, { emitNotification: !isInitialLoad });
|
const unknownTypes = identifyUnknowType(originalNodes, { emitNotification: !isInitialLoad });
|
||||||
|
|
||||||
const nodeZmap = {};
|
|
||||||
let recoveryWorkspace = null;
|
|
||||||
// If it's the initial load, create a recovery workspace if any nodes don't have `node.z` and assign to it.
|
|
||||||
for (const node of originalNodes) {
|
|
||||||
if (node.z) {
|
|
||||||
nodeZmap[node.z] = nodeZmap[node.z] || [];
|
|
||||||
nodeZmap[node.z].push(node);
|
|
||||||
} else if (isInitialLoad && node.hasOwnProperty("x") && node.hasOwnProperty("y")) {
|
|
||||||
// Hit the rare issue where node z values get set to 0.
|
|
||||||
// Repair the flow - but we really need to track that down.
|
|
||||||
if (!recoveryWorkspace) {
|
|
||||||
recoveryWorkspace = {
|
|
||||||
id: getID(),
|
|
||||||
type: "tab",
|
|
||||||
disabled: false,
|
|
||||||
label: RED._("clipboard.recoveredNodes"),
|
|
||||||
info: RED._("clipboard.recoveredNodesInfo"),
|
|
||||||
env: []
|
|
||||||
};
|
|
||||||
|
|
||||||
addWorkspace(recoveryWorkspace);
|
|
||||||
RED.workspaces.add(recoveryWorkspace);
|
|
||||||
nodeZmap[recoveryWorkspace.id] = [];
|
|
||||||
}
|
|
||||||
node.z = recoveryWorkspace.id;
|
|
||||||
nodeZmap[node.z].push(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const newWorkspaces = [];
|
|
||||||
if (recoveryWorkspace) {
|
|
||||||
newWorkspaces.push(recoveryWorkspace);
|
|
||||||
const notification = RED.notify(RED._("clipboard.recoveredNodesNotification", { flowName: RED._("clipboard.recoveredNodes") }), {
|
|
||||||
type: "warning",
|
|
||||||
fixed: true,
|
|
||||||
buttons: [
|
|
||||||
{ text: RED._("common.label.close"), click: function () { notification.close(); } }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const subflowMap = {};
|
const subflowMap = {};
|
||||||
const workspaceMap = {};
|
const workspaceMap = {};
|
||||||
const newSubflows = [];
|
const newSubflows = [];
|
||||||
const subflowDenyList = {};
|
const newWorkspaces = [];
|
||||||
// Find all tabs and subflow tabs and add it to workspace
|
// Find all tabs and subflow tabs and add it to workspace
|
||||||
// NOTE: Subflow tab not the instance
|
// NOTE: Subflow tab not the instance
|
||||||
for (const node of originalNodes) {
|
for (const node of originalNodes) {
|
||||||
@ -2163,43 +2130,32 @@ RED.nodes = (function() {
|
|||||||
newWorkspaces.push(node);
|
newWorkspaces.push(node);
|
||||||
RED.workspaces.add(node);
|
RED.workspaces.add(node);
|
||||||
} else if (node.type === "subflow") {
|
} else if (node.type === "subflow") {
|
||||||
let matchingSubflow;
|
node.in.forEach(function(input, i) {
|
||||||
|
input.type = "subflow";
|
||||||
// TODO: Si l'id est différent on devrait l'importer
|
input.direction = "in";
|
||||||
if (!options.importMap[node.id]) {
|
input.z = node.id;
|
||||||
matchingSubflow = checkForMatchingSubflow(node, nodeZmap[node.id]);
|
input.i = i;
|
||||||
console.log("SUBFLOW", matchingSubflow)
|
input.id = getID();
|
||||||
|
});
|
||||||
|
node.out.forEach(function(output, i) {
|
||||||
|
output.type = "subflow";
|
||||||
|
output.direction = "out";
|
||||||
|
output.z = node.id;
|
||||||
|
output.i = i;
|
||||||
|
output.id = getID();
|
||||||
|
});
|
||||||
|
if (node.status) {
|
||||||
|
node.status.type = "subflow";
|
||||||
|
node.status.direction = "status";
|
||||||
|
node.status.z = node.id;
|
||||||
|
node.status.id = getID();
|
||||||
}
|
}
|
||||||
if (matchingSubflow) {
|
if (createNewIds || options.importMap[node.id] === "copy") {
|
||||||
subflowDenyList[node.id] = matchingSubflow;
|
node.id = getID();
|
||||||
} else {
|
|
||||||
node.in.forEach(function(input, i) {
|
|
||||||
input.type = "subflow";
|
|
||||||
input.direction = "in";
|
|
||||||
input.z = node.id;
|
|
||||||
input.i = i;
|
|
||||||
input.id = getID();
|
|
||||||
});
|
|
||||||
node.out.forEach(function(output, i) {
|
|
||||||
output.type = "subflow";
|
|
||||||
output.direction = "out";
|
|
||||||
output.z = node.id;
|
|
||||||
output.i = i;
|
|
||||||
output.id = getID();
|
|
||||||
});
|
|
||||||
if (node.status) {
|
|
||||||
node.status.type = "subflow";
|
|
||||||
node.status.direction = "status";
|
|
||||||
node.status.z = node.id;
|
|
||||||
node.status.id = getID();
|
|
||||||
}
|
|
||||||
if (createNewIds || options.importMap[node.id] === "copy") {
|
|
||||||
node.id = getID();
|
|
||||||
}
|
|
||||||
subflowMap[oldId] = node;
|
|
||||||
newSubflows.push(node);
|
|
||||||
addSubflow(node, (createNewIds || options.importMap[node.id] === "copy"));
|
|
||||||
}
|
}
|
||||||
|
subflowMap[oldId] = node;
|
||||||
|
newSubflows.push(node);
|
||||||
|
addSubflow(node, (createNewIds || options.importMap[node.id] === "copy"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2212,11 +2168,90 @@ RED.nodes = (function() {
|
|||||||
activeWorkspace = defaultWorkspace.id;
|
activeWorkspace = defaultWorkspace.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let newWorkspace = null;
|
||||||
|
let recoveryWorkspace = null;
|
||||||
|
// Correct or update the z property of each node
|
||||||
|
for (const node of originalNodes) {
|
||||||
|
const isConfigNode = !node.x && !node.y;
|
||||||
|
|
||||||
|
// If it's the initial load, create a recovery workspace if any nodes don't have `node.z` and assign to it.
|
||||||
|
if (!node.z && isInitialLoad && node.hasOwnProperty("x") && node.hasOwnProperty("y")) {
|
||||||
|
// Hit the rare issue where node z values get set to 0.
|
||||||
|
// Repair the flow - but we really need to track that down.
|
||||||
|
if (!recoveryWorkspace) {
|
||||||
|
recoveryWorkspace = {
|
||||||
|
id: getID(),
|
||||||
|
type: "tab",
|
||||||
|
disabled: false,
|
||||||
|
label: RED._("clipboard.recoveredNodes"),
|
||||||
|
info: RED._("clipboard.recoveredNodesInfo"),
|
||||||
|
env: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
node.z = recoveryWorkspace.id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove workspace in next release+1
|
||||||
|
if (node.type === "workspace" || node.type === "tab" || node.type === "subflow") { continue; }
|
||||||
|
|
||||||
|
// Fix `node.z` for not found/new one case
|
||||||
|
if (createNewIds || options.importMap[node.id] === "copy") {
|
||||||
|
// Config Node can have an undefined `node.z`
|
||||||
|
if (!isConfigNode || (isConfigNode && node.z)) {
|
||||||
|
if (subflowMap[node.z]) {
|
||||||
|
node.z = subflowMap[node.z].id;
|
||||||
|
} else {
|
||||||
|
node.z = workspaceMap[node.z];
|
||||||
|
if (!workspaces[node.z]) {
|
||||||
|
node.z = activeWorkspace;
|
||||||
|
if (createNewWorkspace) {
|
||||||
|
if (newWorkspace === null) {
|
||||||
|
newWorkspace = RED.workspaces.add(null, true);
|
||||||
|
newWorkspaces.push(newWorkspace);
|
||||||
|
}
|
||||||
|
node.z = newWorkspace.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const keepNodesCurrentZ = reimport && node.z && (RED.workspaces.contains(node.z) || RED.nodes.subflow(node.z));
|
||||||
|
|
||||||
|
if (isConfigNode && !keepNodesCurrentZ && node.z && !workspaceMap[node.z] && !subflowMap[node.z]) {
|
||||||
|
node.z = activeWorkspace;
|
||||||
|
} else if (!isConfigNode && !keepNodesCurrentZ && (node.z == null || (!workspaceMap[node.z] && !subflowMap[node.z]))) {
|
||||||
|
node.z = activeWorkspace;
|
||||||
|
if (createNewWorkspace) {
|
||||||
|
if (!newWorkspace) {
|
||||||
|
newWorkspace = RED.workspaces.add(null,true);
|
||||||
|
newWorkspaces.push(newWorkspace);
|
||||||
|
}
|
||||||
|
node.z = newWorkspace.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the recovery tab if used and warn the user
|
||||||
|
if (recoveryWorkspace) {
|
||||||
|
addWorkspace(recoveryWorkspace);
|
||||||
|
RED.workspaces.add(recoveryWorkspace);
|
||||||
|
// Put the recovery workspace at the first position
|
||||||
|
newWorkspaces.splice(0, 1, recoveryWorkspace, newWorkspaces[0]);
|
||||||
|
const notification = RED.notify(RED._("clipboard.recoveredNodesNotification", { flowName: RED._("clipboard.recoveredNodes") }), {
|
||||||
|
type: "warning",
|
||||||
|
fixed: true,
|
||||||
|
buttons: [
|
||||||
|
{ text: RED._("common.label.close"), click: function () { notification.close(); } }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const nodeMap = {};
|
const nodeMap = {};
|
||||||
const newNodes = [];
|
const newNodes = [];
|
||||||
const newGroups = [];
|
const newGroups = [];
|
||||||
const newJunctions = [];
|
const newJunctions = [];
|
||||||
let newWorkspace = null;
|
|
||||||
// Find all Config Nodes, Groups, Junctions, Nodes and Subflow instances and add them
|
// Find all Config Nodes, Groups, Junctions, Nodes and Subflow instances and add them
|
||||||
// NOTE: Replaced Config Nodes and Subflow instances no longer appear below
|
// NOTE: Replaced Config Nodes and Subflow instances no longer appear below
|
||||||
for (const node of originalNodes) {
|
for (const node of originalNodes) {
|
||||||
@ -2257,53 +2292,12 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
const isConfigNode = def?.category === "config";
|
const isConfigNode = def?.category === "config";
|
||||||
|
|
||||||
// Fix `node.z` for undefined/not found/new one case
|
|
||||||
if (createNewIds || options.importMap[oldId] === "copy") {
|
|
||||||
// Config Node can have an undefined `node.z`
|
|
||||||
if (!isConfigNode || (isConfigNode && node.z)) {
|
|
||||||
if (subflowDenyList[node.z]) {
|
|
||||||
continue;
|
|
||||||
} else if (subflowMap[node.z]) {
|
|
||||||
node.z = subflowMap[node.z].id;
|
|
||||||
} else {
|
|
||||||
node.z = workspaceMap[node.z];
|
|
||||||
if (!workspaces[node.z]) {
|
|
||||||
if (createNewWorkspace) {
|
|
||||||
if (newWorkspace === null) {
|
|
||||||
newWorkspace = RED.workspaces.add(null, true);
|
|
||||||
newWorkspaces.push(newWorkspace);
|
|
||||||
}
|
|
||||||
node.z = newWorkspace.id;
|
|
||||||
} else {
|
|
||||||
node.z = activeWorkspace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const keepNodesCurrentZ = reimport && node.z && (RED.workspaces.contains(node.z) || RED.nodes.subflow(node.z));
|
|
||||||
|
|
||||||
if (isConfigNode && !keepNodesCurrentZ && node.z && !workspaceMap[node.z] && !subflowMap[node.z]) {
|
|
||||||
node.z = activeWorkspace;
|
|
||||||
} else if (!isConfigNode && !keepNodesCurrentZ && (node.z == null || (!workspaceMap[node.z] && !subflowMap[node.z]))) {
|
|
||||||
if (createNewWorkspace) {
|
|
||||||
if (newWorkspace === null) {
|
|
||||||
newWorkspace = RED.workspaces.add(null,true);
|
|
||||||
newWorkspaces.push(newWorkspace);
|
|
||||||
}
|
|
||||||
node.z = newWorkspace.id;
|
|
||||||
} else {
|
|
||||||
node.z = activeWorkspace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the node definition for subflow instance
|
// Update the node definition for subflow instance
|
||||||
if (!isUnknownNode && node.type.substring(0, 7) === "subflow") {
|
if (!isUnknownNode && node.type.substring(0, 7) === "subflow") {
|
||||||
const parentId = node.type.split(":")[1];
|
const parentId = node.type.split(":")[1];
|
||||||
const subflow = subflowDenyList[parentId] || subflowMap[parentId] || getSubflow(parentId);
|
const subflow = subflowMap[parentId] || getSubflow(parentId);
|
||||||
|
|
||||||
if (subflowDenyList[parentId] || createNewIds || options.importMap[node.id] === "copy") {
|
if (createNewIds || options.importMap[node.id] === "copy") {
|
||||||
node.type = "subflow:" + subflow.id;
|
node.type = "subflow:" + subflow.id;
|
||||||
def = registry.getNodeType(node.type);
|
def = registry.getNodeType(node.type);
|
||||||
}
|
}
|
||||||
@ -2312,36 +2306,10 @@ RED.nodes = (function() {
|
|||||||
node.outputs = subflow.out.length;
|
node.outputs = subflow.out.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now the properties have been corrected, copy the node properties:
|
// Now the properties have been fixed, copy the node properties:
|
||||||
|
|
||||||
// Config Node
|
// Config Node
|
||||||
if (isConfigNode) {
|
if (isConfigNode) {
|
||||||
// TODO: A quoi sert ce bloc ? Replace?
|
nodeMap[oldId] = copyConfigNode(node, def, options);
|
||||||
let existingConfigNode;
|
|
||||||
if (createNewIds || options.importMap[oldId] === "copy") {
|
|
||||||
if (options.importMap[oldId] !== "copy") {
|
|
||||||
existingConfigNode = RED.nodes.node(oldId);
|
|
||||||
if (existingConfigNode) {
|
|
||||||
if (node.z && existingConfigNode.z !== node.z) {
|
|
||||||
existingConfigNode = null;
|
|
||||||
// Check the config nodes on n.z
|
|
||||||
// TODO: pourquoi utiliser z au lieu de l'id ?
|
|
||||||
for (var cn in configNodes) {
|
|
||||||
if (configNodes.hasOwnProperty(cn)) {
|
|
||||||
if (configNodes[cn].z === node.z && compareNodes(configNodes[cn], node, false)) {
|
|
||||||
existingConfigNode = configNodes[cn];
|
|
||||||
nodeMap[oldId] = configNodes[cn];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
|
|
||||||
nodeMap[oldId] = copyConfigNode(node, def, options);
|
|
||||||
}
|
|
||||||
// Node, Group, Junction or Subflow
|
// Node, Group, Junction or Subflow
|
||||||
} else {
|
} else {
|
||||||
nodeMap[oldId] = copyNode(node, def, options);
|
nodeMap[oldId] = copyNode(node, def, options);
|
||||||
@ -2385,7 +2353,7 @@ RED.nodes = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
allNodes.eachNode(function (node) {
|
allNodes.eachNode(function (node) {
|
||||||
// The event will be triggered after the import
|
// TODO: The event will be triggered after the import - Quid?
|
||||||
updateConfigNodeUsers(node, { emitEvent: false });
|
updateConfigNodeUsers(node, { emitEvent: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2397,7 +2365,6 @@ RED.nodes = (function() {
|
|||||||
const wires = Array.isArray(wiresGroup) ? wiresGroup : [wiresGroup];
|
const wires = Array.isArray(wiresGroup) ? wiresGroup : [wiresGroup];
|
||||||
wires.forEach(function (wire) {
|
wires.forEach(function (wire) {
|
||||||
// Skip if the wire is clinked to a non-existent node
|
// Skip if the wire is clinked to a non-existent node
|
||||||
// TODO: Add warning message?
|
|
||||||
if (!nodeMap.hasOwnProperty(wire)) { return; }
|
if (!nodeMap.hasOwnProperty(wire)) { return; }
|
||||||
if (node.z === nodeMap[wire].z) {
|
if (node.z === nodeMap[wire].z) {
|
||||||
const link = { source: node, sourcePort: node.wires.indexOf(wiresGroup), target: nodeMap[wire] };
|
const link = { source: node, sourcePort: node.wires.indexOf(wiresGroup), target: nodeMap[wire] };
|
||||||
@ -2438,6 +2405,7 @@ RED.nodes = (function() {
|
|||||||
const n = nodeMap[id];
|
const n = nodeMap[id];
|
||||||
if (n) {
|
if (n) {
|
||||||
if (n._def.category === "config") {
|
if (n._def.category === "config") {
|
||||||
|
// TODO: addNode calls updateConfigNodeUsers so remove here
|
||||||
if (n.users.indexOf(node) === -1) {
|
if (n.users.indexOf(node) === -1) {
|
||||||
n.users.push(node);
|
n.users.push(node);
|
||||||
}
|
}
|
||||||
@ -2454,6 +2422,7 @@ RED.nodes = (function() {
|
|||||||
|
|
||||||
// Add Links to Workspace
|
// Add Links to Workspace
|
||||||
for (const subflow of newSubflows) {
|
for (const subflow of newSubflows) {
|
||||||
|
// TODO: Handled missing node
|
||||||
subflow.in.forEach(function (input) {
|
subflow.in.forEach(function (input) {
|
||||||
input.wires.forEach(function (wire) {
|
input.wires.forEach(function (wire) {
|
||||||
const link = { source: input, sourcePort: 0, target: nodeMap[wire.id] };
|
const link = { source: input, sourcePort: 0, target: nodeMap[wire.id] };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user