Add no-code tablo overview builder design spec

This commit is contained in:
Arthur Belleville 2026-03-14 10:43:16 +01:00
parent 2d965c524e
commit 105fe7645e
No known key found for this signature in database

View file

@ -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: <OverviewLayoutV1> }`
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.