0.3.0 — Native app surfaces for Dial, Pages, Data, Calendar, Inbox
The five main apps move off the React Flow canvas onto full-bleed native shell surfaces with their own opinionated layouts; Home and user-created boards stay canvas-based and keep every dashboard widget.
What's new
- Five apps are now native shell surfaces. Dial, Pages, Data,
Calendar, and Inbox open as full-bleed peers of the top nav
instead of mounting on a React Flow canvas. Each gets an opinionated
layout designed for the workflow — Dial's dialer body, Pages'
tree + editor, Data's rail + grid, Calendar's mini-month + sidebar +
week, Inbox's Outlook-style three-pane folders + list + reader.
Native surfaces never create a
canvasesrow and the top bar hides the canvas toolbar, New / Edit Canvas, and the pan / select picker. - Home and your boards stay canvas-based. Home keeps its dock, recents, and team columns on the React Flow board, and user-created canvases are unchanged. Every dashboard-style widget — Data stats / record, Calendar agenda / month / year / heatmap / stats, Email inbox / compose / stats / accounts, Dial stats / bucket list — is still addable to any canvas through the global Add Widget menu.
- Existing canvases keep rendering. The legacy widget node types
(
DialWidget,EmailInboxWidget,CalendarWeekWidget,DataTableWidget, …) stay registered. Any board you already populated keeps painting the same widgets — filtering applies only at picker entry points. - Per-app layout polish ships with the move.
- Dial — body extracted into a reusable
DialerBodyso the native surface and the legacy widget share one render path. - Pages — editor max-width tightened on the native surface for comfortable line length.
- Data — table list + grid combined into one
DataWorkspace(elevated left rail,z-30shadow over the grid); theReactFlowProviderwrapper keeps the grid'suseReactFlowhooks working. - Calendar — mini-month + My Calendars sidebar + week unified
into
CalendarWorkspace; the mini-month drives the week pane. - Inbox — three-pane Outlook-style layout via a context-aware
WidgetCardLayout(EmailChromeContext); folders moved into the rail and Compose moved to the shell top bar.
- Dial — body extracted into a reusable
Under the hood
kind: 'native' | 'canvas'on everyAPP_CANVAS_CONFIGentry — single source of truth that drives the shell and the sidebar.native-apps/registry.jsmaps each native mode to{ Surface (React.lazy), Skeleton }.showNativeAppinCanvasWorkspaceis dispatched by a pure, unit-testedselectShellView()so the native vs canvas pick is testable in isolation.TopBarcarries ashowCanvasTools={false}prop and hides the canvas toolbar, New / Edit Canvas, and the pan / select tool picker on native surfaces.widgetChrome.jsxsplits layout-neutral chrome out ofwidgetSharedso the native path never imports ReactFlow;widgetSharedretains the canvas-boundWidgetCardLayout.- Registry contract tests extended with
kind/ native invariants — every native app has a surface, native modes are absent from palettes, group keys don't collide with native modes. Plus a pureselectShellViewmatrix, TopBar canvas-tools gating,DataTableListBody+NativeSurfacesmoke tests, and a native-path import guard.
What's next
- A second wave of native apps (Chat, Agents, Automations, Campaigns,
SMS) — currently
in_progressin the canvas registry — picks up the same mechanism once their layouts stabilise. - Cross-canvas widget linking for Home dashboards built out of the data / calendar / email / dial dashboard widgets.
See Canvases and widgets → native apps vs canvases and the per-app pages under Apps.
0.3.1 — Full-height sidebars for Data/Calendar/Dial, default appointment length, snap-to-create
The Data, Calendar, and Dial native surfaces share one layout — a full-height left sidebar with the app's toolbar on the darker top bar over the right column. Calendar gains a default appointment length setting and a click-to-create ghost preview that snaps to 15-min and centers on the pointer.
0.2.2 — Server-side dial queue, authoritative leasing, sensitive Lead Details
The dial queue is now computed in Postgres with keyset pagination, two operators on the same bucket can no longer double-dial, and sensitive Lead Details fields reveal on click with an audit trail.