Commit Graph
1108 Commits
Author SHA1 Message Date
Matthew Meszaros d112657cf2 feat: wire suppression, subscription and hold dependencies into the consumer's Salesforce service, give Salesforce token refreshes their own single-flight keyspace, release the outbox lease in memory after each terminal write so writeback notes land and only on rows with a logged Task, drop stale Salesforce import previews, keep keys from the import row menu from opening the edit dialog, and document the Salesforce callback URL and OAuth variables 2026-10-04 09:10:37 +02:00
Matthew Meszaros 6b7e254e56 feat: add native Salesforce sync with Lead and Contact matching and links, a leased activity outbox that logs sends, replies, bounces, opt-outs and meetings as Tasks, Lead Status and Email Opt Out writeback, a pull loop with CRM pause rules, list view and Campaign imports, sandbox and My Domain OAuth that refreshes expired sessions, a Salesforce settings page with contact and inbox cards in web, and docs 2026-10-04 08:54:27 +02:00
Matthew Meszaros 37e91fc89f feat: add HubSpot CRM mode where HubSpot deals, pipelines, tasks, notes and owners are mirrored and written through, sends and replies log as HubSpot emails, exit rules hold campaigns, list import, sync health, setup wizard in web, HubSpot app project with record card and workflow action, and docs 2026-10-04 07:47:51 +02:00
Matthew Meszaros 75840247c8 feat: replace the stored Outlook admin approval link on every Outlook sign-in start in useMailboxOAuth, clearing it when the start response carries none 2026-10-03 20:33:53 +02:00
Matthew Meszaros 8883a1df6b feat: connect Microsoft 365 organizations through Microsoft's v2.0 admin consent page followed by a sign-in on the same state, read the approving admin's directory role from the Graph token as well as the ID token, return an organization-wide approval link for single-mailbox Outlook sign-in (admin_consent_url) and show it in the connect panel, and document publisher verification and the admin approval path 2026-10-03 20:17:38 +02:00
Matthew Meszaros f05bd572d2 feat: repaint dither charts on a theme switch, apply cross-tab theme changes from the current storage value without writing them back, treat HTML colour attributes as designed mail, keep editor dark text to light inline fills, and give the step button spinner its colour 2026-10-03 08:58:36 -07:00
Matthew Meszaros 232d226211 Merge remote-tracking branch 'origin/main' into feat/dark-theme 2026-10-03 08:49:37 -07:00
Matthew Meszaros f1e3ea5bd9 feat: add a Linear-style dark theme to the dashboard (web/) with Light, Dark and System options in the user menu, Settings > Profile > Appearance and the command palette, light by default, and an Appearance guide in docs 2026-10-03 08:49:37 -07:00
Matthew Meszaros 61d16dfe9a feat: add Warmbly for Slack with the AI assistant in DMs, mentions and the assistant pane, unified inbox threads with reply, AI draft and lead actions, per-category notification routing and DMs, account linking, dashboard Slack settings, manifest and docs 2026-10-03 15:35:11 +02:00
Matthew Meszaros c3da0d684b Merge pull request #805 from Skylinerffm97/feat/unibox-long-press-menu
feat(unibox): open the row menu on a long press on touch screens
2026-10-03 07:57:35 +00:00
Matthew Meszaros c84368f2c4 feat: ignore Android's native contextmenu in useAnchoredMenu once a touch press has moved past the 10 px drift, so a scroll that stalls on a unibox row never opens its menu, with a hook test for the moved press 2026-10-03 08:59:01 +02:00
Claude 3288238cc0 feat: paginate and batch GET /analytics/accounts so account status reads are bounded per page and the overflow past 1000 mailboxes is reachable via cursor 2026-10-03 06:46:20 +00:00
Matthew Meszaros a184877cc7 Merge pull request #802 from Skylinerffm97/fix/click-outside-iframe-taps-ios
fix(web): close dropdowns on a tap inside the email body on iOS Safari
2026-10-03 05:11:54 +00:00
Matthew Meszaros 9ef54798dc Merge pull request #804 from Skylinerffm97/fix/unibox-mark-unread
fix(unibox): make Mark as unread stick, and let it reach a sent-only conversation
2026-10-03 05:11:39 +00:00
Skylinerffm97andClaude Opus 5.5 3f6617000a feat(unibox): open the row menu on a long press on touch screens
iOS Safari fires no contextmenu on a long press, so the conversation rows and the scope rail had no way to reach the right-click menu on a phone. useAnchoredMenu now opens the same menu after a 500 ms touch hold at the finger, cancels on a move over 10 px, swallows the click and touchend that follow the hold (so the row does not open and no menu item under the finger fires), and ignores Android's native contextmenu after a fired hold. Mouse and pen are unchanged.

