From 105fe7645e458ee76b6c4e65417d493248c6f41d Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sat, 14 Mar 2026 10:43:16 +0100 Subject: [PATCH] Add no-code tablo overview builder design spec --- ...14-tablo-overview-nocode-builder-design.md | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-14-tablo-overview-nocode-builder-design.md diff --git a/docs/superpowers/specs/2026-03-14-tablo-overview-nocode-builder-design.md b/docs/superpowers/specs/2026-03-14-tablo-overview-nocode-builder-design.md new file mode 100644 index 0000000..f6dd26f --- /dev/null +++ b/docs/superpowers/specs/2026-03-14-tablo-overview-nocode-builder-design.md @@ -0,0 +1,225 @@ +# Tablo Details No-Code Overview Builder (V1) - Design + +Date: 2026-03-14 +Status: Approved in brainstorming session (user confirmations captured in chat) + +## 1) Problem and Outcome + +`apps/main/src/pages/tablo-details.tsx` currently renders the `Aperçu` layout in a fixed order. +Goal: make the overview feel "no-code" by letting editors drag-and-drop existing overview blocks to reorganize the page, directly inside xtablo. + +V1 outcome: +- Edit mode lives inside `tablo-details` (no separate builder page). +- Drag-and-drop reorders existing blocks only. +- Reordering is limited to fixed zones (left zone reorders internally, right zone reorders internally). +- Changes auto-save on each drop. +- Shared layout: everyone in the tablo sees the same saved order. +- Reset to default layout is available. + +## 2) Scope + +### In scope (V1) +- `Aperçu` section only. +- Existing overview blocks only: + - `description` + - `myTasks` + - `files` + - `info` +- Auto-save after drop. +- Reset action to restore default order. +- Graceful fallback to default order if saved config is missing/invalid. + +### Out of scope (V1) +- Adding brand-new block types. +- Resizing blocks. +- Cross-zone moves (left -> right or right -> left). +- Layout customization for non-overview tabs. +- Version history / undo timeline. + +## 3) Product Decisions Captured + +- Layout storage: per `tablo`. +- Editing access: tablo admins + organization members (aligned with existing org-wide tablo access model). +- Entry point: in-page `Edit layout` toggle in `tablo-details`. +- Reorder area: `Aperçu` only. +- Visibility of result: shared for all tablo members. +- Drag model: fixed zones. +- Persistence mode: auto-save + `Reset default`. + +## 4) Architecture Overview + +Recommended architecture for V1: store layout JSON on `public.tablos` as `layout_overview_v1`. + +Why: +- Smallest change that fully supports shared per-tablo layout. +- Uses existing update route (`PATCH /api/v1/tablos/update`) and query invalidation flow. +- Keeps V1 fast while leaving room to migrate later to a dedicated layout table if needed. + +### Units and Boundaries + +1. **Layout Schema Unit** + - Owns valid overview layout shape + sanitization. + - Input: unknown JSON. + - Output: safe `OverviewLayoutV1` + fallback behavior. + +2. **Overview Renderer Unit** + - Owns data-driven rendering order of overview blocks. + - Input: `OverviewLayoutV1`. + - Output: JSX for left/right zones in correct order. + +3. **Edit Interaction Unit** + - Owns edit mode UX and drag/drop reorder events. + - Input: current zone arrays + drop event. + - Output: reordered arrays + save trigger. + +4. **Persistence Unit** + - Owns optimistic save, rollback on failure, and reset flow. + - Input: reordered layout. + - Output: mutation call + success/failure UI feedback. + +Each unit is testable independently and can evolve without rewriting the others. + +## 5) Data Model and Contracts + +## 5.1 Database + +Add column: +- `public.tablos.layout_overview_v1 jsonb null` + +No default required in DB; default layout is resolved in app if null. + +## 5.2 Layout JSON shape + +```json +{ + "version": 1, + "leftZone": ["description", "myTasks"], + "rightZone": ["files", "info"], + "updatedAt": "2026-03-14T12:00:00.000Z", + "updatedBy": "user_id" +} +``` + +Notes: +- `version` is mandatory for forward compatibility. +- Allowed IDs in V1: + - Left zone: `description`, `myTasks` + - Right zone: `files`, `info` +- Unknown IDs are ignored by sanitizer. + +## 5.3 Type-level model (frontend) + +- `OverviewBlockId = "description" | "myTasks" | "files" | "info"` +- `OverviewLayoutV1 = { version: 1; leftZone: OverviewBlockId[]; rightZone: OverviewBlockId[]; updatedAt?: string; updatedBy?: string }` + +## 5.4 API contract usage + +Reuse existing `PATCH /api/v1/tablos/update` payload: +- `{ id: tabloId, layout_overview_v1: }` + +No new endpoint in V1. + +## 6) Frontend Design (`apps/main/src/pages/tablo-details.tsx`) + +## 6.1 Render strategy + +Replace hardcoded block order with configuration-driven rendering: + +- Define block registry: + - key: block id + - value: render function/component for that block +- Render left and right zones by iterating `layout.leftZone` and `layout.rightZone`. + +## 6.2 Edit mode UX + +- Add `Edit layout` button visible only to allowed editors. +- Toggle to `Done editing` while active. +- In edit mode: + - Show drag handles on block cards. + - Enable draggable containers per zone. + - Show subtle "saved" status after successful drop save. + +## 6.3 Drag-and-drop behavior + +- HTML5 DnD approach (consistent with current kanban style in codebase). +- Reorder within same zone only. +- Cross-zone drop is blocked in V1. +- On valid drop: + 1. Compute next zone order. + 2. Optimistically update local UI. + 3. Persist via `useUpdateTablo`. + 4. On failure, revert to last persisted layout snapshot. + +## 6.4 Reset flow + +- `Reset default` sets: + - `leftZone = ["description", "myTasks"]` + - `rightZone = ["files", "info"]` +- Writes reset layout via same mutation path. + +## 7) Permissions and Access + +Current backend `updateTablo` checks `tablo_access.is_admin = true`. +Organization migration sync already grants org members admin tablo access. + +Therefore V1 permission model aligns with existing backend rules: +- Editors: users with current update permission on tablo. +- Viewers: everyone with read access sees saved layout. + +No special permission endpoint needed. + +## 8) Error Handling and Resilience + +- Missing/null layout in DB -> use default layout. +- Invalid/corrupted JSON -> sanitize; if invalid after sanitize, fallback default. +- Save failure: + - Revert optimistic state. + - Toast: layout save failed. + - Keep edit mode active. +- Partial/unknown block IDs: + - Filter unknown IDs. + - Reinsert required missing IDs into default zone positions. + +## 9) Testing Strategy + +## 9.1 Unit tests + +- `sanitizeOverviewLayoutV1`: + - null input -> default + - unknown IDs removed + - missing required IDs recovered + - duplicates deduplicated +- Reorder helper: + - same-zone reorder correctness + - no-op behavior on invalid target indices + - cross-zone rejection + +## 9.2 Page/component tests + +- `Aperçu` renders default order when no saved layout. +- Saved layout order is respected. +- Drop action calls mutation with `layout_overview_v1`. +- Mutation failure rolls back UI order. +- Reset action writes canonical default layout. + +## 9.3 Integration confidence checks + +- Existing tabs (`tasks`, `files`, `discussion`, `events`, `etapes`, `roadmap`) render unchanged. +- Non-editor users do not see edit controls. + +## 10) Rollout Plan + +1. Add DB migration for `layout_overview_v1`. +2. Regenerate shared DB types. +3. Implement frontend schema + renderer + edit interactions. +4. Add tests. +5. Ship behind normal deploy (no feature flag required for V1 scope). + +## 11) Future Extensions (Post-V1) + +- Hide/show blocks. +- Cross-zone moves. +- Block sizing and grid spans. +- New widget catalog (metrics, activity feed, shortcuts). +- Dedicated `tablo_layouts` table for multi-surface layouts and version history. +