mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 08:15:41 +00:00
fix: keep archived messages in the Archive and in search results after a plugin's batch, and update folder counts
This commit is contained in:
@@ -32,7 +32,10 @@ describe('batch functions with an explicit target', () => {
|
||||
// The selection names another message: a targeted call must leave it alone.
|
||||
selectedEmailKeys: new Set(['keep']),
|
||||
isUnifiedView: true,
|
||||
selectedMailbox: 'inbox',
|
||||
searchQuery: '',
|
||||
fetchTagCounts: vi.fn(),
|
||||
fetchMailboxes: vi.fn(async () => {}),
|
||||
} as never);
|
||||
});
|
||||
|
||||
@@ -48,6 +51,19 @@ describe('batch functions with an explicit target', () => {
|
||||
expect([...useEmailStore.getState().selectedEmailKeys]).toEqual(['keep']);
|
||||
});
|
||||
|
||||
it('keeps the rows where they are still listed, and refreshes the folder counts', async () => {
|
||||
const target = { emailIds: ['m1'], client, emails: [email('m1')] };
|
||||
// The Archive is the open folder: the archived message belongs there.
|
||||
useEmailStore.setState({ selectedMailbox: 'arch' } as never);
|
||||
await useEmailStore.getState().batchArchive(other, target);
|
||||
expect(useEmailStore.getState().emails.map((e) => e.id)).toEqual(['m1', 'keep']);
|
||||
// A search still finds it.
|
||||
useEmailStore.setState({ selectedMailbox: 'inbox', searchQuery: 'invoice' } as never);
|
||||
await useEmailStore.getState().batchArchive(other, target);
|
||||
expect(useEmailStore.getState().emails.map((e) => e.id)).toEqual(['m1', 'keep']);
|
||||
expect(useEmailStore.getState().fetchMailboxes).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('refuses an Archive someone else reads, asking the server for its share map', async () => {
|
||||
Object.assign(client, {
|
||||
supportsMailboxSharing: () => true,
|
||||
|
||||
+21
-4
@@ -1415,11 +1415,28 @@ async function archiveTarget(client: IJMAPClient, target: BatchActionTarget): Pr
|
||||
);
|
||||
emitEmailMove(move, hookMailboxes);
|
||||
const moved = new Set(move.emailIds);
|
||||
useEmailStore.setState(state => ({
|
||||
emails: state.emails.filter(e => !moved.has(e.id)),
|
||||
selectedEmailKeys: dropFromSelection(state, e => moved.has(e.id)),
|
||||
}));
|
||||
// The rows leave the open list only where they no longer belong: not the
|
||||
// Archive itself (or a year or month folder in it), not a search, which
|
||||
// still finds them. Elsewhere the refresh below settles the rest.
|
||||
const state = useEmailStore.getState();
|
||||
const archiveTree = new Set([archive.id]);
|
||||
for (let grew = true; grew;) {
|
||||
grew = false;
|
||||
for (const m of [...state.mailboxes, ...mailboxes]) {
|
||||
if (m.parentId && archiveTree.has(m.parentId) && !archiveTree.has(m.id)) { archiveTree.add(m.id); grew = true; }
|
||||
}
|
||||
}
|
||||
const searching = !!state.searchQuery || !isFilterEmpty(state.searchFilters);
|
||||
const stillListed = searching || (!!state.selectedMailbox && archiveTree.has(state.selectedMailbox));
|
||||
if (!stillListed) {
|
||||
useEmailStore.setState(current => ({
|
||||
emails: current.emails.filter(e => !moved.has(e.id)),
|
||||
selectedEmailKeys: dropFromSelection(current, e => moved.has(e.id)),
|
||||
}));
|
||||
}
|
||||
if (!useEmailStore.getState().isUnifiedView) await useEmailStore.getState().refreshCurrentMailbox(client);
|
||||
// The folders' message and unread counts changed.
|
||||
await useEmailStore.getState().fetchMailboxes(client);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user