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
46 changes: 46 additions & 0 deletions .changeset/9061-calendar-map-inline-query-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
'@object-ui/plugin-calendar': minor
'@object-ui/plugin-map': minor
---

Honour `filter`, `sort` and the platform row ceiling on a calendar's and a map's
inline (`provider: 'value'`) data (objectui#9061) — the port of objectui#8769's
repair off `ObjectGantt`.

**The defect was fail-open.** Both renderers' fetch effect short-circuited the
inline provider: it set the authored rows and returned BEFORE the adapter query,
which is the one site in each file that lowers `schema.filter` to `$filter`,
`schema.sort` to `$orderby` and the objectui#7210 ceiling to `$top`. So an
inline calendar or map that declared a `filter` drew **every** authored row, with
no diagnostic. The key that was dropped is the key that NARROWS, which is why
this matters: the view answered a wider question than the author asked. Nothing
was exposed that was not already in the authored schema — this is a correctness
defect, not a data-access one.

**What changed.** Each renderer resolves a `ValueDataSource` for the inline
provider and issues the same query the `object` arm issues. The `api` arm is
untouched, and no dependency array moves. `ValueDataSource` already implements
`$filter` / `$orderby` / `$skip` / `$top` / `$select` over its own array, so no
filter combinator was written for this change.

**Behaviour you may notice.**

- An authored `filter` / `sort` now narrows and orders inline rows. Every
spelling reaches it: `data: { provider: 'value', items }` and `staticData` on
both renderers, plus the map's bare-array `data` shorthand.
- The row ceiling now applies to inline rows: past 2,000 drawn rows the view
draws 2,000 and shows the footnote naming both numbers, as it already did for
fetched rows. It is applied to the **filtered** set, so a large inline array
that a `filter` cuts below the ceiling draws every matching row and stays
quiet. Rows a host passes down through the `data` React prop are still never
capped — those are not ours to cap.
- Inline rows now reach the view as the adapter's own deep copy rather than as
the authored array's object identities. Code comparing a row handed to
`onEventClick` / `onMarkerClick` against the authored array with `===` needs
`id` equality instead.
- That copy is a JSON round-trip, so inline rows must be JSON-serializable.
A record graph carrying a back-reference, or a `BigInt` id, now renders an
error panel instead of the view. `ObjectGantt` has refused the same input
since before objectui#8769; `ObjectMap` did not, and pinned that it need not
(objectui#6018). ⚠️ That pin is left RED and untouched in this change — see
the pull request body.
10 changes: 10 additions & 0 deletions content/docs/plugins/plugin-calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@ const schema: ObjectCalendarSchema = {
}
```

`filter` and `sort` are not object-only keys (objectui#9061). They narrow and
order inline records — `staticData` or `data: { provider: 'value' }` — exactly as
they narrow and order fetched ones, and the platform row ceiling (2,000 drawn
records with a footnote naming both numbers) applies to inline records too. The
ceiling is applied to the **filtered** set, so a large inline array that a
`filter` cuts below the ceiling draws every matching record and shows no
footnote. Inline records reach the calendar as the in-memory adapter's own deep
copy, so they must be JSON-serializable and a record handed to `onEventClick` is
not `===` the authored object.

### CalendarConfig

```plaintext
Expand Down
10 changes: 10 additions & 0 deletions content/docs/plugins/plugin-map.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ const schema: ObjectMapSchema = {
}
```

`filter` and `sort` are not object-only keys (objectui#9061). They narrow and
order inline rows — `staticData`, a bare array under `data`, or
`data: { provider: 'value' }` — exactly as they narrow and order fetched ones,
and the platform row ceiling (2,000 plotted rows with a footnote naming both
numbers) applies to inline rows too. The ceiling is applied to the **filtered**
set, so a large inline array that a `filter` cuts below the ceiling plots every
matching row and shows no footnote. Inline rows reach the map as the in-memory
adapter's own deep copy, so they must be JSON-serializable and a record handed
to `onMarkerClick` is not `===` the authored object.

### ObjectMapConfig

```plaintext
Expand Down
18 changes: 18 additions & 0 deletions packages/plugin-calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,24 @@ const schema: ObjectCalendarSchema = {

Pass the adapter to `SchemaRendererProvider` to wire the fetch up.

**The provider does not change which query keys apply** (objectui#9061, the port
of objectui#8769). An authored `filter` and `sort` narrow and order the records
on **every** provider, inline ones included — both `staticData` and
`data: { provider: 'value', items }` reach the same in-memory adapter the
`object` provider goes through, so `filter` is evaluated with the same matcher.
Before objectui#9061 the inline provider skipped that query and drew every
authored record with an authored `filter` silently dropped. The platform row
ceiling (2,000 drawn rows, with a footnote naming both numbers — objectui#7210,
ruling a′) applies to inline records too, and it is applied to the **filtered**
set, never to the raw one: a large inline array that a `filter` cuts below the
ceiling draws every matching record and shows no footnote.

⚠️ Two consequences of routing inline records through the adapter. They reach the
calendar as that adapter's own deep copy rather than as the authored array's
object identities, so code comparing a record handed to `onEventClick` against
the authored array with `===` needs `id` equality instead; and the copy is a JSON
round-trip, so inline records must be JSON-serializable.

## Customization

Style the calendar with Tailwind classes:
Expand Down
Loading
Loading