diff --git a/api/src/chat/repositories/block.repository.ts b/api/src/chat/repositories/block.repository.ts index 78903a3c..ec2a3f64 100644 --- a/api/src/chat/repositories/block.repository.ts +++ b/api/src/chat/repositories/block.repository.ts @@ -140,12 +140,12 @@ export class BlockRepository extends BaseRepository< // Step 1: Map IDs and Category const objIds = ids.map((id) => new Types.ObjectId(id)); - const objCategoryId = new Types.ObjectId(categoryId); + const sourceCategoryId = movedBlocks[0].category; - // Step 2: Find other blocks + // Step 2: Find blocks in source category that reference the moved blocks const otherBlocks = await this.find({ _id: { $nin: objIds }, - category: { $ne: objCategoryId }, + category: sourceCategoryId, $or: [ { attachedBlock: { $in: objIds } }, { nextBlocks: { $in: objIds } }, @@ -154,7 +154,7 @@ export class BlockRepository extends BaseRepository< // Step 3: Update blocks in the provided scope await this.prepareBlocksInCategoryUpdateScope(categoryId, ids); - // Step 4: Update external blocks + // Step 4: Update blocks in source category await this.prepareBlocksOutOfCategoryUpdateScope(otherBlocks, ids); } } @@ -178,18 +178,27 @@ export class BlockRepository extends BaseRepository< }); for (const { id, nextBlocks, attachedBlock } of blocks) { - const updatedNextBlocks = nextBlocks.filter((nextBlock) => - ids.includes(nextBlock), - ); + try { + const updatedNextBlocks = nextBlocks.filter((nextBlock) => + ids.includes(nextBlock), + ); - const updatedAttachedBlock = ids.includes(attachedBlock || '') - ? attachedBlock - : null; + const updatedAttachedBlock = ids.includes(attachedBlock || '') + ? attachedBlock + : null; - await this.updateOne(id, { - nextBlocks: updatedNextBlocks, - attachedBlock: updatedAttachedBlock, - }); + const updates: Partial = { + nextBlocks: updatedNextBlocks, + attachedBlock: updatedAttachedBlock, + }; + + await this.updateOne(id, updates); + } catch (error) { + this.logger?.error( + `Failed to update block ${id} during in-category scope update.`, + error, + ); + } } } @@ -206,16 +215,33 @@ export class BlockRepository extends BaseRepository< ids: string[], ): Promise { for (const block of otherBlocks) { - if (block.attachedBlock && ids.includes(block.attachedBlock)) { - await this.updateOne(block.id, { attachedBlock: null }); - } + try { + const updates: Partial = {}; - const nextBlocks = block.nextBlocks?.filter( - (nextBlock) => !ids.includes(nextBlock), - ); + // Check if the block has an attachedBlock + if (block.attachedBlock) { + if (ids.includes(block.attachedBlock)) { + updates.attachedBlock = null; + } + } else { + // Only check nextBlocks if there is no attachedBlock + const filteredNextBlocks = block.nextBlocks?.filter( + (nextBlock) => !ids.includes(nextBlock), + ); - if (nextBlocks?.length) { - await this.updateOne(block.id, { nextBlocks }); + if (filteredNextBlocks?.length !== block.nextBlocks?.length) { + updates.nextBlocks = filteredNextBlocks || []; + } + } + + if (Object.keys(updates).length > 0) { + await this.updateOne(block.id, updates); + } + } catch (error) { + this.logger?.error( + `Failed to update block ${block.id} during out-of-category scope update.`, + error, + ); } } } diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index 5173d80f..50dbac01 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -118,6 +118,7 @@ "logout_failed": "Something went wrong during logout", "duplicate_labels_not_allowed": "Duplicate labels are not allowed", "duplicate_block_error": "Something went wrong while duplicating block", + "move_block_error": "Something went wrong. Unable to move block", "image_error": "Image not found", "file_error": "File not found", "audio_error": "Audio not found", diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json index 8bc2f29f..a50eac87 100644 --- a/frontend/public/locales/fr/translation.json +++ b/frontend/public/locales/fr/translation.json @@ -118,6 +118,7 @@ "logout_failed": "Une erreur s'est produite lors de la déconnexion", "duplicate_labels_not_allowed": "Les étiquettes en double ne sont pas autorisées", "duplicate_block_error": "Une erreur est survenue lors de la duplication du bloc", + "move_block_error": "Une erreur est survenue. Impossible de déplacer le bloc", "image_error": "Image introuvable", "file_error": "Fichier introuvable", "audio_error": "Audio introuvable", diff --git a/frontend/src/components/visual-editor/v2/Diagrams.tsx b/frontend/src/components/visual-editor/v2/Diagrams.tsx index f6708e09..5f03b6b7 100644 --- a/frontend/src/components/visual-editor/v2/Diagrams.tsx +++ b/frontend/src/components/visual-editor/v2/Diagrams.tsx @@ -559,9 +559,14 @@ const Diagrams = () => { }, }); - onCategoryChange( - categories.findIndex(({ id }) => id === targetCategoryId), + const targetCategoryIndex = categories.findIndex( + ({ id }) => id === targetCategoryId, ); + + onCategoryChange(targetCategoryIndex); + }, + onError: () => { + toast.error(t("message.move_block_error")); }, }, );