Mainly refactor the copy of subflow + slight cleanup

This commit is contained in:
GogoVega 2024-06-16 17:48:55 +02:00
parent e5db6661c3
commit 507038947d
No known key found for this signature in database
GPG Key ID: E1E048B63AC5AC2B

View File

@ -1806,6 +1806,7 @@ RED.nodes = (function() {
id: configNode.id,
z: configNode.z,
type: configNode.type,
changed: false,
icon: configNode.icon,
info: configNode.info,
label: def.label,
@ -1854,8 +1855,8 @@ RED.nodes = (function() {
y: parseFloat(node.y || 0),
z: node.z,
type: node.type,
info: node.info,
changed: false,
info: node.info,
_config: {},
_def: def
};
@ -1866,9 +1867,6 @@ RED.nodes = (function() {
newNode.outputLabels = node.outputLabels;
newNode.icon = node.icon;
}
if (node.type === "junction") {
newNode.wires = node.wires || [];
}
if (node.hasOwnProperty("l")) {
newNode.l = node.l;
}
@ -1879,11 +1877,10 @@ RED.nodes = (function() {
newNode.g = node.g;
}
if (options.markChanged) {
newNode.changed = true
newNode.changed = true;
}
if (node.type === "group") {
newNode._def = RED.group.def;
for (const d in newNode._def.defaults) {
if (newNode._def.defaults.hasOwnProperty(d) && d !== "inputs" && d !== "outputs") {
newNode[d] = node[d];
@ -1893,46 +1890,25 @@ RED.nodes = (function() {
newNode._config.x = node.x;
newNode._config.y = node.y;
if (node.hasOwnProperty("w")) { // Weight
newNode.w = node.w
newNode.w = node.w;
}
if (node.hasOwnProperty("h")) { // Height
newNode.h = node.h
newNode.h = node.h;
}
} else if (node.type === "junction") {
newNode._def = { defaults: {} };
newNode._config.x = node.x
newNode._config.y = node.y
newNode.inputs = 1
newNode.outputs = 1
newNode._config.x = node.x;
newNode._config.y = node.y;
newNode.wires = node.wires || [];
newNode.inputs = 1;
newNode.outputs = 1;
newNode.w = 0;
newNode.h = 0;
} else if (node.type.substring(0, 7) === "subflow") {
const parentId = node.type.split(":")[1];
/*
const subflow = subflow_denylist[parentId]||subflow_map[parentId]||getSubflow(parentId);
// TODO: Pourquoi ne pas l'avoir mis dans les tabs ?
if (!subflow){
node._def = {
color:"#fee",
defaults: {},
label: "unknown: "+n.type,
labelStyle: "red-ui-flow-node-label-italic",
outputs: n.outputs|| (n.wires && n.wires.length) || 0,
set: registry.getNodeSet("node-red/unknown")
}
} else {
// TODO: Normal que la copie utilise le Subflow parent ?
if (subflow_denylist[parentId] || createNewIds || options.importMap[n.id] === "copy") {
parentId = subflow.id;
node.type = "subflow:"+parentId;
node._def = registry.getNodeType(node.type);
delete node.i;
}
node.name = n.name;
node.outputs = subflow.out.length;
node.inputs = subflow.in.length;
node.env = n.env;
}*/
newNode.name = node.name;
newNode.inputs = node.inputs;
newNode.outputs = node.outputs;
newNode.env = node.env;
} else {
newNode._config.x = node.x;
newNode._config.y = node.y;
@ -2001,7 +1977,7 @@ RED.nodes = (function() {
options = Object.assign({}, defaultOptions, options);
const createNewIds = options.generateIds;
const createMissingWorkspace = options.addFlow;
const createNewWorkspace = options.addFlow;
const reimport = (!createNewIds && !!options.reimport);
// Checks and converts nodes into an Array if necessary
@ -2024,7 +2000,7 @@ RED.nodes = (function() {
const existingNodes = [];
const nodesToReplace = [];
// Checks if the imported nodes contains duplicates or existing nodes.
originalNodes = originalNodes.filter(function(node) {
originalNodes = originalNodes.filter(function (node) {
const id = node.id;
// This is a temporary fix to help resolve corrupted flows caused by 0.20.0 where multiple
@ -2077,14 +2053,13 @@ RED.nodes = (function() {
throw existingNodesError;
}
// TODO: check the z of the subflow instance and check _that_ if it exists
// TODO: Handled activeWorkspace = 0
let activeWorkspace = RED.workspaces.active();
const activeSubflow = getSubflow(activeWorkspace);
for (const node of originalNodes) {
const group = /^subflow:(.+)$/.exec(node.type);
if (group) {
const subflowId = group[1];
// NOTE: activeWorkspace can be equal to 0 if it's the initial load
if (activeSubflow) {
let error;
if (subflowId === activeSubflow.id) {
@ -2114,27 +2089,28 @@ RED.nodes = (function() {
initialLoad = JSON.parse(JSON.stringify(originalNodes));
}
const unknownTypes = identifyUnknowType(originalNodes, { emitNotification: isInitialLoad });
const unknownTypes = identifyUnknowType(originalNodes, { emitNotification: !isInitialLoad });
const nodeZmap = {};
let recoveryWorkspace = null;
let missingWorkspace = 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')) {
} 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: RED.nodes.id(),
id: getID(),
type: "tab",
disabled: false,
label: RED._("clipboard.recoveredNodes"),
info: RED._("clipboard.recoveredNodesInfo"),
env: []
};
addWorkspace(recoveryWorkspace);
RED.workspaces.add(recoveryWorkspace);
nodeZmap[recoveryWorkspace.id] = [];
@ -2144,9 +2120,6 @@ RED.nodes = (function() {
}
}
// TODO
const subflow_denylist = {};
const newWorkspaces = [];
if (recoveryWorkspace) {
newWorkspaces.push(recoveryWorkspace);
@ -2154,7 +2127,7 @@ RED.nodes = (function() {
type: "warning",
fixed: true,
buttons: [
{ text: RED._("common.label.close"), click: function() { notification.close(); } }
{ text: RED._("common.label.close"), click: function () { notification.close(); } }
]
});
}
@ -2162,6 +2135,7 @@ RED.nodes = (function() {
const subflowMap = {};
const workspaceMap = {};
const newSubflows = [];
const subflowDenyList = {};
// Find all tabs and subflow tabs and add it to workspace
// NOTE: Subflow tab not the instance
for (const node of originalNodes) {
@ -2177,8 +2151,9 @@ RED.nodes = (function() {
if (defaultWorkspace == null) {
defaultWorkspace = node;
}
if (activeWorkspace === 0) { // TODO: Why?
activeWorkspace = node.id;
// If it is the initial load, the value is equal to 0
if (activeWorkspace === 0) {
activeWorkspace = defaultWorkspace.id;
}
if (createNewIds || options.importMap[node.id] === "copy") {
node.id = getID();
@ -2190,12 +2165,13 @@ RED.nodes = (function() {
} else if (node.type === "subflow") {
let matchingSubflow;
// TODO: Toujours lié à node.z ?
// TODO: Si l'id est différent on devrait l'importer
if (!options.importMap[node.id]) {
matchingSubflow = checkForMatchingSubflow(node, nodeZmap[node.id]);
console.log("SUBFLOW", matchingSubflow)
}
if (matchingSubflow) {
subflow_denylist[node.id] = matchingSubflow;
subflowDenyList[node.id] = matchingSubflow;
} else {
node.in.forEach(function(input, i) {
input.type = "subflow";
@ -2233,40 +2209,71 @@ RED.nodes = (function() {
addWorkspace(defaultWorkspace);
RED.workspaces.add(defaultWorkspace);
newWorkspaces.push(defaultWorkspace);
activeWorkspace = RED.workspaces.active();
activeWorkspace = defaultWorkspace.id;
}
const nodeMap = {};
const newNodes = [];
const newGroups = [];
const newJunctions = [];
let newWorkspace = null;
// Find all Config Nodes, Groups, Junctions, Nodes and Subflow instances and add them
// NOTE: Replaced Config Nodes and Subflow instances no longer appear below
for (const node of originalNodes) {
const def = registry.getNodeType(node.type);
const isConfigNode = def?.category === "config";
const oldId = node.id;
// TODO: remove workspace in next release+1
if (node.type === "workspace" || node.type === "tab" || node.type === "subflow") { continue; }
// TODO: Fixes weird thing with `node.z`
// Try to fix the node definition
let def = registry.getNodeType(node.type);
let isUnknownNode = false;
if (!def) {
// Group Node
if (node.type === "group") {
def = RED.group.def;
}
// Unknown Config Node
else if (!node.x && !node.y) {
isUnknownNode = true;
def = {
category: "config",
//defaults: {},
set: registry.getNodeSet("node-red/unknown")
};
// Unknown Node
} else {
isUnknownNode = true;
def = {
color: "#fee",
defaults: {},
label: "unknown: " + node.type,
labelStyle: "red-ui-flow-node-label-italic",
outputs: node.outputs ?? node.wires?.length ?? 0,
set: registry.getNodeSet("node-red/unknown")
};
}
}
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 (subflow_denylist[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 (createMissingWorkspace) {
if (missingWorkspace === null) {
missingWorkspace = RED.workspaces.add(null, true);
newWorkspaces.push(missingWorkspace);
if (createNewWorkspace) {
if (newWorkspace === null) {
newWorkspace = RED.workspaces.add(null, true);
newWorkspaces.push(newWorkspace);
}
node.z = missingWorkspace.id;
node.z = newWorkspace.id;
} else {
node.z = activeWorkspace;
}
@ -2279,19 +2286,34 @@ RED.nodes = (function() {
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]))) {
// TODO: Encore ?
if (createMissingWorkspace) {
if (missingWorkspace === null) {
missingWorkspace = RED.workspaces.add(null,true);
newWorkspaces.push(missingWorkspace);
if (createNewWorkspace) {
if (newWorkspace === null) {
newWorkspace = RED.workspaces.add(null,true);
newWorkspaces.push(newWorkspace);
}
node.z = missingWorkspace.id;
node.z = newWorkspace.id;
} else {
node.z = activeWorkspace;
}
}
}
// Update the node definition for subflow instance
if (!isUnknownNode && node.type.substring(0, 7) === "subflow") {
const parentId = node.type.split(":")[1];
const subflow = subflowDenyList[parentId] || subflowMap[parentId] || getSubflow(parentId);
if (subflowDenyList[parentId] || createNewIds || options.importMap[node.id] === "copy") {
node.type = "subflow:" + subflow.id;
def = registry.getNodeType(node.type);
}
node.inputs = subflow.in.length;
node.outputs = subflow.out.length;
}
// Now the properties have been corrected, copy the node properties:
// Config Node
if (isConfigNode) {
// TODO: A quoi sert ce bloc ? Replace?
@ -2320,41 +2342,26 @@ RED.nodes = (function() {
if (!existingConfigNode || existingConfigNode._def.exclusive) { //} || !compareNodes(existingConfigNode,n,true) || existingConfigNode.z !== n.z) {
nodeMap[oldId] = copyConfigNode(node, def, options);
}
//nodeMap[oldId] = copyConfigNode(node, def, options);
// Node, Group, Junction or Subflow
} else if (def || node.type === "group") {
nodeMap[oldId] = copyNode(node, def, options);
// Unknown Node
} else {
// Config Node
if (!node.x && !node.y) {
node._def = {
category: "config",
set: registry.getNodeSet("node-red/unknown")
};
} else {
node._def = {
color: "#fee",
defaults: {},
label: "unknown: " + node.type,
labelStyle: "red-ui-flow-node-label-italic",
outputs: node.outputs ?? node.wires?.length ?? 0,
set: registry.getNodeSet("node-red/unknown")
};
}
nodeMap[oldId] = copyNode(node, def, options);
}
// Unknown Node
// TODO: Error: Cannot find subflow defintion 148a957f98ce9770 used by subflow instance 6d7f8e702e60f976
if (isUnknownNode && !node.type.startsWith("subflow")) {
const propertiesNotCopyable = ["x", "y", "z", "id", "wires"];
node._orig = Object.entries(node).reduce(function (orig, [prop, value]) {
nodeMap[oldId]._orig = Object.entries(node).reduce(function (orig, [prop, value]) {
if (node.hasOwnProperty(prop) && !propertiesNotCopyable.includes(prop)) {
orig[prop] = value;
}
return orig;
}, {});
node.name = node.type;
node.type = "unknown";
nodeMap[oldId] = node;
nodeMap[oldId].name = node.type;
nodeMap[oldId].type = "unknown";
}
// Now the properties have been copied, change the `id` if it's a copy
// Now the node has been copied, change the `id` if it's a copy
if (createNewIds || options.importMap[oldId] === "copy") {
nodeMap[oldId].id = getID();
}
@ -2445,6 +2452,7 @@ RED.nodes = (function() {
}
}
// Add Links to Workspace
for (const subflow of newSubflows) {
subflow.in.forEach(function (input) {
input.wires.forEach(function (wire) {
@ -2486,38 +2494,38 @@ RED.nodes = (function() {
}
// Order the groups to ensure they are outer-most to inner-most
var groupDepthMap = {};
const groupDepthMap = {};
const groupsId = newGroups.map(function (group) { return group.id; });
for (const group of newGroups) {
// Delete the group if it is not part of the import
if (group.g && !groupsId.includes(group.g)) {
delete group.g;
}
// If the group does not contain a group, it's the outer-most
if (!group.g) {
groupDepthMap[group.id] = 0;
}
}
// TODO: C'est quoi ce brol ?
var changedDepth;
let changedDepth;
do {
changedDepth = false;
for (let i=0;i<newGroups.length;i++) {
const n = newGroups[i];
if (n.g) {
if (groupDepthMap[n.id] !== groupDepthMap[n.g] + 1) {
groupDepthMap[n.id] = groupDepthMap[n.g] + 1;
for (const group of newGroups) {
if (group.g) {
if (groupDepthMap[group.id] !== groupDepthMap[group.g] + 1) {
groupDepthMap[group.id] = groupDepthMap[group.g] + 1;
changedDepth = true;
}
}
}
} while(changedDepth);
console.log("GROUP", groupDepthMap);
newGroups.sort(function(a, b) {
newGroups.sort(function (a, b) {
return (groupDepthMap[a.id] - groupDepthMap[b.id]);
});
// Add Groups to Workspace
for (const index in newGroups) {
if (newGroups.indexOf(newGroups[index]) !== -1) {
newGroups[index] = addGroup(newGroups[index]);
@ -2525,6 +2533,7 @@ RED.nodes = (function() {
}
}
// Add Junctions to Workspace
for (const index in newJunctions) {
if (newJunctions.indexOf(newJunctions[index]) !== -1) {
newJunctions[index] = addJunction(newJunctions[index]);
@ -2589,7 +2598,7 @@ RED.nodes = (function() {
junctions: newJunctions,
workspaces: newWorkspaces,
subflows: newSubflows,
missingWorkspace: missingWorkspace,
missingWorkspace: newWorkspace,
removedNodes: removedNodes
};
}