feat: implement updateTagTreeStatus function to manage tag status updates without mutating original tree

This commit is contained in:
mlogclub
2026-05-30 21:02:37 +08:00
parent 21ac67de5e
commit 6f05d1ebcc
3 changed files with 53 additions and 1 deletions
+11
View File
@@ -102,3 +102,14 @@ test("flattens only visible branches when a parent is collapsed", async () => {
JSON.stringify([1, 3])
)
})
test("updates a tag status in tree data without mutating the original tree", async () => {
const { updateTagTreeStatus } = await loadModule()
const nextTags = updateTagTreeStatus(tags, 2, 1)
assert.equal(tags[0].children[0].status, 0)
assert.equal(nextTags[0].children[0].status, 1)
assert.equal(nextTags[0].status, 0)
assert.equal(nextTags[1], tags[1])
})
+37
View File
@@ -87,3 +87,40 @@ export function flattenVisibleTagTree(
walk(nodes, 0, "")
return result
}
type MutableTagTreeLike<T> = {
id: number
status: number
children: T[]
}
export function updateTagTreeStatus<T extends MutableTagTreeLike<T>>(
nodes: T[] | null | undefined,
id: number,
status: number
): T[] {
const safeNodes = Array.isArray(nodes) ? nodes : []
function walk(items: T[]): { nodes: T[]; changed: boolean } {
let changed = false
const nextNodes = items.map((item) => {
const nextChildren = walk(item.children)
const statusChanged = item.id === id && item.status !== status
if (!statusChanged && !nextChildren.changed) {
return item
}
changed = true
return {
...item,
status: statusChanged ? status : item.status,
children: nextChildren.nodes,
}
})
return { nodes: changed ? nextNodes : items, changed }
}
return walk(safeNodes).nodes
}