Session UI
Main chat container with resizable panels and responsive layout.
ChatSessionUI is the top-level container for an active chat conversation. It orchestrates messages, the map panel, the document viewer, and the settings sheet.
Props
interface ChatSessionUIProps {
chatSession: ChatSession;
enableDocumentStatusPolling?: boolean;
}State Management
The component manages several pieces of state:
// Map visibility (synced with URL query params)
const [isMapVisible, setIsMapVisible] = useQueryParam("map");
// Document viewer tabs
const [openDocuments, setOpenDocuments] = useState<DocumentTab[]>([]);
const [activeDocumentId, setActiveDocumentId] = useState<string | null>(null);
// Mobile document sheet
const [isMobileDocumentSheetOpen, setIsMobileDocumentSheetOpen] = useState(false);
// Document processing status
const [documentStatuses, setDocumentStatuses] = useState<DocumentStatus[]>([]);Desktop Layout (Resizable Panels)
On desktop, the chat uses ResizablePanelGroup for a flexible multi-panel layout:
┌─────────────────┬──────────────┬──────────────────┐
│ │ │ │
│ Message List │ Google Map │ Document Viewer │
│ + Input Form │ (optional) │ (optional) │
│ │ │ │
└─────────────────┴──────────────┴──────────────────┘- Panel 1 (Messages): Always visible, min 30% width
- Panel 2 (Map): Toggled via header button, shows Google Maps with location markers
- Panel 3 (Documents): Opens when clicking a citation source, tabbed document viewer
Users can drag panel borders to resize.
Mobile Layout
On mobile, the layout stacks vertically:
┌──────────────────┐
│ Chat Header │
├──────────────────┤
│ │
│ Message List │
│ │
├──────────────────┤
│ Input Form │
└──────────────────┘
+ Sheet modals for Map & DocumentsDocuments and map open in Sheet components (slide-up panels).
Document Status Polling
When enableDocumentStatusPolling is true, the component polls document processing status every 5 seconds:
useEffect(() => {
if (!enableDocumentStatusPolling) return;
const interval = setInterval(async () => {
const statuses = await fetchDocumentStatuses(chatSession.id);
setDocumentStatuses(statuses);
}, 5000);
return () => clearInterval(interval);
}, []);This keeps the UI updated when documents are being ingested in the background.
Citation Click Flow
When a user clicks a citation source in a message:
onCitationClick(documentId, chunkId)is called- If document not already open, add to
openDocumentstabs - Set
activeDocumentIdto the clicked document - Pass
highlightChunkIdto the document viewer - On mobile, open the document sheet
Settings Sheet
The ChatSettingsForm opens as a side sheet with:
- Chat name editor
- AI model selection (dropdown with all supported models)
- Temperature, top_p, max_tokens controls
- Knowledge base management (attach/detach KBs)
Changes are saved via PUT to the chat session API.
Location Sheet
When a location tag is clicked in a message:
onLocationClick(location)is called- A floating sheet opens with
LocationDetailView - Shows location name, address, and details
- Map panel centers on the location marker