@object-ui/react 17.7.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +497 -0
- package/README.md +89 -4
- package/dist/SchemaRenderer.d.ts +27 -1
- package/dist/SchemaRenderer.js +139 -50
- package/dist/context/AppShellContext.d.ts +27 -0
- package/dist/context/DiscussionContext.d.ts +15 -0
- package/dist/context/DiscussionContext.js +2 -0
- package/dist/context/InlineEditContext.d.ts +70 -0
- package/dist/context/InlineEditContext.js +30 -2
- package/dist/context/PrintPageContext.d.ts +60 -0
- package/dist/context/PrintPageContext.js +32 -0
- package/dist/context/RelatedRecordActionsContext.d.ts +67 -1
- package/dist/context/RelatedRecordActionsContext.js +4 -0
- package/dist/context/SchemaRendererContext.d.ts +7 -4
- package/dist/context/SchemaRendererContext.js +1 -1
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.js +1 -0
- package/dist/element-data-source/ElementApiDataSourcePanel.d.ts +28 -0
- package/dist/element-data-source/ElementApiDataSourcePanel.js +10 -0
- package/dist/element-data-source/ElementDataSourceGate.d.ts +30 -2
- package/dist/element-data-source/ElementDataSourceGate.js +75 -6
- package/dist/element-data-source/useElementApiDataSource.d.ts +119 -0
- package/dist/element-data-source/useElementApiDataSource.js +198 -0
- package/dist/hooks/useActionTextLocalizer.d.ts +20 -7
- package/dist/hooks/useActionTextLocalizer.js +43 -12
- package/dist/hooks/useConfigBagEvaluator.d.ts +5 -4
- package/dist/hooks/useConfigBagEvaluator.js +5 -4
- package/dist/hooks/useDatasetDimensionLabels.js +25 -10
- package/dist/hooks/useDensityMode.d.ts +4 -2
- package/dist/hooks/useDensityMode.js +4 -2
- package/dist/hooks/usePageAssignment.d.ts +31 -8
- package/dist/hooks/usePageAssignment.js +68 -25
- package/dist/hooks/useViewData.d.ts +3 -1
- package/dist/hooks/useViewData.js +5 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/utils/localeMap.d.ts +27 -0
- package/dist/utils/localeMap.js +106 -0
- package/dist/utils/propsBagDiagnostic.js +3 -2
- package/dist/utils/unevaluatedExpression.d.ts +3 -1
- package/dist/utils/unevaluatedExpression.js +18 -0
- package/dist/utils/visibilityDiagnostic.d.ts +14 -5
- package/dist/utils/visibilityDiagnostic.js +10 -2
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,502 @@
|
|
|
1
1
|
# @object-ui/react
|
|
2
2
|
|
|
3
|
+
## 18.0.0
|
|
4
|
+
|
|
5
|
+
### Dependency floors
|
|
6
|
+
|
|
7
|
+
Computed from `.objectstack-sha` `06cab4849a8a`: the earliest published `@objectstack/spec` that contains it is `18.0.0`.
|
|
8
|
+
|
|
9
|
+
- `@objectstack/spec` (`dependencies`): `^18.0.0-next.1` → `^18.0.0`
|
|
10
|
+
|
|
11
|
+
### Major Changes
|
|
12
|
+
|
|
13
|
+
- 6f3299f: objectui moves to major 18, following `@objectstack/*` from 17 to 18 (objectui#12334). objectui's major is not a count of its own breaking changes: it tracks the major of the `@objectstack/spec` its packages depend on, so that the same major means compatible across the two projects. These packages already declare `@objectstack/*` on the 18 line (objectui#12030), so every package in the fixed release group crosses to 18 together. It is the one `major` that rule admits: objectui's own breaking changes ship as `minor`, described in their entries.
|
|
14
|
+
|
|
15
|
+
The 18 line is released from Changesets pre mode on the `next` tag (`.changeset/pre.json`), as `@objectstack/*` 18 is: these releases are `18.0.0-next.N` on the npm `next` dist-tag, and they do not move `latest`. The first `18.0.0` on `latest` comes when `@objectstack` 18 is generally available and this repository leaves pre mode.
|
|
16
|
+
|
|
17
|
+
What a consumer must do to take it is in the `@objectstack/*` 18 entry of this release (objectui#12030): move its own `@objectstack/*` packages to the 18 line at the same time.
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- fd060f0: `ElementDataSourceGate` takes a `requiresObject` prop: when a placement opts in
|
|
22
|
+
and its node names its object in neither place, the gate renders a short "no
|
|
23
|
+
object named" hint instead of the block (objectui#11605).
|
|
24
|
+
|
|
25
|
+
The object-bound registrations stopped declaring their object key required,
|
|
26
|
+
because the `dataSource` binding can supply it and the page compile has no "this
|
|
27
|
+
key or that binding" form. So the page compile accepts a node that names no
|
|
28
|
+
object at all, and the runtime's answer is the only signal left for it. Several
|
|
29
|
+
blocks answered such a node with an empty list, board, form, chart, dash or pivot,
|
|
30
|
+
which reads as an empty query.
|
|
31
|
+
|
|
32
|
+
**Clause-②: yes (widening)** — `ElementDataSourceGateProps` gains the optional
|
|
33
|
+
`requiresObject` boolean. With it set, the gate reads the mapping's object key
|
|
34
|
+
(`objectName` unless the mapping names another) on the node after the binding
|
|
35
|
+
lands, so a node bound by `dataSource.object` renders as before; a node that names
|
|
36
|
+
no object gets the hint, "No object named: set objectName or dataSource.object."
|
|
37
|
+
(`data-testid` `{testId}-no-object`), and the block is not mounted. Without the
|
|
38
|
+
prop, or with a mapping whose `object` is `false`, nothing changes. The hint is
|
|
39
|
+
drawn after the view states, so a binding that is still resolving or failed to
|
|
40
|
+
resolve keeps its own panel.
|
|
41
|
+
- 2312bd9: A page that declares `print` now prints as a document, and a record page bound to such a page offers a Print action (objectui#11958, the objectui half of the print-page ruling on objectstack#8346, M1, zero server).
|
|
42
|
+
|
|
43
|
+
- **The print stylesheet.** `PageRenderer` mounts a stylesheet built from the page's `print` declaration, only for a page that declares it. Every rule sits inside `@media print`, so the page on screen is drawn as before. `paperSize` and `orientation` set `@page { size }` (A4 and portrait when omitted). `margins` set one `@page` margin per declared side, in millimetres. `pageNumbers` prints "page / pages" in the bottom-right margin. `repeatHeader` and `repeatFooter` repeat the page's own `header` and `footer` regions on every sheet. `repeatTableHeaders` (on when omitted) repeats a table's column headings on every sheet it runs onto. `avoidBreakInside` keeps each block of a region whole on one sheet when it fits. Only the print page reaches paper: the console chrome and the record view's own panels around the page are hidden, and the page runs onto as many sheets as it needs.
|
|
44
|
+
- **The printable blocks print whole.** On a print page, `record:line_items` no longer cuts lines off at its row cap in silence: when the child object has more lines than the cap (500 unless `limit` is set), the panel draws the cap's lines and the shared row-ceiling note under them, naming both numbers when the server reports a total. A collapsible `record:details` section draws open, because a closed section never reaches paper. Off a print page both blocks behave as before.
|
|
45
|
+
- **The record page's Print action.** When the record page bound to a record declares `print`, the record view shows a Print button that opens the browser's print preview of that page.
|
|
46
|
+
- **New exports from `@object-ui/react`:** `PrintPageProvider`, `usePrintPage` and `PrintPageContext`. `usePrintPage()` returns the enclosing page's `print` declaration, or `null` outside a print page.
|
|
47
|
+
- The source comments that described PDF export as declined now say where a printable document lives: a page that declares `print`.
|
|
48
|
+
- c5406c2: Depend on the `@objectstack/*` 18 prerelease line (objectui#12030).
|
|
49
|
+
|
|
50
|
+
Every `@objectstack/*` range these packages declare in `dependencies` or `peerDependencies` moves from `^17.x` to `^18.0.0-next.0`, the `next` prerelease of `@objectstack/*` 18 (raised to `^18.0.0-next.1` by objectui#12370 before release).
|
|
51
|
+
|
|
52
|
+
**Breaking for consumers:** an install that resolves `@objectstack/spec` (or `@objectstack/client`, `@objectstack/formula`, `@objectstack/lint`) 17.x no longer satisfies these ranges. A consumer must move its own `@objectstack/*` packages to the 18 line, starting with `18.0.0-next.1` (objectui#12370), at the same time as it takes this release.
|
|
53
|
+
|
|
54
|
+
**objectui's own surface moves with it:**
|
|
55
|
+
|
|
56
|
+
- `element:record_picker`'s registration stops publishing the `object`, `filter`, `sort` and `limit` inputs, which spec 18 retires; a JSX page that writes one now gets `unknown-prop`.
|
|
57
|
+
- The `CapabilityMultiSelectField` widget's curated capability set (`@object-ui/fields`) follows spec 18: `manage_mailboxes` in, `manage_org_presentation` out.
|
|
58
|
+
- `element:number` and `element:repeater` nodes that bind no object are accepted, as spec 18's row and `PageComponentSchema` accept them; the two `ELEMENT_*_OBJECT_REQUIRED` refusals are gone.
|
|
59
|
+
|
|
60
|
+
**Retired with the spec:** `@objectstack/spec` 18 tombstones `object-grid`'s `defaultFilters` and refuses it by name, and `ObjectGrid` and `ObjectView` stop reading it (`table.defaultFilters` on an `object-view` included). A view that still carries it renders unfiltered: rename the key to `filter`, whose value is the same rule array.
|
|
61
|
+
- c4dd707: feat(react): a page element's API data source is rendered — `dataSource: { provider: 'api', read: { url }, path? }` binds the selected answer as `data` (objectui#12197)
|
|
62
|
+
|
|
63
|
+
Clause-②: yes
|
|
64
|
+
|
|
65
|
+
`SchemaRenderer` now honours `@objectstack/spec`'s `ElementApiDataSourceSchema` on every node. It reads the same-origin `read.url` with `GET` through `SchemaRendererProvider`'s `apiFetch` (the global `fetch` when no host supplies one), selects `path` from the answer, and binds the value as `data` in the node's `${…}` holes and its `visibleWhen`, and in its subtree's. While the read is in flight the node draws a loading line; a failed read, or a `path` that selects nothing, draws an error panel naming why, titled in the page's language from two new keys, `element.component.apiRefused` and `element.component.apiUnreadable` (all ten packs). The binding is parsed with the spec's own schema first: a cross-origin or protocol-relative `url`, a credential key, or a non-`GET` method is refused with the spec's message and no request is sent. Elements binding the same URL at once share one request; nothing is cached.
|
|
66
|
+
|
|
67
|
+
New exports: `useElementApiDataSource`, `judgeElementApiDataSource`, `isElementApiDataSourceShape`, `selectElementApiPath`, `readElementApi`, and the types `ElementApiDataSourceStatus` and `UseElementApiDataSourceResult`. A node without an API binding renders as before and issues no request.
|
|
68
|
+
- 5c2982a: A record whose `approval_status` reads `pending` no longer opens locked when the approvals read answered and found no request (objectui#12220).
|
|
69
|
+
|
|
70
|
+
A composition without the approvals service answers `GET /api/v1/approvals/requests?object=…&recordId=…` with `200 { "data": [] }` and enforces no lock: a `PATCH` to the record succeeds. The record page still showed "Locked for approval", disabled Edit and offered Recall, which had nothing to recall, because the page and the detail body's approval band fell back to the literal `approval_status` column whenever no pending request was found. Records that an app stamped `pending` with no request behind them stayed locked in the console.
|
|
71
|
+
|
|
72
|
+
- **The rule:** when the approvals read answers, the lock follows the open request. No pending request means no approval band, no lock and no Recall. The `approval_status` column stands in only while no read has answered: the route is absent (404 or 501), the read has not landed yet, or the first read failed. A record with an open request is unchanged, including a `lockRecord: false` node, which stays editable.
|
|
73
|
+
- **`@object-ui/react` adds** `resolveApprovalLock`, the one function the record page and the band both call, with its `ApprovalLockInput` and `ApprovalLockState` types. It also adds an optional `approvalReadAnswered` prop on `InlineEditProvider`, read back on `InlineEditContextValue`. A host sets it when its `locked` and `approvalPending` come from an approvals read that answered. Omitted, the band keeps the column fallback exactly as before.
|
|
74
|
+
- **`@object-ui/app-shell`:** the record page sets `approvalReadAnswered` from its approvals read.
|
|
75
|
+
- **`@object-ui/plugin-detail`:** the band decides through `resolveApprovalLock`.
|
|
76
|
+
|
|
77
|
+
Nothing is removed or renamed.
|
|
78
|
+
- 7af0ab3: The author of a comment on a record page can now edit and delete it from the record feed (objectui#12268).
|
|
79
|
+
|
|
80
|
+
`sys_comment` declares the generic Edit and Delete affordances (`managedBy: 'platform'`), and the platform lets an author update and delete their own comment, but the record feed only offered reactions and replies. Now the author's own comment and reply show Edit and Delete. Nobody else sees either control on it.
|
|
81
|
+
|
|
82
|
+
- **Edit** opens the comment's text in place. Save stores the new text and marks the comment edited; the row then shows the new text with the usual "(edited)" mark. If the server refuses, an error appears, the editor keeps the draft, and the comment keeps its previous text. A comment stored as edited reads as edited.
|
|
83
|
+
- **Delete** asks first, through the console's usual destructive confirm dialog. Cancel deletes nothing. If the server refuses, an error appears and the comment stays.
|
|
84
|
+
- **Replies outlive their comment on screen.** A reply whose comment the feed does not hold, because that comment was deleted or lies before the loaded page, now shows as a row of its own instead of disappearing, so deleting a comment no longer hides anyone's replies to it.
|
|
85
|
+
- Each control appears only with the matching permission on `sys_comment` (update for Edit, delete for Delete). The server's own rule still decides every write.
|
|
86
|
+
|
|
87
|
+
Published surface, all additive:
|
|
88
|
+
|
|
89
|
+
- `@object-ui/collaboration`: new export `isCommentAuthor(authorId, viewerId)`, the owner rule `CommentThread` gates Edit and Delete on. Two missing or empty ids no longer count as a match.
|
|
90
|
+
- `@object-ui/types`: `FeedItem.authoredByViewer?: boolean`, set by the host that read the row.
|
|
91
|
+
- `@object-ui/react`: `DiscussionContextValue.onEditComment` and `onDeleteComment`.
|
|
92
|
+
- `@object-ui/plugin-detail`: `onEditComment` and `onDeleteComment` on `RecordActivityTimelineProps`, `RecordChatterPanelProps` and `ThreadedRepliesProps`. A reply now shows the "(edited)" mark too.
|
|
93
|
+
- `@object-ui/core`: two rows in the affordance-to-grant map, `feedCommentEdit` and `feedCommentDelete`.
|
|
94
|
+
- `@object-ui/i18n`: five new `detail.*` keys in all ten language packs (`editComment`, `deleteComment`, `deleteCommentConfirm`, `commentEditFailed`, `commentDeleteFailed`).
|
|
95
|
+
- 524136e: The view-level `provider: 'api'` data source is no longer read anywhere in objectui (objectui#12325). `@objectstack/spec` retires it (objectstack#23082, ADR-0049): a view binds its object (`provider: 'object'`) or static rows (`provider: 'value'`), and a metadata-declared API call is the page element's `dataSource` binding.
|
|
96
|
+
|
|
97
|
+
Breaking, declared as `minor` per the version-alignment rule:
|
|
98
|
+
|
|
99
|
+
- **`resolveDataSource`** (`@object-ui/core`) has no `api` arm. A block that still says `provider: 'api'` is an unknown provider and gets an unknown provider's answer (the fallback DataSource, else `null`); no `ApiDataSource` is built from its `read` / `write`. `ResolveDataSourceOptions` loses `fetch` and `defaultHeaders`, which only that arm read.
|
|
100
|
+
- **`ViewDataProvider`** (`@object-ui/core`) has no `api` arm: such a config resolves with `Unknown data provider: api`. `ViewDataConfig` and `ResolvedData.provider` drop `'api'`, and `DataFetcher.fetchUrl`, which only that arm called, is removed.
|
|
101
|
+
- **`useViewData`** (`@object-ui/react`) no longer keys on or threads anything for an `api` block.
|
|
102
|
+
- **`ObjectGantt`** reads no `api` block: its `read` URL is never requested, and the chart answers it like any unknown provider. `ObjectCalendar` and `ObjectMap` drop their `api` branches, which only warned "not yet implemented".
|
|
103
|
+
- **`ListView`** no longer stands down for a gantt view with an `api` block: it fetches the bound object like any other list.
|
|
104
|
+
|
|
105
|
+
Unchanged: `ApiDataSource` stays a class for code that constructs it from an `ApiDataSourceConfig`, so the console's approvals inbox reads exactly as before.
|
|
106
|
+
- ff9df88: Depend on `@objectstack/*` `18.0.0-next.1` (objectui#12370).
|
|
107
|
+
|
|
108
|
+
Every `@objectstack/*` range these packages declare moves from `^18.0.0-next.0` to `^18.0.0-next.1`; the console and the runner bundle `18.0.0-next.1`. A consumer moves its own `@objectstack/*` packages to `18.0.0-next.1` with this release.
|
|
109
|
+
|
|
110
|
+
**Accept sets that narrow with it.** `@object-ui/types` validates page action rows and view data bindings through the spec's own rows, so its faces (`safeValidateSchema` and `StrictAnyComponentSchema`) now refuse what `18.0.0-next.1` refuses. Each was accepted on `18.0.0-next.0`:
|
|
111
|
+
|
|
112
|
+
- `onSuccess` on an `action:button` / `action:icon` row, or an `action:group` / `action:menu` member, whose executor is the `url`, `navigation`, `modal`, `flow` or `form` built-in, or that has no executor at all. Write the hop on an `api` or `script` action (or a host handler name), or drop it.
|
|
113
|
+
- `onSuccess` beside `operation: 'update'`, and an `onSuccess` block carrying a key outside `{ navigate, openIn }`.
|
|
114
|
+
- `actionType: 'navigation'` on a row (and `type: 'navigation'` on a container member): write `'url'`.
|
|
115
|
+
- A `url` executor's `target` that is not openable, judged on the executor the runner runs, including a row whose `name` selects it.
|
|
116
|
+
- A view `data` binding with `provider: 'api'`: bind the object or static rows; an API call is the page element's binding.
|
|
117
|
+
- 611566b: `SchemaRenderer` no longer reads a page component's `visibility` key (objectui#12654). `@objectstack/spec` 18 retires it as a `retiredKey` tombstone naming `visibleWhen` (objectstack#23543 F4), so `visibleWhen` is the one conditional-visibility key the renderer reads for it.
|
|
118
|
+
|
|
119
|
+
What a raw schema loses: a node handed straight to `SchemaRenderer`, without passing through the spec's parse, that carries only `visibility: 'PREDICATE'` is no longer hidden when the predicate is false; it now draws, and the `visibility` value is no longer stripped before the component's props. Write `visibleWhen` instead. The `SchemaRenderer` working-copy type no longer declares `visibility`.
|
|
120
|
+
|
|
121
|
+
What is unaffected: metadata served by an ObjectStack runtime. A served page row already reaches the renderer with `visibleWhen`: the spec's parse folds the old key through the 18 pre-releases, and spec 18's stored-row rehydration rewrites a row stored with it. `BaseSchema`'s own deprecated `visibleOn` is a different key and is still read.
|
|
122
|
+
- 71243db: A navigation entry whose `visible` predicate cannot be evaluated is no longer drawn for everyone (objectui#12700).
|
|
123
|
+
|
|
124
|
+
The shell's navigation surfaces (the sidebar, the app root's landing, the activity roster read from app navigation, the `nav:menu` block and the command palette's navigation list) answer a FAULTING `visible` predicate by withholding the entry, where they used to draw it. The case that made this matter is a `current_user.can("OBJECT", "read")` gate asked where no `/auth/me/permissions` payload is bound: the expression engine refuses it, and the shell used to read that refusal as "shown", so permission-gated navigation hid nothing there. Where the payload is bound, the gate answers from it as before: a member without the grant is not shown the entry and one with it is. The fault is still reported once per predicate, now with a consequence line saying the entry was withheld. A blank gate is still "no gate" and is drawn. This is UI gating, not a security boundary: the server enforces what a member may read.
|
|
125
|
+
|
|
126
|
+
`@object-ui/react`: `PredicateGateKind` gains a `'withholding'` member, the consequence line for a visibility gate whose fault is answered by withholding the entry. `@object-ui/app-shell`'s published `evaluateVisibility` keeps its fail-open answer; the object-field gate uses it unchanged.
|
|
127
|
+
- 33ee9de: A `list-view` block drawn as a compact list in a narrow page region now shows a "View all" link under its rows (objectui#12703).
|
|
128
|
+
|
|
129
|
+
- `@object-ui/react`: `RelatedRecordActionsValue` gains two optional members, `listHref(objectName, viewName?)` and `openList(objectName, viewName?)`. They address an object's list page, or one of its saved views, the way `recordHref` / `openRecord` address a record. A host that omits them is unchanged.
|
|
130
|
+
- `@object-ui/app-shell`: a custom page supplies them. The routes are `/apps/APP/OBJECT/view/VIEW` for a block bound to a saved view (`dataSource.view`) and `/apps/APP/OBJECT` otherwise. The block's inline filter, columns and sort are never put in the URL.
|
|
131
|
+
- `@object-ui/plugin-list`: the compact list draws the link only when the host answers a destination. It is a real anchor with in-app navigation on a plain click.
|
|
132
|
+
- `@object-ui/i18n`: one new key, `list.viewAll`, in all ten packs.
|
|
133
|
+
- c7462e7: New export `isRecordPageOf(page, objectName)` (objectui#12715): true when `page` is a record page bound to `objectName` (`type: 'record'` and `object` names it). It is the one reading of "a record page of object O": `usePageAssignment`'s object-based lookup now filters its candidates with it, unchanged in behaviour, and the console's named record page route asks it before it renders a named page for a record.
|
|
134
|
+
|
|
135
|
+
`usePageAssignment`'s `pageName` option is unchanged: it still returns the page with that name whatever its type or object, so a caller that renders a record on the page it gets back asks `isRecordPageOf` first.
|
|
136
|
+
- 8df2608: `RelatedRecordHandlers` gains an optional `onViewAll` (objectui#12741). A host returns it from `resolve` to open the child object's full list page, scoped to the parent on the relationship it was handed. `record:related_list` calls it from its "View all" link. A host that omits it draws no link, as for every other handler on this interface.
|
|
137
|
+
|
|
138
|
+
Clause-② line, the same as the pull request's:
|
|
139
|
+
Clause-②: yes
|
|
140
|
+
One optional member is added to the exported `RelatedRecordHandlers` interface. Nothing else on the package entry changes.
|
|
141
|
+
- 5ff64ef: feat(react): `MetadataContextValue.readObjectScope`, the object definitions one app reads (objectui#12811)
|
|
142
|
+
|
|
143
|
+
A new optional member of the metadata context. `readObjectScope({ packageId, names })` answers the
|
|
144
|
+
objects of one package, read with `GET /api/v1/meta/object?package=ID`, plus each of `names` that the
|
|
145
|
+
package does not hold, read by name. Each definition is shaped exactly as the same object in
|
|
146
|
+
`objects`. The answer carries `objects`, `served` (the same definitions as the server served them,
|
|
147
|
+
before views are merged, as `getItemsByType('object')` holds the whole list), `missing` (the names the
|
|
148
|
+
server answered without a definition) and `settled` (the package list and every name have answered). With no `packageId` it is
|
|
149
|
+
the whole registry, as `objects` is.
|
|
150
|
+
|
|
151
|
+
`objects` is unchanged: it is the whole registry. A context value without the member (a hand-rolled
|
|
152
|
+
one in a test, an older host) has nothing narrower to offer, and its readers read `objects`.
|
|
153
|
+
- a7ae252: A `${…}` hole inside an inline locale map is evaluated (objectui#12936). In a node's `properties` bag (or its legacy `props` alias, or a block member evaluated with `useConfigBagEvaluator`), each member of a map such as `title: { en: 'Published ${data.at}', 'zh-CN': '…${data.at}' }` is evaluated like a plain string on the same key: against `record`, `current_user` / `user`, `page`, the host's roots, and `data` on a node with an API binding. A block that picks the viewer's language with `pickLocalized` off its evaluated props, such as `hero`, now draws the bound value instead of the template text, with no change to the block. A member's result is always a string, so the map stays a map.
|
|
154
|
+
|
|
155
|
+
A value counts as a locale map exactly when `@objectstack/spec`'s `InlineLocaleMapSchema` accepts it: every key a locale tag or `default`, every value a string. Any other object keeps the data-object rule and is handed over as authored, with nothing inside it evaluated. A map without a hole arrives as the same object. In development builds, a member whose expression throws keeps its source text and is now reported by the unevaluated-expression diagnostic by its locale (`properties.title.zh-CN`), as a plain string with the same hole is.
|
|
156
|
+
|
|
157
|
+
**Clause-②: yes (widening)** — the renderer honours a shape it used to hand over raw: a hole inside an inline locale map's member. No export is added or removed and no type changes; the set of authored values `SchemaRenderer` evaluates widens by that one shape.
|
|
158
|
+
- 024b7b6: A page route reads the objects its page binds, not the whole object registry (objectui#12980, part 1).
|
|
159
|
+
|
|
160
|
+
Opening a page (`/apps/APP/page/NAME`) used to load every object definition (`GET /api/v1/meta/object`, 751 KB on the control plane), because the route, the page view and three page blocks read `useMetadata().objects`. Now:
|
|
161
|
+
|
|
162
|
+
- **`readObjectScope({ names })` with no `packageId` is a names-only scope** (`@object-ui/react`, `MetadataContextValue.readObjectScope`). Each name is read by name, with no package list. Only a scope with neither `packageId` nor `names` is the whole registry. This widens what the published contract accepts, which is why `@object-ui/react` is a minor bump.
|
|
163
|
+
- **A page route reads the objects its page definition binds**: the page's `object`, its interface source, and every `objectName` and `dataSource.object` on its blocks. They are read by name, beside the app's package list when the app names a package, or through the names-only scope when it does not. A page that binds no object, such as one whose data sources are all `api`, reads none. The chrome around the page gets the same scope.
|
|
164
|
+
- **An object a block asks about outside that set is read by name when it asks.** A link to it is drawn once the object arrives, and opening it navigates once the object is known.
|
|
165
|
+
- **The page blocks:** the interface list page reads its source object by name, `nav:menu`'s capability gate reads the objects its app's entries require by name, and `global:search` reads the registry only once the user types. A record overlay still reads the whole registry, because a record's related lists come from every object that points at it.
|
|
166
|
+
|
|
167
|
+
No export, prop or type member is added.
|
|
168
|
+
- 9e7e1a5: `@object-ui/react` now exports `buildNodeEvaluationScope(predicateScope, boundRecord, pageVariables)`, the one builder of the scope a page node's `visibleWhen` and other values are evaluated against (objectui#12992). It returns four roots: the ambient predicate scope, `current_user` aliased to `user`, the bound row as `record` (only when there is one), and page variables as `page`. `SchemaRenderer` and `evaluateConfigBagInScope` call it as before. `page:tabs` in `@object-ui/components` now calls it for its derived-badge gates and its item-level `visibleWhen` instead of spelling the scope again, so a root added to the builder reaches the tab strip too. No root changes for any caller.
|
|
169
|
+
|
|
170
|
+
### Patch Changes
|
|
171
|
+
|
|
172
|
+
- 92f4e2b: An action's translated copy is now read from ONE bundle node, chosen by the object the action belongs to, the same way `@objectstack/spec` 17.7.0 reads it on the server (objectui#11439). That object is the action's declared `objectName`, else the object whose `actions` embed it.
|
|
173
|
+
|
|
174
|
+
- An action that belongs to an object reads `objects.OBJECT._actions.ACTION.*` only. Copy for it filed under `globalActions.ACTION` no longer applies: its label, confirm text, success message, outcome messages, description, parameters and result dialog show the authored text instead, as they already did everywhere the server translates. Move that copy to `objects.OBJECT._actions.ACTION`, which is where `os validate` asks for it.
|
|
175
|
+
- An action with no object (no `objectName`, not embedded in an object) still reads `globalActions.ACTION.*`.
|
|
176
|
+
- `useActionTextLocalizer` keys on the action's declared `objectName` before the object its caller passes, so an action declared on one object reads that object's copy wherever it is drawn.
|
|
177
|
+
|
|
178
|
+
`useObjectLabel()` and `useActionTextLocalizer()` keep their signatures; no input, export or translation key is added.
|
|
179
|
+
- 92f979d: `usePageAssignment` opens an object's default record page: among the record pages served for the object, the one declared `isDefault: true` is returned, and declaration order decides only when none is (objectui#12195).
|
|
180
|
+
|
|
181
|
+
The hook used to return the first matching record page in served order and never read `PageSchema.isDefault`, so the flag on a shipped page (the platform's `sys_user_detail`, `sys_organization_detail` and `sys_approval_request_detail`, and the showcase's record pages) did nothing. `@objectstack/spec` 18.0.0-next.1 states the rule this follows (maintainer ruling A on objectstack#23015): at most one default record page may exist for an object in a deployment, and a second is refused at `os validate`, at package registration and at metadata save, naming both pages. So the hook adds no tie-break of its own. It reads "the default record page of an object" through the spec's `defaultRecordPageObject`, the same reading those refusals use.
|
|
182
|
+
|
|
183
|
+
**Who sees a different page.** An app or environment that authors its own record page for an object without `isDefault: true`, for an object that also has a served default record page, and whose page came first in the served list. That page used to open; the default opens now. Ruling A keeps two ways to replace a platform record page: an ADR-0005 overlay saved under that page's own name, and host composition (composing the stack without the platform's page). Shipping a second default is not one: the platform refuses it. With no default for an object, nothing changes: the first matching page still opens, and an explicit `pageName` still wins over the default.
|
|
184
|
+
|
|
185
|
+
No type, option or export changes (`Clause-②: no`).
|
|
186
|
+
- 97e7d4e: Lookup links on a record page and on a custom page now carry the console's base path, so the same link works from a left click, a new tab, a middle-click and a copied link (objectui#12233).
|
|
187
|
+
|
|
188
|
+
On a console mounted under a router basename, such as `/_console`, a lookup value rendered as an anchor whose href was the bare route `/apps/APP/OBJECT/record/ID`. On a record page this hit, for example, a lead's converted account or contact and its owner. The same held for a lookup, or a grid's link column, on a custom page. A plain left click worked, because the anchor hands it to the console router and the router adds the basename. Opening the link in a new tab, middle-clicking it or pasting a copied link sent the browser to the bare route on the server, which answered `ENDPOINT_NOT_FOUND`.
|
|
189
|
+
|
|
190
|
+
- `@object-ui/app-shell`: both record-link builders, the record page's and the custom page's, now give lookups an href that includes the router's basename. They read the basename from the router, so a console mounted at the root keeps the bare href. A left click still navigates inside the app, to the same record the href names.
|
|
191
|
+
- `@object-ui/react`: the documentation of `RelatedRecordActionsValue.recordHref` now says the value is a document href that carries the host router's basename, while `openRecord` navigates by the router path. The type is unchanged.
|
|
192
|
+
|
|
193
|
+
Nothing is added to or removed from any package entry.
|
|
194
|
+
- d75f212: Published text no longer teaches the retired view-level `provider: 'api'` data source (objectui#12364). A view binds `provider: 'object'` or `provider: 'value'`; a metadata-declared API call is the page element's `dataSource` binding. Text only: no schema accepts or refuses anything new, and no renderer behaves differently.
|
|
195
|
+
|
|
196
|
+
- **`@object-ui/types`:** the `object-tree` `data` description drops the `api` provider from the providers it names.
|
|
197
|
+
- **`@object-ui/plugin-grid` / `@object-ui/plugin-map`:** the `data` input descriptions drop the `api` provider.
|
|
198
|
+
- **`@object-ui/plugin-calendar` / `@object-ui/plugin-gantt` / `@object-ui/plugin-map`:** the error thrown when no `DataSource` is available now reads `DataSource required for the object provider` (was `DataSource required for object/api providers`). It fires in exactly the same conditions as before.
|
|
199
|
+
- **`@object-ui/react` / `@object-ui/auth`:** the README and docblocks describe `SchemaRendererProvider`'s `apiFetch` as what it is now: the host's authenticated fetch the renderers use for their own reads of the host's API (chart metadata, dataset dimension labels, record-permission probes). It is not a channel for a view's data source.
|
|
200
|
+
- **`@object-ui/app-shell`:** comment wording only in `ConsoleShell`, `useConsoleActionRuntime` and `ObjectView` (these comments ship in the built JS): no behaviour change.
|
|
201
|
+
- **`@object-ui/core`:** docblock wording only on `normalizeListViewSchema` and `resolveRecordSourceObjectName` (these ship in `dist/*.d.ts` and the built JS): no behaviour change.
|
|
202
|
+
- 3eb3ec1: The console's list toolbar no longer has a write into the shared view, and the data-source method that write used is retired (objectui#12504).
|
|
203
|
+
|
|
204
|
+
**BREAKING:** `DataSource.updateViewConfig` is removed from `@object-ui/types`, and `ObjectStackAdapter.updateViewConfig` is removed from `@object-ui/data-objectstack`. The capability gate that only that method read goes with it: `ObjectStackAdapter.setSystemCapabilities`, the `systemCapabilities` option of the adapter constructor and of `createObjectStackAdapter`, `VIEW_CONFIG_CAPABILITY`, `ViewConfigPermissionDeniedError` and `isViewConfigPermissionDeniedError`. A class that implements `DataSource` and keeps an `updateViewConfig` method still compiles, but nothing calls the method any more; an object literal annotated as `DataSource` that carries it is refused as an unknown property. Code that calls `updateViewConfig` through a `DataSource` or an `ObjectStackAdapter`, or imports one of the gate names, no longer compiles. To change a view for everyone, save the view: `createView` / `updateView` on the data source, or the console's view editor, which writes through the runtime metadata seam.
|
|
205
|
+
|
|
206
|
+
Since objectui#12418 and objectui#12474, the toolbar's sort, column layout, density and Hide Fields are each user's own list state, so the toolbar write had no caller. The view editor's explicit save is now the one write path to the shared view, and it is unchanged.
|
|
207
|
+
|
|
208
|
+
Personalization rows that earlier consoles wrote into `/meta/view` stay readable: the overlay marker, `narrowPersonalizationOverlay` and `listViews()` exclusion still apply to them. Nothing new writes such a row.
|
|
209
|
+
|
|
210
|
+
`@object-ui/i18n` drops `console.objectView.viewConfigPermissionDenied` from all ten packs. It was the toast the retired write raised when the gate refused it. The other packages change only in comments and tests that named the retired path.
|
|
211
|
+
- 655e897: `useActionTextLocalizer` resolves every `I18nLabel` copy an action declares (objectui#12757). It used to collapse a per-locale map only for `label` and `successMessage`, and only when the action had a `name`. A `confirmText` or `errorMessage` map, or any map on a nameless action, such as an inline `element:button` action, reached the action runner as an object, so the confirm prompt received an object and the toasts fell back to the runner's generic copy.
|
|
212
|
+
|
|
213
|
+
The localizer now collapses `label`, `confirmText`, `successMessage` and `errorMessage` to the active language on every action, named or not. A translation-bundle entry for a named action still wins over the collapsed copy. `errorMessage` has no bundle key, so the collapse is all it gets. An action whose copy is already plain text comes back unchanged.
|
|
214
|
+
|
|
215
|
+
Clause-②: no. The hook's signature and the package entry are unchanged; no export, prop or i18n key is added or removed.
|
|
216
|
+
- 9753811: Page element blocks draw their loading, empty and error defaults in the page's language (objectui#12889).
|
|
217
|
+
|
|
218
|
+
- **`element:repeater`.** While its query runs it shows the `common.loading` text ("Loading…", "加载中…") instead of an English literal. With no rows it shows `common.noData` ("No data"; it read "No records" before), and when the query fails with no message it shows `list.loadErrorTitle` ("Couldn’t load records"). An authored `emptyText` still wins, and a failure's own message is still shown as thrown.
|
|
219
|
+
- **`element:number`.** While its aggregate runs it draws a skeleton bar the height of the number's line instead of a bare `…` glyph. The bar is a status region named by `common.loading`.
|
|
220
|
+
- **The saved-view placeholder** (`ElementDataSourceLoadingPanel`, drawn by every block bound through a named `view` while it resolves) reads `common.loading` instead of an English "Loading view…".
|
|
221
|
+
|
|
222
|
+
No language-pack key, prop or export is added: all four keys already exist in every pack.
|
|
223
|
+
- 1e6d83b: Data-bound blocks title their "data source could not be resolved" panel in the page's language (objectui#12920, the family of objectui#12910). The panel shows when a block's `dataSource.view` names a view its object does not have. Each block's title now reads `@object-ui/i18n` through `useObjectTranslation`, with the `en` pack's value as the inline default, so a page with no `I18nProvider` draws the same English it drew before.
|
|
224
|
+
|
|
225
|
+
- **Plugin blocks.** `object-calendar`, `object-chart`, `object-metric`, `object-pivot`, `detail-view`, `record:related_list`, `object-form`, `embeddable-form`, `object-master-detail-form`, `record:line_items`, `object-gantt`, `object-grid`, `object-kanban`, `list-view`, `object-map` and `object-timeline` read one `element.KIND.sourceUnresolved` key per block kind. `object-metric` reads `element.number.sourceUnresolved`, the key `element:number` already reads for the same sentence. The three forms share `element.form.sourceUnresolved`. `record:related_list`'s panel for a failed `parentDataSource` read reads `element.relatedList.parentUnreadable` ("This related list’s parent record could not be read").
|
|
226
|
+
- **`@object-ui/react` panel defaults.** `ElementDataSourceErrorPanel` with no `title` reads `element.component.sourceUnresolved`, and `NoDataSourcePanel` with no `title` reads `element.component.noDataSource`. A passed `title` still wins, an empty string included. Props and markup do not change.
|
|
227
|
+
|
|
228
|
+
Clause-②: yes
|
|
229
|
+
|
|
230
|
+
The new keys in `@object-ui/i18n` widen its exported `TranslationKeys`. No prop, input or export of these packages changes.
|
|
231
|
+
- 988aa9f: Charts and dataset widgets read their object's metadata through the data source, so the widgets of one dashboard ask for one object's metadata once (objectui#13039).
|
|
232
|
+
|
|
233
|
+
The chart's category colours and dimension labels come from the bound object's field options. It read them with its own request to `/api/v1/meta/object/NAME`, outside the data source's metadata cache, so every chart over one object sent one more request for the same document. The chart now reads it through the data source's `getObjectSchema` when one is in scope: the read that its own group-by labels, the metric tile and the data table already use, and that the ObjectStack adapter joins while it is in flight. With no data source, or one that cannot answer `getObjectSchema`, the chart reads the document directly as before.
|
|
234
|
+
|
|
235
|
+
The dataset label hook in `@object-ui/react` (`useDatasetDimensionMeta`, behind `useDatasetDimensionLabels`) made the same per-widget request, one for every non-metric dataset widget on a dashboard and for the dataset report block. It now reads through the `SchemaRendererProvider`'s data source in the same way when that source answers `getObjectSchema`, and reads the document directly otherwise.
|
|
236
|
+
|
|
237
|
+
Colours, labels and dotted dimension paths resolve as they did. Nothing is added to the package entry.
|
|
238
|
+
- d11174a: A list's `addRecord` Add button opens the create form on a console page and on the console's object list (objectui#13089).
|
|
239
|
+
|
|
240
|
+
- **Page `list-view` nodes.** The console's page host now serves the record-form create to a list that names no `relationshipField` and has no parent: a page `list-view` node. So `addRecord: { enabled: true }` draws its Add button, and a click opens the create form for the listed object. A related list whose parent did not resolve is still served nothing, so it draws no "+ New" that would open a child form linked to no parent. No Edit, Delete or row click is served to a list without a parent.
|
|
241
|
+
- **`list-view.addRecord` is a published input** of the `list-view` and `list` registrations. `enabled` and `position` are read; `mode` and `formView` are not.
|
|
242
|
+
- **The console's object list.** A saved view that declares `addRecord.enabled` used to draw an Add button whose click did nothing, also for a viewer who may not create. The button now opens the header New's create, and is withheld wherever that New is not offered or is greyed.
|
|
243
|
+
- **`editMode: 'page'`.** A create linked to no parent, from the record-actions bridge, now opens an `editMode: 'page'` object's full-page create route, as the object list does, instead of the overlay.
|
|
244
|
+
- **`ResolveRelatedRecordActionsInput`** (`@object-ui/react`) documents what an input without `relationshipField` asks for: an object-scoped list's handlers. No type or member changes.
|
|
245
|
+
- Updated dependencies [18d7b48]
|
|
246
|
+
- Updated dependencies [172acc3]
|
|
247
|
+
- Updated dependencies [f0496bd]
|
|
248
|
+
- Updated dependencies [c4c506b]
|
|
249
|
+
- Updated dependencies [9db9ff3]
|
|
250
|
+
- Updated dependencies [d92b2a1]
|
|
251
|
+
- Updated dependencies [92f4e2b]
|
|
252
|
+
- Updated dependencies [b10c68e]
|
|
253
|
+
- Updated dependencies [bdc9049]
|
|
254
|
+
- Updated dependencies [e8c0b96]
|
|
255
|
+
- Updated dependencies [b92329c]
|
|
256
|
+
- Updated dependencies [2e818d0]
|
|
257
|
+
- Updated dependencies [fd060f0]
|
|
258
|
+
- Updated dependencies [8b14aec]
|
|
259
|
+
- Updated dependencies [2abec3a]
|
|
260
|
+
- Updated dependencies [9dfaca6]
|
|
261
|
+
- Updated dependencies [7b17705]
|
|
262
|
+
- Updated dependencies [fc3c2cc]
|
|
263
|
+
- Updated dependencies [f9f4a62]
|
|
264
|
+
- Updated dependencies [848ba0e]
|
|
265
|
+
- Updated dependencies [57d82cb]
|
|
266
|
+
- Updated dependencies [de96f3d]
|
|
267
|
+
- Updated dependencies [9ca3cac]
|
|
268
|
+
- Updated dependencies [c910630]
|
|
269
|
+
- Updated dependencies [ce464d9]
|
|
270
|
+
- Updated dependencies [e6dcd85]
|
|
271
|
+
- Updated dependencies [96fcf30]
|
|
272
|
+
- Updated dependencies [834c559]
|
|
273
|
+
- Updated dependencies [22b503c]
|
|
274
|
+
- Updated dependencies [da35453]
|
|
275
|
+
- Updated dependencies [d50f724]
|
|
276
|
+
- Updated dependencies [17acfbb]
|
|
277
|
+
- Updated dependencies [6be0f7a]
|
|
278
|
+
- Updated dependencies [4590363]
|
|
279
|
+
- Updated dependencies [89cc738]
|
|
280
|
+
- Updated dependencies [c0862c1]
|
|
281
|
+
- Updated dependencies [c0862c1]
|
|
282
|
+
- Updated dependencies [c0862c1]
|
|
283
|
+
- Updated dependencies [c0862c1]
|
|
284
|
+
- Updated dependencies [c0862c1]
|
|
285
|
+
- Updated dependencies [ded4494]
|
|
286
|
+
- Updated dependencies [d172f63]
|
|
287
|
+
- Updated dependencies [4c0de52]
|
|
288
|
+
- Updated dependencies [a80fef7]
|
|
289
|
+
- Updated dependencies [3bf8894]
|
|
290
|
+
- Updated dependencies [b9814b3]
|
|
291
|
+
- Updated dependencies [4a9fe31]
|
|
292
|
+
- Updated dependencies [6d8bf0c]
|
|
293
|
+
- Updated dependencies [5dff027]
|
|
294
|
+
- Updated dependencies [1e1f09e]
|
|
295
|
+
- Updated dependencies [455c646]
|
|
296
|
+
- Updated dependencies [f34e877]
|
|
297
|
+
- Updated dependencies [f34e877]
|
|
298
|
+
- Updated dependencies [7ebff39]
|
|
299
|
+
- Updated dependencies [054fd84]
|
|
300
|
+
- Updated dependencies [5275d1f]
|
|
301
|
+
- Updated dependencies [74add0c]
|
|
302
|
+
- Updated dependencies [aaba865]
|
|
303
|
+
- Updated dependencies [f1781be]
|
|
304
|
+
- Updated dependencies [fbad078]
|
|
305
|
+
- Updated dependencies [45d5853]
|
|
306
|
+
- Updated dependencies [2312bd9]
|
|
307
|
+
- Updated dependencies [6d5eb34]
|
|
308
|
+
- Updated dependencies [c5406c2]
|
|
309
|
+
- Updated dependencies [c5406c2]
|
|
310
|
+
- Updated dependencies [d99b731]
|
|
311
|
+
- Updated dependencies [2571a3e]
|
|
312
|
+
- Updated dependencies [2a48bd4]
|
|
313
|
+
- Updated dependencies [8a55f0c]
|
|
314
|
+
- Updated dependencies [c7b30bd]
|
|
315
|
+
- Updated dependencies [20c6d35]
|
|
316
|
+
- Updated dependencies [417e245]
|
|
317
|
+
- Updated dependencies [69bca0a]
|
|
318
|
+
- Updated dependencies [023f00d]
|
|
319
|
+
- Updated dependencies [158c75d]
|
|
320
|
+
- Updated dependencies [7525045]
|
|
321
|
+
- Updated dependencies [5af42db]
|
|
322
|
+
- Updated dependencies [3c0f806]
|
|
323
|
+
- Updated dependencies [1071393]
|
|
324
|
+
- Updated dependencies [5f75cfa]
|
|
325
|
+
- Updated dependencies [6757a93]
|
|
326
|
+
- Updated dependencies [b7cd5c8]
|
|
327
|
+
- Updated dependencies [43e1505]
|
|
328
|
+
- Updated dependencies [dc6d28e]
|
|
329
|
+
- Updated dependencies [c0c2f79]
|
|
330
|
+
- Updated dependencies [0665c3b]
|
|
331
|
+
- Updated dependencies [d2500d8]
|
|
332
|
+
- Updated dependencies [e723f58]
|
|
333
|
+
- Updated dependencies [82bb1d5]
|
|
334
|
+
- Updated dependencies [b231607]
|
|
335
|
+
- Updated dependencies [b231607]
|
|
336
|
+
- Updated dependencies [466a219]
|
|
337
|
+
- Updated dependencies [6fb281d]
|
|
338
|
+
- Updated dependencies [54159d3]
|
|
339
|
+
- Updated dependencies [d48071e]
|
|
340
|
+
- Updated dependencies [fa778e6]
|
|
341
|
+
- Updated dependencies [334f0cf]
|
|
342
|
+
- Updated dependencies [c08c933]
|
|
343
|
+
- Updated dependencies [c4dd707]
|
|
344
|
+
- Updated dependencies [c4dd707]
|
|
345
|
+
- Updated dependencies [7578323]
|
|
346
|
+
- Updated dependencies [38bb373]
|
|
347
|
+
- Updated dependencies [923504f]
|
|
348
|
+
- Updated dependencies [10aba37]
|
|
349
|
+
- Updated dependencies [5d3f437]
|
|
350
|
+
- Updated dependencies [51c661e]
|
|
351
|
+
- Updated dependencies [7af0ab3]
|
|
352
|
+
- Updated dependencies [9f282ef]
|
|
353
|
+
- Updated dependencies [fd4872f]
|
|
354
|
+
- Updated dependencies [f0532d8]
|
|
355
|
+
- Updated dependencies [cea429b]
|
|
356
|
+
- Updated dependencies [3092aca]
|
|
357
|
+
- Updated dependencies [82e5f53]
|
|
358
|
+
- Updated dependencies [d81e460]
|
|
359
|
+
- Updated dependencies [40cb13b]
|
|
360
|
+
- Updated dependencies [8106db1]
|
|
361
|
+
- Updated dependencies [068a540]
|
|
362
|
+
- Updated dependencies [ca45c6d]
|
|
363
|
+
- Updated dependencies [093d55b]
|
|
364
|
+
- Updated dependencies [b64fda3]
|
|
365
|
+
- Updated dependencies [a8051d6]
|
|
366
|
+
- Updated dependencies [866763b]
|
|
367
|
+
- Updated dependencies [524136e]
|
|
368
|
+
- Updated dependencies [2b06a91]
|
|
369
|
+
- Updated dependencies [6f3299f]
|
|
370
|
+
- Updated dependencies [d12bc5f]
|
|
371
|
+
- Updated dependencies [065a1cf]
|
|
372
|
+
- Updated dependencies [f2b17c6]
|
|
373
|
+
- Updated dependencies [52d6194]
|
|
374
|
+
- Updated dependencies [23bf859]
|
|
375
|
+
- Updated dependencies [1c72d77]
|
|
376
|
+
- Updated dependencies [dbc8c11]
|
|
377
|
+
- Updated dependencies [2b4d3f1]
|
|
378
|
+
- Updated dependencies [d75f212]
|
|
379
|
+
- Updated dependencies [37db09f]
|
|
380
|
+
- Updated dependencies [ff9df88]
|
|
381
|
+
- Updated dependencies [919d5cd]
|
|
382
|
+
- Updated dependencies [431cece]
|
|
383
|
+
- Updated dependencies [cfbca7f]
|
|
384
|
+
- Updated dependencies [caac3b2]
|
|
385
|
+
- Updated dependencies [a2225f9]
|
|
386
|
+
- Updated dependencies [a8e5b73]
|
|
387
|
+
- Updated dependencies [d9d9d98]
|
|
388
|
+
- Updated dependencies [21f9577]
|
|
389
|
+
- Updated dependencies [9b82ced]
|
|
390
|
+
- Updated dependencies [3821a3a]
|
|
391
|
+
- Updated dependencies [3eb3ec1]
|
|
392
|
+
- Updated dependencies [92c2a69]
|
|
393
|
+
- Updated dependencies [646caea]
|
|
394
|
+
- Updated dependencies [8ed7e5a]
|
|
395
|
+
- Updated dependencies [6c4d00d]
|
|
396
|
+
- Updated dependencies [db8ce2f]
|
|
397
|
+
- Updated dependencies [f0e760a]
|
|
398
|
+
- Updated dependencies [a5bb7ac]
|
|
399
|
+
- Updated dependencies [f78efdd]
|
|
400
|
+
- Updated dependencies [8a8bcf3]
|
|
401
|
+
- Updated dependencies [f74638c]
|
|
402
|
+
- Updated dependencies [8614705]
|
|
403
|
+
- Updated dependencies [619e3f7]
|
|
404
|
+
- Updated dependencies [ca7a4c3]
|
|
405
|
+
- Updated dependencies [f62b6ff]
|
|
406
|
+
- Updated dependencies [efa9cb4]
|
|
407
|
+
- Updated dependencies [d66d7e8]
|
|
408
|
+
- Updated dependencies [15d8ca6]
|
|
409
|
+
- Updated dependencies [378896d]
|
|
410
|
+
- Updated dependencies [9d857c9]
|
|
411
|
+
- Updated dependencies [670ea10]
|
|
412
|
+
- Updated dependencies [ff215d9]
|
|
413
|
+
- Updated dependencies [33ee9de]
|
|
414
|
+
- Updated dependencies [4839f5c]
|
|
415
|
+
- Updated dependencies [a23e804]
|
|
416
|
+
- Updated dependencies [36e2f7b]
|
|
417
|
+
- Updated dependencies [ac59073]
|
|
418
|
+
- Updated dependencies [44cb469]
|
|
419
|
+
- Updated dependencies [3bcf314]
|
|
420
|
+
- Updated dependencies [c999d4c]
|
|
421
|
+
- Updated dependencies [260ef71]
|
|
422
|
+
- Updated dependencies [8d80845]
|
|
423
|
+
- Updated dependencies [35ef750]
|
|
424
|
+
- Updated dependencies [64acb7e]
|
|
425
|
+
- Updated dependencies [4ff5b6b]
|
|
426
|
+
- Updated dependencies [473e5a0]
|
|
427
|
+
- Updated dependencies [b279016]
|
|
428
|
+
- Updated dependencies [bb6c38c]
|
|
429
|
+
- Updated dependencies [26323c4]
|
|
430
|
+
- Updated dependencies [2727527]
|
|
431
|
+
- Updated dependencies [3da39ae]
|
|
432
|
+
- Updated dependencies [2cfdc99]
|
|
433
|
+
- Updated dependencies [1e6d83b]
|
|
434
|
+
- Updated dependencies [6058bf8]
|
|
435
|
+
- Updated dependencies [c219165]
|
|
436
|
+
- Updated dependencies [fb501bc]
|
|
437
|
+
- Updated dependencies [30083da]
|
|
438
|
+
- Updated dependencies [7f9cc37]
|
|
439
|
+
- Updated dependencies [025130c]
|
|
440
|
+
- Updated dependencies [76f91f8]
|
|
441
|
+
- Updated dependencies [ea34d9b]
|
|
442
|
+
- Updated dependencies [8aa8e3e]
|
|
443
|
+
- Updated dependencies [cb80001]
|
|
444
|
+
- Updated dependencies [2493e85]
|
|
445
|
+
- Updated dependencies [a928aaa]
|
|
446
|
+
- Updated dependencies [47508f3]
|
|
447
|
+
- Updated dependencies [61ed5ad]
|
|
448
|
+
- Updated dependencies [1b94d50]
|
|
449
|
+
- Updated dependencies [6f877f1]
|
|
450
|
+
- Updated dependencies [65fe4c2]
|
|
451
|
+
- Updated dependencies [1ce0711]
|
|
452
|
+
- Updated dependencies [fb85637]
|
|
453
|
+
- Updated dependencies [cd4623d]
|
|
454
|
+
- Updated dependencies [9f1dd79]
|
|
455
|
+
- Updated dependencies [df71568]
|
|
456
|
+
- Updated dependencies [cbac9d7]
|
|
457
|
+
- Updated dependencies [9eb1479]
|
|
458
|
+
- Updated dependencies [74e37aa]
|
|
459
|
+
- Updated dependencies [961b69f]
|
|
460
|
+
- Updated dependencies [52907d7]
|
|
461
|
+
- Updated dependencies [f466b0a]
|
|
462
|
+
- Updated dependencies [673a71c]
|
|
463
|
+
- Updated dependencies [616df65]
|
|
464
|
+
- Updated dependencies [58798ec]
|
|
465
|
+
- Updated dependencies [8803ca5]
|
|
466
|
+
- Updated dependencies [e70c21d]
|
|
467
|
+
- Updated dependencies [06be396]
|
|
468
|
+
- Updated dependencies [7c05f21]
|
|
469
|
+
- Updated dependencies [daeb77f]
|
|
470
|
+
- Updated dependencies [eb4552e]
|
|
471
|
+
- Updated dependencies [3c3115e]
|
|
472
|
+
- Updated dependencies [55e90fd]
|
|
473
|
+
- Updated dependencies [9b75509]
|
|
474
|
+
- Updated dependencies [b13ea3c]
|
|
475
|
+
- Updated dependencies [d7e9e9a]
|
|
476
|
+
- Updated dependencies [cf62edf]
|
|
477
|
+
- Updated dependencies [0253416]
|
|
478
|
+
- Updated dependencies [5d77c09]
|
|
479
|
+
- Updated dependencies [3fd8625]
|
|
480
|
+
- Updated dependencies [1473757]
|
|
481
|
+
- Updated dependencies [d73d987]
|
|
482
|
+
- Updated dependencies [12ff256]
|
|
483
|
+
- Updated dependencies [12ff256]
|
|
484
|
+
- Updated dependencies [26b0bd2]
|
|
485
|
+
- Updated dependencies [d328698]
|
|
486
|
+
- Updated dependencies [d328698]
|
|
487
|
+
- Updated dependencies [b4e0787]
|
|
488
|
+
- Updated dependencies [1b2d016]
|
|
489
|
+
- Updated dependencies [088e0f7]
|
|
490
|
+
- Updated dependencies [78b07f4]
|
|
491
|
+
- Updated dependencies [f962cdc]
|
|
492
|
+
- Updated dependencies [b403bb3]
|
|
493
|
+
- Updated dependencies [8a25fee]
|
|
494
|
+
- Updated dependencies [12dc7b4]
|
|
495
|
+
- @object-ui/types@18.0.0
|
|
496
|
+
- @object-ui/core@18.0.0
|
|
497
|
+
- @object-ui/i18n@18.0.0
|
|
498
|
+
- @object-ui/data-objectstack@18.0.0
|
|
499
|
+
|
|
3
500
|
## 17.7.0
|
|
4
501
|
|
|
5
502
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -131,10 +131,11 @@ declare const schema: DeclaredNode
|
|
|
131
131
|
|
|
132
132
|
<SchemaRendererProvider
|
|
133
133
|
dataSource={adapter}
|
|
134
|
-
// Optional: host-authenticated fetch
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
134
|
+
// Optional: host-authenticated fetch the renderers use for their own reads
|
|
135
|
+
// of the host's API (chart metadata, dataset dimension labels, permission
|
|
136
|
+
// probes), so they carry the same credentials (Authorization, tenant,
|
|
137
|
+
// locale headers) as the native data channel. When omitted, those reads
|
|
138
|
+
// fall back to the bare global fetch (cookies only).
|
|
138
139
|
apiFetch={authenticatedFetch}
|
|
139
140
|
>
|
|
140
141
|
<SchemaRenderer schema={schema} />
|
|
@@ -216,6 +217,15 @@ const ObjectGridRenderer = elementDataSourceBlock<FC<{ schema: BaseSchema }>>(({
|
|
|
216
217
|
))
|
|
217
218
|
```
|
|
218
219
|
|
|
220
|
+
**Say when the placement cannot draw anything.** Two boolean props let the call
|
|
221
|
+
site, which knows its block's other record sources, ask the gate to answer instead
|
|
222
|
+
of mounting an empty block. `requiresDataSource` draws a "no data source" panel
|
|
223
|
+
when no adapter resolves. `requiresObject` draws a short "No object named: set
|
|
224
|
+
objectName or dataSource.object." hint when the node names its object in neither
|
|
225
|
+
place, read after the binding lands on the mapping's object key, so a node bound
|
|
226
|
+
by `dataSource.object` never sees it (objectui#11605). Leave either one false for
|
|
227
|
+
a placement that draws from inline rows or another source the block reads.
|
|
228
|
+
|
|
219
229
|
**Wrap the registered renderer in `elementDataSourceBlock`.** It is what makes
|
|
220
230
|
`ComponentRegistry.register` emit the `dataSource` input on that block's
|
|
221
231
|
authoring surface, so the key the gate READS is also the key the manifest, the
|
|
@@ -250,6 +260,21 @@ That form still reads `dataSource`, so it still owes the seam: mark the renderer
|
|
|
250
260
|
at its registration, `register('x', elementDataSourceBlock(XRenderer), { … })` —
|
|
251
261
|
again importing `elementDataSourceBlock` from `@object-ui/core`.
|
|
252
262
|
|
|
263
|
+
### useElementApiDataSource — the API binding
|
|
264
|
+
|
|
265
|
+
`SchemaRenderer` honours the spec's API binding of a page element,
|
|
266
|
+
`dataSource: { provider: 'api', read: { url }, path? }`, on every node: it reads
|
|
267
|
+
the same-origin `url` with `GET` through the provider's `apiFetch` (the global
|
|
268
|
+
`fetch` when none is given), selects `path` from the answer, and binds the value
|
|
269
|
+
as `data` in the node's `${…}` holes and `visibleWhen` — and in its subtree's.
|
|
270
|
+
A binding the spec refuses (a cross-origin `url`, a credential key) is refused
|
|
271
|
+
with the spec's message and nothing is read; a failed read or an empty `path`
|
|
272
|
+
draws an error panel in place of the node.
|
|
273
|
+
|
|
274
|
+
`useElementApiDataSource(schema)` is the hook behind it, exported for renderers
|
|
275
|
+
that need the same reading; `selectElementApiPath` and `readElementApi` are its
|
|
276
|
+
pure halves.
|
|
277
|
+
|
|
253
278
|
### useSettledSchema
|
|
254
279
|
|
|
255
280
|
The settled-schema RESOLUTION half, shared by every view that gates a record
|
|
@@ -421,6 +446,66 @@ This is not the reader `SchemaRenderer` applies to a node's FLAT `ariaLabel`,
|
|
|
421
446
|
which is objectui's keyed `{ key, defaultValue }` form. Each resolver returns
|
|
422
447
|
nothing useful for the other's shape, so the two stay separate (objectui#4580).
|
|
423
448
|
|
|
449
|
+
### usePrintPage / PrintPageProvider
|
|
450
|
+
|
|
451
|
+
`usePrintPage()` returns the `print` declaration of the page the component
|
|
452
|
+
renders in, or `null` outside a print page (objectui#11958). `PageRenderer` in
|
|
453
|
+
`@object-ui/components` mounts `PrintPageProvider` for a page whose `print` is
|
|
454
|
+
an object. A block that draws only part of its data on screen reads it so that
|
|
455
|
+
a printed copy does not drop data in silence:
|
|
456
|
+
|
|
457
|
+
```tsx
|
|
458
|
+
import type { ReactNode } from 'react'
|
|
459
|
+
import { usePrintPage } from '@object-ui/react'
|
|
460
|
+
|
|
461
|
+
function Section({ collapsed, children }: { collapsed: boolean; children: ReactNode }) {
|
|
462
|
+
// A collapsed section never reaches paper, so a print page draws it open.
|
|
463
|
+
const open = usePrintPage() !== null || !collapsed
|
|
464
|
+
return open ? <section>{children}</section> : null
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### RelatedRecordActionsProvider / useRelatedRecordActions
|
|
469
|
+
|
|
470
|
+
The host's navigation seam for low-level renderers that have no router. The
|
|
471
|
+
host (the console's record, list and custom pages) publishes a
|
|
472
|
+
`RelatedRecordActionsValue`; renderers read it with `useRelatedRecordActions()`,
|
|
473
|
+
which returns `null` when no host provides one.
|
|
474
|
+
|
|
475
|
+
- `resolve(input)` returns the CRUD and action handlers for a related list.
|
|
476
|
+
- `recordHref(objectName, recordId)` / `openRecord(...)` address one record's
|
|
477
|
+
page: a document href for a real anchor, and the SPA navigation a plain left
|
|
478
|
+
click uses.
|
|
479
|
+
- `listHref(objectName, viewName?)` / `openList(...)` address an object's list
|
|
480
|
+
page, or one of its saved views when `viewName` is given. The compact list a
|
|
481
|
+
page draws in a narrow region links "View all" through them. They take an
|
|
482
|
+
object and a view name only: a caller cannot hand them a filter, columns or a
|
|
483
|
+
sort to encode.
|
|
484
|
+
|
|
485
|
+
Every member but `resolve` is optional. An absent member, or one that answers
|
|
486
|
+
`null`, means the host cannot route there, and the renderer draws no link.
|
|
487
|
+
|
|
488
|
+
```tsx
|
|
489
|
+
import type { ReactNode } from 'react'
|
|
490
|
+
import { RelatedRecordActionsProvider } from '@object-ui/react'
|
|
491
|
+
import type { RelatedRecordActionsValue } from '@object-ui/react'
|
|
492
|
+
|
|
493
|
+
declare const navigate: (to: string) => void
|
|
494
|
+
|
|
495
|
+
const listPath = (objectName: string, viewName?: string): string =>
|
|
496
|
+
viewName ? `/apps/crm/${objectName}/view/${encodeURIComponent(viewName)}` : `/apps/crm/${objectName}`
|
|
497
|
+
|
|
498
|
+
const host: RelatedRecordActionsValue = {
|
|
499
|
+
resolve: () => ({}),
|
|
500
|
+
listHref: (objectName: string, viewName?: string) => listPath(objectName, viewName),
|
|
501
|
+
openList: (objectName: string, viewName?: string) => navigate(listPath(objectName, viewName)),
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export function PageHost({ children }: { children: ReactNode }) {
|
|
505
|
+
return <RelatedRecordActionsProvider value={host}>{children}</RelatedRecordActionsProvider>
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
424
509
|
### ComponentRegistry
|
|
425
510
|
|
|
426
511
|
There is no registry hook: the registry is a process-level singleton exported
|