feat: Phase 7.2 — wire highlightTerms into ResponsePanel + mark CSS
- Add HighlightMark component rendering <mark class="bg-yellow-200..."> - 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)
This commit is contained in:
parent
534559b2e0
commit
e78f53b687
|
|
@ -3,7 +3,7 @@ import { MessageSquare, AlertCircle, Copy, ChevronDown, ChevronRight } from 'luc
|
||||||
import ReactMarkdown from 'react-markdown'
|
import ReactMarkdown from 'react-markdown'
|
||||||
import type { SourceMetadata, SubQuestionSources } from '../types'
|
import type { SourceMetadata, SubQuestionSources } from '../types'
|
||||||
import { getPdfViewerUrl } from '../lib/api'
|
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'
|
import { bulletizeMarkdown } from '../utils/citationParser'
|
||||||
|
|
||||||
function getHighlightUrl(document_id: string, chunk_index: number, sub_question: string): string {
|
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
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const HighlightMark = ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<mark className="bg-yellow-200 rounded px-0.5">{children}</mark>
|
||||||
|
)
|
||||||
|
|
||||||
function parseAnswerSections(answer: string): string[] {
|
function parseAnswerSections(answer: string): string[] {
|
||||||
const sections = answer.split(/## Sub-question \d+:[^\n]*\n/)
|
const sections = answer.split(/## Sub-question \d+:[^\n]*\n/)
|
||||||
if (sections.length <= 1) return [bulletizeMarkdown(answer)]
|
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 }))
|
sq.sources.map(s => ({ ...s, sub_question_text: sq.sub_question_text }))
|
||||||
)
|
)
|
||||||
const processedAnswer = processCitations(answerSection, allSources, highlightReadyKeys)
|
const processedAnswer = processCitations(answerSection, allSources, highlightReadyKeys)
|
||||||
|
const highlightedAnswer = highlightTerms(processedAnswer)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -120,8 +125,8 @@ function SubQuestionSection({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="prose prose-sm max-w-none text-gray-800">
|
<div className="prose prose-sm max-w-none text-gray-800">
|
||||||
<ReactMarkdown components={{ a: CitationLink }}>
|
<ReactMarkdown components={{ a: CitationLink, mark: HighlightMark }}>
|
||||||
{processedAnswer}
|
{highlightedAnswer}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -353,6 +358,7 @@ function FlatResponse({
|
||||||
const safeSources = sources ?? []
|
const safeSources = sources ?? []
|
||||||
|
|
||||||
const processedAnswer = answer ? processCitations(answer, safeSources) : answer ?? ''
|
const processedAnswer = answer ? processCitations(answer, safeSources) : answer ?? ''
|
||||||
|
const highlightedAnswer = processedAnswer ? highlightTerms(processedAnswer) : processedAnswer
|
||||||
|
|
||||||
const handleCopyAnswer = async (): Promise<void> => {
|
const handleCopyAnswer = async (): Promise<void> => {
|
||||||
if (answer) {
|
if (answer) {
|
||||||
|
|
@ -454,9 +460,9 @@ function FlatResponse({
|
||||||
</div>
|
</div>
|
||||||
<div className="prose prose-sm max-w-none text-gray-800">
|
<div className="prose prose-sm max-w-none text-gray-800">
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
components={{ a: CitationLink }}
|
components={{ a: CitationLink, mark: HighlightMark }}
|
||||||
>
|
>
|
||||||
{processedAnswer}
|
{highlightedAnswer}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,8 @@
|
||||||
list-style: decimal !important;
|
list-style: decimal !important;
|
||||||
padding-left: 1.5rem !important;
|
padding-left: 1.5rem !important;
|
||||||
}
|
}
|
||||||
|
.prose mark {
|
||||||
|
background-color: #FEF08A;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
padding: 0 0.125rem;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue