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 ?
- select({nodes: [], day})} phase={phase} onPhase={next => chooseView(lens, next)} onSelect={id => choose(id)} onSelectMany={nodes => select({nodes, day: null})} timeLabel={fullTime} dayLabel={dayTime}/>
+ select({nodes: [], day})} phase={phase} onPhase={next => chooseView(lens, next)} onSelect={(id, finding) => choose(id, true, finding)} onSelectMany={nodes => select({nodes, day: null})} timeLabel={fullTime} dayLabel={dayTime}/>
:
: null}
- {readingSelection ?
- {zh ? "研究全景" : "Research overview"}
- {historyView}
- : historyView}
+
+ {zh ? "研究全景" : "Research overview"}
+ {readingSelection ? : null}{historyView}
+
: null}
{(selection.nodes.some(id => !value?.nodes.some(node => node.id === id)) || (selection.day !== null && !selectedGroup)) && read.complete && !busy && !error && !history.error ? {copy.lost}
: null}
{value?.events.length && !value.nodes.length ? {zh ? "尚未记录节点结构;可展开下面的已读记录。" : "Node structure has not been recorded; loaded records remain available below."}
: null}
diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-timeline.tsx b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-timeline.tsx
index 327b9b836b..ffb4354ba0 100644
--- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-timeline.tsx
+++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-timeline.tsx
@@ -12,7 +12,7 @@ type Copy = Record;
type Props = {
timeline: ExploreTimeline; zh: boolean; selectedIds: readonly string[]; phase: number | null;
selectedDay: string | null; dayGroups: ReturnType["groups"]; onGroupSelect: (day: string) => void;
- onSelect: (id: string) => void; onSelectMany: (ids: string[]) => void; onPhase: (index: number | null) => void;
+ onSelect: (id: string, finding?: string) => void; onSelectMany: (ids: string[]) => void; onPhase: (index: number | null) => void;
timeLabel: (value: number) => string; dayLabel: (value: number) => string;
};
@@ -198,13 +198,13 @@ export function GoalResearchTimeline({timeline, zh, selectedIds, selectedDay, da
;
}
-function TrailList({items, copy, label, timeLabel, selectedIds, onSelect}: {items: TimelineFinding[]; copy: Copy; label: (key: string) => string; timeLabel: (value: number) => string; selectedIds: readonly string[]; onSelect: (id: string) => void}) {
+function TrailList({items, copy, label, timeLabel, selectedIds, onSelect}: {items: TimelineFinding[]; copy: Copy; label: (key: string) => string; timeLabel: (value: number) => string; selectedIds: readonly string[]; onSelect: (id: string, finding?: string) => void}) {
const [limit, setLimit] = useState(3);
return <>
{items.slice(0, limit).map(item => {
const decision = item.sections!.decision!;
return -
-