diff --git a/Projects/Foundations/UI/Function-Libraries/ProtocolNode.js b/Projects/Foundations/UI/Function-Libraries/ProtocolNode.js index 50696f57c..1fdc985b3 100644 --- a/Projects/Foundations/UI/Function-Libraries/ProtocolNode.js +++ b/Projects/Foundations/UI/Function-Libraries/ProtocolNode.js @@ -259,13 +259,25 @@ function newFoundationsFunctionLibraryProtocolNode() { name: node.payload.referenceParent.name, id: node.payload.referenceParent.id } + // If the path has not been saved save it now + if (node.payload.referenceParentCombinedNodePath === undefined) { + let attachNodePath = UI.projects.foundations.utilities.hierarchy.getNodeNameTypePath(node.payload.referenceParent) + // Save path to reference parent for auto restore + savedPayload.referenceParentCombinedNodePath = { path: attachNodePath } + } else { + // Save path to reference parent for auto restore + savedPayload.referenceParentCombinedNodePath = node.payload.referenceParentCombinedNodePath + } } else { /* The referenceParent property can be inherited from the previous saved payload. */ if (node.savedPayload !== undefined) { savedPayload.referenceParent = node.savedPayload.referenceParent + // Save path to reference parent for auto restore + savedPayload.referenceParentCombinedNodePath = node.savedPayload.referenceParentCombinedNodePath } } } + return savedPayload } } diff --git a/Projects/Foundations/UI/Function-Libraries/ReferenceAttachDetach.js b/Projects/Foundations/UI/Function-Libraries/ReferenceAttachDetach.js index eaeee4f98..c50184947 100644 --- a/Projects/Foundations/UI/Function-Libraries/ReferenceAttachDetach.js +++ b/Projects/Foundations/UI/Function-Libraries/ReferenceAttachDetach.js @@ -7,17 +7,39 @@ function newFoundationsFunctionLibraryAttachDetach() { return thisObject function referenceDetachNode(node) { - completeDetachment(node) + cleanAttachNodePath(node) + completeDetachment(node) + } function referenceAttachNode(node, attachToNode) { + storeAttachNodePath(node, attachToNode) completeAttachment(node, attachToNode) } + // Store the path to the reference parent to make restoring it possible if the reference partent is updated and given a new id + function storeAttachNodePath(node, attachToNode) { + let attachNodePath = UI.projects.foundations.utilities.hierarchy.getNodeNameTypePath(attachToNode) + // Save attach path to active payload + node.payload.referenceParentCombinedNodePath = attachNodePath + } + + // Clear the path to reference parent when the reference is cleared + function cleanAttachNodePath(node){ + if (node.payload !== undefined) { + node.payload.referenceParentCombinedNodePath = undefined + if (node.savedPayload !== undefined) { + node.savedPayload.referenceParentCombinedNodePath = undefined + } + } + } + + // Establish the reference between node and it's reference parent function completeAttachment(node, attachToNode) { node.payload.referenceParent = attachToNode } + // Detach the reference between node and it's reference parent function completeDetachment(node) { if (node.payload !== undefined) { if (node.payload.referenceParent !== undefined) { diff --git a/Projects/Foundations/UI/Function-Libraries/UiObjectsFromNodes.js b/Projects/Foundations/UI/Function-Libraries/UiObjectsFromNodes.js index 987a87b04..c9d079d0a 100644 --- a/Projects/Foundations/UI/Function-Libraries/UiObjectsFromNodes.js +++ b/Projects/Foundations/UI/Function-Libraries/UiObjectsFromNodes.js @@ -295,6 +295,7 @@ function newFoundationsFunctionLibraryUiObjectsFromNodes() { console.log('ACA') } if (node.payload === undefined) { continue } + if (node.payload.referenceParent !== undefined) { if (node.payload.referenceParent.cleaned === true) { node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id) @@ -306,13 +307,89 @@ function newFoundationsFunctionLibraryUiObjectsFromNodes() { continue // In this case the reference is already good. } } + if (node.savedPayload !== undefined) { if (node.savedPayload.referenceParent !== undefined) { // these are children recreated + // Reestablish based on Id node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id) - if (node.payload.referenceParent === undefined) { - //console.log('[WARN]' + node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') - } - } + + // if Reestablishment failed now reestablish reference based on saved path + if (node.payload.referenceParent === undefined) { + console.log('this node failed to connect by id ' + node.type + ' ' + node.name, node ) + // Gather saved path + let rawPath = node.savedPayload.referenceParentCombinedNodePath + if (rawPath !== undefined) { + // Step down node hierarchy to find missing referenceParent + let pathNode + let pathName + let pathType + for (let i = 0; i < rawPath.length; i++) { + + // Get Hierarchy head node + if (i === 0) { + pathName = rawPath[i][0] + pathType = rawPath[i][1] + pathNode = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByCodeNameAndNodeType( pathName, pathType ) + // If reference parent is workspace node grab node + if (pathType === "Workspace") { + pathNode = UI.projects.foundations.spaces.designSpace.workspace.workspaceNode + } + continue + } else { // Walk through children nodes and find the next node from saved path + pathName = rawPath[i][0] + pathType = rawPath[i][1] + pathNode = getNextNodeFromPath(pathNode, pathName, pathType) + } + } + if (pathNode !== undefined ) { + UI.projects.foundations.functionLibraries.attachDetach.referenceAttachNode(node, pathNode) + } else { + console.log("[WARN] ", node.name, ' ', node.type, "failed to fix reference. Unable to find reference parent ", pathName, ' ', pathType ) + } + + function getNextNodeFromPath(node, pathName, pathType) { + let schemaDocument = getSchemaDocument(node) + let nextNode = undefined + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + + let property = schemaDocument.childrenNodesProperties[i] + switch (property.type) { + // If child node is directly withing parent node look for it + case 'node': { + if (node[property.name] !== undefined) { + if (node[property.name].name === pathName && node[property.name].type === pathType) { + nextNode = node[property.name] + console.log("we have a match!", nextNode) + return nextNode + } + } + break + } + // If child node is in an array look for it + case 'array': { + if (node[property.name] !== undefined) { + let nodePropertyArray = node[property.name] + for (let m = 0; m < nodePropertyArray.length; m++) { + if (nodePropertyArray[m].name === pathName && nodePropertyArray[m].type === pathType) { + + nextNode = nodePropertyArray[m] + return nextNode + } + } + } + break + } + } + + } + } + } + } + if (node.payload.referenceParent === undefined) { + console.log('[WARN]' + node.type + ' ' + node.name + ' reference parent lost during re-binding phase.') + } + + } } } } diff --git a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js index 711f5f20d..907ab42cd 100644 --- a/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js +++ b/Projects/Foundations/UI/Spaces/Design-Space/Workspace.js @@ -558,6 +558,9 @@ function newWorkspace() { let hierarchyHeadCodeName = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(hierarchyHead.payload, 'codeName') if (hierarchyHeadCodeName === codeName && hierarchyHead.type === nodeType) { return hierarchyHead + } else if (hierarchyHead.name === codeName && hierarchyHead.type === nodeType) { + // This condition is used for auto fixing references in UiObjectsFromNodes.js + return hierarchyHead } } }