You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Application-Web/src/editor/StepsDomain.ts

113 lines
2.5 KiB

import { StepInfoNode } from "../model/tactic/Tactic"
export function addStepNode(
root: StepInfoNode,
parent: StepInfoNode,
child: StepInfoNode,
): StepInfoNode {
if (root.id === parent.id) {
return {
...root,
children: root.children.concat(child),
}
}
return {
...root,
children: root.children.map((c) => addStepNode(c, parent, child)),
}
}
export function getStepName(root: StepInfoNode, step: number): string {
let ord = 1
const nodes = [root]
while (nodes.length > 0) {
const node = nodes.pop()!
if (node.id === step) break
ord++
nodes.push(...[...node.children].reverse())
}
return ord.toString()
}
export function getStepNode(
root: StepInfoNode,
stepId: number,
): StepInfoNode | undefined {
if (root.id === stepId) return root
for (const child of root.children) {
const result = getStepNode(child, stepId)
if (result) return result
}
}
export function removeStepNode(
root: StepInfoNode,
targetId: number,
): StepInfoNode | undefined {
const path = getPathTo(root, targetId)
path.reverse()
const [removedNode, ...pathToRoot] = path
let child = removedNode
for (const node of pathToRoot) {
child = {
id: node.id,
children: node.children.flatMap((c) => {
if (c.id === removedNode.id) return []
else if (c.id === child.id) {
return [child]
}
return [c]
}),
}
}
return child
}
export function getPathTo(
root: StepInfoNode,
targetId: number,
): StepInfoNode[] {
if (root.id === targetId) return [root]
for (const child of root.children) {
const subPath = getPathTo(child, targetId)
if (subPath.length > 0) return [root, ...subPath]
}
return []
}
/**
* Returns an available identifier that is not already present into the given node tree
* @param root
*/
export function getAvailableId(root: StepInfoNode): number {
const acc = (root: StepInfoNode): number =>
Math.max(root.id, ...root.children.map(acc))
return acc(root) + 1
}
export function getParent(
root: StepInfoNode,
node: StepInfoNode,
): StepInfoNode | null {
if (root.children.find((n) => n.id === node.id)) return root
for (const child of root.children) {
const result = getParent(child, node)
if (result != null) {
return result
}
}
return null
}