style: clarify lifecycle diagrams at presentation distance
This commit is contained in:
@@ -121,8 +121,9 @@ describe("PresentationRoute", () => {
|
||||
expect(within(result).getByText("missing_outcome_edge")).toBeInTheDocument();
|
||||
expect(within(result).getByText("nodes[analyze]")).toBeInTheDocument();
|
||||
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
||||
expect(within(result).getByRole("note", { name: /prepared fault injection/i })).toHaveTextContent(
|
||||
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||
expect(within(result).queryByRole("note", { name: /prepared fault injection/i })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("note", { name: /prepared fault injection/i })).toHaveTextContent(
|
||||
/valid revision 2.*remove analyze\.ok.*invalid revision 3/i,
|
||||
);
|
||||
expect(screen.queryByText(/missing output projection/i)).not.toBeInTheDocument();
|
||||
}, 15000);
|
||||
|
||||
@@ -76,9 +76,7 @@ describe("AuthoringPhaseVisual", () => {
|
||||
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
||||
expect(within(result).getByText(/cannot prove where execution goes next/i)).toBeInTheDocument();
|
||||
expect(within(result).getByText("Revision 3")).toBeInTheDocument();
|
||||
expect(within(result).getByRole("note", { name: /prepared fault injection/i })).toHaveTextContent(
|
||||
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||
);
|
||||
expect(within(result).queryByRole("note", { name: /prepared fault injection/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders route repair as a valid revision with compact prior context", () => {
|
||||
|
||||
@@ -173,11 +173,6 @@ const DiagnosticResult = ({ evidence }: { readonly evidence: EvidenceOf<"diagnos
|
||||
]}
|
||||
/>
|
||||
<p className="authoring-result__explanation">{evidence.diagnostic.explanation}</p>
|
||||
<section className="authoring-result__fault-injection" role="note" aria-label={evidence.faultInjection.label}>
|
||||
<span>{evidence.faultInjection.label}</span>
|
||||
<code>{evidence.faultInjection.command}</code>
|
||||
<p>Valid revision {evidence.faultInjection.fromRevision} became invalid revision {evidence.faultInjection.toRevision}.</p>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -36,9 +36,7 @@ describe("AuthoringWorkflowDiagram", () => {
|
||||
it("shows an absent analyze.ok route as the diagnostic headline", () => {
|
||||
renderDiagram("diagnose");
|
||||
|
||||
expect(screen.getByText("Missing route")).toBeInTheDocument();
|
||||
expect(screen.getByRole("img", { name: /analyze ok route is missing/i })).toBeInTheDocument();
|
||||
expect(document.querySelector('[data-authoring-edge-id="analyze.ok"]')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("restores analyze.ok without retaining the missing-route marker", () => {
|
||||
@@ -46,6 +44,15 @@ describe("AuthoringWorkflowDiagram", () => {
|
||||
|
||||
expect(screen.getByRole("img", { name: /analyze ok route restored/i })).toBeInTheDocument();
|
||||
expect(screen.queryByText("Missing route")).not.toBeInTheDocument();
|
||||
expect(document.querySelector('[data-authoring-edge-id="analyze.ok"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("reserves a wider rank for the route-state edge label", () => {
|
||||
renderDiagram("repair");
|
||||
const analyze = document.querySelector('[data-id="analyze"]');
|
||||
const end = document.querySelector('[data-id="__end__"]');
|
||||
|
||||
expect(analyze).toHaveStyle({ width: "224px" });
|
||||
expect(end).toHaveStyle({ width: "224px" });
|
||||
expect(analyze?.getAttribute("style")).not.toEqual(end?.getAttribute("style"));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,9 +7,12 @@ import {
|
||||
type Node,
|
||||
type NodeProps,
|
||||
type NodeTypes,
|
||||
type ReactFlowInstance,
|
||||
} from "@xyflow/react";
|
||||
import "@xyflow/react/dist/style.css";
|
||||
import { CircleStop, Database, SquareFunction, TriangleAlert } from "lucide-react";
|
||||
import Dagre from "@dagrejs/dagre";
|
||||
import { CircleStop, Database, SquareFunction } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { ReviewedAuthoringEvidence } from "./reviewed-authoring-evidence.js";
|
||||
|
||||
type WorkflowEvidence = Extract<
|
||||
@@ -49,28 +52,56 @@ const AuthoringFlowNode = ({ id, data }: NodeProps<Node<AuthoringNodeData>>) =>
|
||||
|
||||
const nodeTypes: NodeTypes = { authoring: AuthoringFlowNode };
|
||||
|
||||
// Stable positions make Draft -> Diagnose -> Repair read as one changing object.
|
||||
const workflowNodes: Node<AuthoringNodeData>[] = [
|
||||
const NODE_WIDTH = 224;
|
||||
const NODE_HEIGHT = 76;
|
||||
const FIT_VIEW_OPTIONS = { padding: 0.16, minZoom: 0.55, maxZoom: 1.25, duration: 0 } as const;
|
||||
|
||||
const workflowNodeDefinitions: Omit<Node<AuthoringNodeData>, "position">[] = [
|
||||
{
|
||||
id: "read_documents",
|
||||
type: "authoring",
|
||||
position: { x: 0, y: 60 },
|
||||
style: { width: NODE_WIDTH },
|
||||
data: { label: "read_documents", role: "source" },
|
||||
},
|
||||
{
|
||||
id: "analyze",
|
||||
type: "authoring",
|
||||
position: { x: 310, y: 60 },
|
||||
style: { width: NODE_WIDTH },
|
||||
data: { label: "analyze", role: "action" },
|
||||
},
|
||||
{
|
||||
id: "__end__",
|
||||
type: "authoring",
|
||||
position: { x: 620, y: 60 },
|
||||
style: { width: NODE_WIDTH },
|
||||
data: { label: "END", role: "outcome" },
|
||||
},
|
||||
];
|
||||
|
||||
const layoutWorkflowNodes = (): Node<AuthoringNodeData>[] => {
|
||||
const graph = new Dagre.graphlib.Graph();
|
||||
graph.setGraph({ rankdir: "LR", ranksep: 72, nodesep: 48, marginx: 0, marginy: 0 });
|
||||
graph.setDefaultEdgeLabel(() => ({}));
|
||||
for (const node of workflowNodeDefinitions) {
|
||||
graph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT });
|
||||
}
|
||||
graph.setEdge("read_documents", "analyze", { width: 28, height: 22 });
|
||||
// Reserve the widest label once so all three beats retain identical node positions.
|
||||
graph.setEdge("analyze", "__end__", { width: 154, height: 24 });
|
||||
Dagre.layout(graph);
|
||||
return workflowNodeDefinitions.map((node) => {
|
||||
const position = graph.node(node.id);
|
||||
return {
|
||||
...node,
|
||||
position: {
|
||||
x: position.x - NODE_WIDTH / 2,
|
||||
y: position.y - NODE_HEIGHT / 2,
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const workflowNodes = layoutWorkflowNodes();
|
||||
|
||||
const edgesForMode = (mode: AuthoringWorkflowMode): Edge[] => [
|
||||
{
|
||||
id: "read_documents.ok",
|
||||
@@ -79,18 +110,13 @@ const edgesForMode = (mode: AuthoringWorkflowMode): Edge[] => [
|
||||
label: "ok",
|
||||
className: "authoring-workflow-diagram__edge",
|
||||
},
|
||||
...(mode === "diagnostic"
|
||||
? []
|
||||
: [
|
||||
{
|
||||
id: "analyze.ok",
|
||||
source: "analyze",
|
||||
target: "__end__",
|
||||
label: mode === "repair" ? "restored · ok" : "ok",
|
||||
animated: mode === "repair",
|
||||
className: `authoring-workflow-diagram__edge${mode === "repair" ? " authoring-workflow-diagram__edge--restored" : ""}`,
|
||||
label: mode === "diagnostic" ? "Missing route · ok" : mode === "repair" ? "Route restored · ok" : "ok",
|
||||
className: `authoring-workflow-diagram__edge${mode === "diagnostic" ? " authoring-workflow-diagram__edge--missing" : ""}${mode === "repair" ? " authoring-workflow-diagram__edge--restored" : ""}`,
|
||||
},
|
||||
]),
|
||||
];
|
||||
|
||||
const accessibleLabelForMode = (mode: AuthoringWorkflowMode): string => {
|
||||
@@ -99,8 +125,30 @@ const accessibleLabelForMode = (mode: AuthoringWorkflowMode): string => {
|
||||
return "Authoring workflow diagram: valid draft routes";
|
||||
};
|
||||
|
||||
const AuthoringWorkflowDiagramInner = ({ mode }: AuthoringWorkflowDiagramProps) => (
|
||||
const AuthoringWorkflowDiagramInner = ({ mode }: AuthoringWorkflowDiagramProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [flow, setFlow] = useState<ReactFlowInstance<Node<AuthoringNodeData>, Edge>>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!flow) return undefined;
|
||||
let frame = window.requestAnimationFrame(() => void flow.fitView(FIT_VIEW_OPTIONS));
|
||||
// Scene columns resize without remounting React Flow, so fit the settled box again.
|
||||
const observer = typeof ResizeObserver === "undefined" || !containerRef.current
|
||||
? undefined
|
||||
: new ResizeObserver(() => {
|
||||
window.cancelAnimationFrame(frame);
|
||||
frame = window.requestAnimationFrame(() => void flow.fitView(FIT_VIEW_OPTIONS));
|
||||
});
|
||||
if (containerRef.current) observer?.observe(containerRef.current);
|
||||
return () => {
|
||||
window.cancelAnimationFrame(frame);
|
||||
observer?.disconnect();
|
||||
};
|
||||
}, [flow, mode]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="authoring-workflow-diagram"
|
||||
role="img"
|
||||
aria-label={accessibleLabelForMode(mode)}
|
||||
@@ -110,8 +158,9 @@ const AuthoringWorkflowDiagramInner = ({ mode }: AuthoringWorkflowDiagramProps)
|
||||
nodes={workflowNodes}
|
||||
edges={edgesForMode(mode)}
|
||||
nodeTypes={nodeTypes}
|
||||
onInit={setFlow}
|
||||
fitView
|
||||
fitViewOptions={{ padding: 0.16, minZoom: 0.7, maxZoom: 1.25 }}
|
||||
fitViewOptions={FIT_VIEW_OPTIONS}
|
||||
nodesDraggable={false}
|
||||
nodesConnectable={false}
|
||||
elementsSelectable={false}
|
||||
@@ -121,24 +170,9 @@ const AuthoringWorkflowDiagramInner = ({ mode }: AuthoringWorkflowDiagramProps)
|
||||
preventScrolling={false}
|
||||
proOptions={{ hideAttribution: true }}
|
||||
/>
|
||||
<div className="authoring-workflow-diagram__route-state" aria-hidden="true">
|
||||
{mode === "diagnostic" ? (
|
||||
<span className="authoring-workflow-diagram__missing-route">
|
||||
<TriangleAlert />
|
||||
<strong>Missing route</strong>
|
||||
<small>analyze · ok</small>
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
data-authoring-edge-id="analyze.ok"
|
||||
data-route-state={mode === "repair" ? "restored" : "present"}
|
||||
>
|
||||
{mode === "repair" ? "Route restored" : "Complete route"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
/** Renders the same authored workflow while its route state changes between beats. */
|
||||
export const AuthoringWorkflowDiagram = (props: AuthoringWorkflowDiagramProps) => (
|
||||
|
||||
@@ -52,6 +52,12 @@ describe("PreparedAuthoringLifecycleScene", () => {
|
||||
expect(frame).toHaveTextContent("missing_outcome_edge");
|
||||
expect(frame).toHaveTextContent("nodes[analyze]");
|
||||
expect(frame).toHaveTextContent(/missing edges for outcomes.*ok/i);
|
||||
const setup = within(frame).getByRole("note", { name: /prepared fault injection/i });
|
||||
expect(setup).toHaveTextContent(/valid revision 2/i);
|
||||
expect(setup).toHaveTextContent(/remove analyze\.ok/i);
|
||||
expect(setup).toHaveTextContent(/invalid revision 3/i);
|
||||
expect(within(screen.getByRole("region", { name: "draft validation diagnostic" }))
|
||||
.queryByRole("note", { name: /prepared fault injection/i })).not.toBeInTheDocument();
|
||||
expect(frame).toHaveAttribute("data-authoring-step", "diagnose");
|
||||
expect(frame).toHaveAttribute("data-recording-phase", "validate");
|
||||
expect(screen.getByRole("region", { name: "draft validation diagnostic" })).toHaveAttribute(
|
||||
|
||||
@@ -127,6 +127,24 @@ export const PreparedAuthoringLifecycleScene = ({ scene, beat, onAdvance, discus
|
||||
</div>
|
||||
</dl>
|
||||
</header>
|
||||
{projection.evidence.kind === "diagnostic" && (
|
||||
<aside
|
||||
className="prepared-lifecycle-scene__setup-strip"
|
||||
role="note"
|
||||
aria-label={projection.evidence.faultInjection.label}
|
||||
>
|
||||
<span>Prepared setup</span>
|
||||
<strong>
|
||||
Valid revision {projection.evidence.faultInjection.fromRevision}
|
||||
{" → remove analyze.ok → "}
|
||||
invalid revision {projection.evidence.faultInjection.toRevision}
|
||||
</strong>
|
||||
<details>
|
||||
<summary>Exact command</summary>
|
||||
<code>{projection.evidence.faultInjection.command}</code>
|
||||
</details>
|
||||
</aside>
|
||||
)}
|
||||
<AuthoringPhaseVisual projection={projection} />
|
||||
</article>
|
||||
</div>
|
||||
|
||||
@@ -138,33 +138,29 @@ describe("presentation.css", () => {
|
||||
expect(editorialScene).not.toContain("0.76fr");
|
||||
});
|
||||
|
||||
it("gives factual result roots a scrollable editorial hierarchy", () => {
|
||||
it("gives lifecycle diagrams the primary editorial hierarchy", () => {
|
||||
const result = cssBlocks(css, ".authoring-result")
|
||||
.find((body) => body.includes("grid-template-rows: auto minmax(0, 1fr);"));
|
||||
const diagnostic = cssBlocks(css, ".authoring-result--diagnostic .authoring-result__body")
|
||||
.find((body) => body.includes("grid-template-columns: minmax(0, 1fr);"));
|
||||
const primaryDiagnostic = cssBlocks(
|
||||
css,
|
||||
'.authoring-result--diagnostic [data-result-primary="true"]',
|
||||
).find((body) => body.includes("min-width: 0;"));
|
||||
const repair = cssBlocks(css, ".authoring-result--repair .authoring-result__body")
|
||||
.find((body) => body.includes("gap: 1rem;"));
|
||||
const repairCommand = cssBlocks(
|
||||
css,
|
||||
'.authoring-result--repair [data-result-primary="true"] .authoring-result__rows > div:first-child',
|
||||
).find((body) => body.includes("border-block"));
|
||||
const composition = cssBlock(css, ".authoring-result__composition");
|
||||
const diagram = cssBlock(css, ".authoring-result__diagram");
|
||||
const receipt = cssBlocks(css, ".authoring-result__receipt")
|
||||
.find((body) => body.includes("display: flex;"));
|
||||
const status = cssBlocks(css, ".authoring-result__header > strong")
|
||||
.find((body) => body.includes("border: 1px solid"));
|
||||
const diagnoseFrame = cssBlocks(css, '.prepared-lifecycle-scene__frame[data-authoring-step="diagnose"]')
|
||||
.find((body) => body.includes("grid-template-rows: auto auto minmax(0, 1fr);"));
|
||||
|
||||
expect(result).toContain("min-height: 0;");
|
||||
expect(result).toContain("overflow: auto;");
|
||||
expect(diagnostic).toContain("grid-template-columns: minmax(0, 1fr);");
|
||||
expect(primaryDiagnostic).toContain("min-width: 0;");
|
||||
expect(repair).toContain("gap: 1rem;");
|
||||
expect(repairCommand).toContain("border-block");
|
||||
expect(composition).toContain("grid-template-rows: minmax(12rem, 1fr) auto;");
|
||||
expect(composition).toContain("min-height: min-content;");
|
||||
expect(diagram).toContain("min-height: 0;");
|
||||
expect(diagram).toContain("overflow: hidden;");
|
||||
expect(receipt).toContain("flex: 0 0 auto;");
|
||||
expect(receipt).toMatch(/font-size:\s*clamp/);
|
||||
expect(status).toContain("border: 1px solid");
|
||||
expect(css).not.toContain(".authoring-repair__");
|
||||
expect(css).not.toContain(".authoring-visual--repair");
|
||||
expect(diagnoseFrame).toBeDefined();
|
||||
expect(css).toContain(".authoring-workflow-diagram .react-flow__node");
|
||||
});
|
||||
|
||||
it("keeps result evidence internally scrollable and stacks metadata on narrow canvases", () => {
|
||||
@@ -172,14 +168,18 @@ describe("presentation.css", () => {
|
||||
const narrowContainer = cssBlock(css, "@container presentation-canvas (max-width: 600px)") ?? "";
|
||||
const compactResult = cssBlocks(compactContainer, ".authoring-result")
|
||||
.find((body) => body.includes("overflow: auto;"));
|
||||
const narrowBody = cssBlocks(narrowContainer, ".authoring-result__body")
|
||||
.find((body) => body.includes("grid-template-columns: minmax(0, 1fr);"));
|
||||
const compactComposition = cssBlocks(compactContainer, ".authoring-result__composition")
|
||||
.find((body) => body.includes("grid-template-rows: minmax(12rem, 1fr) auto;"));
|
||||
const narrowComposition = cssBlocks(narrowContainer, ".authoring-result__composition")
|
||||
.find((body) => body.includes("grid-template-rows: minmax(16rem, 1fr) auto;"));
|
||||
const narrowRows = cssBlocks(narrowContainer, ".authoring-result__rows")
|
||||
.find((body) => body.includes("grid-template-columns: minmax(0, 1fr);"));
|
||||
|
||||
expect(compactResult).toContain("min-height: 0;");
|
||||
expect(compactResult).toContain("overflow: auto;");
|
||||
expect(narrowBody).toContain("grid-template-columns: minmax(0, 1fr);");
|
||||
expect(compactComposition).toContain("min-height: min-content;");
|
||||
expect(compactComposition).toContain("overflow: visible;");
|
||||
expect(narrowComposition).toContain("min-width: 42rem;");
|
||||
expect(narrowRows).toContain("grid-template-columns: minmax(0, 1fr);");
|
||||
});
|
||||
|
||||
@@ -197,12 +197,11 @@ describe("presentation.css", () => {
|
||||
it("gives the prepared lifecycle rail and operation frame the primary hierarchy", () => {
|
||||
const frameRules = cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame');
|
||||
const editorialFrame = frameRules.find((body) => body.includes("background: var(--authoring-paper);"));
|
||||
const frameContent = cssBlock(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame > *');
|
||||
|
||||
expect(cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__rail')
|
||||
.some((body) => body.includes("grid-template-columns: repeat(6, minmax(0, 1fr));"))).toBe(true);
|
||||
expect(cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__rail')
|
||||
.some((body) => body.includes("min-height: 5.4rem;"))).toBe(true);
|
||||
.some((body) => body.includes("min-height: 4.4rem;"))).toBe(true);
|
||||
expect(cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__rail li')
|
||||
.some((body) => body.includes("opacity: 0.78;"))).toBe(true);
|
||||
expect(cssBlocks(css, ".prepared-lifecycle-scene__rail li")
|
||||
@@ -211,7 +210,7 @@ describe("presentation.css", () => {
|
||||
expect(frameRules.some((body) => body.includes("grid-template-rows: auto minmax(0, 1fr);"))).toBe(true);
|
||||
expect(editorialFrame).toContain("border: 0;");
|
||||
expect(editorialFrame).not.toContain("border-bottom:");
|
||||
expect(frameContent).toContain("animation: authoring-frame-content-enter 220ms");
|
||||
expect(css).not.toContain("authoring-frame-content-enter");
|
||||
});
|
||||
|
||||
it("keeps the lifecycle rail scrollable at narrow presentation widths", () => {
|
||||
|
||||
@@ -3577,6 +3577,10 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__frame[data-authoring-step="diagnose"] {
|
||||
grid-template-rows: auto auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__frame > .authoring-visual {
|
||||
min-width: 0;
|
||||
}
|
||||
@@ -3796,6 +3800,10 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame[data-authoring-step="diagnose"] {
|
||||
grid-template-rows: auto auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame-header {
|
||||
border-color: var(--authoring-rule);
|
||||
}
|
||||
@@ -3929,6 +3937,10 @@
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame[data-authoring-step="diagnose"] {
|
||||
grid-template-rows: auto auto auto;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__presentation {
|
||||
min-height: max-content;
|
||||
overflow: visible;
|
||||
@@ -3945,6 +3957,13 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Preserve the graph's authored height; the result root owns any vertical overflow. */
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result__composition {
|
||||
grid-template-rows: minmax(12rem, 1fr) auto;
|
||||
min-height: min-content;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result__rows {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@@ -3996,6 +4015,10 @@
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame[data-authoring-step="diagnose"] {
|
||||
grid-template-rows: auto auto max-content;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result {
|
||||
height: min(34rem, 56vh);
|
||||
max-height: min(34rem, 56vh);
|
||||
@@ -4017,6 +4040,11 @@
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result__composition {
|
||||
grid-template-rows: minmax(16rem, 1fr) auto;
|
||||
min-width: 42rem;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] > .presentation-assistant-pane {
|
||||
grid-area: assistant;
|
||||
align-self: start;
|
||||
@@ -4052,10 +4080,96 @@
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
padding: 0.2rem 0.1rem 0.4rem;
|
||||
color: var(--authoring-ink, var(--text-primary));
|
||||
}
|
||||
|
||||
.authoring-result::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.authoring-result__composition {
|
||||
display: grid;
|
||||
grid-template-rows: minmax(12rem, 1fr) auto;
|
||||
gap: 0.65rem;
|
||||
min-width: 0;
|
||||
min-height: min-content;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.authoring-result__diagram {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
padding: 0.42rem 0.6rem;
|
||||
border-bottom: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
font: 650 0.72rem/1.25 var(--font-evidence);
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip > span {
|
||||
color: var(--accent-amber);
|
||||
font-weight: 750;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip > strong {
|
||||
color: var(--authoring-ink, var(--text-primary));
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip details {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip summary {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.prepared-lifecycle-scene__setup-strip details[open] code {
|
||||
position: absolute;
|
||||
z-index: 8;
|
||||
inset-inline-end: 0;
|
||||
top: calc(100% + 0.4rem);
|
||||
width: min(34rem, 70vw);
|
||||
padding: 0.65rem;
|
||||
border: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
background: var(--authoring-paper, white);
|
||||
box-shadow: 0 0.7rem 1.4rem rgb(0 0 0 / 12%);
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.authoring-result__receipt {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
gap: 0.7rem;
|
||||
min-width: 0;
|
||||
padding-top: 0.55rem;
|
||||
border-top: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
font-size: clamp(0.68rem, 0.8vw, 0.82rem);
|
||||
}
|
||||
|
||||
.authoring-result__receipt > * {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.authoring-result__receipt > h3 {
|
||||
flex: 0 0 auto;
|
||||
margin: 0;
|
||||
color: var(--authoring-ink, var(--text-primary));
|
||||
font: 700 0.7rem/1.2 var(--font-evidence);
|
||||
}
|
||||
|
||||
.authoring-result__header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
@@ -4244,73 +4358,268 @@
|
||||
border-bottom: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
}
|
||||
|
||||
.authoring-result--inventory .authoring-result__body,
|
||||
.authoring-result--artifact .authoring-result__body,
|
||||
.authoring-result--deployment .authoring-result__body {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(13rem, 0.9fr);
|
||||
}
|
||||
|
||||
.authoring-result--inventory .authoring-result__rows,
|
||||
.authoring-result--artifact .authoring-result__rows,
|
||||
.authoring-result--deployment .authoring-result__rows {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.authoring-result--inventory .authoring-result__list-section,
|
||||
.authoring-result--artifact .authoring-result__list-section,
|
||||
.authoring-result--deployment .authoring-result__list-section {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.authoring-result--inventory .authoring-result__contract {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.authoring-result--draft .authoring-result__body {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.authoring-result--draft .authoring-result__rows {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.authoring-result--diagnostic .authoring-result__body {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
max-width: 54rem;
|
||||
}
|
||||
|
||||
.authoring-result--diagnostic {
|
||||
grid-template-rows: auto auto auto;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.authoring-result--diagnostic [data-result-primary="true"] {
|
||||
min-width: 0;
|
||||
padding-inline-start: 0.9rem;
|
||||
border-inline-start: 3px solid var(--accent-amber);
|
||||
}
|
||||
|
||||
.authoring-result--repair .authoring-result__body {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 1rem;
|
||||
max-width: 58rem;
|
||||
}
|
||||
|
||||
.authoring-result--repair [data-result-primary="true"] {
|
||||
.authoring-result--repair .authoring-result__receipt {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
min-width: 0;
|
||||
padding-inline-start: 0.9rem;
|
||||
border-inline-start: 3px solid var(--success);
|
||||
grid-template-columns: minmax(10rem, 0.48fr) minmax(0, 1.52fr);
|
||||
}
|
||||
|
||||
.authoring-result--repair .authoring-result__prior {
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 0.2rem;
|
||||
padding: 0.35rem 0.75rem 0.35rem 0;
|
||||
border-right: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
border-bottom: 0;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.authoring-result--repair .authoring-result__prior code {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.authoring-result--repair [data-result-primary="true"] .authoring-result__rows {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-template-columns: minmax(12rem, 1.4fr) repeat(2, minmax(6rem, 0.6fr));
|
||||
}
|
||||
|
||||
.authoring-result--repair [data-result-primary="true"] .authoring-result__rows > div:first-child {
|
||||
grid-column: 1 / -1;
|
||||
padding: 0.8rem 0.9rem;
|
||||
border-block: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
background: color-mix(in oklch, var(--authoring-paper, white) 92%, var(--success));
|
||||
.authoring-workflow-diagram {
|
||||
position: relative;
|
||||
min-width: 42rem;
|
||||
min-height: 12rem;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__pane {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__node {
|
||||
width: 14rem;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__node {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 0.65rem;
|
||||
width: 100%;
|
||||
min-height: 4.8rem;
|
||||
padding: 0.8rem 0.9rem;
|
||||
border: 2px solid var(--authoring-ink, var(--text-primary));
|
||||
border-radius: 0.55rem;
|
||||
background: var(--authoring-paper, white);
|
||||
color: var(--authoring-ink, var(--text-primary));
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__node[data-node-role="outcome"] {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
justify-items: center;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__node > svg {
|
||||
width: 1.35rem;
|
||||
height: 1.35rem;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__node strong {
|
||||
overflow-wrap: anywhere;
|
||||
font: 700 clamp(0.95rem, 1.5vw, 1.3rem)/1.1 var(--font-evidence);
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__node[data-node-role="source"] strong {
|
||||
font-size: clamp(0.82rem, 1.15vw, 1rem);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__handle {
|
||||
width: 0.62rem;
|
||||
height: 0.62rem;
|
||||
border: 2px solid var(--authoring-paper, white);
|
||||
background: var(--authoring-ink, var(--text-primary));
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__edge-path {
|
||||
stroke: var(--authoring-ink, var(--text-primary));
|
||||
stroke-width: 2.4;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__edge-text {
|
||||
fill: var(--authoring-ink, var(--text-primary));
|
||||
font: 700 0.78rem var(--font-evidence);
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram .react-flow__edge-textbg {
|
||||
fill: var(--authoring-paper, white);
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__edge--restored .react-flow__edge-path {
|
||||
stroke: var(--success);
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__edge--missing .react-flow__edge-path {
|
||||
stroke: var(--accent-amber);
|
||||
stroke-width: 2.8;
|
||||
stroke-dasharray: 7 6;
|
||||
}
|
||||
|
||||
.authoring-workflow-diagram__edge--missing .react-flow__edge-text,
|
||||
.authoring-workflow-diagram__edge--restored .react-flow__edge-text {
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(13rem, 0.9fr) minmax(5rem, auto) minmax(16rem, 1.1fr);
|
||||
align-items: center;
|
||||
gap: clamp(1rem, 2vw, 2rem);
|
||||
min-width: 42rem;
|
||||
min-height: 12rem;
|
||||
height: 100%;
|
||||
color: var(--authoring-ink, var(--text-primary));
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__flow {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 0.4rem;
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
font: 700 0.72rem/1 var(--font-evidence);
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__flow > svg {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__source-stack,
|
||||
.authoring-lifecycle-diagram__bindings {
|
||||
display: grid;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__source,
|
||||
.authoring-lifecycle-diagram__binding {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
align-items: center;
|
||||
gap: 0.55rem;
|
||||
padding: 0.7rem 0.8rem;
|
||||
border-bottom: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__binding {
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__source code,
|
||||
.authoring-lifecycle-diagram__binding code {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability,
|
||||
.authoring-lifecycle-diagram__draft-shape,
|
||||
.authoring-lifecycle-diagram__artifact-object,
|
||||
.authoring-lifecycle-diagram__deployment-object {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
gap: 0.55rem;
|
||||
min-width: 0;
|
||||
min-height: 9rem;
|
||||
padding: 1rem 1.1rem;
|
||||
border: 2px solid var(--authoring-ink, var(--text-primary));
|
||||
border-radius: 0.65rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability > svg,
|
||||
.authoring-lifecycle-diagram__draft-shape > svg,
|
||||
.authoring-lifecycle-diagram__artifact-object > svg,
|
||||
.authoring-lifecycle-diagram__deployment-object > svg {
|
||||
width: 1.6rem;
|
||||
height: 1.6rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability > span,
|
||||
.authoring-lifecycle-diagram__draft-shape > span,
|
||||
.authoring-lifecycle-diagram__artifact-object > span,
|
||||
.authoring-lifecycle-diagram__deployment-object > span {
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
font: 700 0.72rem/1.1 var(--font-evidence);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability > strong,
|
||||
.authoring-lifecycle-diagram__artifact-object > strong,
|
||||
.authoring-lifecycle-diagram__deployment-object > strong {
|
||||
overflow-wrap: anywhere;
|
||||
font: 700 clamp(1rem, 1.7vw, 1.45rem)/1.1 var(--font-display);
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability dl {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.45rem 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability dl > div {
|
||||
display: flex;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability dt {
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__capability dd {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__draft-shape > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__draft-shape code:not(:last-child)::after {
|
||||
content: " →";
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__artifact-object {
|
||||
border-color: var(--success);
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__artifact-object > b,
|
||||
.authoring-lifecycle-diagram__deployment-object > b {
|
||||
color: var(--success);
|
||||
font: 700 0.82rem/1.1 var(--font-evidence);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__requirements {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__requirements code {
|
||||
padding: 0.22rem 0.38rem;
|
||||
border: 1px solid var(--authoring-rule, var(--stage-line));
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram--deployment {
|
||||
grid-template-columns: minmax(21rem, 1.1fr) minmax(4rem, auto) minmax(18rem, 0.9fr);
|
||||
}
|
||||
|
||||
.authoring-lifecycle-diagram__binding-headings {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 2.5rem;
|
||||
color: var(--authoring-muted, var(--text-secondary));
|
||||
font: 700 0.68rem/1.1 var(--font-evidence);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user