265 lines
9.5 KiB
JavaScript
265 lines
9.5 KiB
JavaScript
function newUiObjectsFromNodes () {
|
|
thisObject = {
|
|
recreateWorkspace: recreateWorkspace,
|
|
tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents,
|
|
createUiObjectFromNode: createUiObjectFromNode,
|
|
addUIObject: addUIObject,
|
|
addMissingChildren: addMissingChildren
|
|
}
|
|
|
|
let mapOfReferenceChildren = new Map()
|
|
let mapOfNodes
|
|
|
|
return thisObject
|
|
|
|
function recreateWorkspace (node) {
|
|
mapOfNodes = new Map()
|
|
|
|
/* Create the workspace UI OBject and then continue with the root nodes. */
|
|
createUiObject(false, 'Workspace', node.name, node, undefined, undefined, 'Workspace')
|
|
if (node.rootNodes !== undefined) {
|
|
for (let i = 0; i < node.rootNodes.length; i++) {
|
|
let rootNode = node.rootNodes[i]
|
|
createUiObjectFromNode(rootNode, undefined, undefined)
|
|
}
|
|
}
|
|
|
|
tryToConnectChildrenWithReferenceParents()
|
|
}
|
|
|
|
function tryToConnectChildrenWithReferenceParents () {
|
|
/* We reconstruct here the reference relationships. */
|
|
for (const [key, node] of mapOfNodes) {
|
|
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)
|
|
continue // We were referencing a deleted node, so we replace it potentially with a newly created one.
|
|
} else {
|
|
continue // In this case the reference is already good.
|
|
}
|
|
}
|
|
if (node.savedPayload !== undefined) {
|
|
if (node.savedPayload.referenceParent !== undefined) { // these are children recreated
|
|
node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function createUiObjectFromNode (node, parentNode, chainParent, positionOffset) {
|
|
/* Get node definition */
|
|
let nodeDefinition = APP_SCHEMA_MAP.get(node.type)
|
|
if (nodeDefinition !== undefined) {
|
|
/* Resolve Initial Values */
|
|
if (nodeDefinition.initialValues !== undefined) {
|
|
if (nodeDefinition.initialValues.code !== undefined) {
|
|
if (node.code === undefined) {
|
|
node.code = nodeDefinition.initialValues.code
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Create Self */
|
|
createUiObject(false, node.type, node.name, node, parentNode, chainParent, node.type, positionOffset)
|
|
|
|
/* Create Children */
|
|
if (nodeDefinition.properties !== undefined) {
|
|
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
|
for (let i = 0; i < nodeDefinition.properties.length; i++) {
|
|
let property = nodeDefinition.properties[i]
|
|
if (node[property.name] !== undefined) {
|
|
switch (property.type) {
|
|
case 'node': {
|
|
if (property.name !== previousPropertyName) {
|
|
createUiObjectFromNode(node[property.name], node, node, positionOffset)
|
|
previousPropertyName = property.name
|
|
}
|
|
}
|
|
break
|
|
case 'array': {
|
|
let nodePropertyArray = node[property.name]
|
|
for (let m = 0; m < nodePropertyArray.length; m++) {
|
|
let arrayItem = nodePropertyArray[m]
|
|
createUiObjectFromNode(arrayItem, node, node, positionOffset)
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function addUIObject (parent, type) {
|
|
let object = {
|
|
name: 'New ' + type,
|
|
type: type
|
|
}
|
|
|
|
let parentNodeDefinition = APP_SCHEMA_MAP.get(parent.type)
|
|
if (parentNodeDefinition !== undefined) {
|
|
/* Resolve Initial Values */
|
|
let nodeDefinition = APP_SCHEMA_MAP.get(object.type)
|
|
|
|
if (nodeDefinition.isHierarchyHead === true) {
|
|
parent.rootNodes.push(object)
|
|
createUiObject(true, object.type, object.name, object, parent, undefined)
|
|
return object
|
|
}
|
|
|
|
createUiObject(true, object.type, object.name, object, parent, parent)
|
|
|
|
if (nodeDefinition !== undefined) {
|
|
if (nodeDefinition.initialValues !== undefined) {
|
|
if (nodeDefinition.initialValues.code !== undefined) {
|
|
object.code = nodeDefinition.initialValues.code
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Connect to Parent */
|
|
if (parentNodeDefinition.properties !== undefined) {
|
|
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
|
for (let i = 0; i < parentNodeDefinition.properties.length; i++) {
|
|
let property = parentNodeDefinition.properties[i]
|
|
if (property.childType === type) {
|
|
switch (property.type) {
|
|
case 'node': {
|
|
if (property.name !== previousPropertyName) {
|
|
parent[property.name] = object
|
|
previousPropertyName = property.name
|
|
}
|
|
}
|
|
break
|
|
case 'array': {
|
|
if (parent[property.name] === undefined) {
|
|
parent[property.name] = []
|
|
}
|
|
parent[property.name].push(object)
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return object
|
|
}
|
|
|
|
function addMissingChildren (node) {
|
|
|
|
}
|
|
|
|
function createUiObject (userAddingNew, uiObjectType, name, node, parentNode, chainParent, title, positionOffset) {
|
|
let payload = {}
|
|
|
|
/* Mechanism related to keeping references when cloning */
|
|
if (node.id === undefined) {
|
|
node.id = newUniqueId()
|
|
} else {
|
|
let testNode = mapOfNodes.get(node.id)
|
|
if (testNode !== undefined && testNode.cleaned !== true) {
|
|
node.id = newUniqueId()
|
|
}
|
|
}
|
|
|
|
/* Default Naming */
|
|
if (name === '' || name === undefined) { name = 'My ' + uiObjectType }
|
|
|
|
/* If we are creating this object as the result of restoring a backup, share or clone, we will bring some of the saved properties to the new running instance. */
|
|
if (userAddingNew === false && uiObjectType !== 'Workspace') {
|
|
/* This following info can not be missing. */
|
|
if (node.savedPayload === undefined) {
|
|
console.log('Node ' + node.type + ' without savedPayload.', node)
|
|
return
|
|
}
|
|
if (node.savedPayload.position === undefined) {
|
|
console.log('Node ' + node.type + ' without savedPayload.position.', node)
|
|
return
|
|
}
|
|
if (node.savedPayload.targetPosition === undefined) {
|
|
console.log('Node ' + node.type + ' without savedPayload.targetPosition.', node)
|
|
return
|
|
}
|
|
|
|
/* If there is not a position offset, which happens when we are dropping a node into the designer, we create a cero vector then. */
|
|
if (positionOffset === undefined) {
|
|
positionOffset = {
|
|
x: 0,
|
|
y: 0
|
|
}
|
|
}
|
|
|
|
/* Adding the offset to the saved positions. */
|
|
node.savedPayload.targetPosition.x = node.savedPayload.targetPosition.x + positionOffset.x
|
|
node.savedPayload.targetPosition.y = node.savedPayload.targetPosition.y + positionOffset.y
|
|
node.savedPayload.position.x = node.savedPayload.position.x + positionOffset.x
|
|
node.savedPayload.position.y = node.savedPayload.position.y + positionOffset.y
|
|
|
|
/* Transferring the saved payload properties into the running instance being created. */
|
|
payload.targetPosition = {
|
|
x: node.savedPayload.targetPosition.x,
|
|
y: node.savedPayload.targetPosition.y
|
|
}
|
|
node.savedPayload.targetPosition = undefined
|
|
|
|
/* Reference children connection to parents */
|
|
if (node.savedPayload.referenceParent !== undefined) {
|
|
payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id)
|
|
|
|
if (payload.referenceParent !== undefined) {
|
|
mapOfReferenceChildren.set(node.id, node)
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If we are adding a new object, then we set the initial values for position and targetPosition */
|
|
if (userAddingNew === true || uiObjectType === 'Workspace') {
|
|
/* Workspace allways to the spawn position */
|
|
if (uiObjectType === 'Workspace') {
|
|
payload.position = {
|
|
x: spawnPosition.x,
|
|
y: spawnPosition.y
|
|
}
|
|
}
|
|
|
|
/* Chain parent pointing to the position of the chain parent if defined. */
|
|
if (chainParent === undefined) {
|
|
payload.targetPosition = {
|
|
x: spawnPosition.x,
|
|
y: spawnPosition.y
|
|
}
|
|
} else {
|
|
payload.targetPosition = {
|
|
x: chainParent.payload.position.x,
|
|
y: chainParent.payload.position.y
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Setting the title */
|
|
if (title !== undefined) {
|
|
payload.subTitle = title
|
|
} else {
|
|
payload.subTitle = uiObjectType
|
|
}
|
|
|
|
payload.visible = true
|
|
payload.title = name
|
|
payload.node = node
|
|
payload.parentNode = parentNode
|
|
payload.chainParent = chainParent
|
|
payload.onMenuItemClick = canvas.designerSpace.workspace.onMenuItemClick
|
|
|
|
node.payload = payload
|
|
node.type = uiObjectType
|
|
|
|
/* Now we mount the floating object where the UIOBject will be laying on top of */
|
|
canvas.floatingSpace.uiObjectConstructor.createUiObject(userAddingNew, payload)
|
|
|
|
mapOfNodes.set(node.id, node)
|
|
}
|
|
}
|