Settings: accounts appear in both Connected Accounts and Mail — one home for accounts #1014

Open
opened 2026-10-03 15:15:31 +00:00 by kayg · 6 comments
Owner

Owner report (2026-10-03, production 7a)

"Right now I see accounts both in Connected Accounts and Mail."
The Settings redesign (job/settings-50, in round 7b) still keeps an account list in Settings → Mail (MailSection.svelte: "keeps existing IMAP accounts manageable while shared provider setup stays in Connected Accounts"), so the duplication survives 7b.

Decision (owner naming rule: "Connected Accounts" for provider sign-ins; one home per concept)

  • Connected Accounts is the only place that lists, adds, removes, re-authenticates and enables/disables accounts. Each account row shows which services it feeds (Mail, Calendar, Contacts) as toggles, plus status and Copy link (§33).
  • Settings → Mail keeps only Mail settings: read marking, remote images, per-account Mail options (sync on/off, folders, backfill) shown per account WITHOUT add/remove/sign-in controls and without a second account list; a "Manage accounts" link opens Connected Accounts at that account (?account=<id>). Same for Settings → Calendars (calendar subscriptions and calendar options stay; account sign-in lives in Connected Accounts).
  • Existing deep links to Mail account rows redirect to the matching Connected Accounts row.

Build on

Branch from job/settings-50 (the redesign), reuse its AccountList/SettingsRow parts; no new list component.

Verification

e2e as a User with two Mail accounts (one IMAP, one provider sign-in) and one CalDAV account: each account appears exactly once in Settings (Connected Accounts); Mail page shows Mail options and the link; toggling Mail off for an account stops its sync. Screenshots 390/820/1440 light/dark.

## Owner report (2026-10-03, production 7a) "Right now I see accounts both in Connected Accounts and Mail." The Settings redesign (job/settings-50, in round 7b) still keeps an account list in Settings → Mail (`MailSection.svelte`: "keeps existing IMAP accounts manageable while shared provider setup stays in Connected Accounts"), so the duplication survives 7b. ## Decision (owner naming rule: "Connected Accounts" for provider sign-ins; one home per concept) - **Connected Accounts is the only place that lists, adds, removes, re-authenticates and enables/disables accounts.** Each account row shows which services it feeds (Mail, Calendar, Contacts) as toggles, plus status and Copy link (§33). - **Settings → Mail keeps only Mail settings**: read marking, remote images, per-account Mail options (sync on/off, folders, backfill) shown per account WITHOUT add/remove/sign-in controls and without a second account list; a "Manage accounts" link opens Connected Accounts at that account (`?account=<id>`). Same for Settings → Calendars (calendar subscriptions and calendar options stay; account sign-in lives in Connected Accounts). - Existing deep links to Mail account rows redirect to the matching Connected Accounts row. ## Build on Branch from job/settings-50 (the redesign), reuse its AccountList/SettingsRow parts; no new list component. ## Verification e2e as a User with two Mail accounts (one IMAP, one provider sign-in) and one CalDAV account: each account appears exactly once in Settings (Connected Accounts); Mail page shows Mail options and the link; toggling Mail off for an account stops its sync. Screenshots 390/820/1440 light/dark.
Author
Owner

Starting #1014 on job/oneacct-1014, based on job/settings-50 at 656d22421df6979fbf3ac5cb7566a317d1ccc59a. Merged origin/dev (cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e) before edits; merge commit is 61325b773. The issue decision and DESIGN §§33, 45, 49, 50 govern the change.

Starting #1014 on `job/oneacct-1014`, based on `job/settings-50` at `656d22421df6979fbf3ac5cb7566a317d1ccc59a`. Merged `origin/dev` (`cfee85c6b11537968aaa0685d1ed1c3ac68a8c3e`) before edits; merge commit is `61325b773`. The issue decision and DESIGN §§33, 45, 49, 50 govern the change.
Author
Owner

