Create Pipeline Wizard
v0.4.1Five-step modal wizard for creating a pipeline: configure name, description, and model orchestration (Details), answer domain context questions (Context), review and confirm derived sub use cases (Use Case), select data source connections (Connectors), then review and submit (Review). Fully controlled props API with per-step loading states.
Preview
Install & usage
npx shadcn@4.1.2 add @signalos/pipelinewizard-01Pulls the page source plus its widget dependencies (@signalos/tokens, @signalos/utils, @signalos/badge, @signalos/button, @signalos/dialog, @signalos/label, @signalos/select, @signalos/textarea, @signalos/form-dialog, @signalos/text-field, @signalos/icon-button, @signalos/view-controler) into your app - you own the copy. Requires access.
usage
// after: npx shadcn@4.1.2 add @signalos/pipelinewizard-01
// mount the pulled page in a route, e.g. src/app/reusable-components/page.tsx
import CreatePipelineWizard from "@/components/blocks/pipelinewizard-01/CreatePipelineWizard"
export default function Page() {
return <CreatePipelineWizard />
}Props
ConnectionLike
| Prop | Type | Default | Description |
|---|---|---|---|
| id* | string | - | |
| name* | string | - | |
| connector_name | string | undefined | - | Connector type label, e.g. "salesforce". |
| status | string | undefined | - | Connection status label, e.g. "active". |
OrchestrationModelLike
| Prop | Type | Default | Description |
|---|---|---|---|
| canonical* | string | - | |
| display* | string | - | |
| family_display | string | undefined | - | Provider / family grouping label shown as a select section header. |
| lifecycle_warning | boolean | undefined | - | When set, the model is flagged as retiring in the picker. |
ContextQuestion
| Prop | Type | Default | Description |
|---|---|---|---|
| question_key* | string | - | |
| question_text* | string | - | |
| context | string | undefined | - |
CreatePipelinePayload
| Prop | Type | Default | Description |
|---|---|---|---|
| name* | string | - | |
| description | string | undefined | - | |
| platform_connection_ids* | string[] | - | Selected connection ids. |
| onboarding_context | string | undefined | - | Collected onboarding context, already formatted as a string. |
| model | string | undefined | - | |
| supporting_model | string | undefined | - | |
| embedding_model | string | undefined | - |
CreatePipelineWizardProps
| Prop | Type | Default | Description |
|---|---|---|---|
| open* | boolean | - | |
| onOpenChange* | (open: boolean) => void | - | |
| step | number | undefined | - | The currently active step index (0–3). When provided, the wizard is fully controlled: the parent owns step transitions and should react to `onStepChange` to kick off per-step data fetches. |
| onStepChange | ((step: number) => void) | undefined | - | Called when the wizard wants to move to a different step index. |
| name | string | undefined | - | |
| onNameChange | ((value: string) => void) | undefined | - | |
| description | string | undefined | - | |
| onDescriptionChange | ((value: string) => void) | undefined | - | |
| selectedConnectionIds | string[] | undefined | - | |
| onSelectedConnectionIdsChange | ((ids: string[]) => void) | undefined | - | |
| fieldErrors | Record<string, string> | undefined | - | |
| onFieldErrorsChange | ((errors: Record<string, string>) => void) | undefined | - | |
| reasoningModel | string | undefined | - | |
| onReasoningModelChange | ((canonical: string) => void) | undefined | - | |
| supportingModel | string | undefined | - | |
| onSupportingModelChange | ((canonical: string) => void) | undefined | - | |
| embeddingModel | string | undefined | - | |
| onEmbeddingModelChange | ((canonical: string) => void) | undefined | - | |
| connections | ConnectionLike[] | undefined | - | |
| llmModels | OrchestrationModelLike[] | undefined | - | |
| embeddingModels | OrchestrationModelLike[] | undefined | - | |
| isLoadingModels | boolean | undefined | - | True while models are being fetched (Step 1). |
| isLoadingQuestions | boolean | undefined | - | True while onboarding questions are being fetched (Step 2). |
| isLoadingConnectors | boolean | undefined | - | True while connectors are being fetched (Step 3). |
| isSubmitting | boolean | undefined | - | True while the create mutation is in-flight. |
| contextQuestions | ContextQuestion[] | undefined | - | |
| contextAnswers | Record<string, string> | undefined | - | Current answer map, keyed by `question_key`. |
| onContextAnswerChange | ((key: string, value: string) => void) | undefined | - | |
| onOpen | (() => void) | undefined | - | Called when the wizard is first opened so the parent can kick off fetches. |
| onSubmit | ((payload: CreatePipelinePayload) => void) | undefined | - | Called with the collected form data when the user clicks "Create pipeline". |
| onCreateCustomModel | (() => void) | undefined | - | Called when the user clicks "Create model" inside the model picker. |
| data-testid | string | undefined | - | Test identifier rendered as `data-testid` on the dialog content. |
| contextMode | ContextMode | undefined | - | |
| onContextModeChange | ((mode: ContextMode) => void) | undefined | - | |
| supportingDocuments | File[] | undefined | - | Supporting documents staged on the Context step, in "document" mode. |
| onSupportingDocumentsChange | ((files: File[]) => void) | undefined | - | Called with the full next list whenever staged supporting documents change. |
| resolvedUseCase | string | undefined | - | The use case as resolved by the backend from an uploaded document. |
| resolvedOrgDomain | string | undefined | - | The organization domain as the backend resolved it, alongside `resolvedUseCase`. |
| subUseCaseProposals | SubUseCaseProposal[] | undefined | - | Proposed / confirmed / rejected sub use cases derived from the context. |
| onSubUseCaseProposalsChange | ((proposals: SubUseCaseProposal[]) => void) | undefined | - | Called whenever the proposal list changes (confirm, reject, edit, add, undo). |
| isLoadingSubUseCases | boolean | undefined | - | True while the initial derivation call is in flight. |
| subUseCasesFailed | boolean | undefined | - | True when the derivation call itself failed; not the same as an empty proposal list. |
| onRederiveSubUseCases | (() => void) | undefined | - | Called when the user asks to re-derive sub use cases from the current wording. |
| isRederivingSubUseCases | boolean | undefined | - | True while a re-derive call is in flight. |
| subUseCaseEditTargetId | string | null | undefined | - | The proposal id currently being edited, or null when the dialog is closed. |
| onSubUseCaseEditTargetIdChange | ((id: string | null) => void) | undefined | - | Called to open/close the edit dialog (opening also seeds the draft). |
| subUseCaseEditDraftTitle | string | undefined | - | Draft title field value for the edit dialog. |
| onSubUseCaseEditDraftTitleChange | ((title: string) => void) | undefined | - | Called when the edit dialog's title field changes. |
| subUseCaseEditDraftStatement | string | undefined | - | Draft statement field value for the edit dialog. |
| onSubUseCaseEditDraftStatementChange | ((statement: string) => void) | undefined | - | Called when the edit dialog's statement field changes. |
| subUseCaseEditError | string | null | undefined | - | Validation error shown in the edit dialog, if any. |
| onSubmitSubUseCaseEdit | (() => void) | undefined | - | Called when the user submits the edit dialog. |
| subUseCaseRejectTargetId | string | null | undefined | - | The proposal id currently being rejected, or null when the dialog is closed. |
| onSubUseCaseRejectTargetIdChange | ((id: string | null) => void) | undefined | - | Called to open/close the reject dialog. |
| subUseCaseRejectNote | string | undefined | - | Reject-reason note field value. |
| onSubUseCaseRejectNoteChange | ((note: string) => void) | undefined | - | Called when the reject dialog's note field changes. |
| onSubmitSubUseCaseReject | (() => void) | undefined | - | Called when the user submits the reject dialog. |
| subUseCaseAddOpen | boolean | undefined | - | Whether the add dialog is open. |
| onSubUseCaseAddOpenChange | ((open: boolean) => void) | undefined | - | Called to open/close the add dialog. |
| subUseCaseAddDraftTitle | string | undefined | - | Draft title field value for the add dialog. |
| onSubUseCaseAddDraftTitleChange | ((title: string) => void) | undefined | - | Called when the add dialog's title field changes. |
| subUseCaseAddDraftStatement | string | undefined | - | Draft statement field value for the add dialog. |
| onSubUseCaseAddDraftStatementChange | ((statement: string) => void) | undefined | - | Called when the add dialog's statement field changes. |
| subUseCaseAddError | string | null | undefined | - | Validation error shown in the add dialog, if any. |
| onSubmitSubUseCaseAdd | (() => void) | undefined | - | Called when the user submits the add dialog. |
SubUseCaseProposal
| Prop | Type | Default | Description |
|---|---|---|---|
| id* | string | - | Stable identity within this session — index-based ids (UC1.1, UC1.2, …) are assigned for display. |
| title* | string | - | |
| statement* | string | - | |
| status* | SubUseCaseStatus | - | |
| derivation_basis | string[] | undefined | - | |
| hand_added | boolean | undefined | - | |
| review_note | string | undefined | - | Recorded when rejected — why this proposal was declined. |
SubUseCaseDraft
| Prop | Type | Default | Description |
|---|---|---|---|
| title* | string | - | |
| statement* | string | - |
SubUseCaseEditDialogState
| Prop | Type | Default | Description |
|---|---|---|---|
| targetId* | string | null | - | The proposal id being edited, or null when the dialog is closed. |
| draft* | SubUseCaseDraft | - | |
| onDraftChange* | (draft: SubUseCaseDraft) => void | - | |
| error* | string | null | - | |
| onSubmit* | () => void | - | |
| onCancel* | () => void | - |
SubUseCaseRejectDialogState
| Prop | Type | Default | Description |
|---|---|---|---|
| targetId* | string | null | - | The proposal id being rejected, or null when the dialog is closed. |
| note* | string | - | |
| onNoteChange* | (note: string) => void | - | |
| onSubmit* | () => void | - | |
| onCancel* | () => void | - |
SubUseCaseAddDialogState
| Prop | Type | Default | Description |
|---|---|---|---|
| open* | boolean | - | |
| draft* | SubUseCaseDraft | - | |
| onDraftChange* | (draft: SubUseCaseDraft) => void | - | |
| error* | string | null | - | |
| onSubmit* | () => void | - | |
| onCancel* | () => void | - |
SubUseCasesStepProps
| Prop | Type | Default | Description |
|---|---|---|---|
| proposals* | SubUseCaseProposal[] | - | |
| isLoading | boolean | undefined | - | True while the initial derivation call is in flight. |
| hasFailed | boolean | undefined | - | True when the derivation call itself failed; not the same as an empty proposal list. |
| onRederive | (() => void) | undefined | - | Re-run derivation from the current use case / org domain wording. |
| isRederiving | boolean | undefined | - | True while a re-derive call is in flight. |
| onConfirm* | (id: string) => void | - | Marks a proposal confirmed. |
| onUndo* | (id: string) => void | - | Reverts a decided proposal back to "proposed". |
| onOpenEdit* | (id: string) => void | - | Opens the edit dialog for a proposal. |
| onOpenReject* | (id: string) => void | - | Opens the reject dialog for a proposal. |
| onOpenAdd* | () => void | - | Opens the add dialog. |
| onConfirmAll* | () => void | - | Confirms every undecided proposal, leaving rejected ones alone. |
| editDialog* | SubUseCaseEditDialogState | - | |
| rejectDialog* | SubUseCaseRejectDialogState | - | |
| addDialog* | SubUseCaseAddDialogState | - |
Supporting types
export type SubUseCaseStatus = "proposed" | "confirmed" | "rejected"
export type ContextMode = "questions" | "document"
More Reusable Components variants
Changelog
0.4.1
- Lift all sub use case actions and dialog state (confirm, undo, edit, reject, add) out of
SubUseCasesStepand intoCreatePipelineWizard, makingSubUseCasesStepprops-in/events-out: it now takesonConfirm/onUndo/onOpenEdit/onOpenReject/onOpenAdd/onConfirmAllplus fully controllededitDialog/rejectDialog/addDialogstate instead of owninguseStateinternally. - Add
SubUseCaseDraft,SubUseCaseEditDialogState,SubUseCaseRejectDialogState, andSubUseCaseAddDialogStatetype definitions;WizardStepBodyandCreatePipelineWizardProps's wiring pass these through unchanged.
0.3.1
- Declare
react-markdownindependenciesand add@signalos/icon-button/@signalos/view-controlertoregistryDependencies, previously undeclared imports used byDocumentPreviewDialog.tsxandWizardStepContext.tsx.
0.3.0
- Fix compile errors:
CreatePipelineWizardreferenced an undeclaredsupportingDocumentslocal and a nonexistentsetSupportingDocumentssetter instead of the controlledsupportingDocuments/onSupportingDocumentsChangeprops;WizardStepBodyrenderedSubUseCasesStepoff six identifiers it never received as props. - Thread
subUseCaseProposals,onSubUseCaseProposalsChange,isLoadingSubUseCases,subUseCasesFailed,onRederiveSubUseCases, andisRederivingSubUseCasesthroughWizardStepBodyso the "Use Case" step renders. - Add
@signalos/badge,@signalos/dialog, and@signalos/labeltoregistryDependencies, and ship the previously-unlistedSubUseCasesStep.tsxinfiles[].
0.2.0
- Extract
WizardStepBodyandWizardStepIndicatorinto dedicated component files; exportModelSelectandReviewRowfrom thecomponents/folder. - Add
WizardStepandWizardStepIndicatorPropstype definitions; ship new component files in registry manifest.
0.1.6
- Fix cross-item imports to use canonical @/components paths; add missing signalos.category to manifests.
pipelinewizard01
0.1.5
- format the code
0.1.4
- Post-initial content update.
0.1.0
- Initial release: four-step pipeline creation wizard (Details → Context → Connectors → Review)
composed from FormDialog, TextField, Textarea, and Select primitives. Fully controlled props API
with per-step loading states, context questions, model orchestration pickers, and connector
multi-selection. Step state can be lifted to the parent via
step/onStepChangeto trigger per-step data fetches.