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.
113 lines
2.5 KiB
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
|
|
}
|