Clear stale collection-tree selection when filtering

Filtering rebuilds the rows, but the selected indices from before pointed at
different (or out-of-range) rows afterward, so a multi-selection rendered the
wrong rows as selected. Clear the selection after the rebuild and re-select the
focused row, collapsing a multi-selection to that row while filtering.
This commit is contained in:
Dan Stillman 2026-06-16 12:32:36 -04:00
parent bd606f76e7
commit 206ab311db
2 changed files with 23 additions and 0 deletions

View file

@ -2721,6 +2721,10 @@ var CollectionTree = class CollectionTree extends LibraryTree {
this.selection.clearSelection();
}
await this.reload();
// reload() rebuilds the rows, so any selected indices from before now point at
// different (or out-of-range) rows. Clear them and re-select just the current
// row below, collapsing a multi-selection to the focused row while filtering.
this.selection.clearSelection();
if (currentRow) {
// Special treatment for when there are no filter matches
// Otherwise, selection.focused does not get updated by selectByID, which breaks ZoteroPane.

View file

@ -755,6 +755,25 @@ describe("Zotero.CollectionTree", function () {
assert.equal(cv.selection.count, 1);
assert.isTrue(cv.selection.isSelected(cv.getRowIndexByID("C" + c1.id)));
});
it("should not leave a stale multi-selection after filtering", async function () {
let cA = await createDataObject('collection', { name: 'filterAAA' });
let cB = await createDataObject('collection', { name: 'filterBBB' });
let cC = await createDataObject('collection', { name: 'filterCCC' });
// Select all three, focusing the one that will still match the filter
await cv.selectByID("C" + cB.id);
toggleRow(cv.getRowIndexByID("C" + cC.id));
toggleRow(cv.getRowIndexByID("C" + cA.id));
assert.equal(cv.selection.count, 3);
await cv.setFilter("filterAAA");
// Only the still-matching focused row is selected -- no stale indices
assert.deepEqual(cv.getSelectedRows().map(r => r.id), ["C" + cA.id]);
await cv.setFilter("");
});
});
describe("#onDrop()", function () {