fix: prevent authoring evidence clipping

This commit is contained in:
lda
2026-07-13 02:48:43 +07:00 Verified
parent 70f1d1e9cf
commit 759b14a070
4 changed files with 22 additions and 17 deletions
@@ -1,4 +1,4 @@
import { useLayoutEffect, useReducer, useRef } from "react"; import { useReducer } from "react";
import { projectPreparedAuthoringPhase } from "./authoring-projection.js"; import { projectPreparedAuthoringPhase } from "./authoring-projection.js";
import { AuthoringPhaseVisual } from "./AuthoringPhaseVisual.js"; import { AuthoringPhaseVisual } from "./AuthoringPhaseVisual.js";
import { PresentationAssistantPane } from "./PresentationAssistantPane.js"; import { PresentationAssistantPane } from "./PresentationAssistantPane.js";
@@ -41,16 +41,6 @@ export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance }: Prep
// if a future beat reaches this scene before its authoring mapping is added. // if a future beat reaches this scene before its authoring mapping is added.
const beatId = phases.find((phase) => phase.id === beat.id)?.id ?? "discover"; const beatId = phases.find((phase) => phase.id === beat.id)?.id ?? "discover";
const projection = projectPreparedAuthoringPhase(beatId); const projection = projectPreparedAuthoringPhase(beatId);
const lifecycleRef = useRef<HTMLElement>(null);
useLayoutEffect(() => {
// The assistant owns its aside markup; decorate that existing boundary here
// so the scene can expose hierarchy metadata without widening its API.
lifecycleRef.current
?.querySelector<HTMLElement>('[aria-label="prepared authoring assistant"]')
?.setAttribute("data-visual-role", "support");
}, [beatId]);
return ( return (
<> <>
<StageCaption eyebrow="Prepared workflow" title={scene.title}> <StageCaption eyebrow="Prepared workflow" title={scene.title}>
@@ -58,7 +48,6 @@ export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance }: Prep
</StageCaption> </StageCaption>
<section <section
className="prepared-lifecycle-scene" className="prepared-lifecycle-scene"
ref={lifecycleRef}
aria-label="prepared workflow authoring lifecycle" aria-label="prepared workflow authoring lifecycle"
data-active-phase={beatId} data-active-phase={beatId}
data-primary-surface="authoring-phase" data-primary-surface="authoring-phase"
@@ -67,6 +56,7 @@ export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance }: Prep
> >
<PresentationAssistantPane <PresentationAssistantPane
phase={beatId} phase={beatId}
visualRole="support"
message={projectScene9Message(messageState, beatId)} message={projectScene9Message(messageState, beatId)}
submittedOverrides={projectScene9SubmittedOverrides(messageState)} submittedOverrides={projectScene9SubmittedOverrides(messageState)}
runRequested={messageState.runRequested} runRequested={messageState.runRequested}
@@ -36,12 +36,23 @@ describe("PresentationAssistantPane", () => {
it("renders a persistent prepared replay surface for the current phase", () => { it("renders a persistent prepared replay surface for the current phase", () => {
renderPane("validate"); renderPane("validate");
expect(screen.getByRole("complementary", { name: /prepared authoring assistant/i })).toBeInTheDocument(); expect(screen.getByRole("complementary", { name: /prepared authoring assistant/i })).not.toHaveAttribute(
"data-visual-role",
);
expect(screen.getByRole("heading", { name: /authoring assistant/i })).toBeInTheDocument(); expect(screen.getByRole("heading", { name: /authoring assistant/i })).toBeInTheDocument();
expect(screen.getByText(/current phase: validate/i)).toBeInTheDocument(); expect(screen.getByText(/current phase: validate/i)).toBeInTheDocument();
expect(screen.getByText(/prepared replay only/i)).toBeInTheDocument(); expect(screen.getByText(/prepared replay only/i)).toBeInTheDocument();
}); });
it("exposes an explicit support role when composed in the lifecycle scene", () => {
renderPane("validate", { visualRole: "support" });
expect(screen.getByRole("complementary", { name: /prepared authoring assistant/i })).toHaveAttribute(
"data-visual-role",
"support",
);
});
it("keeps the active tool group synchronized with the phase", () => { it("keeps the active tool group synchronized with the phase", () => {
renderPane("artifact"); renderPane("artifact");
@@ -10,6 +10,7 @@ import type {
export type PresentationAssistantPaneProps = { export type PresentationAssistantPaneProps = {
readonly phase: AuthoringPhaseId; readonly phase: AuthoringPhaseId;
readonly visualRole?: "support";
readonly message: Scene9MessageProjection; readonly message: Scene9MessageProjection;
readonly submittedOverrides: Scene9SubmittedOverrides; readonly submittedOverrides: Scene9SubmittedOverrides;
readonly runRequested: string | null; readonly runRequested: string | null;
@@ -33,6 +34,7 @@ const phaseLabels: Readonly<Record<AuthoringPhaseId, string>> = {
*/ */
export const PresentationAssistantPane = ({ export const PresentationAssistantPane = ({
phase, phase,
visualRole,
message, message,
submittedOverrides, submittedOverrides,
runRequested, runRequested,
@@ -67,6 +69,7 @@ export const PresentationAssistantPane = ({
aria-label="prepared authoring assistant" aria-label="prepared authoring assistant"
data-phase={phase} data-phase={phase}
data-surface="prepared-replay" data-surface="prepared-replay"
data-visual-role={visualRole}
> >
<header className="presentation-assistant-pane__header"> <header className="presentation-assistant-pane__header">
<p className="presentation-assistant-pane__eyebrow">Prepared workflow</p> <p className="presentation-assistant-pane__eyebrow">Prepared workflow</p>
@@ -1763,14 +1763,15 @@
.scene-body__authoring-evidence .authoring-repair__diagnostic, .scene-body__authoring-evidence .authoring-repair__diagnostic,
.scene-body__authoring-evidence .authoring-repair__correction { .scene-body__authoring-evidence .authoring-repair__correction {
min-height: 8rem; min-height: 0;
padding: 1rem; padding: 1rem;
} }
.scene-body__authoring-evidence .authoring-visual--inventory, .scene-body__authoring-evidence .authoring-visual--inventory,
.scene-body__authoring-evidence .authoring-visual--graph, .scene-body__authoring-evidence .authoring-visual--graph,
.scene-body__authoring-evidence .authoring-visual--repair { .scene-body__authoring-evidence .authoring-visual--repair {
min-height: 15rem; min-height: 0;
height: 100%;
} }
.scene-body__authoring-evidence .authoring-visual--graph .authoring-graph__node { .scene-body__authoring-evidence .authoring-visual--graph .authoring-graph__node {
@@ -1790,7 +1791,7 @@
.scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="diagnose"] .authoring-repair__diagnostic { .scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="diagnose"] .authoring-repair__diagnostic {
grid-column: 1; grid-column: 1;
min-height: 12rem; min-height: 0;
} }
.scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="repair"] { .scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="repair"] {
@@ -1804,7 +1805,7 @@
.scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="repair"] .authoring-repair__correction { .scene-body__authoring-evidence .authoring-visual--repair[data-authoring-focus="repair"] .authoring-repair__correction {
grid-column: 1; grid-column: 1;
min-height: 12rem; min-height: 0;
} }
.scene-body__authoring-composition .scene-body__authoring-loop { .scene-body__authoring-composition .scene-body__authoring-loop {