Add Phase 8 detailed implementation plan for grouped chat UI
This commit is contained in:
+168
@@ -0,0 +1,168 @@
|
||||
# Phase 8: Grouped Chat UI — Detailed Implementation Plan
|
||||
|
||||
## Overview
|
||||
|
||||
Add UI for organizing chat sessions into collapsible groups.
|
||||
|
||||
**Data available:**
|
||||
- `SessionEntry.groupSlug` — null for ungrouped, string for grouped
|
||||
- `GroupEntry` — `{ name, slug, description, createdAt, updatedAt, sessionCount }`
|
||||
- `useChatGroups()` hook — `{ groups, createGroup, updateGroup, deleteGroup, moveSession }`
|
||||
|
||||
---
|
||||
|
||||
## Phase 8.1: Grouped SessionList UI
|
||||
|
||||
**File:** `src/apps/officer-web/Screens/Dashboard/ChatHistory/Screen.tsx`
|
||||
|
||||
### Changes
|
||||
|
||||
1. **Import `useChatGroups`** alongside `useChatSessions`
|
||||
|
||||
2. **Group sessions by `groupSlug`:**
|
||||
```ts
|
||||
const ungrouped = sessions.filter(s => !s.groupSlug);
|
||||
const grouped = groups.map(g => ({
|
||||
...g,
|
||||
sessions: sessions.filter(s => s.groupSlug === g.slug)
|
||||
}));
|
||||
```
|
||||
|
||||
3. **Add collapsible state:**
|
||||
```ts
|
||||
const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
|
||||
const toggleGroup = (slug: string) => {
|
||||
setCollapsed(prev => {
|
||||
const next = new Set(prev);
|
||||
next.has(slug) ? next.delete(slug) : next.add(slug);
|
||||
return next;
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
4. **Render structure:**
|
||||
```
|
||||
Header (Sessions + New Chat button + Create Group button)
|
||||
├─ Ungrouped sessions (flat list)
|
||||
├─ Group 1 header (collapsible, with count badge)
|
||||
│ └─ Group 1 sessions (hidden if collapsed)
|
||||
├─ Group 2 header
|
||||
│ └─ Group 2 sessions
|
||||
└─ ...
|
||||
```
|
||||
|
||||
5. **Group header component:**
|
||||
```tsx
|
||||
<div className="flex items-center gap-2 px-3 py-2 cursor-pointer" onClick={() => toggleGroup(slug)}>
|
||||
<ChevronRight className={`h-4 w-4 transition-transform ${!collapsed.has(slug) ? 'rotate-90' : ''}`} />
|
||||
<Folder className="h-4 w-4 text-duck-teal" />
|
||||
<span className="font-medium">{group.name}</span>
|
||||
<span className="text-xs text-duck-dark/40">({group.sessionCount})</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
6. **Session item:** Add group indicator badge if grouped
|
||||
|
||||
---
|
||||
|
||||
## Phase 8.2: Group Management UI
|
||||
|
||||
### 8.2.1: Create Group Dialog
|
||||
|
||||
**File:** New component `src/apps/officer-web/Screens/Dashboard/ChatHistory/CreateGroupDialog.tsx`
|
||||
|
||||
**Trigger:** Button in SessionList header (next to "New Chat")
|
||||
|
||||
**Fields:**
|
||||
- Name (required) — auto-generates slug
|
||||
- Description (optional)
|
||||
|
||||
**Slug generation:**
|
||||
```ts
|
||||
const toSlug = (name: string) => name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
||||
```
|
||||
|
||||
**On submit:** Call `createGroup(name, slug, description)`
|
||||
|
||||
### 8.2.2: Group Context Menu
|
||||
|
||||
**File:** Update `Screen.tsx`
|
||||
|
||||
**On group header right-click or "..." button:**
|
||||
- Rename group → inline edit or dialog
|
||||
- Delete group → confirmation dialog ("Sessions will be ungrouped")
|
||||
|
||||
### 8.2.3: Session Context Menu
|
||||
|
||||
**File:** Update `Screen.tsx`
|
||||
|
||||
**On session right-click or "..." button:**
|
||||
- Move to group → submenu with group list + "Ungrouped"
|
||||
- Rename session (existing)
|
||||
- Delete session (existing)
|
||||
|
||||
**Implementation:** Use `moveSession(sessionId, groupSlug)` from `useChatGroups`
|
||||
|
||||
---
|
||||
|
||||
## Phase 8.3: Widget Updates (Optional)
|
||||
|
||||
**File:** `src/apps/officer-web/Screens/Dashboard/ChatHistory/Widget.tsx`
|
||||
|
||||
Simpler version — just show recent sessions, no grouping. Or:
|
||||
- Show 3 most recent ungrouped
|
||||
- Show group names with expand link to full view
|
||||
|
||||
**Decision:** Keep Widget simple for now, grouping only in full SessionList.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Order
|
||||
|
||||
1. **8.1.1** — Add `useChatGroups` import and group sessions by slug
|
||||
2. **8.1.2** — Add collapsible state and group headers
|
||||
3. **8.1.3** — Style group headers with icons and counts
|
||||
4. **8.2.1** — Create Group dialog
|
||||
5. **8.2.2** — Group context menu (rename/delete)
|
||||
6. **8.2.3** — Session context menu (move to group)
|
||||
|
||||
---
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
| File | Action |
|
||||
|------|--------|
|
||||
| `ChatHistory/Screen.tsx` | Major update — grouping logic, collapsible UI, context menus |
|
||||
| `ChatHistory/CreateGroupDialog.tsx` | New — create group form |
|
||||
| `ChatHistory/GroupContextMenu.tsx` | New — rename/delete group actions |
|
||||
| `ChatHistory/SessionContextMenu.tsx` | New — move/rename/delete session actions |
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
- [ ] Sessions without groupSlug appear in "Ungrouped" section
|
||||
- [ ] Sessions with groupSlug appear under correct group
|
||||
- [ ] Groups are collapsible (click header to toggle)
|
||||
- [ ] Group session counts are accurate
|
||||
- [ ] Create group dialog opens and creates group
|
||||
- [ ] Slug is auto-generated from name
|
||||
- [ ] Rename group works (inline or dialog)
|
||||
- [ ] Delete group moves sessions to ungrouped
|
||||
- [ ] Move session to group works
|
||||
- [ ] Move session to ungrouped works
|
||||
- [ ] UI updates immediately after all operations
|
||||
|
||||
---
|
||||
|
||||
## Estimated Effort
|
||||
|
||||
- **8.1 (Grouped UI):** ~1-2 hours
|
||||
- **8.2 (Group Management):** ~2-3 hours
|
||||
- **8.3 (Widget):** Skip for now
|
||||
|
||||
**Total:** ~3-5 hours
|
||||
|
||||
---
|
||||
|
||||
Ready to implement?
|
||||
Reference in New Issue
Block a user