fix: cockpit/flowpilot bugs and redesign view toggle placement

- Fix return type annotation on unified_chat_service.send_chat_message (6→7 tuple)
- Fix stale closure in CockpitPage handleStepComplete auto-advance logic
- Fix IncidentHeader copy link hardcoding /assistant/ path (now uses current URL)
- Wire psaTicketId from session data through to CockpitPage incident header
- Fix FlowPilotAsks showing only first question — add chevron navigation for all
- Redesign ViewToggle: add icons (MessageSquare/LayoutDashboard) and subtitles
- Move view toggle from chatbar toolbar to standalone row above input on dashboard
- Standardize toggle placement across dashboard, FlowPilot, and Cockpit pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-03 05:02:42 +00:00
parent ed6e6cd1ed
commit 813b598101
9 changed files with 121 additions and 88 deletions

View File

@@ -26,6 +26,7 @@ export default function CockpitPage() {
client_name: null, asset_name: null, issue_category: null,
triage_hypothesis: null, evidence_items: [],
})
const [psaTicketId, setPsaTicketId] = useState<string | null>(null)
const [workZonePct, setWorkZonePct] = useState(() => {
const saved = localStorage.getItem('rf-assistant-work-zone-height')
return saved ? parseFloat(saved) : 55
@@ -62,6 +63,7 @@ export default function CockpitPage() {
triage_hypothesis: detail.triage_hypothesis ?? null,
evidence_items: (detail.evidence_items as EvidenceItem[]) ?? [],
})
setPsaTicketId(detail.psa_ticket_id ?? null)
}
return () => { session.onSessionLoadedRef.current = null }
}, [session.onSessionLoadedRef])
@@ -130,16 +132,16 @@ export default function CockpitPage() {
setCompletedSteps(prev => {
const next = new Set(prev)
next.add(index)
// Auto-advance using the updated set (avoids stale closure)
const nextIncomplete = session.activeActions.findIndex((_, i) => i > index && !next.has(i))
if (nextIncomplete !== -1) {
setActiveStepIndex(nextIncomplete)
} else if (index + 1 < session.activeActions.length) {
setActiveStepIndex(index + 1)
}
return next
})
// Auto-advance to the next incomplete step
const nextIncomplete = session.activeActions.findIndex((_, i) => i > index && !completedSteps.has(i))
if (nextIncomplete !== -1) {
setActiveStepIndex(nextIncomplete)
} else if (index + 1 < session.activeActions.length) {
setActiveStepIndex(index + 1)
}
}, [session.activeActions, completedSteps])
}, [session.activeActions])
const handleStepSelect = useCallback((index: number) => {
setActiveStepIndex(index)
@@ -240,6 +242,9 @@ export default function CockpitPage() {
Cases
</button>
<div className="flex-1" />
{session.activeChatId && (
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} showSubtitle={false} />
)}
<button
onClick={session.handleNewChat}
className="rounded-lg px-3 py-2 text-sm font-medium text-primary hover:bg-primary/10 transition-colors"
@@ -253,13 +258,15 @@ export default function CockpitPage() {
{/* Incident Header */}
<IncidentHeader
triageMeta={triageMeta}
psaTicketId={session.messages.length > 0 ? null : null}
sessionId={session.activeChatId}
psaTicketId={psaTicketId}
onFieldSave={handleTriageFieldSave}
onResolve={() => session.setShowConclude(true)}
onClose={() => session.setShowConclude(true)}
/>
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} />
{/* View toggle bar — desktop only (mobile has it in the header) */}
<div className="hidden sm:flex items-center justify-end px-4 py-1.5 border-b border-border/50">
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} />
</div>
{/* Resizable work zone + conversation log split */}
<div ref={splitContainerRef} className="flex-1 flex flex-col min-h-0 relative">