useDocyrusDataImportWizard
One-call wiring of a Docyrus data source to the native DataImportWizard. Picks a spreadsheet, uploads and analyses it on the server, auto-maps columns, imports the rows and returns a ready-to-render wizard element plus imperative helpers.
Installation
pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-data-import-wizardpnpm add @docyrus/api-client @docyrus/app-utils @tanstack/react-query expo-document-picker (optional)This is a port of the web hook with the same options and result. It needs an authenticated RestApiClient and a QueryClientProvider above it. The file is picked with the optional expo-document-picker peer and parsed on the server, so no spreadsheet library runs on the device. The hook renders DataImportWizard.
How it works
- Fields. Target fields come from
useDocyrusDataSourceFieldswhile the wizard is open (cache-first through the shared inventory), unless you passfields. - Upload. Picking a file POSTs multipart
FormDatawith a React Native file part ({ uri, name, type }) to…/import/upload.RestApiClientdetectsFormDataand leaves theContent-Typetofetch. PassuploadFileto replace this phase. - Analyse.
GET …/import/details?fileName=…returns the columns, rows (datais normalized torows) and unique-field hints. The mapping is seeded frominitialMappingorbuildAutoMapping(columns, fields). If the fields load after the analysis, auto-mapping runs again. - Import. Enum-like columns are resolved to option ids on the device and sent as
uniqueData. Relation lookups are left to the server. The hook POSTs{ fileName, options }to…/import, whereoptionscomes frombuildImportOptions(mapping, fields, upsertUniqueFields, uniqueData).
All three endpoints default to /v1/apps/{appSlug}/data-sources/{dataSourceSlug}/import/… and can be overridden with endpoints. Closing the wizard resets the run, so the next open starts fresh.
Deployments without an upload route
When the API has no POST …/import/upload, the raw file must already be in tenant storage under tenant-{tenantNo}/tmp/import/{fileName}. Pass uploadFile to put it there yourself and return the UploadedFileInfo. The returned fileName is what the analyse and import phases use.
Usage
import { useDocyrusClient } from '@docyrus/signin/react-native';
import { Button } from '@/components/docyrus-native/button';
import { useDocyrusDataImportWizard } from '@/hooks/docyrus-native/use-docyrus-data-import-wizard';
export function ImportContacts({ onDone }: { onDone: () => void }) {
const client = useDocyrusClient();
const { wizard, openWizard, isImporting } = useDocyrusDataImportWizard({
client: client!,
appSlug: 'base',
dataSourceSlug: 'contact',
requiredFieldSlugs: ['name'],
onImported: () => onDone(),
onError: (error, phase) => console.warn(phase, error.message)
});
return (
<>
<Button onPress={openWizard} disabled={isImporting}>Import</Button>
{wizard}
</>
);
}Imperative usage
uploadAsync and analyseAsync call the endpoints directly and resolve their responses without changing the wizard state. They are useful for custom flows and tests. importAsync imports the file the wizard has already analysed, using the current mapping. It throws when no file has been analysed yet, and it skips the on-device uniqueData pre-resolution.
const importer = useDocyrusDataImportWizard({ client, appSlug, dataSourceSlug });
const uploaded = await importer.uploadAsync(file); // DataImportFile
const analysed = await importer.analyseAsync(uploaded.fileName);
// …after the user went through the mapping step:
const result = await importer.importAsync();API Reference
Options (UseDocyrusDataImportWizardOptions)
| Option | Type | Default | Description |
|---|---|---|---|
client | RestApiClient | — | Authenticated REST client (required). |
appSlug | string | — | App slug (required). |
dataSourceSlug | string | — | Data source slug (required). |
appId | string | — | Accepted for web parity (web scopes its saved-view lookup by app id). |
fields | ReadonlyArray<DocyrusFieldLike> | — | Pre-resolved target fields. Skips the schema fetch. |
requiredFieldSlugs | ReadonlyArray<string> | [] | Slugs that must be mapped before leaving the mapping step. |
uniqueFieldSlugs | ReadonlyArray<string> | from the analyse response | Slugs covered by unique indexes. |
endpoints | { upload?: string; analyse?: string; import?: string } | …/import/upload, …/import/details, …/import | Endpoint overrides. |
uploadFile | (file: DataImportFile) => Promise<UploadedFileInfo> | — | Replace the upload phase (see above). |
previewRowCount | number | 10 | Rows shown in the preview step. |
maxFileSizeBytes | number | 20 * 1024 * 1024 | Maximum file size (20 MB). |
acceptedExtensions | ReadonlyArray<string> | ['xlsx', 'xls', 'csv'] | Accepted extensions. |
initialMapping | WizardMappingMap | — | Mapping seed that overrides auto-mapping. |
enabled | boolean | true | false returns wizard: null (feature flag). |
open | boolean | — | Controlled open state. When omitted, the hook owns it. |
onOpenChange | (open: boolean) => void | — | Called whenever the open state changes. |
onImported | (result: ImportResultPayload) => void | — | Called after a successful import. |
onError | (error: Error, phase: 'upload' | 'analyse' | 'import') => void | — | Called when any phase throws. |
title | ReactNode | — | Wizard header title. |
description | ReactNode | — | Wizard header description. |
Result (UseDocyrusDataImportWizardResult)
| Field | Type | Description |
|---|---|---|
open | boolean | Current open state. |
openWizard / closeWizard | () => void | Open or close (closing resets the run). |
resetWizard | () => void | Back to the upload step with a clean state. |
step | ImportWizardStep | Current step. |
setStep | (next: ImportWizardStep) => void | Change the step. |
wizard | ReactElement | null | The wired DataImportWizard. Render it once next to your trigger. |
uploadAsync | (file: DataImportFile) => Promise<UploadedFileInfo> | Imperative upload. |
analyseAsync | (fileName: string) => Promise<AnalysedFile> | Imperative analyse. |
importAsync | () => Promise<ImportResultPayload> | Imperative import with the current mapping. |
uploadedFile | UploadedFileInfo | null | Upload response. |
analysedFile | AnalysedFile | null | Analyse response. |
importResult | ImportResultPayload | null | Import response. |
fields | ReadonlyArray<DocyrusFieldLike> | Resolved target fields. |
isUploading / isAnalysing / isImporting | boolean | Phase flags. |
error | Error | null | First error of the upload, analyse or import phase. |
Differences from web
FilebecomesDataImportFile(NativeFile:{ uri, name, type, size? }), and the upload sends a React NativeFormDatafile part.- Target fields come from the lightweight
useDocyrusDataSourceFieldsschema hook instead ofuseDocyrusDataViewSelect. - The wizard is a full-height bottom sheet, and the file comes from the system document picker instead of drag-and-drop.
Type Exports
| Type | Description |
|---|---|
UseDocyrusDataImportWizardOptions | Hook options. |
UseDocyrusDataImportWizardResult | Hook result. |
The wizard types (DataImportFile, ImportWizardStep, WizardMappingMap, UploadedFileInfo, AnalysedFile, ImportResultPayload, …) are exported from data-import-wizard.
useDocyrusDataGrid
Everything a Docyrus-backed native DataGrid needs in one hook — columns from the schema, server-side filters / sort / search / paging, saved views, pivot filters, advanced AND/OR filter, borrowed relation columns, inline edit, status updates, bulk actions, exports and persisted view parameters.
useDocyrusDataSourceFields
Lightweight schema hook for one Docyrus data source on React Native. Returns the data source and its field list (including inline enum options), served cache-first from the shared inventory so no extra request is made after the post-sign-in warm-up.