> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veloiq.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# DynamicResource: Schema-Driven React CRUD Pages

> DynamicList, DynamicShow, DynamicCreate, and DynamicEdit render full CRUD pages from a ModelDef schema — no component code required.

DynamicResource is the core UI abstraction in `@veloiq/ui`. It provides four React components — `DynamicList`, `DynamicShow`, `DynamicCreate`, and `DynamicEdit` — that render complete CRUD pages entirely from a `ModelDef` schema object. You pass the schema and the full model registry; the components handle field rendering, relation display, form validation, pagination, sorting, filtering, and role-based field visibility automatically.

## Components

### `DynamicList`

Renders a paginated, sortable, filterable list page. Columns are derived from the model's `FieldDef` array. The list integrates with Refine's data provider for pagination (using `_start`/`_end` query parameters) and reads `x-total-count` from the response header. Bulk actions can be supplied via the `BulkActionDef` type.

```tsx theme={null}
import { DynamicList } from "@veloiq/ui";

<DynamicList model={taskModel} allModels={allModels} />
```

### `DynamicShow`

Renders a detail page for a single record. Displays all readable fields grouped by the model schema. Shows related records using the `RelationDef` configuration — each relation can render as a table, editable table, list, gallery, calendar, tree, or tree-details view depending on its `showViewType`. Also renders a relations explorer panel and supports side-by-side Miller-columns tree navigation.

```tsx theme={null}
import { DynamicShow } from "@veloiq/ui";

<DynamicShow model={taskModel} allModels={allModels} />
```

### `DynamicCreate`

Renders a creation form. Each form field is generated from the corresponding `FieldDef`: type determines the input widget, `options` populates select inputs, `required` adds validation, and `writeRoles` hides inputs that the current user cannot write.

```tsx theme={null}
import { DynamicCreate } from "@veloiq/ui";

<DynamicCreate model={taskModel} allModels={allModels} />
```

### `DynamicEdit`

Renders an edit form with the same field generation logic as `DynamicCreate`. Pre-populates fields from the fetched record. Read-only fields (those with `readOnly: true` or where the user lacks `writeRoles`) are displayed but not editable.

```tsx theme={null}
import { DynamicEdit } from "@veloiq/ui";

<DynamicEdit model={taskModel} allModels={allModels} />
```

***

## `ModelDef` type

`ModelDef` is the top-level schema object that describes a single resource. All four DynamicResource components accept `model: ModelDef` as their primary prop.

