From 86dbd917a51741899ecb0c74b81f90e0f838f92b Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Tue, 27 Oct 2026 02:55:19 +0800 Subject: [PATCH] fix(research): search displayed translations and export original matches Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- .../goal-research-history.tsx | 1 + .../research-record-browser.tsx | 12 +++--- .../research-record-export.test.mjs | 10 +++++ .../research-record-export.ts | 8 ++-- .../research-record-search.test.mjs | 19 +++++++++ .../research-record-search.ts | 19 ++++++++- .../research-search/after-body-390.png | Bin 0 -> 70854 bytes .../research-search/after-search-1440.png | Bin 0 -> 99914 bytes .../research-search/after-search-390.png | Bin 0 -> 59198 bytes .../research-search/before-search-1440.png | Bin 0 -> 98648 bytes .../research-search/first-1440.png | Bin 0 -> 99394 bytes .../research-search/first-390.png | Bin 0 -> 56626 bytes .../research-display-language.mjs | 36 ++++++++++++++++++ 13 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/after-body-390.png create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/after-search-1440.png create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/after-search-390.png create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/before-search-1440.png create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/first-1440.png create mode 100644 apps/presentation/dashboard/visual-evidence/research-search/first-390.png diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx index 4552545bf7..30c93d4964 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx @@ -540,6 +540,7 @@ export function GoalResearchHistory({goalId, active, zh, refreshRevision = 0, re {value?.events.length ?
setRecordsOpen(event.currentTarget.open)}>{zh ? "全部已读记录" : "All loaded records"} · {value.events.length} {recordsOpen ? : null}
: null} diff --git a/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx b/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx index 03bc5f7090..70b3001352 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/research-record-browser.tsx @@ -3,14 +3,15 @@ import {CircleHelp, TriangleAlert} from "lucide-react"; import {ContextHelp} from "./context-help"; import {useMemo, useState, type ReactNode} from "react"; import type {ExploreHistoryEvent} from "../../../../../../loopx/control_plane/presentation/explore_history.ts"; -import {searchResearchRecords} from "./research-record-search"; +import {searchResearchRecords, type ResearchRecordDisplay} from "./research-record-search"; import {exportResearchRecords} from "./research-record-export"; import {downloadReport} from "./report-download"; /** Local read controls over the existing validated history snapshot. */ -export function ResearchRecordSearch({goalId, events, displayEvents, renderBody, complete, stale, busy, zh, stateLabel, timeLabel}: { +export function ResearchRecordSearch({goalId, events, displayEvents, displaySections, renderBody, complete, stale, busy, zh, stateLabel, timeLabel}: { goalId: string; displayEvents?: readonly ExploreHistoryEvent[]; renderBody?: (event: ExploreHistoryEvent) => ReactNode; + displaySections?: ResearchRecordDisplay["sections"]; events: readonly ExploreHistoryEvent[]; complete: boolean; stale: boolean; busy: boolean; zh: boolean; stateLabel: (status: string) => string; timeLabel: (at: string) => string; }) { @@ -18,8 +19,9 @@ export function ResearchRecordSearch({goalId, events, displayEvents, renderBody, const [status, setStatus] = useState(""); const [limit, setLimit] = useState(50); const [downloadFailed, setDownloadFailed] = useState(false); - const matches = useMemo(() => searchResearchRecords(events, query, status), [events, query, status]); const displayed = useMemo(() => new Map(displayEvents?.map(event => [event.event_id, event])), [displayEvents]); + const display = useMemo(() => ({events: displayed, sections: displaySections}), [displayed, displaySections]); + const matches = useMemo(() => searchResearchRecords(events, query, status, display), [events, query, status, display]); const statuses = [...new Set(events.map(event => event.status).filter(Boolean))].sort(); const countLabel = zh ? `匹配 ${matches.length} / ${events.length} 条已读记录` : `${matches.length} matches in ${events.length} loaded records`; const readState = busy ? (zh ? "读取中" : "Reading") : stale ? (zh ? "刷新失败" : "Refresh failed") : ""; @@ -27,7 +29,7 @@ export function ResearchRecordSearch({goalId, events, displayEvents, renderBody, return
{setQuery(event.target.value); setLimit(50);}}/>