Finding: the Mail Settings page has a separate Mail Accounts AccountList with one row per email, account status, Sync now, a menu, Copy link, and legacy Turn off/Disconnect actions (apps/web/src/routes/settings/mail/MailSection.svelte). Settings → Calendars similarly has a Calendar Accounts AccountList with account status and account actions (CalendarsSection.svelte). Connected Accounts already has the canonical provider rows and Mail/Calendar service switches. I will remove account management rows from the service pages, keep service-specific controls/status available without a second visible account list, and route the old Mail account group to Connected Accounts while preserving the account query.

Finding: the Mail Settings page has a separate `Mail Accounts` AccountList with one row per email, account status, Sync now, a menu, Copy link, and legacy Turn off/Disconnect actions (`apps/web/src/routes/settings/mail/MailSection.svelte`). Settings → Calendars similarly has a `Calendar Accounts` AccountList with account status and account actions (`CalendarsSection.svelte`). Connected Accounts already has the canonical provider rows and Mail/Calendar service switches. I will remove account management rows from the service pages, keep service-specific controls/status available without a second visible account list, and route the old Mail account group to Connected Accounts while preserving the account query.
Author
Owner

Production review finding: the existing Connected Accounts screenshot assertion still expected Your accounts, but SettingsCard applies the upstream #474 Title Case rule and renders Your Accounts. The review stopped before its first capture. I updated only that exact heading check to match the documented title rule; the UI is unchanged.

Production review finding: the existing Connected Accounts screenshot assertion still expected `Your accounts`, but SettingsCard applies the upstream #474 Title Case rule and renders `Your Accounts`. The review stopped before its first capture. I updated only that exact heading check to match the documented title rule; the UI is unchanged.
Author
Owner

Design review finding: my first Mail settings pass replaced the Load remote content switch with a note about per-sender Load images. Current DESIGN §45 requires server-proxied remote content with one default-on setting and no per-sender load action. I am restoring the specified preference control and will rerun its focused tests and screenshots.

Design review finding: my first Mail settings pass replaced the Load remote content switch with a note about per-sender Load images. Current DESIGN §45 requires server-proxied remote content with one default-on setting and no per-sender load action. I am restoring the specified preference control and will rerun its focused tests and screenshots.
Author
Owner

Follow-up evidence for the remote-content gap: the Mail plugin exposes only per-sender remote-content state and a message-level write endpoint. It has no global preference or proxy endpoint for the default-on control in DESIGN §45. Adding that would change Mail crate behavior beyond this Settings consolidation. I am removing the unsupported placeholder from Settings and listing the remote-content control as a known gap; no false setting will ship.

Follow-up evidence for the remote-content gap: the Mail plugin exposes only per-sender remote-content state and a message-level write endpoint. It has no global preference or proxy endpoint for the default-on control in DESIGN §45. Adding that would change Mail crate behavior beyond this Settings consolidation. I am removing the unsupported placeholder from Settings and listing the remote-content control as a known gap; no false setting will ship.
Author
Owner

#1014 final report

Built

  • Connected Accounts is the single place to list, add, remove, re-authenticate, and enable or disable accounts.
  • Mail settings now select one account by its stable shared ID. They retain read marking, sync status, Sync now, folder and backfill status, and a Manage account link. They do not repeat account management.
  • Calendar settings retain calendar visibility, colour, refresh, and external subscriptions. Account sign-in and service switches stay in Connected Accounts.
  • Retired Mail account/setup URLs and the Calendar add URL resolve to Connected Accounts.

Files

  • Settings routes and tests: apps/web/src/routes/settings/sections.ts, sections.test.ts.
  • Mail settings and tests: apps/web/src/routes/settings/mail/MailSection.svelte, MailSection.svelte.test.ts.
  • Calendar settings and tests: apps/web/src/routes/settings/calendars/CalendarsSection.svelte, CalendarsSection.svelte.test.ts.
  • Production review and Calendar E2E: apps/web/e2e/integrations-review.mjs, apps/web/e2e/calendar.mjs.

Commits

  • bc4e01f33 — keep account management in one home.
  • 005b50c35 — cover shared account settings flows.
  • 12893025e — omit unsupported remote-content placeholder.
  • Head: 12893025eece78d0ecd6ed1f07d349bd91cc9b68.

