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
24 changes: 24 additions & 0 deletions .changeset/8348-record-source-data-arm-per-spec-row.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@object-ui/core': minor
'@object-ui/plugin-calendar': minor
'@object-ui/plugin-grid': minor
'@object-ui/plugin-map': minor
'@object-ui/plugin-gantt': minor
'@object-ui/plugin-tree': minor
---

**Breaking behaviour change — a view block now honours only the `data` spelling its published row declares.**

Maintainer ruling, decision batch #83 (2026-09-08), verbatim 「8348 以协议为准」: the contract decides. What `os validate` and the save gate refuse under `data`, the renderer refuses too. The shared record-source ladder (`resolveRecordSourceConfig` in `@object-ui/core`) now takes the arm the calling block's row declares, and rung 1 applies only on that arm.

⚠️ **`object-calendar` documents authored against the tolerated spelling stop rendering those rows.** The ladder falls past `data` to `staticData`, then to `objectName` — so such a calendar queries its object instead, or draws nothing when it names neither. This is accepted, with no transition window and no staged deprecation (the standing 2026-08-27 posture).

**Per block — what the published row says, and what actually moves:**

- **`object-calendar`** — row: `ComponentPropsMap['object-calendar'].data` is `z.array(z.unknown())` ("Pre-fetched records — skips the internal fetch"). A record-source **config object** under `data` — `{ provider: 'value', items }`, `{ provider: 'object', object }`, `{ provider: 'api', … }` — is no longer honoured, and this is a real end-to-end change: that object had exactly one carrier into the block, so an authored calendar written that way now queries its object (or draws nothing) instead of drawing the authored rows. There is no longer an api-provider branch to reach here. An **array** under `data` is unchanged, as are `staticData` and `objectName`.
- **`object-grid`** — row: the `ViewData` union, whose own description says "the bare-array shortcut is refused". `getDataConfig`'s `Array.isArray(schema.data)` head is removed, so the array is no longer a record source at the ladder. ⛔ Measured: this is **not** an end-to-end change for a node rendered through `SchemaRenderer`. An authored `data` array also arrives on the **props channel** (`SchemaRenderer` spreads node keys as props; `ObjectGrid`'s `passedData` lifts an array at higher priority), so such a grid still draws its rows. The removal takes the second read, not the last one.
- **`object-map`** — no `ComponentPropsMap` row exists; the governing row is this repo's own `ObjectMapSchema.data`, `ViewDataSchema.optional()`. Its array-shorthand head is removed on the same terms, with the same measured caveat: through `SchemaRenderer` the props channel still draws an authored array. `data: { provider: 'value', items }` and `staticData` are unchanged.
- **`object-gantt`** — no `ComponentPropsMap` row; the governing row is `ObjectGanttSchema.data`, `ViewDataSchema.optional()`. A bare array under `data` is no longer a record source. Nothing observable moves: this block never lifted one, the array carried no `provider` and matched no fetch branch, and its renderer forwards no host props.
- **`object-tree`** — **unchanged.** No published face declares a `data` row for this block: not `ComponentPropsMap`, not `ObjectTreeSchema` (which declares `objectName` required and no `data`), not its registration `inputs`. Neither arm of the ruling reaches it, so its rung 1 keeps its previous behaviour and the block is reported rather than guessed at.

The `data` **prop** — the pre-fetched rows a host such as `ObjectView` or `ListView` passes down — is a different carrier and is untouched on every block. That it is also reachable from an authored node key, because `SchemaRenderer` spreads node keys as props, is what limits the grid and map halves above; it is reported on objectui#8348 rather than changed here.
35 changes: 23 additions & 12 deletions content/docs/plugins/plugin-calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,10 @@ const schema: ObjectCalendarSchema = {
type: 'object-calendar',
objectName?: string, // ObjectQL object name
staticData?: Array<any>, // Static data array
data?: ViewData, // Advanced data configuration
data?: Array<any>, // Pre-fetched records, drawn in place of the
// calendar's own query. An ARRAY — this block's
// published row refuses the `{ provider, items }`
// config object (objectui#8348)
calendar?: CalendarConfig, // Calendar-specific configuration
filter?: ViewFilterRule[], // Query filter, lowered to $filter
sort?: SortConfig[], // Query sort, lowered to $orderby
Expand Down Expand Up @@ -344,17 +347,25 @@ const valueProviderCalendar: ObjectCalendarSchema = {
};
```

#### API Provider — not implemented

`data.provider: 'api'` has no fetch implementation in `ObjectCalendar`. A schema
that reaches this branch logs `API provider not yet implemented for
ObjectCalendar`, sets the record set to empty and renders a calendar with no
events; `endpoint` and `method` have no read point anywhere in the package.
Without a `DataSource` it fails one step earlier, with `DataSource required for
object/api providers`.

Read from the database with the **Object Provider** above, or pass events you
already hold with the **Value Provider**.
#### `data: { provider: … }` — refused on this block

⚠️ Since **objectui#8348** a calendar authored with a record-source *config
object* under `data` — `{ provider: 'value', items: [...] }`,
`{ provider: 'object', object: … }`, `{ provider: 'api', … }` — is not honoured
here. `object-calendar`'s published `data` row is an **array of pre-fetched
records**, so the config object is refused by kind: `os validate` and the save
gate reject it, and as of that card the renderer does too.

That is a behaviour change for stored documents. A calendar written that way no
longer draws those rows; the record-source ladder falls past `data` to
`staticData`, then to `objectName`, so it queries its object instead — or draws
nothing when it names neither.

Read from the database with the **Object Provider** above (`objectName`), pass
events you already hold with the **Value Provider** (`staticData`), or hand the
block rows it already has as an array under `data`. There is no api-provider
branch to reach on this block; `endpoint` and `method` have no read point
anywhere in the package.

## Comparison: CalendarView vs ObjectCalendar

Expand Down
Loading
Loading