From 6b8aa16ace17a65006720ead26fa895a6e608377 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Mon, 26 Oct 2026 13:01:34 +0800 Subject: [PATCH] fix(research): preserve historical reading context and concise source state Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- .../goal-research-history.css | 1 + .../goal-research-history.tsx | 14 +++--- .../goal-research-timeline.tsx | 6 +-- .../src/features/personal-workspace/i18n.tsx | 4 +- .../personal-workspace-page.tsx | 2 +- .../personal-workspace/personal-workspace.css | 4 +- .../dashboard/src/views/dashboard-page.tsx | 5 ++- .../after-decision-desktop.png | Bin 0 -> 125411 bytes .../after-decision-phone.png | Bin 0 -> 71879 bytes .../after-first-desktop.png | Bin 0 -> 86175 bytes .../before-decision-desktop.png | Bin 0 -> 138174 bytes .../research-display-language.mjs | 13 ++++-- .../research-finding-reader.mjs | 42 +++++++++++++++++- .../research-route-reading.mjs | 2 +- ...runtime-source-workspace-browser-smoke.mjs | 8 ++++ 15 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 examples/personal-workspace-browser/evidence/research-reading-context/after-decision-desktop.png create mode 100644 examples/personal-workspace-browser/evidence/research-reading-context/after-decision-phone.png create mode 100644 examples/personal-workspace-browser/evidence/research-reading-context/after-first-desktop.png create mode 100644 examples/personal-workspace-browser/evidence/research-reading-context/before-decision-desktop.png diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.css b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.css index e49d0bc268..58702688d6 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.css +++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.css @@ -223,6 +223,7 @@ /* A selected question is a reading surface; the whole history stays reachable. */ .research-history-layout.has-selection > .research-history-detail { border-top: 0; } .research-history-context { border-top: 1px solid var(--pw-line); min-width: 0; } +.research-history-context.is-overview { border-top: 0; } .research-history-context > summary { min-height: 44px; padding: 12px 24px; font-size: var(--text-body); cursor: pointer; } .research-history-context > .research-progress { margin: 16px 24px; } .research-history .research-finding-navigation { display: flex; align-items: flex-end; gap: 16px; margin-top: 16px; min-width: 0; } 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 f60c846b50..bf18a04eae 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 @@ -264,7 +264,7 @@ export function GoalResearchHistory({goalId, active, zh, refreshRevision = 0, re if (focusPending.current && detail.current) { focusPending.current = false; detail.current.focus({preventScroll: true}); - detail.current.scrollIntoView({block: "nearest"}); + detail.current.scrollIntoView({block: "start"}); } }, [active, selected, selectedMembers]); const clusterY = layout.length ? Math.max(...layout.map(item => item.y + 124)) + 24 : 24; @@ -288,7 +288,7 @@ export function GoalResearchHistory({goalId, active, zh, refreshRevision = 0, re else url.searchParams.set("research_goal", goalId); if (selection.finding !== next.finding || selection.day !== next.day || selection.nodes.length !== next.nodes.length || selection.nodes.some((id, index) => id !== next.nodes[index])) window.history.pushState(null, "", url); }; - const choose = (id: string, focus = true) => {readerParent.current = null; select({nodes: id ? [id] : [], day: null}, focus);}; + const choose = (id: string, focus = true, finding?: string) => {readerParent.current = null; select({nodes: id ? [id] : [], day: null, finding}, focus);}; const closeReader = () => { const parent = readerParent.current; readerParent.current = null; @@ -331,7 +331,7 @@ export function GoalResearchHistory({goalId, active, zh, refreshRevision = 0, re : null; const historyView = !value ? null : lens === "timeline" && timeline ?
{copy.lost}
: null} {value?.events.length && !value.nodes.length ?{zh ? "尚未记录节点结构;可展开下面的已读记录。" : "Node structure has not been recorded; loaded records remain available below."}