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} +
+ + {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
  1. -