From fefad8a9e34a8f5e7d76fc125fe3175a8ab8d5ab Mon Sep 17 00:00:00 2001 From: abaevbog Date: Mon, 6 Oct 2025 12:30:01 -0700 Subject: [PATCH] Fix item sometimes not added to collection on cross-library drag-drop (#5547) When drag-dropping items into a collection in another library, perform the addition to collection in the same transaction as creating a new item in the target library. When the librariesCollectionsBox refreshes on the `modify` event when a newly created group item is linked to the selected item, it re-loads the data of the linked item via item.loadAllData(). This could happen after the item is added to the collection but before this change is saved. In that case, item._changed.collections would be cleared, and when the item is saved, there would be no changes to collections to save. Fixes: #5539 Also, cleanup leftover unused logic of restoring linked item from trash on drop that was removed in 2dd16b44d654669255463cb7342055708b92c593 --- chrome/content/zotero/collectionTree.jsx | 49 +++++++++++++----------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/chrome/content/zotero/collectionTree.jsx b/chrome/content/zotero/collectionTree.jsx index f9bd4d77a8..7350cd6db8 100644 --- a/chrome/content/zotero/collectionTree.jsx +++ b/chrome/content/zotero/collectionTree.jsx @@ -1896,15 +1896,6 @@ var CollectionTree = class CollectionTree extends LibraryTree { // Check if there's already a copy of this item in the library var linkedItem = await item.getLinkedItem(targetLibraryID, true); if (linkedItem) { - // If linked item is in the trash, undelete it and remove it from collections - // (since it shouldn't be restored to previous collections) - if (linkedItem.deleted) { - linkedItem.setCollections(); - linkedItem.deleted = false; - await linkedItem.save({ - skipSelect: true - }); - } return linkedItem.id; /* @@ -2298,8 +2289,20 @@ var CollectionTree = class CollectionTree extends LibraryTree { toMove.push(item.id); } } - - if (!sameLibrary) { + if (sameLibrary) { + // Add items to target container in the same library. + if (targetCollectionID) { + let ids = newIDs.filter(itemID => Zotero.Items.get(itemID).isTopLevelItem()); + await Zotero.DB.executeTransaction(async function () { + let collection = await Zotero.Collections.getAsync(targetCollectionID); + await collection.addItems(ids); + }.bind(this)); + } + else if (targetTreeRow.isPublications()) { + await Zotero.Items.addToPublications(newItems, copyOptions); + } + } + else { let toReconcile = []; await Zotero.Utilities.Internal.forEachChunkAsync( @@ -2307,6 +2310,7 @@ var CollectionTree = class CollectionTree extends LibraryTree { 100, function (chunk) { return Zotero.DB.executeTransaction(async () => { + let copiedItemIDs = []; for (let item of chunk) { var id = await this._copyItem({ item, @@ -2318,7 +2322,17 @@ var CollectionTree = class CollectionTree extends LibraryTree { if (!id) { continue; } - newIDs.push(id); + copiedItemIDs.push(id); + } + // Add copied items to target collection + if (targetCollectionID) { + for (let itemID of copiedItemIDs) { + let item = Zotero.Items.get(itemID); + if (item.isTopLevelItem()) { + item.addToCollection(targetCollectionID); + await item.save({ skipSelect: true }); + } + } } }); }.bind(this) @@ -2360,17 +2374,6 @@ var CollectionTree = class CollectionTree extends LibraryTree { } } - // Add items to target collection - if (targetCollectionID) { - let ids = newIDs.filter(itemID => Zotero.Items.get(itemID).isTopLevelItem()); - await Zotero.DB.executeTransaction(async function () { - let collection = await Zotero.Collections.getAsync(targetCollectionID); - await collection.addItems(ids); - }.bind(this)); - } - else if (targetTreeRow.isPublications()) { - await Zotero.Items.addToPublications(newItems, copyOptions); - } // If moving, remove items from source collection if (dropEffect == 'move' && toMove.length) {