feat(pilot): EscalateInterceptDialog popover
Anchored above the Escalate button, captures fix outcome before the engineer hands off the ticket. Defaults to 'didn't work' on Enter (the common case). Alternatives: 'worked, escalating for another reason' (preserves success) and 'never actually applied' (dismiss). Task 11 will wire this to AssistantChatPage's Escalate handler. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
76
frontend/src/components/pilot/EscalateInterceptDialog.tsx
Normal file
76
frontend/src/components/pilot/EscalateInterceptDialog.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* EscalateInterceptDialog — popover anchored above the Escalate button.
|
||||||
|
*
|
||||||
|
* Fires when the engineer clicks Escalate while a fix is in Verifying or
|
||||||
|
* Partial state. Captures the fix outcome before the escalation so the
|
||||||
|
* handoff narrative is honest for whoever picks up the ticket.
|
||||||
|
*
|
||||||
|
* Visual reference: docs/FlowAssist_Migration/mockups/07-verify-states.html
|
||||||
|
* (panel C).
|
||||||
|
*/
|
||||||
|
import { X, AlertCircle, Check } from 'lucide-react'
|
||||||
|
import type { FixOutcome } from '@/api/sessionSuggestedFixes'
|
||||||
|
|
||||||
|
export type InterceptChoice = FixOutcome | 'never_applied'
|
||||||
|
|
||||||
|
export interface EscalateInterceptDialogProps {
|
||||||
|
fixTitle: string
|
||||||
|
onChoose: (choice: InterceptChoice) => void
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EscalateInterceptDialog({
|
||||||
|
fixTitle,
|
||||||
|
onChoose,
|
||||||
|
onClose,
|
||||||
|
}: EscalateInterceptDialogProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="fixed inset-0 z-40"
|
||||||
|
onClick={onClose}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
role="dialog"
|
||||||
|
aria-label="Capture fix outcome before escalating"
|
||||||
|
className="absolute bottom-full mb-2 left-0 z-50 w-[340px] rounded-lg border border-white/15 bg-card p-3.5 shadow-[0_18px_40px_rgba(0,0,0,0.55)]"
|
||||||
|
>
|
||||||
|
<div className="font-heading font-semibold text-[13px] text-heading mb-1">
|
||||||
|
Before escalating — what happened with the fix?
|
||||||
|
</div>
|
||||||
|
<div className="text-[12px] text-muted-foreground leading-[1.5] mb-3">
|
||||||
|
“{fixTitle}” is still in the Verifying state. Tag its outcome so
|
||||||
|
the senior picking this up knows what's been tried.
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-1.5">
|
||||||
|
<button
|
||||||
|
autoFocus
|
||||||
|
onClick={() => onChoose('applied_failed')}
|
||||||
|
className="flex items-center gap-2.5 px-3 py-2.5 rounded-lg border border-danger/30 bg-danger-dim text-[12.5px] text-primary hover:bg-danger-dim/80 hover:border-danger transition-colors text-left"
|
||||||
|
>
|
||||||
|
<X size={13} strokeWidth={2.5} className="text-danger" />
|
||||||
|
<span className="flex-1">The fix didn't work</span>
|
||||||
|
<span className="text-[10.5px] text-muted-foreground font-mono px-1.5 py-[2px] rounded bg-white/[0.05]">↵</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => onChoose('applied_success')}
|
||||||
|
className="flex items-center gap-2.5 px-3 py-2.5 rounded-lg border border-white/10 bg-elevated text-[12.5px] text-primary hover:bg-sidebar transition-colors text-left"
|
||||||
|
>
|
||||||
|
<Check size={13} strokeWidth={2} />
|
||||||
|
<span className="flex-1">It worked — escalating for another reason</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => onChoose('never_applied')}
|
||||||
|
className="flex items-center gap-2.5 px-3 py-2.5 rounded-lg border border-white/10 bg-elevated text-[12.5px] text-primary hover:bg-sidebar transition-colors text-left"
|
||||||
|
>
|
||||||
|
<AlertCircle size={13} strokeWidth={2} />
|
||||||
|
<span className="flex-1">Never actually applied it</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EscalateInterceptDialog
|
||||||
Reference in New Issue
Block a user