Production screenshots (Playwright reports macOS; light and dark; 390, 820, 1440 px)

UX gaps closed

  • Removed duplicate account lists and add/remove/service-switch controls from Mail and Calendar settings.
  • Kept per-account Mail sync and backfill status, Calendar options, canonical Manage account links, Copy link, and stable deep links.
  • Preserved calm loading, error, and empty states from the existing API resources.

UX gaps left

  • The Mail API has per-sender remote-content state only. It has no global preference or proxy endpoint for DESIGN §45's default-on “Load remote content” setting. Settings does not show a fake control. Existing reader behavior needs a separate Mail API/plugin change.

Decisions not specified by the issue

  • Mail uses a named account selector with ?account=<shared-id> so one account's options stay addressable without a second list.
  • I left the Remote Images group out until its global setting has a real backend contract. This follows DESIGN §45 and the no-placeholder rule; a correct implementation changes Mail plugin behavior and is outside this UI issue's scope.

Gate output

bun run check

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/oneacct-1014/apps/web
Getting Svelte diagnostics...
svelte-check found 0 errors and 0 warnings

bunx vitest run src/routes/settings/sections.test.ts src/routes/settings/mail/MailSection.svelte.test.ts src/routes/settings/calendars/CalendarsSection.svelte.test.ts --maxWorkers=2

Test Files  3 passed (3)
Tests       24 passed (24)
Start at  18:36:20
Duration  10.68s (transform 74%, tests 9%, environment 8%, import 6%, setup 2%)

bun run build

✓ built in 40.59s
> Using @sveltejs/adapter-static
  Wrote site to "build"
  ✔ done

bun e2e/integrations-review.mjs

PASS Connected Accounts and service Settings review: 66 screenshots in /home/kayg/Developer/calternal-wt/oneacct-1014/artifacts/connected-accounts

Rust source did not change, so cargo fmt, cargo clippy, and cargo test were not run. The server build was required for the production review; the first attempt hit a shared sccache reset, and the build passed with RUSTC_WRAPPER cleared. cargo clean removed 7,242 files / 4.6 GiB. The web build output was deleted.

For the merge round

  • bun run test — full web regression suite.
  • bun e2e/calendar.mjs — updated Calendar settings flow and its legacy fixture cleanup.
