feat: implement updateTagTreeStatus function to manage tag status updates without mutating original tree
This commit is contained in:
@@ -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])
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user