From e78f53b687263d15e5b7eb25b3331cc30db77e23 Mon Sep 17 00:00:00 2001 From: Woody Date: Fri, 15 May 2026 10:51:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=207.2=20=E2=80=94=20wire=20highli?= =?UTF-8?q?ghtTerms=20into=20ResponsePanel=20+=20mark=20CSS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add HighlightMark component rendering - Call highlightTerms() in SubQuestionSection and FlatResponse before ReactMarkdown - Add mark: HighlightMark to ReactMarkdown components in both paths - Add .prose mark CSS rule (yellow-200 bg, rounded, px-0.5) - Tests: 56/56 pass (citation + highlight + ResponsePanel) --- frontend/src/components/ResponsePanel.tsx | 16 +++++++++++----- frontend/src/styles.css | 5 +++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/ResponsePanel.tsx b/frontend/src/components/ResponsePanel.tsx index b93c6ba..067b599 100644 --- a/frontend/src/components/ResponsePanel.tsx +++ b/frontend/src/components/ResponsePanel.tsx @@ -3,7 +3,7 @@ import { MessageSquare, AlertCircle, Copy, ChevronDown, ChevronRight } from 'luc import ReactMarkdown from 'react-markdown' import type { SourceMetadata, SubQuestionSources } from '../types' import { getPdfViewerUrl } from '../lib/api' -import { processCitations, processCitationsForSubq, extractCitedSources } from '../utils/citationParser' +import { processCitations, processCitationsForSubq, extractCitedSources, highlightTerms } from '../utils/citationParser' import { bulletizeMarkdown } from '../utils/citationParser' function getHighlightUrl(document_id: string, chunk_index: number, sub_question: string): string { @@ -32,6 +32,10 @@ const CitationLink = ({ href, children }: { href?: string; children?: React.Reac ) +const HighlightMark = ({ children }: { children?: React.ReactNode }) => ( + {children} +) + function parseAnswerSections(answer: string): string[] { const sections = answer.split(/## Sub-question \d+:[^\n]*\n/) if (sections.length <= 1) return [bulletizeMarkdown(answer)] @@ -107,6 +111,7 @@ function SubQuestionSection({ sq.sources.map(s => ({ ...s, sub_question_text: sq.sub_question_text })) ) const processedAnswer = processCitations(answerSection, allSources, highlightReadyKeys) + const highlightedAnswer = highlightTerms(processedAnswer) return (
- - {processedAnswer} + + {highlightedAnswer}
@@ -353,6 +358,7 @@ function FlatResponse({ const safeSources = sources ?? [] const processedAnswer = answer ? processCitations(answer, safeSources) : answer ?? '' + const highlightedAnswer = processedAnswer ? highlightTerms(processedAnswer) : processedAnswer const handleCopyAnswer = async (): Promise => { if (answer) { @@ -454,9 +460,9 @@ function FlatResponse({
- {processedAnswer} + {highlightedAnswer}
diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 3a03ad5..b994a85 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -10,3 +10,8 @@ list-style: decimal !important; padding-left: 1.5rem !important; } +.prose mark { + background-color: #FEF08A; + border-radius: 0.125rem; + padding: 0 0.125rem; +}