feat: add highlight status toast notification (Phase 5.4)

- Shows 'Preparing highlights...' (amber spinner) while LLM batch runs
- Shows 'Highlights ready' (green) for 4 seconds when batch completes
- Fixed position top-left corner, auto-dismisses
This commit is contained in:
Woody 2026-04-29 10:00:54 +08:00
parent 1c490ce2fa
commit bcf4a853bf
1 changed files with 23 additions and 0 deletions

View File

@ -167,6 +167,7 @@ function SubQuestionSections({
}) { }) {
const [copied, setCopied] = useState(false) const [copied, setCopied] = useState(false)
const [highlightReadyKeys, setHighlightReadyKeys] = useState<Set<string>>(new Set()) const [highlightReadyKeys, setHighlightReadyKeys] = useState<Set<string>>(new Set())
const [highlightStatus, setHighlightStatus] = useState<'loading' | 'done' | ''>('')
useEffect(() => { useEffect(() => {
if (!answer || isLoading || !subQuestionSources.length) return if (!answer || isLoading || !subQuestionSources.length) return
@ -197,6 +198,8 @@ function SubQuestionSections({
if (targets.length === 0) return if (targets.length === 0) return
setHighlightStatus('loading')
fetch('/api/v1/v2/highlights/batch', { fetch('/api/v1/v2/highlights/batch', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
@ -210,6 +213,8 @@ function SubQuestionSections({
keys.add(`${t.document_id}_${t.chunk_index}_${encodeURIComponent(t.sub_question_text)}`) keys.add(`${t.document_id}_${t.chunk_index}_${encodeURIComponent(t.sub_question_text)}`)
}) })
setHighlightReadyKeys(keys) setHighlightReadyKeys(keys)
setHighlightStatus('done')
setTimeout(() => setHighlightStatus(''), 4000)
} }
}) })
.catch((err) => { .catch((err) => {
@ -276,6 +281,24 @@ function SubQuestionSections({
return ( return (
<div className="p-4 space-y-4"> <div className="p-4 space-y-4">
{highlightStatus !== '' && (
<div
data-testid="highlight-status-toast"
className={`fixed top-4 left-4 z-50 px-4 py-2 rounded-lg shadow-lg text-sm font-medium transition-opacity duration-300 ${
highlightStatus === 'done'
? 'bg-green-50 border border-green-200 text-green-700'
: 'bg-amber-50 border border-amber-200 text-amber-700'
}`}
>
{highlightStatus === 'loading' && (
<span className="flex items-center gap-2">
<span className="w-3 h-3 border-2 border-amber-400 border-t-transparent rounded-full animate-spin" />
Preparing highlights...
</span>
)}
{highlightStatus === 'done' && 'Highlights ready'}
</div>
)}
<div className="flex items-start justify-between"> <div className="flex items-start justify-between">
<div className="flex-1" /> <div className="flex-1" />
<button <button