# useDocyrusKanban URL: /docs/native/hooks/use-docyrus-kanban Kanban board backed by a Docyrus data source. Groups records by an enum, user or date field, and saves a card's move to the API when it is dropped. Enum options marked final become drop zones. ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/rn-hooks-use-docyrus-kanban ``` **Dependencies:** - [@docyrus/api-client](https://www.npmjs.com/package/@docyrus/api-client) - [@docyrus/app-utils](https://www.npmjs.com/package/@docyrus/app-utils) - [@tanstack/react-query](https://tanstack.com/query/latest) This is a port of the web hook with the same signature. It builds on [`useDocyrusDataViewSelect`](/docs/native/hooks/use-docyrus-data-view-select) for the schema and saved views. The items request uses the active view's filters and sort, the search keyword and `listParams` (whose `filters` are AND-merged with the view's filters). It returns a pre-wired `toolbar` and `board`. The board is the native [rn-kanban](/docs/native/docyrus/kanban) in grouped-`value` mode. **Supported group fields:** `field-select`, `field-radioGroup`, `field-status`, `field-userSelect` (one column per user or per team) and `field-date` / `field-dateTime` (bucketed by day, week or month; the time part is ignored). **Moving cards:** long-press a card to drag it. The hook sends a single PATCH of the group field when you drop the card, never during the drag. Only enum and user columns can be changed this way. Date buckets and team columns are derived, so a card dropped there snaps back. ## Usage ```tsx import { useDocyrusClient } from '@docyrus/signin/react-native'; import { useDocyrusKanban } from '@/hooks/docyrus-native/use-docyrus-kanban'; export function TasksBoard() { const client = useDocyrusClient(); const { toolbar, board } = useDocyrusKanban({ client: client!, appSlug: 'base', dataSourceSlug: 'task', groupByFieldSlug: 'status', titleColumn: 'subject', descriptionColumn: 'description', userColumn: 'created_by', persistState: true, onCardOpen: row => router.push(`/tasks/${row.id}`), cardMenuItems: (row, defaults) => [ { key: 'duplicate', label: 'Duplicate', icon: 'fal copy', onAction: duplicate }, ...defaults ] }); return ( ); } ``` ## API Reference ### Options (`UseDocyrusKanbanOptions`) Extends every [`useDocyrusDataViewSelect`](/docs/native/hooks/use-docyrus-data-view-select) option (`appId`, `staleTime`, `systemViews`, `persistKey`, `activeViewStorage`, …). | Prop | Type | Default | Description | |------|------|---------|-------------| | `client` | `RestApiClient` | — | Authenticated Docyrus API client (required) | | `appSlug` | `string` | — | App slug (required) | | `dataSourceSlug` | `string` | — | Data source slug (required) | | `groupByFieldSlug` | `string` | — | Field whose values become the columns (required) | | `data` | `TData[]` | — | Pre-loaded rows. When set, the items query is skipped | | `collection` | `DocyrusKanbanCollection` | — | Custom `list` / `update` / `remove` adapter | | `listParams` | `DocyrusKanbanListParams` | — | Extra query params. `filters` is AND-merged; every other key overrides | | `defaultLimit` | `number` | `200` | Page size | | `enableItemsQuery` | `boolean` | `data === undefined` | Runs the internal items query | | `dateGroupBy` | `'day' \| 'week' \| 'month'` | `'day'` | Initial date bucket | | `userGroupBy` | `'user' \| 'team'` | `'user'` | Initial user grouping | | `showAllColumns` | `boolean` | `true` | Enum grouping: also shows options with no cards | | `avatarColumn` | `string` | — | Field for the card avatar (icon, color or image) | | `titleColumn` | `string` | — | Field for the card title | | `descriptionColumn` | `string` | — | Field for the card description | | `userColumn` | `string` | — | User field shown in the card footer | | `cardContent` | `(ctx: DocyrusKanbanCardContext) => ReactNode` | — | Extra card content | | `cardMenuItems` | `DocyrusKanbanCardMenuItem[] \| (row, defaults) => DocyrusKanbanCardMenuItem[]` | Open / Edit / Delete | Items of the card's action sheet | | `cardActions` | `ReadonlyArray<'open' \| 'edit' \| 'delete'>` | `['open', 'edit', 'delete']` | Built-in actions to keep | | `onCardOpen` | `(row) => void` | — | Open action. Also handles card taps when `onCardClick` is not set | | `onCardEdit` | `(row) => void` | — | Edit action | | `onCardDelete` | `(row) => void \| Promise` | API delete | Custom delete, run after the confirmation dialog | | `onCardClick` | `(row) => void` | `onCardOpen` | Card tap | | `enableViewSelect` | `boolean` | `true` | Saved-view picker (shown when views exist) | | `enableSearchInput` | `boolean` | `true` | Search input | | `enableDateGroupMenu` | `boolean` | `true` | Date-bucket picker (date grouping only) | | `enableUserGroupMenu` | `boolean` | `true` | User / team picker (user grouping only) | | `enableShowAllColumnsSwitch` | `boolean` | `true` | "Show all" switch (enum grouping only) | | `enableReloadButton` | `boolean` | `true` | Reload button | | `onReload` | `() => void` | — | Called after a reload | | `searchPlaceholder` | `string` | `t('ui.kanban.search', 'Search…')` | Search placeholder | | `searchDebounceMs` | `number` | `300` | Search debounce in ms | | `toolbarClassName` | `string` | — | Classes for the toolbar root | | `toolbarStartContent` | `ReactNode` | — | Content before the view picker | | `toolbarEndContent` | `ReactNode` | — | Content at the end of the control row | | `onItemMove` | `(params: { row, fromColumnId, toColumnId, column }) => void` | — | Called after a drop into another column. The built-in PATCH still runs | | `onItemMoveCommit` | `(params: { row, fromColumnId, toColumnId, column, payload }) => void \| Promise` | — | Takes over saving the move. Throw or reject to roll the board back | | `persistState` | `boolean \| { storage?: 'session' \| 'local'; key?: string }` | — | Saves search, date / user grouping and "show all" for each saved view (`…:kanban`). The active view follows the same store | ### DocyrusKanbanCardMenuItem | Field | Type | Description | |-------|------|-------------| | `key` | `string` | Stable key | | `label` | `string` | Row label (native: string) | | `icon` | `string` | `DocyrusIcon` string, e.g. `'fal pen'` (native: string) | | `destructive` | `boolean` | Red row | | `disabled` | `boolean \| (row) => boolean` | Disables the row | | `onAction` | `(row) => void` | Runs after the sheet closes | ### Result (`UseDocyrusKanbanResult`) | Key | Type | Description | |-----|------|-------------| | `toolbar` | `ReactNode` | Toolbar plus the delete dialog and card action sheet. Always render it | | `board` | `ReactNode` | The board. Shows a spinner while loading and an empty state for an unsupported field | | `items` | `TData[]` | Rows on the board | | `resolvedListParams` | `DocyrusKanbanListParams` | Query payload | | `groupByField` | `DataSourceField \| undefined` | Group field metadata | | `columns` | `DocyrusKanbanColumnMeta[]` | Visible columns (`id`, `label`, `color`, `icon`, `imageUrl`, `isFinal`, `count`) | | `columnsItems` | `Record` | Rows grouped by column id | | `dateGroupBy` / `setDateGroupBy` | `DocyrusKanbanDateGroupBy` / setter | Date bucket | | `userGroupBy` / `setUserGroupBy` | `DocyrusKanbanUserGroupBy` / setter | User grouping | | `showAllColumns` / `setShowAllColumns` | `boolean` / setter | "Show all" switch | | `reload` / `refetch` | `() => void` | Refetches the views and the items | | `views` / `fields` / `forms` / `dataSource` / `activeViewId` / `setActiveViewId` / `isLoading` / `error` / `hasNoViews` | — | From `useDocyrusDataViewSelect` | ### Exports `DOCYRUS_KANBAN_SUPPORTED_FIELD_TYPES` (`Set`) and `readUserMeta(value, mode)`, which normalizes a user or team payload to `{ id, label, imageUrl }`. ## Native deltas - The card `⋮` button (and the info icon) opens an **action sheet** with the menu items. The created / modified audit trail is the sheet message, where web uses a hover tooltip. `label` and `icon` are strings. - Delete asks for confirmation in the native `RecordDeleteConfirmDialog`. - If a move fails (the built-in PATCH rejects or `onItemMoveCommit` throws), the board returns to the server's distribution. - The toolbar is stacked: start content and view picker, then search, then a horizontal row with the group pickers, "Show all", reload and end content. ## Translation Keys | Key | Fallback | |-----|----------| | `ui.kanban.search` | Search… | | `ui.kanban.view` | View | | `ui.kanban.groupBy` | Group by | | `ui.kanban.day` / `week` / `month` | Day / Week / Month | | `ui.kanban.user` / `team` | User / Team | | `ui.kanban.showAll` | Show all | | `ui.kanban.uncategorized` | Uncategorized | | `ui.kanban.weekOf` | Week of | | `ui.kanban.open` / `edit` / `delete` | Open / Edit / Delete | | `ui.kanban.cardActions` | Card actions | | `ui.kanban.recordInfo` | Record info | | `ui.kanban.created` / `modified` | Created / Modified | | `ui.kanban.configureGroupBy` | Configure a group-by field that points to … | | `ui.kanban.unsupportedField` | This field is not supported as a kanban group column: | ## Type Exports | Type | Description | |------|-------------| | `UseDocyrusKanbanOptions` / `UseDocyrusKanbanResult` | Hook options and result | | `DocyrusKanbanCollection` | Collection adapter | | `DocyrusKanbanListParams` | Query params | | `DocyrusKanbanColumnMeta` | Column metadata | | `DocyrusKanbanCardMenuItem` / `DocyrusKanbanCardAction` / `DocyrusKanbanCardContext` | Card types | | `DocyrusKanbanDateGroupBy` / `DocyrusKanbanUserGroupBy` | Grouping modes |