fix: drop a search folder scope that belongs to the account being left

`selectAccountMailbox` switches the viewed account but kept
`searchMailboxId`, which names a folder of the account being left.

Since #1082 that scope resolves against `resolveActionMailboxes()`, which
now returns the NEW account's mailbox list, so the id no longer matches
anything. `searchEmails` / `advancedSearch` then take the picked-folder
branch with `mailbox === undefined`, fall back to `jmapMailboxId =
searchMailboxId` and `accountId = undefined`, and query a foreign folder
id against the wrong account — which comes back empty.

It is invisible in the UI: the <select> binds `value={searchMailboxId}`
and has no matching <option>, so a native select renders the first one and
the dropdown reads "All folders" while the store still holds the stale id.
The user sees an empty result list for a search they believe is unscoped.

Reset it on the account switch, so the scope always matches what the
dropdown shows.
This commit is contained in:
Patrick Rotter
2026-09-22 19:25:18 +02:00
parent 9ef7068bd8
commit 74f9b63f2c
2 changed files with 20 additions and 0 deletions
@@ -105,6 +105,19 @@ describe('useEmailStore multi-account state', () => {
expect(state.expandedThreadIds.size).toBe(0);
});
it('selectAccountMailbox drops a search scope belonging to the account being left', () => {
// The scope names a folder of the previous account and resolves against
// resolveActionMailboxes(), which now returns the new account's list. Kept,
// it would query that foreign folder id against the wrong account and come
// back empty, while the dropdown has no matching option and reads "All
// folders". (#1082)
useEmailStore.setState({ searchMailboxId: 'a-archive' });
useEmailStore.getState().selectAccountMailbox('account-b', 'b-inbox');
expect(useEmailStore.getState().searchMailboxId).toBe('');
});
it('selectAccountMailbox with null accountId switches back to the active account', () => {
useEmailStore.getState().selectAccountMailbox('account-b', 'b-inbox');
expect(useEmailStore.getState().viewingAccountId).toBe('account-b');
+7
View File
@@ -1436,6 +1436,13 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
selectAccountMailbox: (accountId, mailboxId) => set({
viewingAccountId: accountId,
selectedMailbox: mailboxId,
// The search panel's folder scope names a folder of the account we are
// leaving. It resolves against `resolveActionMailboxes()`, which now
// returns the NEW account's list, so the id no longer matches: the search
// would query that foreign folder id against the wrong account and come
// back empty, while the dropdown (which renders no matching option) reads
// "All folders". Reset it so the scope matches what is shown. (#1082)
searchMailboxId: "",
isLoadingMore: false,
selectedEmail: null,
selectedEmailIds: new Set(),