Changelog

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 canvases row 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 DialerBody so 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-30 shadow over the grid); the ReactFlowProvider wrapper keeps the grid's useReactFlow hooks 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.

Under the hood

  • kind: 'native' | 'canvas' on every APP_CANVAS_CONFIG entry — single source of truth that drives the shell and the sidebar.
  • native-apps/registry.js maps each native mode to { Surface (React.lazy), Skeleton }.
  • showNativeApp in CanvasWorkspace is dispatched by a pure, unit-tested selectShellView() so the native vs canvas pick is testable in isolation.
  • TopBar carries a showCanvasTools={false} prop and hides the canvas toolbar, New / Edit Canvas, and the pan / select tool picker on native surfaces.
  • widgetChrome.jsx splits layout-neutral chrome out of widgetShared so the native path never imports ReactFlow; widgetShared retains the canvas-bound WidgetCardLayout.
  • 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 pure selectShellView matrix, TopBar canvas-tools gating, DataTableListBody + NativeSurface smoke tests, and a native-path import guard.

What's next

  • A second wave of native apps (Chat, Agents, Automations, Campaigns, SMS) — currently in_progress in 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.

On this page