| Field          | Type                                                     | Required | Description                                                                                   |
| -------------- | -------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------- |
| `name`         | `string`                                                 | Yes      | Model identifier, matched against `allModels` for relation resolution.                        |
| `label`        | `string`                                                 | Yes      | Human-readable label shown in page headings and the sidebar.                                  |
| `fields`       | `FieldDef[]`                                             | Yes      | Ordered list of field definitions. See [FieldDef](#fielddef) below.                           |
| `relations`    | `RelationDef[]`                                          | No       | Related resources rendered in the show and edit pages. See [RelationDef](#relationdef) below. |
| `resource`     | `string`                                                 | No       | URL resource name. Defaults to `name` when absent.                                            |
| `module`       | `string`                                                 | No       | Module identifier. Used to group resources in the sidebar via `generateResources`.            |
| `pkField`      | `string`                                                 | No       | Primary key field name. Defaults to `"id"`.                                                   |
| `hideInMenu`   | `boolean`                                                | No       | Exclude this model from the sidebar. Defaults to `false`.                                     |
| `description`  | `string`                                                 | No       | Short description shown in the page header.                                                   |
| `listViewType` | `"table" \| "gallery" \| "calendar" \| "totals-details"` | No       | Default view type for the list page. Defaults to `"table"`.                                   |

***

## `FieldDef` type

Each entry in `ModelDef.fields` is a `FieldDef` that controls how a single attribute is displayed and edited.

| Field         | Type                                                                                 | Required | Description                                                                                          |
| ------------- | ------------------------------------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------- |
| `key`         | `string`                                                                             | Yes      | Column/attribute name matching the API response key.                                                 |
| `label`       | `string`                                                                             | Yes      | Display label for the field.                                                                         |
| `type`        | `"string" \| "number" \| "boolean" \| "date" \| "datetime" \| "time" \| "image_url"` | Yes      | Data type. Controls the input widget and display formatter.                                          |
| `isPk`        | `boolean`                                                                            | No       | Mark this field as the primary key.                                                                  |
| `required`    | `boolean`                                                                            | No       | Adds a required validator to the form field.                                                         |
| `readOnly`    | `boolean`                                                                            | No       | Display the field but prevent editing in forms.                                                      |
| `reference`   | `string`                                                                             | No       | Resource name of a related model, enabling a select input that fetches options.                      |
| `optionLabel` | `string`                                                                             | No       | Field name to use as the display label when fetching reference options.                              |
| `options`     | `{ label: string; value: any }[]`                                                    | No       | Static option list for select inputs.                                                                |
| `optionsUrl`  | `string`                                                                             | No       | URL to fetch dynamic options from.                                                                   |
| `valueColors` | `Record<string, string>`                                                             | No       | Maps field values to hex color strings for badge/tag display.                                        |
| `readRoles`   | `string[]`                                                                           | No       | Roles allowed to read this field. Absent means all roles. Emitted by `veloiq_field(read_roles=…)`.   |
| `writeRoles`  | `string[]`                                                                           | No       | Roles allowed to write this field. Absent means all roles. Emitted by `veloiq_field(write_roles=…)`. |
| `description` | `string`                                                                             | No       | Tooltip text shown next to the field label.                                                          |
| `nullable`    | `boolean`                                                                            | No       | Allows the field to be empty in forms.                                                               |
| `unique`      | `boolean`                                                                            | No       | Displayed as a hint; not enforced client-side.                                                       |
| `formula`     | `string`                                                                             | No       | Computed field formula (display only).                                                               |

***

## `RelationDef` type

Each entry in `ModelDef.relations` describes a related resource rendered in the show and edit pages.

| Field               | Type                                                                                                                                                        | Required | Description                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------- |
| `resource`          | `string`                                                                                                                                                    | Yes      | Resource name of the related model.                                         |
| `targetKey`         | `string`                                                                                                                                                    | Yes      | Foreign key column on the related resource that points to this record's PK. |
| `label`             | `string`                                                                                                                                                    | Yes      | Section heading for the relation block.                                     |
| `showViewType`      | `"table" \| "editable-table" \| "editable-list" \| "list" \| "csv" \| "gallery" \| "calendar" \| "primary" \| "totals-details" \| "tree" \| "tree-details"` | No       | View type for the relation in the show page.                                |
| `editViewType`      | Same as `showViewType`                                                                                                                                      | No       | View type for the relation in the edit page.                                |
| `otherKey`          | `string`                                                                                                                                                    | No       | Join table column pointing to the related resource's PK (for many-to-many). |
| `otherResource`     | `string`                                                                                                                                                    | No       | Intermediate join resource name.                                            |
| `resourcePath`      | `string`                                                                                                                                                    | No       | API path override for the relation (e.g. `"user_role"` for the join table). |
| `minItems`          | `number`                                                                                                                                                    | No       | Minimum cardinality (from `jm_relationship`).                               |
| `maxItems`          | `number`                                                                                                                                                    | No       | Maximum cardinality (from `jm_relationship`).                               |
| `showTab`           | `string`                                                                                                                                                    | No       | Group this relation under a named tab in the show page.                     |
| `editTab`           | `string`                                                                                                                                                    | No       | Group this relation under a named tab in the edit page.                     |
| `millerLeafConfigs` | `MillerLeafConfig[]`                                                                                                                                        | No       | Multiple leaf pane configurations for tree-details Miller columns.          |

***

## Auto-generated schemas

`veloiq generate` creates `{module}Schema.gen.ts` in each module's frontend directory. This file contains the `ModelDef` array for all models in the module and is overwritten on every run — do not edit it directly.

```typescript theme={null}
// tasks/taskSchema.gen.ts — AUTO-GENERATED. Run `veloiq generate` to update.
import type { ModelDef } from "@veloiq/ui";

export const taskModels: ModelDef[] = [
  {
    name: "Task",
    label: "Task",
    resource: "task",
    fields: [
      { key: "id", label: "ID", type: "number", isPk: true },
      { key: "title", label: "Title", type: "string", required: true },
      { key: "status", label: "Status", type: "string" },
    ],
    relations: [],
  },
];
```

## Manual schema overrides

To extend or override the generated schema without losing your changes on the next `veloiq generate` run:

1. Create `{module}Schema.manual.ts` in the same directory.
2. Merge it into `{module}Schema.ts`, which you maintain by hand.

```typescript theme={null}
// tasks/taskSchema.ts — maintained manually
import { taskModels as generated } from "./taskSchema.gen";
import { taskOverrides } from "./taskSchema.manual";
import { deepMergeModels } from "@veloiq/ui"; // or your own merge utility

export const taskModels = deepMergeModels(generated, taskOverrides);
```

***

## `generateResources` and `authSystemModels`

`generateResources(models, moduleName)` converts a `ModelDef[]` into a Refine `ResourceDef[]` array with list/show/create/edit paths set. `authSystemModels` is a static `ModelDef[]` with built-in definitions for User, Role, and Tenant.

```typescript theme={null}
import { generateResources, authSystemModels } from "@veloiq/ui";
import { taskModels } from "./tasks/taskSchema";

const resources = [
    ...generateResources(taskModels, "tasks"),
    ...generateResources(authSystemModels, "access_control", {
        moduleLabel: "Access Control",
    }),
];
```

***

<CardGroup cols={2}>
  <Card title="UI Overview" icon="squares-four" href="/reference/ui-overview">
    All exports from `@veloiq/ui` at a glance.
  </Card>

  <Card title="Auth Providers" icon="lock" href="/reference/ui-providers">
    Wire up authProvider, accessControlProvider, and httpClient.
  </Card>
</CardGroup>
