4.6 KiB
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 groupedGroupEntry—{ 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
-
Import
useChatGroupsalongsideuseChatSessions -
Group sessions by
groupSlug:
const ungrouped = sessions.filter(s => !s.groupSlug);
const grouped = groups.map(g => ({
...g,
sessions: sessions.filter(s => s.groupSlug === g.slug)
}));
- Add collapsible state:
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;
});
};
- 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
└─ ...
- Group header component:
<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>
- 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:
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
- 8.1.1 — Add
useChatGroupsimport and group sessions by slug - 8.1.2 — Add collapsible state and group headers
- 8.1.3 — Style group headers with icons and counts
- 8.2.1 — Create Group dialog
- 8.2.2 — Group context menu (rename/delete)
- 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?