docs(24-02): complete UI components plan — hooks, API methods, search/bookmark/branch components
This commit is contained in:
parent
85bd30b6ee
commit
d20dce57ba
3 changed files with 133 additions and 9 deletions
|
|
@ -94,12 +94,12 @@ Plans:
|
|||
2. User can bookmark any message and later filter or navigate to bookmarked messages
|
||||
3. Editing a message that already has a response creates a new branch; both the original and the new branch are preserved and the user can switch between them
|
||||
4. User can export any conversation as a Markdown file or as a JSON file containing all messages and metadata
|
||||
**Plans:** 2/4 plans executed
|
||||
**Plans:** 3/4 plans executed
|
||||
|
||||
Plans:
|
||||
- [x] 24-00-PLAN.md — DB migrations (branch columns, tsvector+GIN, bookmarks table), shared types, Wave 0 test stubs
|
||||
- [x] 24-01-PLAN.md — Server: search, bookmark, branch, export service methods and Express routes
|
||||
- [ ] 24-02-PLAN.md — UI: ChatSearchDialog, ChatMessageBookmark, ChatBookmarkList, ChatBranchSelector, API client, hooks
|
||||
- [x] 24-02-PLAN.md — UI: ChatSearchDialog, ChatMessageBookmark, ChatBookmarkList, ChatBranchSelector, API client, hooks
|
||||
- [ ] 24-03-PLAN.md — Wiring: ChatPanel integration, CommandPalette search item, scroll-to-message, bookmark toggle, branch-on-edit
|
||||
|
||||
**UI hint**: yes
|
||||
|
|
@ -214,6 +214,6 @@ All 65 v1 requirements are mapped to exactly one phase. No orphans.
|
|||
| 21. Chat Foundation | v1.3 | 7/7 | Complete | 2026-04-01 |
|
||||
| 22. Agent Streaming | v1.3 | 6/6 | Complete | 2026-04-01 |
|
||||
| 23. Brainstormer Flow | v1.3 | 4/4 | Complete | 2026-04-01 |
|
||||
| 24. Search, History & Branching | v1.3 | 2/4 | In Progress| |
|
||||
| 24. Search, History & Branching | v1.3 | 3/4 | In Progress| |
|
||||
| 25. File System | v1.3 | 0/? | Not started | - |
|
||||
| 26. PWA & Performance | v1.3 | 0/? | Not started | - |
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
|||
milestone: v1.3
|
||||
milestone_name: milestone
|
||||
status: executing
|
||||
stopped_at: Completed 24-search-history-branching-24-01-PLAN.md
|
||||
last_updated: "2026-04-01T22:33:10.664Z"
|
||||
stopped_at: Completed 24-search-history-branching-24-02-PLAN.md
|
||||
last_updated: "2026-04-01T22:34:30.283Z"
|
||||
last_activity: 2026-04-01
|
||||
progress:
|
||||
total_phases: 6
|
||||
completed_phases: 3
|
||||
total_plans: 21
|
||||
completed_plans: 19
|
||||
completed_plans: 20
|
||||
percent: 100
|
||||
---
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-03-30)
|
|||
## Current Position
|
||||
|
||||
Phase: 24 (search-history-branching) — EXECUTING
|
||||
Plan: 3 of 4
|
||||
Plan: 4 of 4
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-04-01
|
||||
|
||||
|
|
@ -76,6 +76,7 @@ Progress: [██████████] 100%
|
|||
| Phase 23-brainstormer-flow P03 | 5 | 2 tasks | 4 files |
|
||||
| Phase 24-search-history-branching P00 | 5 | 2 tasks | 9 files |
|
||||
| Phase 24-search-history-branching P01 | 12 | 2 tasks | 2 files |
|
||||
| Phase 24-search-history-branching P02 | 3min | 2 tasks | 7 files |
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
|
|
@ -124,6 +125,9 @@ Recent decisions affecting current work:
|
|||
- [Phase 24-search-history-branching]: content_search tsvector column omitted from Drizzle schema — Postgres-generated stored column queried via raw sql`` only
|
||||
- [Phase 24-search-history-branching]: searchMessages returns empty items early when query.trim() is empty — avoids PostgreSQL error on blank tsquery
|
||||
- [Phase 24-search-history-branching]: exportConversation uses this.getConversation() to reuse notFound guard without duplicating query logic
|
||||
- [Phase 24-search-history-branching]: Used HighlightedText React component instead of innerHTML for term highlighting — eliminates XSS surface
|
||||
- [Phase 24-search-history-branching]: exportConversation returns URL string (not fetch call) since server sends file download via browser navigation
|
||||
- [Phase 24-search-history-branching]: shouldFilter=false pattern on Command for server-side FTS — all future search dialogs should follow this
|
||||
|
||||
### Pending Todos
|
||||
|
||||
|
|
@ -136,6 +140,6 @@ None yet.
|
|||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-04-01T22:33:10.661Z
|
||||
Stopped at: Completed 24-search-history-branching-24-01-PLAN.md
|
||||
Last session: 2026-04-01T22:34:30.280Z
|
||||
Stopped at: Completed 24-search-history-branching-24-02-PLAN.md
|
||||
Resume file: None
|
||||
|
|
|
|||
120
.planning/phases/24-search-history-branching/24-02-SUMMARY.md
Normal file
120
.planning/phases/24-search-history-branching/24-02-SUMMARY.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
phase: 24-search-history-branching
|
||||
plan: 02
|
||||
subsystem: ui
|
||||
tags: [react, tanstack-query, cmdk, lucide-react, typescript]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 24-00
|
||||
provides: shared types (ChatMessageSearchResult, ChatBookmarkWithMessage, ChatBookmarkToggleResponse, ChatBookmarkListResponse, ChatConversation with branch fields)
|
||||
|
||||
provides:
|
||||
- chatApi.searchMessages — FTS endpoint client method
|
||||
- chatApi.toggleBookmark — bookmark toggle client method
|
||||
- chatApi.getBookmarks — bookmark list client method
|
||||
- chatApi.branchConversation — branch creation client method
|
||||
- chatApi.listBranches — branch list client method
|
||||
- chatApi.exportConversation — export download URL helper
|
||||
- useChatSearch hook — debounced FTS query hook with placeholderData
|
||||
- useChatBookmarks hook — bookmark list query hook
|
||||
- useToggleBookmark hook — bookmark mutation with cache invalidation
|
||||
- ChatSearchDialog component — CommandDialog FTS overlay with term highlighting
|
||||
- ChatMessageBookmark component — bookmark toggle icon button
|
||||
- ChatBookmarkList component — filterable scrollable bookmark list
|
||||
- ChatBranchSelector component — horizontal branch picker bar
|
||||
|
||||
affects: [24-03]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "useChatSearch: placeholderData=(prev)=>prev keeps previous results while new query loads"
|
||||
- "ChatSearchDialog: shouldFilter=false on Command for server-side FTS (not cmdk client filtering)"
|
||||
- "HighlightedText: React component splits text into segments to avoid unsafe innerHTML XSS risk"
|
||||
- "useToggleBookmark: invalidates both [chat, bookmarks] and [chat, search] queries after toggle"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- ui/src/hooks/useChatSearch.ts
|
||||
- ui/src/hooks/useChatBookmarks.ts
|
||||
- ui/src/components/ChatSearchDialog.tsx
|
||||
- ui/src/components/ChatMessageBookmark.tsx
|
||||
- ui/src/components/ChatBookmarkList.tsx
|
||||
- ui/src/components/ChatBranchSelector.tsx
|
||||
modified:
|
||||
- ui/src/api/chat.ts
|
||||
|
||||
key-decisions:
|
||||
- "Used HighlightedText React component instead of innerHTML for term highlighting — eliminates XSS surface"
|
||||
- "exportConversation returns URL string (not fetch call) since server sends file download via browser navigation"
|
||||
- "ChatBranchSelector renders null when branches.length === 0 — no empty bar shown"
|
||||
|
||||
patterns-established:
|
||||
- "shouldFilter=false pattern: all server-side search dialogs set this to bypass cmdk client filtering"
|
||||
- "Cache invalidation pattern: bookmark mutations invalidate both bookmarks and search query caches"
|
||||
|
||||
requirements-completed: [CHAT-07, CHAT-13, CHAT-14, HIST-04, HIST-12, PERF-04]
|
||||
|
||||
# Metrics
|
||||
duration: 3min
|
||||
completed: 2026-04-01
|
||||
---
|
||||
|
||||
# Phase 24 Plan 02: Search History Branching UI Summary
|
||||
|
||||
**Six chatApi methods, two React Query hooks, and four components — search/bookmark/branch UI layer built independently from server routes, ready for wiring in Plan 03.**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** ~3 min
|
||||
- **Started:** 2026-04-01T22:29:56Z
|
||||
- **Completed:** 2026-04-01T22:32:55Z
|
||||
- **Tasks:** 2 completed
|
||||
- **Files modified:** 7
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Extended `chatApi` in `ui/src/api/chat.ts` with six new methods covering search, bookmarks, branches, and export
|
||||
- Created `useChatSearch` and `useChatBookmarks`/`useToggleBookmark` TanStack Query hooks with proper cache invalidation
|
||||
- Built four UI components: `ChatSearchDialog` (CommandDialog FTS overlay), `ChatMessageBookmark` (toggle icon button), `ChatBookmarkList` (scrollable list with skeletons/empty state), `ChatBranchSelector` (horizontal branch picker)
|
||||
- UI build passes cleanly with no TypeScript errors
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: API client methods and React Query hooks** - `e1ab0ca0` (feat)
|
||||
2. **Task 2: UI components** - `11145afe` (feat)
|
||||
|
||||
**Plan metadata:** (pending — docs commit)
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `ui/src/api/chat.ts` — Added searchMessages, toggleBookmark, getBookmarks, branchConversation, listBranches, exportConversation methods; added shared type imports
|
||||
- `ui/src/hooks/useChatSearch.ts` — TanStack Query hook for debounced FTS; enabled when query >= 2 chars; placeholderData keeps previous results during load; 30s staleTime
|
||||
- `ui/src/hooks/useChatBookmarks.ts` — useChatBookmarks query hook + useToggleBookmark mutation; invalidates both bookmarks and search caches on success
|
||||
- `ui/src/components/ChatSearchDialog.tsx` — CommandDialog-based FTS overlay; shouldFilter=false for server-side search; HighlightedText component splits text into marked segments without XSS risk
|
||||
- `ui/src/components/ChatMessageBookmark.tsx` — Ghost icon button (h-6 w-6 / h-3.5 w-3.5) matching ChatMessageActions sizing; fill-current on bookmarked state; aria-label toggles
|
||||
- `ui/src/components/ChatBookmarkList.tsx` — Scrollable list using useChatBookmarks; skeleton loading placeholders (matching ChatConversationList pattern); Bookmark icon empty state
|
||||
- `ui/src/components/ChatBranchSelector.tsx` — Horizontal bar with GitBranch icon; "Original" button for parent conv; branch buttons with bg-accent for active; renders null when no branches
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 2 - Security] Replaced innerHTML approach with React HighlightedText component for term highlighting**
|
||||
- **Found during:** Task 2 implementation
|
||||
- **Issue:** Security hook flagged setting innerHTML for XSS risk when highlighting matched terms
|
||||
- **Fix:** Extracted HighlightedText React component that splits text into plain/highlighted segments using regex, rendering mark elements directly without setting innerHTML
|
||||
- **Files modified:** ui/src/components/ChatSearchDialog.tsx
|
||||
- **Commit:** 11145afe
|
||||
|
||||
## Known Stubs
|
||||
|
||||
None. All components accept callback props (onNavigate, onToggle, onSelectBranch) — no routing or state is hardcoded inside. Data fetching is wired to real chatApi endpoints. Plan 03 will integrate these into ChatPanel.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
All 7 files confirmed present on disk. Both task commits (e1ab0ca0, 11145afe) confirmed in git log.
|
||||
Loading…
Add table
Reference in a new issue