Herkunft: [Claude]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:14:35 +02:00
Matthew Meszaros ffc505ab03 feat: make the unibox layout, scope-change and scroll tests wait up to 10 seconds for a conversation row, the reply box and the search box through findThreadRow and findBy queries instead of reading them right after a fixed 300 ms settle, so a slow CI runner rendering the list late no longer fails them 2026-10-02 15:57:43 +02:00
Skylinerffm97andClaude Opus 5.5 c433a483ec fix(unibox): make Mark as unread stick, and let it reach a sent-only conversation
useMarkSeen invalidated every ["unibox"] query after an unread, including the body queries ["unibox", "email", id]. A body GET marks the message read server side (GetByID), so the still-mounted reader undid the unread. Bodies never change once synced, so the unread path now skips them.

MarkSeenByThreads skipped every sent copy, so a conversation with no received message could not be marked unread at all. It now falls back to the newest sent copy when nothing was received. Received mail still wins, drafts never turn unread, and explicit ids and folder sweeps keep refusing sent and draft copies.

Herkunft: [Claude]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 15:31:48 +02:00
Matthew Meszaros a09ba27b0c feat: confirm a missing SPF or DMARC record with the sending domain's own authoritative nameservers before reporting it, look names up fully qualified so a resolver failure is never retried under the host's search domains and read as not found, look up internationalized domains in ASCII, record the verdict when a mailbox manager presses Check in the drawer, and show an unanswered lookup as unverified rather than missing 2026-10-02 06:13:37 -07:00
Skylinerffm97andClaude Opus 5.5 a9945e2e7e [Claude] fix(web): close dropdowns on a tap inside the email body on iOS Safari
WebKit does not run parent-registered listeners in a frame sandboxed without allow-scripts, and a tap does not focus the frame, so neither iframe path from #792 fires on an iPhone. While a layer is open, same-page iframes outside it now get pointer-events: none (shared counter per frame, previous inline value restored), so the tap lands on the page and reaches the existing capture-phase pointerdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 14:37:37 +02:00
Matthew Meszaros b8a8ec4743 Merge remote-tracking branch 'origin/main' into feat/unibox-rail-layout-per-member 2026-10-01 22:58:31 -07:00
Matthew Meszaros 945fadb260 Merge pull request #788 from warmbly/fix/ab-variant-thread-subject
feat: thread campaign follow-ups on the A/B arm each contact was actually sent by recording every send's rendered subject on campaign_tasks.subject (migration 000243) and reusing it verbatim in ThreadParentForLead, and list the opening step's variant subjects in the follow-up composer
2026-10-02 05:46:33 +00:00
Matthew Meszaros 1e1acef6f4 Merge pull request #791 from warmbly/fix/unibox-refresh-load
feat: coalesce and dedupe unibox realtime refreshes in useRealtimeEvents, forward TanStack Query abort signals through every unibox client and the shared Request helper with cancellations kept out of error handling, share one organization-scoped unibox overview computation per second with in-flight dedup and write-time invalidation, bound interactive unibox reads at 30s including pool wait, and log slow pgxpool connection acquisitions
2026-10-02 05:46:17 +00:00
Matthew Meszaros d12b8090c8 Merge origin/main into fix/ab-variant-thread-subject 2026-10-01 22:41:11 -07:00
Matthew Meszaros bce968646f feat: thread campaign follow-ups on the A/B arm each contact was actually sent by recording every send's rendered subject on campaign_tasks.subject (migration 000243) and reusing it verbatim in ThreadParentForLead, and list the opening step's variant subjects in the follow-up composer 2026-10-01 22:41:11 -07:00
Matthew Meszaros 8f89c36756 feat: refresh the open conversation for inbox events that name only a message id, give unibox refresh keys added just before a max-wait flush a trailing flush, cancel a shared unibox overview computation once its last caller leaves and bound it and GET /unibox/overview at 30s, include scheduled sends in the coalesced inbox refresh, and word the slow pgxpool acquire log as acquire time rather than saturation 2026-10-01 22:41:00 -07:00
Matthew Meszaros 596c395cd0 Merge pull request #792 from warmbly/fix/menus-close-on-email-body-tap
feat: close every dashboard dropdown on a tap inside a same-origin iframe such as the unibox email body
2026-10-02 05:37:50 +00:00
Matthew Meszaros 478d3ecc7b Merge remote-tracking branch 'origin/main' into fix/unibox-refresh-load 2026-10-01 22:37:48 -07:00
Matthew Meszaros 7707f6fb02 Merge pull request #789 from warmbly/fix/unibox-unread-latest-received
feat: mark only a conversation's newest received message unread on Mark as unread, never a sent or draft copy
2026-10-02 05:37:48 +00:00
Matthew Meszaros 54a05027cc feat: save the unibox scope rail's favorites, row and section order and hidden rows to the member's account per workspace through a unibox_rail view with a validated layout on /me/views, synced from the dashboard store so every device shows the same rail while folds and widths stay per browser 2026-10-01 22:37:23 -07:00
Matthew Meszaros b894d8f8b9 Merge pull request #790 from warmbly/fix/unibox-leave-select-mode
feat: add a Cancel selection button next to the All box in the unibox list header so Select mode can be left on a phone
2026-10-02 05:29:48 +00:00
Matthew Meszaros f01016c64f feat: close every dashboard dropdown on a tap inside a same-origin iframe such as the unibox email body by listening on the frame's own document in useClickOutside, re-attaching when the frame reloads, since a tap on a phone never moves focus into the frame 2026-10-01 22:27:45 -07:00
Matthew Meszaros dc2cffd786 feat: coalesce and dedupe unibox realtime refreshes in useRealtimeEvents, forward TanStack Query abort signals through every unibox client and the shared Request helper with cancellations kept out of error handling, share one organization-scoped unibox overview computation per second with in-flight dedup and write-time invalidation, bound interactive unibox reads at 30s including pool wait, and log slow pgxpool connection acquisitions 2026-10-01 22:25:53 -07:00
Matthew Meszaros 839235069e feat: add a Cancel selection button next to the All box in the unibox list header so Select mode can be left on a phone without ticking a row or switching folders 2026-10-01 22:25:06 -07:00
Matthew Meszaros a84b3bbbf3 feat: mark only a conversation's newest received message unread on Mark as unread, never a sent or draft copy, from the reader, the row menu, the selection bar, PATCH /unibox/seen and the mark_thread_seen AI tool, with the guide and API docs updated 2026-10-01 22:22:56 -07:00
Matthew Meszaros 7841e34119 feat: keep a unibox conversation unread after Mark as unread by skipping the reader's auto-read once the store has moved off its thread, and close the reader when the selection bar marks the open conversation unread 2026-10-01 22:16:59 -07:00
Matthew Meszaros 8faefb88be feat: leave Escape to a confirm or modal opened above an open dropdown in useClickOutside, drop ImageMenu's duplicate Escape guard, and restore the useDismissAdvisorFinding and useDismissMailboxImport mutation names the hook rename caught 2026-10-01 10:14:55 -07:00
Matthew Meszaros 76f43b9796 feat: close every dashboard dropdown through one useClickOutside(open, onClose, refs) hook that the shared PopoverMenu, the old useClickOutside callers and the hand-rolled pickers now all use, so a press outside (including inside a floating dialog card or an email iframe) closes it, Escape closes only the innermost one and returns focus to its trigger, and opening one closes the others 2026-10-01 08:38:57 -07:00
Matthew Meszaros e920b61371 feat: clear a reported warmup send failure only on a confirmed delivery, word the not-loaded send failure as a possible cause, leave placement seeds out of the adopted-mailbox warmup repair, and describe send_failure as a failure reason in the API schema 2026-10-01 03:20:41 -07:00
Matthew Meszaros a844c506a0 feat: make Warmbly Cloud warmup start and explain itself for linked mailboxes: apply the instance's warmup settings, start warmup on adopted mailboxes, read the warmup day mask Monday-first, report the last refused warmup send and the partner cap to the instance and dashboard, hand changed SMTP credentials to the cloud, refuse cleartext mailboxes at enrollment, and show cloud warmup with the warming animation and a clear Cloud marker 2026-10-01 03:01:36 -07:00
Matthew Meszaros e25b31f992 Merge pull request #772 from warmbly/fix/unibox-template-html-body
feat: send a unibox template's HTML body as written by giving the compose and reply composers an HTML mode, keep that HTML in compose and reply drafts, and render the text part server-side for HTML-only sends
2026-10-01 04:22:11 +00:00
Matthew Meszaros e20efd2544 feat: let a portaled popover inside the unibox composers close itself on Escape instead of the composer closing around it 2026-09-30 21:17:28 -07:00
Matthew Meszaros 2a78dc1a25 Merge remote-tracking branch 'origin/main' into fix/unibox-template-html-body 2026-09-30 21:15:35 -07:00
Matthew Meszaros cfdc0c3d01 feat: keep the signature editor's own plain-text rendering, reuse the campaign HTML-to-text helper in the composers, leave a synced text part to the server, cap HTML bodies in bytes, refuse a send whose HTML was emptied, and keep Escape and AI drafts from discarding HTML composer work 2026-09-30 21:15:29 -07:00
Matthew Meszaros a072f2a618 Merge pull request #771 from warmbly/fix/mailbox-switch-back-on
feat: let a switched-off mailbox be switched back on from its row menu, warmup menu, drawer, settings and the selection bar, and make the Advisor's stop-cold-sending fixes hold the mailbox from campaigns instead of switching it off
2026-10-01 04:08:07 +00:00
Matthew Meszaros f41b377f0c feat: offer the Advisor's campaign hold only while a mailbox is still sending cold, reseed warmup when an AI tool switches a mailbox on or starts warmup, and fix the mailbox switch's bulk selection, double clicks and revoked-mailbox hints 2026-09-30 21:02:00 -07:00
Matthew Meszaros ba6c5aa614 feat: test that unibox conversation row menus stay one at a time across right-clicks and close on a press outside them 2026-09-30 21:00:55 -07:00
Matthew Meszaros 85abe0c0ef Merge pull request #769 from warmbly/fix/popover-menu-outside-close
feat: close every PopoverMenu on a press outside it (pointerdown, capture phase, so taps count) and on Escape innermost first, keep one menu open at a time across the dashboard while nested menus stay open, give scope rail row counts room beside the always-visible phone "…" and line section header menus up with the row menus, and say in the unibox guide how the rail menus close
2026-10-01 03:49:55 +00:00
Matthew Meszaros 588591684b feat: send a unibox template's HTML body as written by giving the compose and reply composers an HTML mode, keep that HTML in compose and reply drafts, and render the text part server-side for HTML-only sends 2026-09-30 20:46:22 -07:00
Matthew Meszaros 7e204ee745 Merge pull request #770 from warmbly/feature/unibox-conversation-context-menu
feat: add a right-click menu to unibox conversation rows with open in new tab, read state, snooze, labels and filing, acting on the whole selection from a ticked row
2026-10-01 03:46:07 +00:00
Matthew Meszaros 4e81213557 feat: close every PopoverMenu on a press outside it (pointerdown, capture phase, so taps count) and on Escape innermost first, keep one menu open at a time across the dashboard while nested menus stay open, give scope rail row counts room beside the always-visible phone "…" and line section header menus up with the row menus, and say in the unibox guide how the rail menus close 2026-09-30 20:45:50 -07:00