# useDocyrusDataViewSelect URL: /docs/native/hooks/use-docyrus-data-view-select Load a Docyrus data source's fields, saved views and forms, and wire them into the native DataGridViewSelect with one hook — view CRUD, reorder, hidden views and persisted active view included. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-data-view-select ``` **Dependencies:** - [@docyrus/app-utils](https://www.npmjs.com/package/@docyrus/app-utils) - [@docyrus/api-client](https://www.npmjs.com/package/@docyrus/api-client) - [@tanstack/react-query](https://tanstack.com/query/latest) - [@react-querybuilder/core](https://react-querybuilder.js.org) A 1:1 port of the web hook (same options, same result). It needs an authenticated `RestApiClient` and a `QueryClientProvider` above it. Schema, saved views and forms are served from the shared inventory cache ([`useDocyrusInventoryLoader`](/docs/native/hooks/use-docyrus-inventory)), so a warmed app pays no per-mount request. ## Overview - Loads the data source (cache-first, then a scoped `getBySlug` with `expand` for data sources outside the inventory) and maps its fields to query-builder `FullField`s — enum / status / select options become `values`, relation fields get their first 200 records (`id, name, autonumber_id`) as picker values. - Loads saved views (`createDataViewClient`) sorted by `sort_order` then name, prepends developer-defined `systemViews`, and wires create / save / delete / reorder with list invalidation (reorder is optimistic, one PATCH per moved view). - Loads active forms (`createDataFormClient`), default form first, so the view editor can bind a form to each view. - Owns the active view: current selection → persisted id → backend `isDefault` → first view. - Keeps a per-user **hidden views** list (`onViewHide` / `onViewUnhide`). ## Usage ```tsx import { useDocyrusClient } from '@docyrus/signin/react-native'; import { DataGridViewSelect } from '@/components/docyrus-native/data-grid-view-select'; import { useDocyrusDataViewSelect } from '@/hooks/docyrus-native/use-docyrus-data-view-select'; export function OrganizationViews({ table }) { const client = useDocyrusClient(); const { gridViewSelectProps, hasNoViews } = useDocyrusDataViewSelect({ client: client!, appSlug: 'base', dataSourceSlug: 'organization' }); return ( ); } ``` The hook does not take `table` — spread `gridViewSelectProps` and pass `table` separately. [`useDocyrusDataGrid`](/docs/native/hooks/use-docyrus-data-grid) and [`useDocyrusDataTable`](/docs/native/hooks/use-docyrus-data-table) call this hook for you. ## API Reference ### Options (`UseDocyrusDataViewSelectOptions`) | Option | Type | Default | Description | |--------|------|---------|-------------| | `client` | `RestApiClient` | — | Authenticated Docyrus API client. | | `appSlug` | `string` | — | App slug of the data source. | | `dataSourceSlug` | `string` | — | Data source slug. | | `appId` | `string` | — | App id filter for views scoped to another app; also part of the storage keys. | | `overrideFields` | `FullField[]` | — | Replace the derived query-builder fields entirely. | | `dataSource` | `DataSource \| null` | — | Pre-resolved schema — skips the schema fetch; fields, relation targets and the returned `dataSource` come from it. | | `mapField` | `(field: DataSourceField, defaultMapped: FullField) => FullField \| null` | — | Per-field transform after the default mapping. `null` drops the field. | | `staleTime` | `number` | `30_000` | TanStack Query `staleTime` for every query. | | `enabled` | `boolean` | `true` | Disable every query. | | `enableDataViews` | `boolean` | `true` | Fetch / manage saved views. `false` for data sources without a view backend — only `systemViews` are shown. | | `dataSourceExpand` | `string \| false` | `'enums'` | `expand` for the scoped schema fetch. `false` / `''` omits it. | | `enableForms` | `boolean` | `true` | Fetch the data source's saved forms (`forms` result + `gridViewSelectProps.forms`). | | `persistActiveView` | `boolean` | `true` | Persist the last-selected view. | | `persistKey` | `string` | `docyrus:data-grid-view::[:]` | Storage key override for the active view. | | `activeViewStorage` | `'session' \| 'local'` | `'local'` | `lib/storage` backend for the active-view id. The data-listing hooks thread `persistState.storage` here. | | `defaultRowGroupingColumn` | `string` | — | Default row-grouping column for views without a `grouping` (applied by the grid / table hooks). | | `systemViews` | `SavedDataGridView[]` | — | Developer-defined views shown before the saved views; marked `isSystem` (no edit / delete). | ### Result (`UseDocyrusDataViewSelectResult`) | Field | Type | Description | |-------|------|-------------| | `gridViewSelectProps` | `Pick` | Spread onto `DataGridViewSelect`: `views`, `activeViewId`, `fields`, `forms`, `onViewChange`, `onViewCreate`, `onViewSave`, `onViewDelete`, `onViewHide`, `onViewUnhide`, `onViewReorder`, `hiddenViewIds`, `disabled`, `defaultRowGroupingColumn`, `isSaving`, `isLoading`. | | `views` | `SavedDataGridView[]` | System views + saved views (mapped from the backend shape). | | `fields` | `FullField[]` | Query-builder fields (from `@react-querybuilder/core`). | | `forms` | `DataForm[]` | Active saved forms, default first. | | `dataSource` | `DataSource \| undefined` | Resolved schema (injected or fetched). | | `activeViewId` | `string` | Active view id (`''` while loading / no views). | | `setActiveViewId` | `(viewId: string) => void` | Switch views programmatically. | | `isLoading` | `boolean` | Schema or views query loading. | | `error` | `Error \| null` | First error of the schema / views queries. | | `refetch` | `() => void` | Refetch schema + views. | | `hasNoViews` | `boolean` | The view list loaded and is empty (the grid then uses the raw field order — a dev warning is logged). | ## How It Works ### View shape mapping | `DataView` field | `SavedDataGridView` fields | |------------------|----------------------------| | `columns` | `columnVisibility`, `columnOrder`, `columnPinning`, `grouping`, `rowHeight`, `displayMode`, `pagingEnabled`, `pagingMode`, `pageSize`, `inlineEditingEnabled`, `readOnlyColumns`, `columnOptions`, `formId`, `galleryCardConfig`, `galleryDisplayConfig` | | `filters` | `columnFilters`, `filterQuery` | | `sort` | `sorting` | | `color_rules` | `rowColorRules`, `cellColorRules` | ### Active view & persistence The id is persisted under `persistKey` in the `lib/storage` store picked by `activeViewStorage` (`'local'` = the store registered through `` / `setDocyLocalStore()`; `'session'` = in-memory for the app process). With `persistState` on a data-listing hook, the key becomes `docyrus:view-params::[:]:__active-view__`. The hidden-views list always lives in the `'local'` store under `docyrus:data-grid-view-hidden::[:]`. ## Native deltas - `FullField` comes from `@react-querybuilder/core` (no DOM `react-querybuilder`). - Storage goes through `lib/storage` (`getDocyStore('local')` / `getPersistStore`) instead of `window.localStorage` / `sessionStorage`. Register a synchronous persistent store (e.g. `expo-sqlite/kv-store`) to survive restarts. - The "no saved view" warning is gated on `__DEV__`. ## Type Exports | Type | Description | |------|-------------| | `UseDocyrusDataViewSelectOptions` | Hook options. | | `UseDocyrusDataViewSelectResult` | Hook result. |