Pages
Notion-style documents made of nested blocks — Project88's writing surface.
A page is a Notion-style document. The page tree lives per-workspace;
each page is a row in pages whose blocks column is a JSONB array of
block objects.
The block model
A page's content is not stored as HTML or Markdown. It's a flat array of block objects:
[
{ "id": "...", "type": "h1", "text": "Project88 launch plan" },
{ "id": "...", "type": "p", "text": "Owner: Phil. Target: Friday." },
{ "id": "...", "type": "todo", "text": "Wire up auth", "checked": true },
{ "id": "...", "type": "code", "language": "ts", "text": "..." },
{ "id": "...", "type": "callout", "icon": "💡", "text": "..." }
]Block operations update local state immediately and debounce-persist the full blocks array to Supabase after 800 ms. You see "Saving..." then "Saved" in the page header.
The 17 block types
- Text blocks — paragraph, h1, h2, h3, bulleted list, numbered list, quote, callout, divider, code, image
- Interactive blocks — todo (checkbox), toggle (collapsible)
- Layout blocks — columns (multi-column container)
- Embed blocks — markdown (live-preview), table (embedded data table), inline page link
Use the / slash command in the editor to insert any of them.
Nesting
Pages are arranged in a tree via the parent_id column. The Pages mode
shows the tree in a left sidebar with:
- Search across all pages
- Inline new-page button
- Drag-and-drop reordering (before, after, nest-as-child)
- Page count
Each tree item is a PageTreeItem with its Lucide icon (from the
IconPicker) and title.
Embedded data tables
The /table slash command opens a table picker. Select any data table from
the Data mode and a TableBlock is inserted into the page. The block
renders the table with column-type-aware cells (select pills, status
badges, email, date, multi-tag) and re-fetches on demand.
This is the bridge between structured data (Data mode) and prose (Pages mode) — write a page that references the underlying table without copy-pasting.
Planning canvas
A page can attach a planning canvas — a text-centric React Flow board with Text, Task, Group, and Link nodes. The planning canvas renders as an inline preview above the page blocks; clicking it opens the full-screen editor.
This is distinct from the Automation editor (used for agent pipelines) and the Office canvas (read-only fleet view).