feat(confidence-engine): v0.54b integrate Investigation Overview UI seam + bounded scroll cleanup

- Wire transient overview state from ScenarioForm to ReasoningWorkspace
- Inline rendering of investigation overview below milestone invitation
- Remove obsolete scrollIntoView after overview request (scrolled away from rendered content)
- All four overview props consumed in ReasoningWorkspace render path
- Targeted Vitest: 9/9 PASS (tests/ui/investigation-overview-ui.test.jsx)
- Production build: compiles successfully
This commit is contained in:
2026-09-02 15:14:20 +01:00
parent 83818c0c71
commit 745026f0a0
4 changed files with 307 additions and 14 deletions
+42 -14
View File
@@ -1331,6 +1331,11 @@ export default function ReasoningWorkspace({
onSituationGraphChange,
/* ── test init seam (no effect → immediate state) ───────── */
initialPostAnalyseStatus,
/* ── v0.54b — investigation overview transient state ─── */
overviewState,
setOverviewState,
overviewLoading,
handleRequestOverview,
}) {
const [investigationHistory, setInvestigationHistory] = useState([]);
const turnCounter = useRef(0);
@@ -1943,20 +1948,43 @@ export default function ReasoningWorkspace({
})()}
</div>
) : openUnknowns.length === 0 && clarifiedQuestions.length > 0 && !cuSynthesisLoading ? (
<div className="rounded-xl border-[2.5px] border-teal-300/60 bg-gradient-to-b from-teal-50/40 to-white px-7 pt-5 pb-6">
<p className="text-sm leading-relaxed text-gray-700 mb-4">
{'You\'ve now worked through all of the questions we surfaced. Would you like to see an overview of what we understand so far?'}
</p>
<button
onClick={() => {
const el = document.getElementById("cu-scroll-target");
if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
}}
style={{ cursor: "pointer" }}
className="rounded-lg border border-teal-600 bg-white px-4 py-2 text-sm font-medium text-teal-700 hover:bg-teal-50 transition"
>
Review current understanding
</button>
<div className="space-y-4">
{/* Milestone invitation + overview action */}
<div className="rounded-xl border-[2.5px] border-teal-300/60 bg-gradient-to-b from-teal-50/40 to-white px-7 pt-5 pb-6">
<p className="text-sm leading-relaxed text-gray-700 mb-4">
{'You\'ve now worked through all of the questions we surfaced. Would you like to see an overview of what we understand so far?'}
</p>
<button
onClick={() => {
handleRequestOverview();
}}
disabled={overviewLoading}
style={{ cursor: overviewLoading ? "wait" : "pointer" }}
className="rounded-lg border border-teal-600 bg-white px-4 py-2 text-sm font-medium text-teal-700 hover:bg-teal-50 transition disabled:opacity-60"
>
{overviewLoading ? "Generating overview…" : "Review current understanding"}
</button>
</div>
{/* Investigation overview surface — transient, non-persistent */}
{overviewState && (
<div className="space-y-4" data-testid="investigation-overview">
<div className="rounded-xl border-[2.5px] border-teal-300/70 bg-gradient-to-b from-teal-50/60 to-white px-8 pt-6 pb-7 shadow-sm">
<h3 className="mb-3 text-[11px] font-bold tracking-[.18em] uppercase text-teal-700/70">
What we understand
</h3>
<p className="text-base leading-relaxed text-gray-800">{overviewState.understanding}</p>
</div>
{overviewState.plausibleInterpretations && (
<div className="rounded-xl border border-blue-200/70 bg-blue-50/40 px-8 pt-6 pb-7 shadow-sm">
<h3 className="mb-3 text-[11px] font-bold tracking-[.18em] uppercase text-blue-600/70">
What remains plausible
</h3>
<p className="text-sm leading-relaxed text-gray-700 italic">{overviewState.plausibleInterpretations}</p>
</div>
)}
</div>
)}
</div>
) : null}