fix: move ViewToggle into header bars and remove subtitle
Eliminates the dedicated ViewToggle row on CockpitPage by merging it into IncidentHeader's action group via extraActions prop. Removes subtitle from ViewToggle component entirely — the icon + label is self-explanatory. Cleans up showSubtitle prop from all call sites. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,8 @@ interface IncidentHeaderProps {
|
|||||||
onStatusUpdate?: () => void
|
onStatusUpdate?: () => void
|
||||||
onPause?: () => void
|
onPause?: () => void
|
||||||
onClose?: () => void
|
onClose?: () => void
|
||||||
|
/** Extra elements rendered in the action group (e.g. ViewToggle) */
|
||||||
|
extraActions?: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditPopoverProps {
|
interface EditPopoverProps {
|
||||||
@@ -168,6 +170,7 @@ export function IncidentHeader({
|
|||||||
onStatusUpdate,
|
onStatusUpdate,
|
||||||
onPause,
|
onPause,
|
||||||
onClose,
|
onClose,
|
||||||
|
extraActions,
|
||||||
}: IncidentHeaderProps) {
|
}: IncidentHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-card border-b border-default px-4 py-2 flex items-center gap-4 flex-wrap">
|
<div className="bg-card border-b border-default px-4 py-2 flex items-center gap-4 flex-wrap">
|
||||||
@@ -223,6 +226,7 @@ export function IncidentHeader({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<OverflowMenu onPause={onPause} onClose={onClose} />
|
<OverflowMenu onPause={onPause} onClose={onClose} />
|
||||||
|
{extraActions}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import { useUserPreferencesStore } from '@/store/userPreferencesStore'
|
|||||||
|
|
||||||
type FlowPilotView = 'flowpilot' | 'cockpit'
|
type FlowPilotView = 'flowpilot' | 'cockpit'
|
||||||
|
|
||||||
const VIEW_OPTIONS: { key: FlowPilotView; label: string; icon: typeof MessageSquare; subtitle: string }[] = [
|
const VIEW_OPTIONS: { key: FlowPilotView; label: string; icon: typeof MessageSquare }[] = [
|
||||||
{ key: 'flowpilot', label: 'FlowPilot', icon: MessageSquare, subtitle: 'Chat-first AI troubleshooting' },
|
{ key: 'flowpilot', label: 'FlowPilot', icon: MessageSquare },
|
||||||
{ key: 'cockpit', label: 'Cockpit', icon: LayoutDashboard, subtitle: 'Steps, evidence & triage board' },
|
{ key: 'cockpit', label: 'Cockpit', icon: LayoutDashboard },
|
||||||
]
|
]
|
||||||
|
|
||||||
interface ViewToggleProps {
|
interface ViewToggleProps {
|
||||||
@@ -16,19 +16,15 @@ interface ViewToggleProps {
|
|||||||
currentView: FlowPilotView
|
currentView: FlowPilotView
|
||||||
/** Session ID for navigation (session pages only). Omit for preference-only mode (dashboard). */
|
/** Session ID for navigation (session pages only). Omit for preference-only mode (dashboard). */
|
||||||
sessionId?: string
|
sessionId?: string
|
||||||
/** Show the subtitle below the toggle. Default true for standalone, false for inline. */
|
|
||||||
showSubtitle?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ViewToggle({ currentView, sessionId, showSubtitle = true }: ViewToggleProps) {
|
export function ViewToggle({ currentView, sessionId }: ViewToggleProps) {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const hasCockpit = useFeatureFlag('flowpilot_cockpit')
|
const hasCockpit = useFeatureFlag('flowpilot_cockpit')
|
||||||
const setPreferredView = useUserPreferencesStore(s => s.setPreferredFlowPilotView)
|
const setPreferredView = useUserPreferencesStore(s => s.setPreferredFlowPilotView)
|
||||||
|
|
||||||
if (!hasCockpit) return null
|
if (!hasCockpit) return null
|
||||||
|
|
||||||
const activeOption = VIEW_OPTIONS.find(o => o.key === currentView) ?? VIEW_OPTIONS[0]
|
|
||||||
|
|
||||||
const handleSwitch = (view: FlowPilotView) => {
|
const handleSwitch = (view: FlowPilotView) => {
|
||||||
if (view === currentView) return
|
if (view === currentView) return
|
||||||
setPreferredView(view)
|
setPreferredView(view)
|
||||||
@@ -41,29 +37,22 @@ export function ViewToggle({ currentView, sessionId, showSubtitle = true }: View
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-start gap-1">
|
<div className="flex items-center rounded-lg border border-border bg-card p-0.5 text-xs">
|
||||||
<div className="flex items-center rounded-lg border border-border bg-card p-0.5 text-xs">
|
{VIEW_OPTIONS.map(({ key, label, icon: Icon }) => (
|
||||||
{VIEW_OPTIONS.map(({ key, label, icon: Icon }) => (
|
<button
|
||||||
<button
|
key={key}
|
||||||
key={key}
|
onClick={() => handleSwitch(key)}
|
||||||
onClick={() => handleSwitch(key)}
|
className={cn(
|
||||||
className={cn(
|
'flex items-center gap-1.5 rounded-md px-2.5 py-1 font-medium transition-colors',
|
||||||
'flex items-center gap-1.5 rounded-md px-2.5 py-1 font-medium transition-colors',
|
currentView === key
|
||||||
currentView === key
|
? 'bg-elevated text-foreground'
|
||||||
? 'bg-elevated text-foreground'
|
: 'text-muted-foreground hover:text-foreground'
|
||||||
: 'text-muted-foreground hover:text-foreground'
|
)}
|
||||||
)}
|
>
|
||||||
>
|
<Icon size={12} />
|
||||||
<Icon size={12} />
|
{label}
|
||||||
{label}
|
</button>
|
||||||
</button>
|
))}
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{showSubtitle && (
|
|
||||||
<span className="text-[10px] text-muted-foreground leading-none pl-0.5">
|
|
||||||
{activeOption.subtitle}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ export default function CockpitPage() {
|
|||||||
</button>
|
</button>
|
||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
{session.activeChatId && (
|
{session.activeChatId && (
|
||||||
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} showSubtitle={false} />
|
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} />
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={session.handleNewChat}
|
onClick={session.handleNewChat}
|
||||||
@@ -275,11 +275,12 @@ export default function CockpitPage() {
|
|||||||
onResolve={() => session.setShowConclude(true)}
|
onResolve={() => session.setShowConclude(true)}
|
||||||
onStatusUpdate={session.messages.length >= 2 ? () => session.setShowStatusUpdate(true) : undefined}
|
onStatusUpdate={session.messages.length >= 2 ? () => session.setShowStatusUpdate(true) : undefined}
|
||||||
onClose={() => session.setShowConclude(true)}
|
onClose={() => session.setShowConclude(true)}
|
||||||
|
extraActions={
|
||||||
|
<div className="hidden sm:block">
|
||||||
|
<ViewToggle currentView="cockpit" sessionId={session.activeChatId} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
{/* 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 */}
|
{/* Resizable work zone + conversation log split */}
|
||||||
<div ref={splitContainerRef} className="flex-1 flex flex-col min-h-0 relative">
|
<div ref={splitContainerRef} className="flex-1 flex flex-col min-h-0 relative">
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default function FlowPilotPage() {
|
|||||||
</button>
|
</button>
|
||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
{session.activeChatId && (
|
{session.activeChatId && (
|
||||||
<ViewToggle currentView="flowpilot" sessionId={session.activeChatId} showSubtitle={false} />
|
<ViewToggle currentView="flowpilot" sessionId={session.activeChatId} />
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={session.handleNewChat}
|
onClick={session.handleNewChat}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export function QuickStartPage() {
|
|||||||
{/* View preference — standalone row above input */}
|
{/* View preference — standalone row above input */}
|
||||||
<div className="flex items-center gap-3 mb-5">
|
<div className="flex items-center gap-3 mb-5">
|
||||||
<span className="text-xs text-muted-foreground">Launch in</span>
|
<span className="text-xs text-muted-foreground">Launch in</span>
|
||||||
<ViewToggle currentView={preferredView} showSubtitle={false} />
|
<ViewToggle currentView={preferredView} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Chat-style input */}
|
{/* Chat-style input */}
|
||||||
|
|||||||
Reference in New Issue
Block a user