docs: add tree forking UI design doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-24 23:58:35 -05:00
parent 2bc8a85bfa
commit a8b5c90e27

View File

@@ -0,0 +1,108 @@
# Tree Forking UI Design
> **Date:** 2026-02-24
> **Feature:** Personal tree forking — explicit modal, reason capture, fork badge
---
## Overview
Add a proper fork UX to the flow library. The backend is fully complete (POST `/trees/:id/fork`, fork fields in API responses, tests passing). The frontend needs: a `ForkModal` component with a "Reason for Forking" field, updated fork handlers in `TreeLibraryPage` and `MyTreesPage`, fork field types on `Tree`, and a "Fork" chip on tree cards.
---
## What's Being Built
### 1. Types — `frontend/src/types/tree.ts`
Add `ForkInfo` interface and fork fields to `Tree`:
```ts
export interface ForkInfo {
parent_tree_id: string
parent_tree_name: string | null
fork_depth: number
fork_reason: string | null
has_parent_updates: boolean
}
```
Add to `Tree`:
```ts
fork_info?: ForkInfo | null
parent_tree_id?: string | null
fork_depth?: number
```
Add to `TreeCreate`:
```ts
fork_reason?: string
```
### 2. `ForkModal` Component — `frontend/src/components/library/ForkModal.tsx`
A focused dialog with:
- **Name field** — pre-filled with `"Copy of <original name>"`
- **"Reason for Forking"** — optional textarea (placeholder: "e.g. customizing for a specific client…")
- **Cancel** (secondary) + **Fork** (gradient) buttons
- Calls `treesApi.fork(treeId, { name, fork_reason })` on submit
- Success: shows toast, navigates to `/my-trees`
- Error: shows inline error, stays open
### 3. Update Fork Handlers
In `TreeLibraryPage` and `MyTreesPage`, replace the current silent `handleForkTree` (which calls `treesApi.fork()` directly) with a handler that:
1. Sets the selected tree to fork
2. Opens `ForkModal`
The modal handles the actual API call and navigation.
### 4. "Fork" Badge on Tree Cards
In `TreeGridView`, `TreeListView`, and `TreeTableView`, render a small chip when `fork_depth > 0` (or `parent_tree_id` is set on `TreeListItem`):
```tsx
{tree.fork_depth > 0 && (
<span className="rounded-full bg-violet-400/15 px-1.5 py-0.5 text-[9px] font-semibold uppercase tracking-wide text-violet-400">
Fork
</span>
)}
```
`fork_depth` needs to be added to `TreeListItem` (it comes from the backend list response).
---
## What's NOT Being Built
- Lineage tree view / "forked from" link — out of scope
- "Has updates available" notification — out of scope
- Fork management / ancestry tracking UI — out of scope
---
## Data Flow
```
User clicks "Fork" on a card
→ onForkTree(tree) called
→ parent sets forkTarget state + opens ForkModal
→ user fills Name + optional Reason
→ ForkModal calls treesApi.fork(treeId, { name, fork_reason })
→ on success: toast "Flow forked!" + navigate('/my-trees')
→ My Trees page loads, forked flow shows "Fork" badge
```
---
## Files Changed
| File | Change |
|------|--------|
| `frontend/src/types/tree.ts` | Add `ForkInfo`, fork fields on `Tree`, `fork_depth` on `TreeListItem` |
| `frontend/src/components/library/ForkModal.tsx` | New component |
| `frontend/src/pages/TreeLibraryPage.tsx` | Open modal instead of silent fork |
| `frontend/src/pages/MyTreesPage.tsx` | Open modal instead of silent fork |
| `frontend/src/components/library/TreeGridView.tsx` | Fork badge |
| `frontend/src/components/library/TreeListView.tsx` | Fork badge |
| `frontend/src/components/library/TreeTableView.tsx` | Fork badge |