fix: harden prepared lifecycle review fixes
This commit is contained in:
@@ -43,6 +43,7 @@ describe("PreparedAuthoringLifecycleScene", () => {
|
||||
expect(frame).toHaveTextContent("wf draft validate lda_report_workflow");
|
||||
expect(frame).toHaveTextContent(/structured missing-output diagnostic/i);
|
||||
expect(frame).toHaveAttribute("data-authoring-step", "diagnose");
|
||||
expect(frame.querySelector('[data-authoring-focus="diagnose"]')).toBeInTheDocument();
|
||||
expect(screen.getByRole("region", { name: "validation repair evidence" })).toHaveAttribute(
|
||||
"data-authoring-focus",
|
||||
"diagnose",
|
||||
@@ -60,6 +61,7 @@ describe("PreparedAuthoringLifecycleScene", () => {
|
||||
expect(frame).toHaveTextContent("workflow.draft_workspaces.set_step_output_map");
|
||||
expect(frame).toHaveTextContent(/wf draft set-output lda_report_workflow/i);
|
||||
expect(frame).toHaveAttribute("data-authoring-step", "repair");
|
||||
expect(frame.querySelector('[data-authoring-focus="repair"]')).toBeInTheDocument();
|
||||
expect(screen.getByRole("region", { name: "validation repair evidence" })).toHaveAttribute(
|
||||
"data-authoring-focus",
|
||||
"repair",
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
preparedLifecycleMessageReducer,
|
||||
} from "./prepared-lifecycle-message-state.js";
|
||||
import type { SceneBeatDefinition, SceneDefinition } from "../storyboard.js";
|
||||
import { StageCaption } from "../StageCaption.js";
|
||||
|
||||
type PreparedAuthoringLifecycleSceneProps = {
|
||||
readonly scene: SceneDefinition;
|
||||
@@ -34,12 +33,12 @@ const steps = [
|
||||
}[];
|
||||
|
||||
/**
|
||||
* Scene 9 — Prepared workflow authoring lifecycle.
|
||||
* Prepared workflow authoring lifecycle.
|
||||
*
|
||||
* Each beat shows a persistent prepared assistant beside one dominant phase
|
||||
* projection sourced from the prepared authoring recording.
|
||||
*/
|
||||
export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance }: PreparedAuthoringLifecycleSceneProps) => {
|
||||
export const PreparedAuthoringLifecycleScene = ({ beat, onAdvance }: PreparedAuthoringLifecycleSceneProps) => {
|
||||
const [messageState, dispatch] = useReducer(
|
||||
preparedLifecycleMessageReducer,
|
||||
initialPreparedLifecycleMessageState,
|
||||
@@ -51,89 +50,83 @@ export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance }: Prep
|
||||
const projection = projectPreparedLifecycleStep(step);
|
||||
const activeStepIndex = steps.findIndex((candidate) => candidate.id === step);
|
||||
return (
|
||||
<>
|
||||
{/* Keep external chrome to scene orientation; beat-specific copy belongs in the frame. */}
|
||||
<StageCaption eyebrow="Prepared workflow" title={scene.title}>
|
||||
{null}
|
||||
</StageCaption>
|
||||
<section
|
||||
className="prepared-lifecycle-scene"
|
||||
aria-label="prepared workflow authoring lifecycle"
|
||||
data-active-phase={step}
|
||||
data-recording-phase={projection.recordingPhase}
|
||||
data-primary-surface="authoring-phase"
|
||||
data-support-surface="prepared-chat"
|
||||
data-presentation-surface="editorial"
|
||||
>
|
||||
<PresentationAssistantPane
|
||||
phase={step}
|
||||
visualRole="support"
|
||||
message={projectPreparedLifecycleMessage(messageState, step)}
|
||||
submittedOverrides={projectPreparedLifecycleSubmittedOverrides(messageState)}
|
||||
runRequested={messageState.runRequested}
|
||||
onDraftChange={(draft) => dispatch({ type: "draft_edited", draft })}
|
||||
onSubmit={(submittedText) => {
|
||||
dispatch({ type: "draft_edited", draft: submittedText });
|
||||
if (step === "discover") {
|
||||
dispatch({ type: "discover_submitted" });
|
||||
}
|
||||
if (step === "draft") {
|
||||
dispatch({ type: "draft_submitted" });
|
||||
onAdvance?.();
|
||||
}
|
||||
if (step === "artifact") {
|
||||
dispatch({ type: "artifact_submitted" });
|
||||
onAdvance?.();
|
||||
}
|
||||
if (step === "deployment") dispatch({ type: "run_requested" });
|
||||
}}
|
||||
/>
|
||||
<div className="prepared-lifecycle-scene__presentation">
|
||||
<ol className="prepared-lifecycle-scene__rail" aria-label="prepared authoring lifecycle">
|
||||
{steps.map((candidate, index) => (
|
||||
<li
|
||||
key={candidate.id}
|
||||
data-active={candidate.id === step ? "true" : "false"}
|
||||
data-complete={index < activeStepIndex ? "true" : "false"}
|
||||
>
|
||||
<span className="prepared-lifecycle-scene__ordinal" aria-hidden="true">
|
||||
{String(index + 1).padStart(2, "0")}
|
||||
</span>
|
||||
<strong>{candidate.label}</strong>
|
||||
<span className="prepared-lifecycle-scene__detail">{candidate.detail}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
<section
|
||||
className="prepared-lifecycle-scene"
|
||||
aria-label="prepared workflow authoring lifecycle"
|
||||
data-active-phase={step}
|
||||
data-recording-phase={projection.recordingPhase}
|
||||
data-primary-surface="authoring-phase"
|
||||
data-support-surface="prepared-chat"
|
||||
data-presentation-surface="editorial"
|
||||
>
|
||||
<PresentationAssistantPane
|
||||
phase={step}
|
||||
visualRole="support"
|
||||
message={projectPreparedLifecycleMessage(messageState, step)}
|
||||
submittedOverrides={projectPreparedLifecycleSubmittedOverrides(messageState)}
|
||||
runRequested={messageState.runRequested}
|
||||
onDraftChange={(draft) => dispatch({ type: "draft_edited", draft })}
|
||||
onSubmit={(submittedText) => {
|
||||
dispatch({ type: "draft_edited", draft: submittedText });
|
||||
if (step === "discover") {
|
||||
dispatch({ type: "discover_submitted" });
|
||||
}
|
||||
if (step === "draft") {
|
||||
dispatch({ type: "draft_submitted" });
|
||||
onAdvance?.();
|
||||
}
|
||||
if (step === "artifact") {
|
||||
dispatch({ type: "artifact_submitted" });
|
||||
onAdvance?.();
|
||||
}
|
||||
if (step === "deployment") dispatch({ type: "run_requested" });
|
||||
}}
|
||||
/>
|
||||
<div className="prepared-lifecycle-scene__presentation">
|
||||
<ol className="prepared-lifecycle-scene__rail" aria-label="prepared authoring lifecycle">
|
||||
{steps.map((candidate, index) => (
|
||||
<li
|
||||
key={candidate.id}
|
||||
data-active={candidate.id === step ? "true" : "false"}
|
||||
data-complete={index < activeStepIndex ? "true" : "false"}
|
||||
>
|
||||
<span className="prepared-lifecycle-scene__ordinal" aria-hidden="true">
|
||||
{String(index + 1).padStart(2, "0")}
|
||||
</span>
|
||||
<strong>{candidate.label}</strong>
|
||||
<span className="prepared-lifecycle-scene__detail">{candidate.detail}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
|
||||
<article
|
||||
className="prepared-lifecycle-scene__frame"
|
||||
role="region"
|
||||
aria-label="active authoring operation"
|
||||
data-authoring-step={step}
|
||||
data-recording-phase={projection.recordingPhase}
|
||||
data-visual-role="lifecycle-primary"
|
||||
>
|
||||
<header className="prepared-lifecycle-scene__frame-header">
|
||||
<article
|
||||
className="prepared-lifecycle-scene__frame"
|
||||
role="region"
|
||||
aria-label="active authoring operation"
|
||||
data-authoring-step={step}
|
||||
data-recording-phase={projection.recordingPhase}
|
||||
data-visual-role="lifecycle-primary"
|
||||
>
|
||||
<header className="prepared-lifecycle-scene__frame-header">
|
||||
<div>
|
||||
<span className="prepared-lifecycle-scene__frame-step">{activeStep.label}</span>
|
||||
<h2>{beat.title}</h2>
|
||||
<p>{beat.caption}</p>
|
||||
</div>
|
||||
<dl className="prepared-lifecycle-scene__evidence">
|
||||
<div>
|
||||
<span className="prepared-lifecycle-scene__frame-step">{activeStep.label}</span>
|
||||
<h2>{beat.title}</h2>
|
||||
<p>{beat.caption}</p>
|
||||
<dt>Method</dt>
|
||||
<dd><code>{projection.primaryCommand.title}</code></dd>
|
||||
</div>
|
||||
<dl className="prepared-lifecycle-scene__evidence">
|
||||
<div>
|
||||
<dt>Method</dt>
|
||||
<dd><code>{projection.primaryCommand.title}</code></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Equivalent CLI</dt>
|
||||
<dd><code>{projection.primaryCommand.command}</code></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</header>
|
||||
<AuthoringPhaseVisual projection={projection} focus={projection.focus} />
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
<div>
|
||||
<dt>Equivalent CLI</dt>
|
||||
<dd><code>{projection.primaryCommand.command}</code></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</header>
|
||||
<AuthoringPhaseVisual projection={projection} focus={projection.focus} />
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user