Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/21284-detail-entry-describes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@objectstack/spec': patch
---

docs(spec): an `object-master-detail-form` detail entry's `inlineMode` and `formFields` describes say what happens when the key is omitted on both of the renderer's paths (#21284)

Clause-②: no

- **Derived entry** (any entry that does not name both `relationshipField` and at least one column): an omitted `inlineMode` is resolved from the relationship field's `inlineEdit`, else from the child object's shape, and an omitted `formFields` is derived from the child object's fields. This is unchanged.
- **Entry kept as authored** (one that names both `relationshipField` and at least one column): the renderer resolves and derives nothing. An omitted `inlineMode` renders the collection as a grid, which offers the per-row form only when `formFields` lists more fields than `columns`. An omitted `formFields` means the per-row form is offered only when `inlineMode` is `form`, and it then draws the child object's full field list.
- The `inlineMode` describe used to say only "resolved from the relationship field's `inlineEdit` when omitted", and the `formFields` describe only "derived from the child object's editable fields when omitted". Neither holds for an entry kept as authored. The `formFields` describe also no longer says "editable": the derived list keeps `readonly` fields, as `deriveInlineRowFormFields` (`@objectstack/spec/data`) does.
- No schema accepts or refuses anything new. Only the two describes, the reference page that lifts them, and one source comment change.
4 changes: 2 additions & 2 deletions content/docs/references/ui/component.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,8 @@ Sort field and direction pair
| **childObject** | `string` | ✅ | Child object whose records are entered inline |
| **relationshipField** | `string` | optional | FK on the child pointing back to the parent (auto-detected from the child's master_detail/lookup field when omitted) |
| **columns** | `{ name: string; label?: string; type?: Enum<'text' \| 'number' \| 'currency' \| 'date' \| 'datetime' \| 'time' \| 'select' \| 'lookup' \| 'file'>; width?: number; … }[]` | optional | Editable grid columns (derived from the child object when omitted). Each entry is the strict, name-keyed inline grid column a relationship field's `inlineColumns` takes (`{ name, label?, type?, … }` — objectui GridColumn); identity-only entries (`{ name }`) hydrate everything else from the child object's fields. Unknown keys and the retired `field` spelling are refused at parse. |
| **formFields** | `string[]` | optional | Child field names for the per-row expand form (derived from the child object's editable fields when omitted) |
| **inlineMode** | `Enum<'grid' \| 'form'>` | optional | Inline-edit form factor: 'grid' = editable cells; 'form' = read-only list + per-row full form. Resolved from the relationship field's `inlineEdit` when omitted |
| **formFields** | `string[]` | optional | Child field names for the per-row expand form. When omitted they are derived from the child object's fields — except on an entry that names both `relationshipField` and at least one column, which is kept as authored: nothing is derived, and the per-row form is offered only when `inlineMode` is 'form', where it draws the child object's full field list |
| **inlineMode** | `Enum<'grid' \| 'form'>` | optional | Inline-edit form factor: 'grid' = editable cells; 'form' = read-only list + per-row full form. When omitted it is resolved from the relationship field's `inlineEdit`, else from the child object's shape — except on an entry that names both `relationshipField` and at least one column, which is kept as authored: nothing is resolved, the collection renders as a grid, and the per-row form is offered only when `formFields` lists more fields than `columns` |
| **amountField** | `string` | optional | Numeric child column summed for the running total |
| **sortField** | `string` | optional | Child field holding the line sort position, stamped on drag-reorder (derived from a `position` / `sort_order` / … field when omitted) |
| **totalField** | `string` | optional | Parent field to receive the rolled-up sum |
Expand Down
7 changes: 4 additions & 3 deletions packages/spec/src/ui/component.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5006,7 +5006,8 @@ const MASTER_DETAIL_DETAIL_HISTORY =
* child-collection surfaces. The three it adds are the renderer's own:
* `formFields` (the per-row expand form), `inlineMode` (the two form factors
* a relationship field's `inlineEdit` names; absence takes the relationship's
* own resolution) and `sortField` (the line-position field the grid stamps on
* own resolution only on an entry the renderer derives, and its describe
* states both paths) and `sortField` (the line-position field the grid stamps on
* drag-reorder). `title` and `addLabel` are plain strings because the
* renderer draws them as a React child and a button label without resolving a
* locale map.
Expand All @@ -5030,8 +5031,8 @@ function masterDetailDetailEntry() {
childObject: z.string().describe('Child object whose records are entered inline'),
relationshipField: z.string().optional().describe('FK on the child pointing back to the parent (auto-detected from the child\'s master_detail/lookup field when omitted)'),
columns: z.array(InlineGridColumnSchema).optional().describe("Editable grid columns (derived from the child object when omitted). Each entry is the strict, name-keyed inline grid column a relationship field's `inlineColumns` takes ({ name, label?, type?, … } — objectui GridColumn); identity-only entries ({ name }) hydrate everything else from the child object's fields. Unknown keys and the retired `field` spelling are refused at parse."),
formFields: z.array(z.string()).optional().describe("Child field names for the per-row expand form (derived from the child object's editable fields when omitted)"),
inlineMode: z.enum(['grid', 'form']).optional().describe("Inline-edit form factor: 'grid' = editable cells; 'form' = read-only list + per-row full form. Resolved from the relationship field's `inlineEdit` when omitted"),
formFields: z.array(z.string()).optional().describe("Child field names for the per-row expand form. When omitted they are derived from the child object's fields — except on an entry that names both `relationshipField` and at least one column, which is kept as authored: nothing is derived, and the per-row form is offered only when `inlineMode` is 'form', where it draws the child object's full field list"),
inlineMode: z.enum(['grid', 'form']).optional().describe("Inline-edit form factor: 'grid' = editable cells; 'form' = read-only list + per-row full form. When omitted it is resolved from the relationship field's `inlineEdit`, else from the child object's shape — except on an entry that names both `relationshipField` and at least one column, which is kept as authored: nothing is resolved, the collection renders as a grid, and the per-row form is offered only when `formFields` lists more fields than `columns`"),
amountField: z.string().optional().describe('Numeric child column summed for the running total'),
sortField: z.string().optional().describe('Child field holding the line sort position, stamped on drag-reorder (derived from a `position` / `sort_order` / … field when omitted)'),
totalField: z.string().optional().describe('Parent field to receive the rolled-up sum'),
Expand Down
Loading