diff --git a/.changeset/21315-detail-entry-sortfield-describe.md b/.changeset/21315-detail-entry-sortfield-describe.md new file mode 100644 index 00000000000..ebcac8f27ea --- /dev/null +++ b/.changeset/21315-detail-entry-sortfield-describe.md @@ -0,0 +1,12 @@ +--- +'@objectstack/spec': patch +--- + +docs(spec): an `object-master-detail-form` detail entry's `sortField` and `amountField` describes say what happens when the key is omitted on each of the renderer's paths (#21315) + +Clause-②: no + +- **Entry the renderer resolves** (any entry that does not name `relationshipField` together with at least one column whose every column has a `type`): an omitted `sortField` is the child object's first field named `position`, `sort_order`, `sequence`, `line_no`, `line_number` or `sort`, and an omitted `amountField` is picked from the grid's number and currency columns. This is unchanged. It includes an entry that names `relationshipField` and columns of which some have no `type`: the renderer keeps that entry's `formFields` and `inlineMode` as authored, but it still derives these two. +- **Entry kept exactly as authored** (one that names `relationshipField` and at least one column, and gives every column a `type`): the renderer derives neither. An omitted `sortField` means the grid stamps no line position, so a drag-reorder is not saved. An omitted `amountField` means the sums read a child column named `amount`, and the grid shows a running total only when `totalField` is set. +- The `sortField` describe used to say only "derived from a `position` / `sort_order` / … field when omitted", which does not hold for an entry kept exactly as authored. The `amountField` describe said nothing about omission. +- No schema accepts or refuses anything new. Only the two describes and the reference page that lifts them change. diff --git a/content/docs/references/ui/component.mdx b/content/docs/references/ui/component.mdx index bcda35e83eb..8ffc008cb22 100644 --- a/content/docs/references/ui/component.mdx +++ b/content/docs/references/ui/component.mdx @@ -978,8 +978,8 @@ Sort field and direction pair | **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. 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) | +| **amountField** | `string` | optional | Numeric child column summed for the running total and the `totalField` rollup. When omitted it is picked from the grid's number and currency columns: a computed one, else one named `amount`, `total`, `subtotal`, `line_total`, `line_amount` or `net_amount`, else the last currency column, else the last numeric one — except on an entry that names `relationshipField` and at least one column and gives every column a `type`. The renderer keeps that entry exactly as authored, so nothing is picked. With no `amountField` authored or picked, the sums read a child column named `amount`, and the grid shows a running total only when `totalField` is set | +| **sortField** | `string` | optional | Child field holding the line sort position, stamped on drag-reorder. When omitted it is the child object's first field named `position`, `sort_order`, `sequence`, `line_no`, `line_number` or `sort`, if it has one — except on an entry that names `relationshipField` and at least one column and gives every column a `type`. The renderer keeps that entry exactly as authored: nothing is derived, the grid stamps no line position, and a drag-reorder is not saved | | **totalField** | `string` | optional | Parent field to receive the rolled-up sum | | **title** | `string` | optional | Section title | | **minRows** | `number` | optional | Minimum number of rows | diff --git a/packages/spec/src/ui/component.zod.ts b/packages/spec/src/ui/component.zod.ts index 0d953a969ab..69e43b9a109 100644 --- a/packages/spec/src/ui/component.zod.ts +++ b/packages/spec/src/ui/component.zod.ts @@ -5033,8 +5033,8 @@ function masterDetailDetailEntry() { 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. 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)'), + amountField: z.string().optional().describe("Numeric child column summed for the running total and the `totalField` rollup. When omitted it is picked from the grid's number and currency columns: a computed one, else one named `amount`, `total`, `subtotal`, `line_total`, `line_amount` or `net_amount`, else the last currency column, else the last numeric one — except on an entry that names `relationshipField` and at least one column and gives every column a `type`. The renderer keeps that entry exactly as authored, so nothing is picked. With no `amountField` authored or picked, the sums read a child column named `amount`, and the grid shows a running total only when `totalField` is set"), + sortField: z.string().optional().describe("Child field holding the line sort position, stamped on drag-reorder. When omitted it is the child object's first field named `position`, `sort_order`, `sequence`, `line_no`, `line_number` or `sort`, if it has one — except on an entry that names `relationshipField` and at least one column and gives every column a `type`. The renderer keeps that entry exactly as authored: nothing is derived, the grid stamps no line position, and a drag-reorder is not saved"), totalField: z.string().optional().describe('Parent field to receive the rolled-up sum'), title: z.string().optional().describe('Section title'), minRows: z.number().optional().describe('Minimum number of rows'),