useDocyrusDummyDataGeneratorWizard
One-call wiring of a Docyrus data source to the DummyDataGenerator — handles field-aware strategies, deterministic generation, preview, and batch insert in a single guided flow.
Installation
pnpm dlx @docyrus/cli add @docyrus/hooks-use-docyrus-dummy-data-generator-wizardpnpm add @docyrus/app-utils @docyrus/api-client @tanstack/react-queryThis hook is distributed as source. It needs an authenticated RestApiClient from @docyrus/api-client and a QueryClientProvider from @tanstack/react-query somewhere above your component tree.
Overview
useDocyrusDummyDataGeneratorWizard is the one-call entry point that wires a Docyrus data source to <DummyDataGenerator> and returns a ready-to-render wizard element plus an openWizard() trigger. The hook owns:
- Field discovery — pass
fieldsdirectly (e.g. fromuseDocyrusDataGrid) or let the hook fetch them viauseDocyrusDataViewSelect. - Strategy seeding — every field gets a sensible default via
inferStrategyForField. Users override per field on the configure step (text shape, number range, date window, enum subset, etc.). - Deterministic generation — Mulberry32 PRNG with a per-render seed. The same seed produces the same preview rows so the preview matches the inserted rows.
- Preview rendering — uses
useDocyrusFieldComponent(field.type, 'value-renderer')so every Docyrus field type (relation, money, phone, date, enum, multi-select, …) renders identically to<DataGrid>. - Batch insert — prefers
collection.createMany({ records })when available, thencollection.create(row), then per-recordclient.post('/v1/apps/:app/data-sources/:ds/items', row). Override completely withinsertRecords.
Backend connection
The hook posts each generated row to one endpoint (or batches via the supplied collection):
| Phase | Method | Endpoint | Purpose |
|---|---|---|---|
| Insert | POST | /v1/apps/:appSlug/data-sources/:dataSourceSlug/items | One call per generated row. Wrap with insertRecords to use a bulk endpoint instead. |
Required fields are sourced from one of:
fieldsoption — pass the sameDataSourceField[]you already use withuseDocyrusDataGridto skip an extra round-trip.- Auto-load — when
fieldsis omitted the hook composesuseDocyrusDataViewSelectunder the hood and readsdataSource.fields.
Usage
The hook returns an inline wizard element — drop it anywhere in the layout. Wrap it in your own dialog / drawer / sheet if you want modal behavior.
'use client';
import { useDocyrusAuth } from '@docyrus/signin';
import { useDocyrusDummyDataGeneratorWizard } from '@docyrus/ui/library/hooks/use-docyrus-dummy-data-generator-wizard';
export function ContactsSeederPanel({ onGenerated }: { onGenerated: () => void }) {
const { client } = useDocyrusAuth();
if (!client) return null;
const { wizard } = useDocyrusDummyDataGeneratorWizard({
client,
appSlug: 'crm',
dataSourceSlug: 'contact',
defaultCount: 25,
onGenerated: () => onGenerated()
});
return wizard;
}Wrapping in a dialog
import { Dialog, DialogContent } from '@docyrus/ui/primitives/ui/dialog';
const [open, setOpen] = useState(false);
const { wizard } = useDocyrusDummyDataGeneratorWizard({
client, appSlug, dataSourceSlug
});
return (
<>
<Button onClick={() => setOpen(true)}>Seed sample contacts…</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>{wizard}</DialogContent>
</Dialog>
</>
);Side-by-side with useDocyrusDataGrid
Both hooks accept the same client + appSlug + dataSourceSlug. Wire onGenerated to the grid's reload() so newly inserted rows show up immediately:
const grid = useDocyrusDataGrid({ client, appSlug, dataSourceSlug });
const seeder = useDocyrusDummyDataGeneratorWizard({
client,
appSlug,
dataSourceSlug,
collection: grid.collection, // bulk-insert via collection.createMany when available
fields: grid.fields, // skip duplicate metadata fetch
users: grid.users, // populate field-userSelect strategies
onGenerated: () => grid.reload()
});
return (
<>
{grid.toolbar}
<DataGrid table={grid.table} {...grid.gridProps} />
{seeder.wizard}
</>
);Preview-only flow (no inserts)
const seeder = useDocyrusDummyDataGeneratorWizard({
client,
appSlug,
dataSourceSlug,
previewOnly: true,
onGenerated: (_result, rows) => {
download('seed.json', JSON.stringify(rows, null, 2));
}
});Custom batch endpoint
const seeder = useDocyrusDummyDataGeneratorWizard({
client,
appSlug,
dataSourceSlug,
insertRecords: async (rows) => {
const response = await client.post(`/v1/apps/${appSlug}/data-sources/${dataSourceSlug}/items/bulk`, { records: rows });
const errors = (response as { errors?: Array<{ index: number; message: string }> }).errors ?? [];
return { errors: errors.map(e => ({ rowIndex: e.index, message: e.message })) };
}
});API Reference
Parameters
| Option | Type | Default | Description |
|---|---|---|---|
client | RestApiClient | — | Authenticated client from @docyrus/api-client. Required. |
appSlug | string | — | Target app slug. Required. |
dataSourceSlug | string | — | Target data source slug. Required. |
appId | string | — | Optional multi-tenant isolation key. |
fields | Array<DocyrusFieldLike> | — | Pre-resolved target fields. When provided, the hook skips its internal data source fetch. |
requiredFieldSlugs | Array<string> | [] | Slugs locked to enabled: true. |
defaultCount | number | 10 | Initial row count. |
maxCount | number | 1000 | UI hard cap. |
previewRowCount | number | 10 | Number of rows shown in the preview step. |
collection | { create?, createMany? } | — | Optional collection wrapper. createMany is preferred over per-record create for batch inserts. |
users | Array<DummyUserOption> | — | Tenant users used for field-userSelect / field-userMultiSelect strategies. |
relationOptionsByFieldSlug | Record<string, Array<DummyRelationOption>> | — | Relation pool keyed by field slug. Without it, relation fields are skipped. |
previewOnly | boolean | false | When true the preview-step CTA is "Finish" — the hook never POSTs anything. |
enabled | boolean | true | When false the hook returns wizard: null (use as a feature flag). |
onGenerated | (result, rows) => void | — | Called after the progress phase completes. |
onError | (error: Error, rowIndex: number) => void | — | Called whenever a per-row insert throws (default insertRecords only). |
insertRecords | (rows) => Promise<{ errors }> | derived | Override the per-row insert pipeline. |
title / description / icon | ReactNode / ReactNode / string | translated default | Override the wizard header copy. |
exportFileName | string | <dataSourceSlug>-dummy-data | File name (without extension) for CSV / XLSX downloads. |
Return Value
| Property | Type | Description |
|---|---|---|
wizard | ReactElement | null | Inline wizard panel. Render it directly or wrap it in a dialog. null when enabled === false. |
resetWizard | () => void | Reset the wizard back to the configure step (clears generated rows + result). |
step | DummyDataGeneratorStep | Current step. |
setStep | (step) => void | Move to a step programmatically. |
count / setCount | number / (next) => void | Row count + setter. Setter clamps to [1, maxCount]. |
strategies / setStrategies | DummyStrategyMap / (next) => void | Per-field strategies + setter. |
generatedRows | Array<Record<string, unknown>> | The rows shown in the preview / saved on the next step. |
result | DummyGenerationResult | null | Final-step summary. |
generateAsync | () => Array<Record<string, unknown>> | Imperative generation that returns the rows (skips the wizard UI). |
insertAsync | (rows) => Promise<DummyGenerationResult> | Imperative insert (skips the wizard UI). |
fields | Array<DocyrusFieldLike> | Resolved target fields (from fields prop or useDocyrusDataViewSelect). |
isGenerating / isCreating | boolean | Pending flags. |
error | Error | null | Last insert error. |
Determinism
Generation uses a Mulberry32 PRNG seeded with a fresh value on every "Regenerate sample" click. Within one click, the preview rows are byte-identical to the rows that get inserted. Pass seed directly to generateDummyRows(ctx) if you want test-stable output.
Error Handling
- Per-row insert errors are collected and shown as a per-row error list on the result step. The wizard always reaches the result step — partial failures don't abort the run.
- A thrown
insertRecords(the override) marks every row as failed and surfaces the message in the per-row list.
See Also
<DummyDataGenerator>— the presentational wizard wired by this hook.useDocyrusDataImportWizard— companion hook for importing real spreadsheets.useDocyrusFieldComponent— the registry that powers preview rendering.useDocyrusDataGrid— companion hook for displaying the inserted records.
useDocyrusDataViewSelect
Fetch data source fields and saved views from Docyrus and wire them into DataGridViewSelect with a single hook.
useDocyrusEmailComposer
Wire an `<EmailComposer />` to the Docyrus messaging API — loads sender accounts, lets the user pick a From address, and ships emails through `/v1/messaging/email/accounts/{id}/send`.