diff --git a/plugins/document-resources/src/components/Move.svelte b/plugins/document-resources/src/components/Move.svelte index 9503f39842..3c295fc463 100644 --- a/plugins/document-resources/src/components/Move.svelte +++ b/plugins/document-resources/src/components/Move.svelte @@ -27,15 +27,63 @@ const client = getClient() const dispatch = createEventDispatcher() + let space: Ref = value.space + let parent: Ref = value.attachedTo + + let children: Ref[] = [] + $: void updateChildren(value) + + async function updateChildren (doc: Document): Promise { + children = await findChildren(doc) + } + async function save (): Promise { - await client.update(value, { + const ops = client.apply(value._id) + + await ops.update(value, { space, attachedTo: parent ?? document.ids.NoParent }) + + if (space !== value.space) { + const children = await findChildren(value) + for (const child of children) { + await client.updateDoc(document.class.Document, value.space, child, { + space + }) + } + } + + await ops.commit() } - let space: Ref = value.space - let parent: Ref = value.attachedTo + async function findChildren (doc: Document): Promise>> { + const documents = await client.findAll( + document.class.Document, + { space: doc.space, attachedTo: { $ne: document.ids.NoParent } }, + { projection: { _id: 1, attachedTo: 1 } } + ) + + const byParent = new Map, Array>>() + for (const document of documents) { + const group = byParent.get(document.attachedTo) ?? [] + group.push(document._id) + byParent.set(document.attachedTo, group) + } + + const result: Ref[] = [] + + const queue = [doc._id] + while (true) { + const next = queue.pop() + if (next === undefined) break + const children = byParent.get(next) ?? [] + result.push(...children) + queue.push(...children) + } + + return result + } $: canSave = space !== value.space || parent !== value.attachedTo @@ -59,6 +107,9 @@ defaultIcon={document.icon.Teamspace} kind={'regular'} size={'small'} + on:change={() => { + parent = document.ids.NoParent + }} />