- Shipped
- September 16, 2026 at 4:29 PM UTC
- Author
- Kamo
- Commit
- 949d388
The widget filed campaigns under its own Live / Sent / Drafts, which put a cancelled campaign under Sent and a scheduled one under Live. Its tabs are now In-Progress, Not Started, Paused and Complete, filed by campaignTabOf and named with marketing.bulkEmail.tabs.*, so the launchpad and /marketing/email never put one campaign in two places. Counts come from EmailService's new `stages` (7481f15); an older server's reply is counted from the campaigns it sent. Choosing the tab: - Until the member picks one, the pane lands on what is happening and stays while that tab still holds anything. It moves only to show a send that just started, or when its own tab runs out. A send that just finished holds In-Progress for its celebration, then the pane moves on. - A row the member pauses or resumes stays where they pressed it, with its Resume, until they leave the tab. - Stage names show where they fit beside "N more", measured against a hidden copy in the member's language; otherwise each stage shows its icon, with the name in its tooltip and accessible name. Fixes found while checking in the browser: - Sparks from new opens and clicks on a finished campaign were never visible: the figures line clipped them. It now clips only below and beside itself, and the sparks fly from the meter's end, so they survive the bars dropping. - A row too narrow for its figures drew the Opened meter over Clicked. The bars go first below 340px, and anything that still does not fit wraps out of sight whole. - A KPI tile too narrow for its name and rate ellipsized the name ("Ope..."). The rate now wraps out of sight instead. - "N more" counted the rows leaving the previous tab. Checked headless at pane widths 322 to 1360: no row cut, no tab overflow, the names/icons switch with and without "N more", arrow keys, a finish held then moved on, and sparks unclipped at 668 and 460. The pause test's server now answers with the paused campaign. It failed under load when the widget's re-read 400ms after a pause returned the campaign still sending.