Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@
.research-history-read-error p, .research-history-empty p { margin: 4px 0 0; color: var(--pw-muted); font-size: var(--text-body); line-height: var(--leading-prose); }
.research-history-read-error > button, .research-history-empty > button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex-shrink: 0; min-height: 44px; padding: 8px 12px; border: 1px solid var(--pw-line); border-radius: 6px; background: var(--pw-bg); color: var(--pw-text); font: inherit; font-size: var(--text-body); cursor: pointer; }
.research-history-read-error > button:hover, .research-history-empty > button:hover { background: var(--pw-hover); }
.research-source-strategy { margin-block-start: 12px; padding-block-start: 12px; border-block-start: 1px solid var(--pw-line); overflow-wrap: anywhere; }
.research-source-strategy time { margin-inline-start: 8px; color: var(--pw-muted); font-size: var(--text-caption); }
.research-source-strategy strong + time + p { color: var(--pw-text); }
.research-history-error { color: var(--pw-red); font-size: var(--text-body); overflow-wrap: anywhere; }
.research-history button:focus-visible, .research-history-canvas:focus-visible, .research-history-detail:focus-visible { outline: 2px solid var(--pw-blue); outline-offset: -2px; }
@media (max-width: 640px) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {GoalResearchTimeline} from "./goal-research-timeline";
import {requestJson} from "../../data/chat";
import {sourceReadApiUrl} from "../../data/local-status-query";
import {ContextHelp} from "./context-help";
import type {WorkspaceGoal} from "./personal-workspace-model";
import {groupUnlinkedHistoryQuestions, layoutExploreHistory, mergeExploreHistoryEvents, parseExploreHistoryPage, projectExploreHistory, type ExploreHistoryEvent, type ExploreHistoryNode} from "../../../../../../loopx/control_plane/presentation/explore_history.js";
import "./goal-research-history.css";
import {ExploreMeasurements, formatExploreMeasurementValue} from "./explore-measurements";
Expand Down Expand Up @@ -54,9 +53,9 @@ const viewFromUrl = (goal: string) => {

/** An effect-free history consumer. Its source is Explore, not raw sessions or
* a judge. All recorded updates survive; unsupported analysis stays unavailable. */
export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHistory = false, active, zh, refreshRevision = 0, readSourceUrl, sourceStrategy, onOpenSourceTasks}: {
export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHistory = false, active, zh, refreshRevision = 0, readSourceUrl, onOpenSourceTasks}: {
goalId: string; originalGoalId?: string; preferHistory?: boolean; active: boolean; zh: boolean; refreshRevision?: number; readSourceUrl?: string;
sourceStrategy?: WorkspaceGoal["sourceStrategy"]; onOpenSourceTasks?: () => void;
onOpenSourceTasks?: () => void;
}) {
const strategies = useGoalStrategyLocation(goalId, readSourceUrl);
const analysis = useResearchAnalysis(goalId, active, zh, readSourceUrl);
Expand Down Expand Up @@ -509,7 +508,7 @@ export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHist
// Keep an explicitly opened study in place during a read failure. A complete
// catalogue with no study still uses the ordinary history view.
const awaitingRequestedCase = requestedCase === true && (analysis.loading || Boolean(analysis.readError));
if (hasNativeSource && strategies.selection !== null) {
if (hasNativeSource && strategies.selection !== null && !emptySourceHistory) {
return <GoalSourceStrategies key={strategies.scope} goalId={goalId} originalGoalId={originalGoalId}
sourceUrl={readSourceUrl} zh={zh} selection={strategies.selection}
onSelect={strategies.choose} onClose={() => strategies.choose(null)}/>;
Expand All @@ -536,7 +535,7 @@ export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHist
<p>{copy.scope} · {copy.time}{zh ? "。" : ". "}{copy.coverage}{zh ? "。" : "."}</p><p>{copy.interpretation}{zh ? "。" : "."}</p>
{lens === "graph" ? <p>{zh ? "按来源分组,实线为已记录关联,虚线仅表示分组;排列不代表时间或进展。未关联问题按首次记录 UTC 日期收纳。" : "Grouped by source. Solid lines are recorded relationships; dotted lines only group nodes. Position does not imply time or progress. Unlinked questions are collected by first-record UTC date."}</p> : null}
<p>{zh ? "合拢仅为避免遮挡,不表示关联或因果;选择一次可读全部原始记录与依据。" : "Nearby points group to avoid overlap, without implying a relationship or causality. Select once to read every original record and source."}</p>
</ContextHelp>{hasNativeSource ? <button type="button" className="research-strategy-entry" ref={element => {if (element) strategies.opener.current = element;}}
</ContextHelp>{hasNativeSource && !emptySourceHistory ? <button type="button" className="research-strategy-entry" ref={element => {if (element) strategies.opener.current = element;}}
onClick={() => strategies.choose("all")}>{zh ? "策略历史" : "Strategy history"}</button> : null}</div>
</div>
<div className={`research-history-controls${readingSelection ? " is-reading" : ""}`}>
Expand Down Expand Up @@ -568,18 +567,15 @@ export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHist
</div>
<button type="button" disabled={busy} onClick={refresh}><RefreshCw size={14} aria-hidden/>{zh ? "重试" : "Retry"}</button>
</div> : null}
{emptySourceHistory ? <div className="research-history-empty research-history-source-empty">
<div>
{emptySourceHistory ? <>
<div className="research-history-empty research-history-source-empty"><div>
<p role="status">{zh ? "这份来源没有可读的 Explore 记录。" : "This source has no readable Explore records."}</p>
{sourceStrategy ? <div className="research-source-strategy">
<strong>{zh ? "最近一条策略记录" : "Last recorded strategy"}</strong>
<time dateTime={sourceStrategy.recordedAt}>{timeLabel(sourceStrategy.recordedAt)}</time>
<p>{sourceStrategy.summary}</p>
{sourceStrategy.observation && sourceStrategy.observation !== sourceStrategy.summary ? <p>{sourceStrategy.observation}</p> : null}
</div> : null}
</div>
{onOpenSourceTasks ? <button type="button" onClick={onOpenSourceTasks}>{zh ? "查看原实验任务" : "View original tasks"}</button> : null}
</div> : emptyHistory && !emptyWithAnalysis ? <div className="research-history-empty">
</div>
<GoalSourceStrategies key={strategies.scope} goalId={goalId} originalGoalId={originalGoalId}
sourceUrl={readSourceUrl} zh={zh} selection={strategies.selection ?? "all"} onSelect={strategies.choose} embedded/>
</> : emptyHistory && !emptyWithAnalysis ? <div className="research-history-empty">
<div role="status"><strong>{emptyHistoryMessage}</strong><ContextHelp icon={FlaskConical} label={zh ? "研究历程来源" : "Research history source"}><p>{zh ? "开启研究模式后,后续研究问题、尝试与证据会在这里形成可回读的历程。" : "Enable research mode to build a readable history of questions, attempts and evidence from later work."}</p></ContextHelp></div>
<button type="button" onClick={focusResearchMode}>{zh ? "查看研究模式" : "Review research mode"}</button>
</div> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function GoalResearchWorkbench(props: {goalId: string; active: boolean; z
active={props.active} refreshRevision={props.refreshRevision}/> : null}
{!props.statusNotice ? <>
<GoalResearchHistory {...props} originalGoalId={source?.original_goal_id}
preferHistory={Boolean(source)} sourceStrategy={selected?.sourceStrategy}
preferHistory={Boolean(source)}
onOpenSourceTasks={source ? props.onOpenTasks : undefined}/>
<details className="research-saved-evidence" open={evidenceOpen} onToggle={event => setEvidenceOpen(event.currentTarget.open)}>
<summary>{props.zh ? "阅读已保存的结论" : "Read saved findings"}</summary>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading