fix(enable-banking): one primary action per connection state on /settings/banking (#1727)

Restructure the banking settings page so every connection state has a
clear hierarchy:

- One "Dina bankkopplingar" group sorted by state precedence
  (pending_selection, pending, error, expired, expiring soon, active),
  replacing the three-way group split. State derivation, sorting and
  worst-state selection live in a pure, unit-tested helper
  (lib/connection-state.ts).
- Exactly one page-level .attn sentence for the worst state, or none;
  the BankSyncStatusChip is removed from this page (it linked to
  itself; it stays on /transactions and /import).
- Each row shows one primary action per state (Valj konton, Forsok
  igen, Fornya samtycke, Synka nu); everything else moves into a "..."
  menu, and details (accounts, IBAN, balances, initial historik) sit
  behind a collapsed disclosure. Expired rows never show balances.
- Expiring-soon active rows get a "Fornya samtycke" primary that
  reconnects without a psu-type override (the server reuses the stored
  psu_type); the explicit account-type choice stays in the menu.
- "Anslut ny bank" collapses behind one outline "Anslut en bank till"
  button whenever a non-revoked connection exists; the reuse-session
  group only shows while the connect-new surface is visible.
- Fresh connects to an already-connected bank are intercepted with a
  renew-instead dialog; "Anslut som ny" proceeds with force_new: true
  for the upcoming server-side 409 guard.
- In-flight 'pending' rows render as a spinner row ("Vantar pa banken")
  instead of being invisible.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-20 10:07:04 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5
parent e1805125af
commit 1ded1af8fe
6 changed files with 759 additions and 325 deletions
+1
View File
@@ -1090,3 +1090,4 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
[2026-08-19] Removed PeriodiseringAutoDetectToggle (settings > Automatik) instead of wiring it: the localStorage key it wrote (periodisering_autodetect_enabled) had no reader anywhere, so it advertised "automatisk periodiseringsdetektering" while changing nothing; auto-detect is already best-effort and review-gated in the wizard, so the row is now a plain link to the periodisering wizard. Deleting the key is safe: it was write-only.
[2026-08-19] Periodisering auto-detect materiality floor uses entity_type as a K1 proxy: no stored flag distinguishes förenklat årsbokslut (K1, BFNAR 2006:1) from full årsbokslut (BFNAR 2017:3) for enskild firma, so every EF gets K1 wording and every AB gets K2, always advisory ("behöver normalt inte"), never prohibitive. Suggestions under 5 000 kr are tagged low-confidence (unticked) rather than dropped because the relief is a MAY, not a MUST; personnel-cost lines (7xxx) are exempt from the floor since K1/K2 require personnel costs to always be accrued.
[2026-08-19] Hem build-assistant hero downgraded to the quiet-sentence pattern (AgentPromo, matches SkatteverketPromoCard; founder direction 2026-08-18 'redesign first, maybe remove later'): dismissal is per-company localStorage (erp_agent_promo_dismissed:<companyId>) like the SKV promo, gate and hasAi/billing routing unchanged.
[2026-08-19] Banking settings UI state derives from a pure helper (extensions/general/enable-banking/lib/connection-state.ts), not inline JSX conditions: sort precedence, the single page-level .attn sentence, and each row's one primary action must agree on which state a connection is in, and only a pure module can unit-test that. The same-bank connect intercept excludes 'pending' rows (an in-flight authorization is not a renewable connection) and the fresh-connect body sends force_new: true after the intercept so the parallel 409 server guard can distinguish deliberate second connections; 'pending' rows now render as a spinner row ("Väntar på banken") for their whole lifetime instead of only locking the connect button for 30 s, since an invisible in-flight row was the confusion.