feat(desktop): every sidebar card can be dismissed, and no em dashes in desktop UI
Links
- Walkthrough with screenshots: https://app.superset.sh/page/every-sidebar-card-can-be-dismissed-ymnn7r
Summary
- Every sidebar card can be dismissed. The "Pro ended" / "Payment failed" card had no close button. It now dismisses per state and invoice.
SidebarCardEntry.onDismissis required, so a new card can't ship without one. - One dismiss button and a quieter warning style. Plain sidebar cards use the release-notes card's hover
−button. The payment card drops its gold outline: a warning-toned badge is now its only urgency signal. - No em dashes in desktop UI copy. 87 strings in 68 files, with translations carried over to the re-keyed messages in all 18 locales.
How to review: three commits. Read 4a07b7a (cards, ~7 files) first, then skim c463aab (string edits). d0c1044 is the catalogs only.
Part 1: Dismissible sidebar cards
Why
The sidebar card slot showed a "Pro ended: $20.00 unpaid" card with no way to close it. Every other card (setup scripts, getting started, release notes, hiring) was already dismissible.
How
usePaymentFailedCardsaves dismissals in a newpayment-failed-card-dismissalsstore (built oncreateDismissalsStore, registered in the persisted-key registry). The key is<past_due|lapsed>:<invoiceId>, so a new failed charge, or a move from "Payment failed" to "Pro ended", shows the card again. Sendspayment_failed_banner_dismissed.SidebarCardEntry.onDismissis required. The payment card was the only entry without it.SidebarCard(packages/ui): the always-visible×on plain cards is now the hover-revealed−the image (release-notes) card uses. New optionaltone="warning"colors only the badge, using the same tint as the billing page'sPaymentFailedBanner.
Design decisions
- Badge tone instead of a colored border: the outline was loud without saying anything. One small cue keeps the card calm but distinct from promo cards.
- Dismiss per invoice, not forever: the card was non-dismissible because orgs had lost Pro without ever seeing a warning. Scoping the dismissal to one state of one invoice means a new billing problem always resurfaces.
Part 2: Em dashes out of desktop UI strings
One rule per pattern so the same kind of text reads the same way everywhere:
| Pattern | Becomes | Example |
|---|---|---|
| Status + detail | colon | Pro ended: $20.00 unpaid, Ports: 3 live |
| Two clauses | period | Copy your key now. You won't be able to see it again. |
| Name pair | middle dot | notification titles, window title, PR #12 · title |
| Short aside | comma | on mac-mini, won't run here |
Unchanged on purpose: the lone — empty-cell placeholder in tables, log messages, code comments, and headings in prompts sent to agents. Web, mobile, marketing, CLI output and server error messages are not swept here.
Catalogs: editing English re-keys a message, so 68 messages needed new entries per locale. Each old translation was reused, with its dash converted the same way the English was (full-width punctuation for ja/zh, a spaced colon for fr). Translations that never used a dash were copied as they were. The catalog integrity test caught 5 placeholders the first pass had capitalized ({failedLabels}); those are fixed.
Manual QA Checklist
Dev desktop app over CDP. The org's billing is healthy, so a lapsed plan and a $20 invoice were seeded into the React Query cache. The hover and click used real mouse input.
- Lapsed card renders "Pro ended: $20.00 unpaid" with a warning-toned badge and a plain border
- Hovering the card reveals
−(opacity 0 to 1) - Clicking
−removes the card and storeslapsed:in_fake_1 - Reload with the same invoice: card stays hidden
- A different invoice id: card comes back
- The
−button on the setup-script, getting-started and hiring cards (same component, not checked on screen) - Translated strings in a non-English locale (checked through the catalogs and tests only)
Testing
bun run check:i18n: passesbun testinpackages/i18n: 169 pass (catalog integrity included)bun test srcinapps/desktop: 9464 pass, 39 fail. The failures are environmental (tests that create real git repos, read the shell environment, or run the native-messaging host) and don't involve UI strings. Not compared againstmain.tsc --noEmitinapps/desktop: no errors in touched files (the worktree has the usual route-tree and path-casing noise)- Biome: clean
Known Limitations
- "Restart Pro" goes to Settings → Billing, where a lapsed org sees a generic "Upgrade to Pro" card with no mention of the lapse or the unpaid invoice. CTA and billing-page copy are left for a follow-up.
- The payment card's English strings were never wrapped in Lingui; still the case.
- The new dismissals store grows by one entry per dismissed invoice. Each entry is tiny, but nothing prunes old ones.
Summary by cubic
Every sidebar card can now be dismissed, and em dashes are replaced in desktop UI copy. The "Pro ended" / "Payment failed" card previously had no way to dismiss it; it now dismisses per billing state and invoice, so a new failed charge or the move to "Pro ended" shows it again. SidebarCardEntry.onDismiss is now required.
Dismissible sidebar cards
- Plain cards use the release-notes card's hover-revealed
−button; the payment card's gold outline is replaced with a warning-toned badge. - Dismissal keeps only the last
<past_due|lapsed>:<invoiceId>entry; with no invoice id the dismissal lasts just for the session, so a later, different failure still shows the card. - The hook subscribes to the stored dismissed state so dismissing removes the card immediately. Dismissing sends
payment_failed_banner_dismissed.
No em dashes in desktop UI copy
- 87 strings in 68 files switch to a consistent pattern: colon for status + detail, period for two clauses, middle dot for name pairs, comma for short asides.
- Trailing punctuation is trimmed from error text before appending ". Click to retry" or ". Try the Paradev tray menu…".
- Re-keyed messages have existing translations carried over in all 18 locales, with doubled punctuation collapsed in zh-CN/zh-TW; empty-cell
—placeholders, log messages, comments, and agent prompt headings are unchanged.
Summary by CodeRabbit
- UI Updates
- Updated punctuation and separators across desktop messages, labels, tooltips, and notifications.
- Updated translations to match revised interface text, including status and guidance messages.
- Billing
- Payment warning cards use warning styling and can be dismissed. Dismissal is remembered for the matching invoice when available; otherwise, it applies for the current session.