Fix child attachment shows up in item pane after being moved to trash (#4777)

fix: #4770
This commit is contained in:
windingwind 2024-11-12 06:14:15 +01:00 committed by GitHub
parent 055fbb68fc
commit c937b36e25
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 98 additions and 1 deletions

View file

@ -95,6 +95,16 @@
return this._preview;
}
get _renderDependencies() {
if (this.item?.isRegularItem()) {
// Render dependencies are used to determine if a re-render is necessary.
// By including the list of attachment IDs as string, we ensure that it
// will re-render if attachments are added or removed.
return [...super._renderDependencies, this.item.getAttachments().join(',')];
}
return super._renderDependencies;
}
init() {
this.initCollapsibleSection();
this._section.addEventListener('add', this._handleAdd);
@ -139,9 +149,10 @@
}
notify(action, type, ids) {
if (!(action === 'add' || action === 'modify' || action === 'refresh' || action === 'delete')) {
if (!['add', 'modify', 'refresh', 'delete', 'trash'].includes(action)) {
return;
}
if (!this._item?.isRegularItem()) return;
this._updateAttachmentIDs().then(() => {
@ -180,6 +191,8 @@
if (this._isAlreadyRendered()) return;
this._renderStage = "initial";
this.updateCount();
// Reset the async render dependencies to allow re-rendering
delete this._asyncRenderDependencies;
}
async asyncRender() {

View file

@ -1259,6 +1259,90 @@ describe("Item pane", function () {
win.resizeTo(null, height);
attachmentsBox._discardPreviewTimeout = currentDiscardTimeout;
});
it("should update after attachment is trashed or restored", async function () {
// https://github.com/zotero/zotero/issues/4770
let itemDetails = ZoteroPane.itemPane._itemDetails;
let attachmentsBox = itemDetails.getPane(paneID);
let item = await createDataObject('item');
let attachment = await importFileAttachment('test.pdf', { parentID: item.id });
function getAttachmentRow() {
return attachmentsBox.querySelector(`attachment-row[attachment-id="${attachment.id}"]`);
}
await ZoteroPane.selectItem(item.id);
await waitForScrollToPane(itemDetails, paneID);
await waitForPreviewBoxRender(attachmentsBox);
// Trash the attachment
let trashPromise = waitForNotifierEvent('trash', 'item');
await Zotero.Items.trashTx([attachment.id]);
await trashPromise;
// Wait for the attachment row to be hidden
await waitForCallback(
() => getAttachmentRow().hidden
, 100, 3);
assert.isTrue(getAttachmentRow().hidden);
// Restore the attachment
let restorePromise = waitForNotifierEvent('modify', 'item');
attachment.deleted = false;
await attachment.saveTx();
await restorePromise;
// Wait for the attachment row to exist and be visible
await waitForCallback(
() => getAttachmentRow()?.hidden === false
, 100, 3);
assert.exists(getAttachmentRow());
assert.isFalse(getAttachmentRow().hidden);
// Basically, our item pane render mechanism will reuse the previous render if the item
// is the same. We want to ensure the attachments box is rerendered after
// the attachments' trash/restore, even if it's already rendered with the same item.
trashPromise = waitForNotifierEvent('trash', 'item');
await Zotero.Items.trashTx([attachment.id]);
await trashPromise;
// Wait for the attachment row to be hidden
await waitForCallback(
() => getAttachmentRow().hidden
, 100, 3);
// Select another non-regular item to ensure the box is not updated by notifier events
// At this point, the box still has the previous render with attachment row hidden
let item2 = await createDataObject('item');
let attachment2 = await importFileAttachment('test.pdf', { parentID: item2.id });
await ZoteroPane.selectItem(attachment2.id);
await waitForPreviewBoxRender(itemDetails.getPane("attachment-info"));
// Restore the attachment
restorePromise = waitForNotifierEvent('modify', 'item');
attachment.deleted = false;
await attachment.saveTx();
await restorePromise;
// Select the item with the restored attachment. A rerender should be triggered
await ZoteroPane.selectItem(item.id);
await waitForScrollToPane(itemDetails, paneID);
await waitForPreviewBoxRender(attachmentsBox);
// Wait for the attachment row to exist and be visible
await waitForCallback(
() => {
let row = getAttachmentRow();
window.console.log(row);
return row && !row.hidden;
}
, 100, 3);
// Should render the attachment row, as the render dependency is different
assert.exists(getAttachmentRow());
});
});