Files
platform/PHASE_8_PLAN.md
T

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 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:

const ungrouped = sessions.filter(s => !s.groupSlug);
const grouped = groups.map(g => ({
  ...g,
  sessions: sessions.filter(s => s.groupSlug === g.slug)
}));
  1. 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;
  });
};
  1. 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
└─ ...
  1. 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>
  1. 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

  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?