## #1014 final report **Built** - Connected Accounts is the single place to list, add, remove, re-authenticate, and enable or disable accounts. - Mail settings now select one account by its stable shared ID. They retain read marking, sync status, Sync now, folder and backfill status, and a Manage account link. They do not repeat account management. - Calendar settings retain calendar visibility, colour, refresh, and external subscriptions. Account sign-in and service switches stay in Connected Accounts. - Retired Mail account/setup URLs and the Calendar add URL resolve to Connected Accounts. **Files** - Settings routes and tests: `apps/web/src/routes/settings/sections.ts`, `sections.test.ts`. - Mail settings and tests: `apps/web/src/routes/settings/mail/MailSection.svelte`, `MailSection.svelte.test.ts`. - Calendar settings and tests: `apps/web/src/routes/settings/calendars/CalendarsSection.svelte`, `CalendarsSection.svelte.test.ts`. - Production review and Calendar E2E: `apps/web/e2e/integrations-review.mjs`, `apps/web/e2e/calendar.mjs`. **Commits** - `bc4e01f33` — keep account management in one home. - `005b50c35` — cover shared account settings flows. - `12893025e` — omit unsupported remote-content placeholder. - Head: `12893025eece78d0ecd6ed1f07d349bd91cc9b68`. **Production screenshots** (Playwright reports macOS; light and dark; 390, 820, 1440 px) - **Connected Accounts:** [390 light](https://git.kayg.org/attachments/fde555bc-2ca7-454a-a822-ae74ebb0f8fd), [390 dark](https://git.kayg.org/attachments/2ba0817f-4abe-496c-b1a3-ed1f9e6f5b09), [820 light](https://git.kayg.org/attachments/435c7737-54e3-490c-b930-e2e3fde7d755), [820 dark](https://git.kayg.org/attachments/69fd7e2a-ed06-468b-a15c-cdeff4752462), [1440 light](https://git.kayg.org/attachments/170bfede-0108-4d95-8b3f-d030ef4d251c), [1440 dark](https://git.kayg.org/attachments/2916c390-b264-41c1-b601-86d92c670912) - **Mail options:** [390 light](https://git.kayg.org/attachments/c4063e9c-8a1e-47e6-abb7-006e0872a9f9), [390 dark](https://git.kayg.org/attachments/2dd96a00-2db8-4d0b-8198-883ea4184538), [820 light](https://git.kayg.org/attachments/18e9337a-b768-4b18-93f3-9ec76804632f), [820 dark](https://git.kayg.org/attachments/bd1317ef-aed7-434d-be56-83c27659ed6f), [1440 light](https://git.kayg.org/attachments/520f2e35-484b-4f1f-9295-18b040f3c606), [1440 dark](https://git.kayg.org/attachments/65e239ad-3e48-4e1e-9f8d-49d55e1a6e0e) - **Calendar options:** [390 light](https://git.kayg.org/attachments/9daa6f93-8f69-47d5-b7b4-d3ed7b696485), [390 dark](https://git.kayg.org/attachments/acb7b332-7d67-427a-aa09-376470423f8e), [820 light](https://git.kayg.org/attachments/0b74481a-4e53-4de5-a5a8-3eb6437cd95f), [820 dark](https://git.kayg.org/attachments/55ec0180-a5a6-469b-85e4-b90a0b9a1771), [1440 light](https://git.kayg.org/attachments/eaabc722-24f1-470d-87e0-a871cdca6e80), [1440 dark](https://git.kayg.org/attachments/364f99bd-0646-4b89-8c17-0f3ba4abc8e7) **UX gaps closed** - Removed duplicate account lists and add/remove/service-switch controls from Mail and Calendar settings. - Kept per-account Mail sync and backfill status, Calendar options, canonical Manage account links, Copy link, and stable deep links. - Preserved calm loading, error, and empty states from the existing API resources. **UX gaps left** - The Mail API has per-sender remote-content state only. It has no global preference or proxy endpoint for DESIGN §45's default-on “Load remote content” setting. Settings does not show a fake control. Existing reader behavior needs a separate Mail API/plugin change. **Decisions not specified by the issue** - Mail uses a named account selector with `?account=<shared-id>` so one account's options stay addressable without a second list. - I left the Remote Images group out until its global setting has a real backend contract. This follows DESIGN §45 and the no-placeholder rule; a correct implementation changes Mail plugin behavior and is outside this UI issue's scope. **Gate output** `bun run check` ```text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/oneacct-1014/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bunx vitest run src/routes/settings/sections.test.ts src/routes/settings/mail/MailSection.svelte.test.ts src/routes/settings/calendars/CalendarsSection.svelte.test.ts --maxWorkers=2` ```text Test Files 3 passed (3) Tests 24 passed (24) Start at 18:36:20 Duration 10.68s (transform 74%, tests 9%, environment 8%, import 6%, setup 2%) ``` `bun run build` ```text ✓ built in 40.59s > Using @sveltejs/adapter-static Wrote site to "build" ✔ done ``` `bun e2e/integrations-review.mjs` ```text PASS Connected Accounts and service Settings review: 66 screenshots in /home/kayg/Developer/calternal-wt/oneacct-1014/artifacts/connected-accounts ``` Rust source did not change, so `cargo fmt`, `cargo clippy`, and `cargo test` were not run. The server build was required for the production review; the first attempt hit a shared sccache reset, and the build passed with `RUSTC_WRAPPER` cleared. `cargo clean` removed 7,242 files / 4.6 GiB. The web build output was deleted. **For the merge round** - `bun run test` — full web regression suite. - `bun e2e/calendar.mjs` — updated Calendar settings flow and its legacy fixture cleanup.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#1014
No description provided.