feat(wizard): per-phase preview — graph in Analyze, form in Generate (#8)
This commit was merged in pull request #8.
This commit is contained in:
+60
-44
@@ -263,59 +263,75 @@ export default function Wizard() {
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderGraphPreview = () => (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Flow · {draft.nodes.length} step{draft.nodes.length === 1 ? "" : "s"}</div>
|
||||
<div className="wizard-preview-graph">
|
||||
{draft.nodes.map((n, i) => (
|
||||
<div key={n._key || i} className="wizard-graph-node">
|
||||
<div className={`wizard-graph-bubble kind-${n.dispatch_kind || "human"}`}>
|
||||
<span className="wizard-graph-idx">{i + 1}</span>
|
||||
<span className="wizard-graph-name">{n.display_name || "Untitled"}</span>
|
||||
</div>
|
||||
<div className="wizard-graph-meta">
|
||||
{({ human: "Manual", agent: "Assistant", system: "System" } as Record<string, string>)[n.dispatch_kind || "human"]}
|
||||
</div>
|
||||
{i < draft.nodes.length - 1 && <div className="wizard-graph-edge" aria-hidden />}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderFormPreview = () => (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Form preview · what users will fill in</div>
|
||||
<div className="wizard-form-preview">
|
||||
{draft.fields.filter((f) => f.name).length === 0 ? (
|
||||
<div className="wizard-preview-empty">Add fields on the left to see the form here.</div>
|
||||
) : (
|
||||
draft.fields.filter((f) => f.name).map((f, i) => (
|
||||
<div key={i} className="wizard-form-field">
|
||||
<label className="wizard-form-label">{f.name}</label>
|
||||
{f.type === "boolean" ? (
|
||||
<select className="wizard-form-input" disabled defaultValue=""><option value="">Yes / No</option></select>
|
||||
) : f.type === "number" ? (
|
||||
<input className="wizard-form-input" type="number" placeholder="0" disabled />
|
||||
) : (
|
||||
<input className="wizard-form-input" type="text" placeholder={`Enter ${f.name.toLowerCase()}`} disabled />
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderRulesPreview = () => (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Rules · {draft.rules.filter((r) => r.trim()).length}</div>
|
||||
<ul className="wizard-preview-rules">
|
||||
{draft.rules.filter((r) => r.trim()).map((r, i) => <li key={i}>{r}</li>)}
|
||||
{draft.rules.filter((r) => r.trim()).length === 0 && (
|
||||
<li className="wizard-preview-empty">No rules typed yet</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderPreviewPane = () => {
|
||||
if (draft.nodes.length === 0 && draft.fields.length === 0 && draft.rules.length === 0) return null;
|
||||
return (
|
||||
<aside className="wizard-preview">
|
||||
<div className="wizard-preview-head">
|
||||
<span className="mc-hero-eyebrow">Preview</span>
|
||||
<span className="mc-hero-eyebrow">Live preview</span>
|
||||
<div className="wizard-preview-title">{draft.name || "Untitled process"}</div>
|
||||
{draft.description && <div className="wizard-preview-desc">{draft.description.slice(0, 140)}</div>}
|
||||
</div>
|
||||
|
||||
{draft.nodes.length > 0 && (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Steps · {draft.nodes.length}</div>
|
||||
<ol className="wizard-preview-chain">
|
||||
{draft.nodes.map((n, i) => (
|
||||
<li key={n._key || i} className="wizard-preview-chain-item">
|
||||
<span className="wizard-preview-chain-idx">{i + 1}</span>
|
||||
<span className="wizard-preview-chain-name">{n.display_name || "Untitled step"}</span>
|
||||
<span className={`wizard-preview-chain-kind kind-${n.dispatch_kind || "human"}`}>{({ human: "Manual review", agent: "Assistant", system: "System" } as Record<string, string>)[n.dispatch_kind || "human"] || "Manual review"}</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{draft.fields.length > 0 && (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Form · {draft.fields.length} field{draft.fields.length === 1 ? "" : "s"}</div>
|
||||
<ul className="wizard-preview-fields">
|
||||
{draft.fields.filter((f) => f.name).map((f, i) => (
|
||||
<li key={i}>
|
||||
<span className="wizard-preview-field-name">{f.name}</span>
|
||||
<span className="wizard-preview-field-type">· {f.type}</span>
|
||||
</li>
|
||||
))}
|
||||
{draft.fields.filter((f) => f.name).length === 0 && (
|
||||
<li className="wizard-preview-empty">No fields named yet</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{draft.rules.length > 0 && (
|
||||
<div className="wizard-preview-section">
|
||||
<div className="wizard-preview-label">Rules · {draft.rules.length}</div>
|
||||
<ul className="wizard-preview-rules">
|
||||
{draft.rules.filter((r) => r.trim()).map((r, i) => <li key={i}>{r}</li>)}
|
||||
{draft.rules.filter((r) => r.trim()).length === 0 && (
|
||||
<li className="wizard-preview-empty">No rules typed yet</li>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
{(draft.step === "Analyze" || draft.step === "Generate" || draft.step === "Validate" || draft.step === "Draft saved") && draft.nodes.length > 0 && renderGraphPreview()}
|
||||
{(draft.step === "Generate" || draft.step === "Validate" || draft.step === "Draft saved") && renderFormPreview()}
|
||||
{(draft.step === "Validate" || draft.step === "Draft saved") && renderRulesPreview()}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user