@object-ui/plugin-detail 4.7.0 → 5.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.
Files changed (24) hide show
  1. package/CHANGELOG.md +391 -0
  2. package/dist/index.js +961 -631
  3. package/dist/index.umd.cjs +3 -3
  4. package/dist/packages/plugin-detail/src/DetailSection.d.ts.map +1 -1
  5. package/dist/packages/plugin-detail/src/DetailView.d.ts.map +1 -1
  6. package/dist/packages/plugin-detail/src/HeaderHighlight.d.ts.map +1 -1
  7. package/dist/packages/plugin-detail/src/HistoryTimeline.d.ts.map +1 -1
  8. package/dist/packages/plugin-detail/src/RecordActivityTimeline.d.ts.map +1 -1
  9. package/dist/packages/plugin-detail/src/RelatedList.d.ts +9 -0
  10. package/dist/packages/plugin-detail/src/RelatedList.d.ts.map +1 -1
  11. package/dist/packages/plugin-detail/src/autoLayout.d.ts +4 -6
  12. package/dist/packages/plugin-detail/src/autoLayout.d.ts.map +1 -1
  13. package/dist/packages/plugin-detail/src/index.d.ts +4 -1
  14. package/dist/packages/plugin-detail/src/index.d.ts.map +1 -1
  15. package/dist/packages/plugin-detail/src/renderers/record-chatter.d.ts.map +1 -1
  16. package/dist/packages/plugin-detail/src/renderers/record-details.d.ts.map +1 -1
  17. package/dist/packages/plugin-detail/src/renderers/record-highlights.d.ts.map +1 -1
  18. package/dist/packages/plugin-detail/src/renderers/record-history.d.ts +16 -0
  19. package/dist/packages/plugin-detail/src/renderers/record-history.d.ts.map +1 -0
  20. package/dist/packages/plugin-detail/src/renderers/record-path.d.ts.map +1 -1
  21. package/dist/packages/plugin-detail/src/renderers/record-related-list.d.ts.map +1 -1
  22. package/dist/packages/plugin-detail/src/synth/buildDefaultPageSchema.d.ts +238 -0
  23. package/dist/packages/plugin-detail/src/synth/buildDefaultPageSchema.d.ts.map +1 -0
  24. package/package.json +12 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,396 @@
1
1
  # @object-ui/plugin-detail
2
2
 
3
+ ## 5.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - bb2ea48: **Phase O.0 — fix: related-list shows wrong records (critical data bug)**
8
+
9
+ `RelatedList` previously called `dataSource.find(api)` with no filter
10
+ when auto-fetching, so every Related tab dumped the entire target
11
+ object table instead of the records that actually reference the
12
+ current parent (e.g. an Account showed every Contact in the system,
13
+ not only contacts of that account).
14
+
15
+ Two coupled fixes:
16
+ 1. `RelatedList` now requires `parentId` + `referenceField` to auto-
17
+ fetch. When both are present it calls `dataSource.find(api,
18
+ { $filter: { [referenceField]: parentId } })`. When either is
19
+ missing it renders the empty state and logs a developer warning —
20
+ never silently fetches the whole object.
21
+ 2. `RelatedCountStore` was sending the probe query as `{ where, limit }`
22
+ which most data-source adapters silently ignored (the codebase
23
+ convention is `{ $filter, $top }`). The tab-count badges were
24
+ therefore showing the global object count, not the parent-scoped
25
+ count. Switched to `$filter` / `$top` to match.
26
+
27
+ `record:related_list` renderer threads `ctx.recordId` through as
28
+ `parentId`; no schema author changes required.
29
+
30
+ **Breaking:** custom callers that depended on `RelatedList` fetching
31
+ the entire object table when `referenceField` is omitted will need to
32
+ either pass `data` explicitly or supply both `parentId` and
33
+ `referenceField`. The previous behaviour was a bug, not a feature.
34
+
35
+ ### Minor Changes
36
+
37
+ - 542cca9: feat(detail): buildDefaultPageSchema synthesizer (Track 3 Phase G slice 1)
38
+
39
+ Pure-function synthesizer that emits a canonical Lightning-style Page
40
+ schema (`page:header` → `record:highlights?` → `record:path?` →
41
+ `page:tabs` → `record:discussion?`) from an object definition and
42
+ optional overrides. Also exports helpers `detectStatusField`,
43
+ `deriveStages`, `deriveHighlightFields`.
44
+
45
+ This is the foundation for converging the default `<DetailView>`
46
+ output with custom Lightning pages. Phase H will wire it into
47
+ `RecordDetailView`'s non-assignedPage branch so the default detail
48
+ page renders through the same `<SchemaRenderer>` pipeline as custom
49
+ pages, inheriting all Phase D/E/F polish automatically.
50
+
51
+ No runtime behaviour change in this slice — synthesizer is exported
52
+ but not yet consumed.
53
+
54
+ - 8930b15: feat(detail): close the gap between Page-assigned and default record detail pages (Track 1)
55
+
56
+ Custom Lightning-style record detail pages (assigned via `assignedPage` /
57
+ `Page` schemas) used to feel meaningfully poorer than the auto-generated
58
+ default detail view. They were missing cross-cutting affordances and
59
+ shipped with English-only tab labels and heavy bordered section cards
60
+ even when the host locale was Chinese. Track 1 closes the visible gap:
61
+ - **app-shell `RecordDetailView`**: the `assignedPage` branch now wears
62
+ the same chrome as the default branch — lifecycle managed-by badge
63
+ and presence avatars in the top-right, `MetadataPanel` debug panel,
64
+ `ActionConfirmDialog` / `ActionParamDialog`, and an auto-appended
65
+ `RecordChatterPanel` at the bottom of the page. Authors opt out of
66
+ the auto-discussion with `assignedPage.disableDiscussion = true`.
67
+ - **plugin-detail `record:details`**: defaults to `inlineEdit: true` so
68
+ fields are click-to-edit just like the default page, and synthesises
69
+ sections with `showBorder: false` by default so a Lightning page
70
+ doesn't double-wrap every block in a heavy Card.
71
+ - **components `page:tabs` / `page:accordion`**: well-known English
72
+ labels (Details / Related / Activity / History / Notes / Files /
73
+ Tasks / Events / Attachments / Chatter / Discussion / Comments /
74
+ Overview / Summary) auto-translate to Chinese (`zh-CN` / `zh-TW`)
75
+ via a built-in dictionary keyed off `document.documentElement.lang`.
76
+ Authors supplying explicit localised labels (string or
77
+ `{ default, zh-CN, ... }`) are not affected.
78
+ - **i18n provider**: applies the initial language to
79
+ `document.documentElement.lang` on mount (i18next does not fire
80
+ `languageChanged` for the bootstrap language), so locale-aware
81
+ renderers downstream see the right value from the first render.
82
+
83
+ - 927187a: Phase N.1 + N.2: visual polish for record detail pages.
84
+
85
+ **N.1 — System actions on full Lightning pages.** `PageHeaderRenderer`
86
+ now merges `headerSystemActions` from `RecordContext` with authored
87
+ actions (authored wins on name/id collision), so full custom pages
88
+ (lead, opportunity, ...) once again show 编辑 / 分享 / 删除 alongside
89
+ their authored actions. `sys_share` and `sys_delete` now use the
90
+ `outline` variant instead of `destructive` to read better in
91
+ multi-button clusters.
92
+
93
+ **N.2 — Hide empty fields by default in synth detail pages.**
94
+ `record:details` defaults `section.hideEmpty` to `true` so synthesized
95
+ pages don't render label graveyards on first load. The "显示 N 个空字段"
96
+ reveal toggle is preserved as the user-facing escape hatch. Authors can
97
+ opt back into showing every field by setting `hideEmpty: false` on the
98
+ section schema.
99
+
100
+ - bae8ba8: Phase N.3 + N.4 + N.6: record detail visual polish.
101
+
102
+ **N.3 — Highlight strip packs left.** `HeaderHighlight` no longer
103
+ stretches a 1-2 chip strip across the full page. Each cell is now
104
+ `min-w-[8rem] max-w-[16rem]` and wraps via flexbox so sparse strips
105
+ sit naturally at the left edge.
106
+
107
+ **N.4 — De-duplicate highlight ↔ body.** `record:details` accepts a
108
+ new `hideFields: string[]` prop. The synth pipeline auto-populates it
109
+ with the highlight-strip field list so a field surfaced in
110
+ `record:highlights` no longer appears a second time in the section
111
+ grid below. Authors can also set it directly on the schema.
112
+
113
+ **N.6 — Tab count badges only show when >0.** `page:tabs` suppresses
114
+ the count pill when the count is exactly 0 (was rendering "0" as a
115
+ muted badge on every empty Activity/History tab).
116
+
117
+ - 8435860: Phase N.4b: highlight↔body dedup now works for hand-authored Lightning
118
+ pages too.
119
+
120
+ Adds a small `HighlightFieldsContext` registry. `record:highlights`
121
+ registers the field names it currently surfaces; `record:details` unions
122
+ that live set into its `hideFieldNames` filter so a field shown in the
123
+ highlight strip is never duplicated in the section grid below.
124
+
125
+ Previously the dedup only fired for synth-generated pages (via the
126
+ `hideFields` prop passed by `buildDefaultPageSchema`). Custom Lightning
127
+ pages (e.g. opportunity) showed `所属客户` both in the strip and in the
128
+ body. The registry-based approach covers both code paths uniformly with
129
+ no schema author work required.
130
+
131
+ The registry uses `useSyncExternalStore` so adding/removing highlights
132
+ notifies consumers without triggering the provider value identity to
133
+ change — avoiding the update-loop that a naive context implementation
134
+ would cause.
135
+
136
+ `RecordDetailView` mounts `<HighlightFieldsProvider>` once per record
137
+ page so the two renderers share state.
138
+
139
+ - bece8ca: Phase N (continued): merge custom record_header actions into `page:header`
140
+ instead of emitting a sibling `record:quick_actions` node. This fixes a
141
+ visual collision on objects (contact, account, ...) that author custom
142
+ record_header actions: previously the floating quick-actions bar
143
+ (`-mt-12` overlay) collided with the system Edit/Share/Delete cluster
144
+ already rendered by `page:header`. Now all action buttons live on a single
145
+ header row.
146
+
147
+ `buildDefaultHeader` accepts an optional `actions` array; `buildDefaultActions`
148
+ remains exported as a sub-builder for authors who explicitly want the
149
+ floating quick-action bar via a slot override.
150
+
151
+ - 77c1877: **Phase O.1 — Cap detail body grid at 2 columns for denser, more legible layout.**
152
+
153
+ The auto-layout previously emitted **3 columns** for sections with 11+
154
+ fields, which on typical desktop widths produced very sparse rows
155
+ (label/value cells filled ~30% of each column, lots of whitespace).
156
+ Capped the inferred maximum at 2 columns so paired fields read as
157
+ cleanly-aligned label/value pairs.
158
+
159
+ Authors who explicitly set `section.columns: 3` retain the 3-column
160
+ layout — only the auto-inference default changed.
161
+
162
+ - b14fe09: Phase P.0 + P.5: tighten record-detail header chrome.
163
+ - `RecordTitleChip` collapses the title row to a single baseline-aligned line — H1, eyebrow object label, copy-id, favorite star — instead of the previous two-row title + subtitle layout.
164
+ - `record:details` extends the highlight-field dedup set to also exclude the title field resolved from `objectSchema.primaryField` (or the standard `name`/`full_name`/`title`/`subject`/`display_name`/`label` fallbacks). Removes the duplicate row that previously echoed the H1 (e.g. "客户名称: Acme Corporation") inside the field grid.
165
+
166
+ - 1911d34: **Phase P.1 — Collapse empty Related-list cards to header-only.**
167
+
168
+ Previously each empty related list rendered a full Card with a 200px+
169
+ "暂无相关记录" empty-state block (header + 32px icon + label +
170
+ optional CTA). With 5-10 related objects mostly empty (common on
171
+ fresh records), the Related tab became a wall of empty cards
172
+ spanning 1500+ vertical pixels.
173
+
174
+ Now: when a related list has zero records (and isn't loading), the
175
+ CardContent is skipped entirely. The header row shows the title +
176
+ `(0)` badge + an inline italic "暂无相关记录" hint + the `+ 新建`
177
+ button (downgraded to ghost variant). A 200px empty card becomes a
178
+ 40px row.
179
+
180
+ Lists with data are unchanged.
181
+
182
+ - ba98039: **Phase P.2 — Collapse CREATE event field-dump in History timeline.**
183
+
184
+ CREATE events render every populated field as a `from: — → to: value`
185
+ diff row. For a record with 20+ fields this turned the History tab
186
+ into a wall of debug-looking `Field: — → value` lines.
187
+
188
+ For `action === 'create'` we now render a single `▸ N fields
189
+ populated` disclosure that expands on click. The expanded view shows
190
+ just `Field: value` (no useless `— →` arrow), since for a creation
191
+ event the "from" is implicitly empty.
192
+
193
+ UPDATE / DELETE events are unchanged — their field diffs are
194
+ genuinely informative.
195
+
196
+ - 86c04f1: Phase Q: unify record-detail visual rhythm — one canvas, one box idiom.
197
+
198
+ Audit revealed three competing chrome treatments fighting on the same
199
+ page: the highlight strip was a filled Card, the discussion panel was
200
+ another filled Card, the related-list cards used heavy borders — while
201
+ the title chip, field grid, and history timeline were naked. The
202
+ result was visually noisy ("有的下划线,有的有边框,有的没边框").
203
+
204
+ This change commits to a single design language:
205
+ - **Highlights** (`HeaderHighlight`): drop the `Card`/`CardContent`
206
+ wrapper. Render as a borderless `<section>` of stat cells with a
207
+ subtle `border-b` separator. The tab strip below now carries the
208
+ only visible anchor in that vertical band.
209
+ - **Discussion / activity feed** (`RecordActivityTimeline`): drop the
210
+ `Card`/`CardHeader`/`CardContent` wrapper. Render as a borderless
211
+ `<section>` with a top divider and a semantic `<header>` for the
212
+ title. Right-side chatter panel still wraps with its own border so
213
+ no chrome is lost in pinned mode.
214
+ - **Related list** (`RelatedList`): keep the card grouping (each is a
215
+ table of child records — earned chrome), but tone it down to
216
+ `border-border/60 bg-transparent` so the boxes recede instead of
217
+ competing with the rest of the canvas.
218
+
219
+ Net effect: title / highlights / details / history sit on one
220
+ continuous bg-background canvas separated by whitespace + hairline
221
+ dividers; related lists are the one (subtle) boxed treatment, justified
222
+ by their tabular content. No internal package APIs changed.
223
+
224
+ - 74962b0: feat(detail): record:discussion schema component + flush accordion variant
225
+ - New `record:discussion` schema type lets authors place the record
226
+ chatter feed anywhere in a custom Page schema. Wired through a
227
+ shared `DiscussionContext` provider on the `assignedPage` branch
228
+ of `RecordDetailView`; auto-append still applies when no explicit
229
+ `record:discussion` / `record:chatter` node is present.
230
+ - `page:accordion` gains a `variant` prop. Default `flush` strips the
231
+ per-item border so accordion sections no longer double-wrap inner
232
+ Card-bearing renderers (RelatedList, etc.). Authors who want the
233
+ old visual pass `variant: 'card'`.
234
+ - `translateLabel` now handles compound labels split by `&`, `and`,
235
+ or `和` (e.g. `Notes & Attachments` → `备注与附件`).
236
+
237
+ - 8b850b5: feat(detail): record:path chevron stepper + record:highlights surface refresh (Phase E)
238
+ - `record:path` now renders Salesforce Lightning-style chevron segments
239
+ (clip-path arrows + overlap) with a primary glow on the current step
240
+ and a check mark on completed steps. On mobile (`<sm`) it falls back
241
+ to a horizontally-scrollable pill row that keeps the same semantics
242
+ but never overflows the viewport.
243
+ - `record:highlights` surface drops the dashed border in favour of a
244
+ solid `bg-muted/40` card with a softer border, so the highlights
245
+ strip reads as a continuous extension of the header chip above it
246
+ rather than a separate framed widget.
247
+
248
+ - fa4c2cb: feat(detail): renderViaSchema opt-in routes default detail through SchemaRenderer (Track 3 Phase G slice 2)
249
+
250
+ When `?renderViaSchema=1` is in the URL, or `objectDef.detail.renderViaSchema === true`,
251
+ `RecordDetailView`'s no-assignedPage branch now synthesizes a canonical
252
+ Page schema (`page:header` → `record:highlights` → `record:path` →
253
+ `page:tabs(record:details)` → `record:discussion`) via
254
+ `buildDefaultPageSchema(objectDef, { sections, highlightFields })` and
255
+ renders it through the existing `<SchemaRenderer>` pipeline.
256
+
257
+ This means every object without a custom assigned page can opt in to
258
+ the same chrome (record-aware header chip, chevron path, flush
259
+ accordion, discussion slot) that custom Lightning pages already enjoy.
260
+
261
+ Changes:
262
+ - `buildDefaultPageSchema` now emits `page:tabs.items` (correct shape
263
+ for the renderer) rather than `tabs`.
264
+ - `PageHeaderRenderer.resolvedTitle` honors `objectSchema.primaryField`
265
+ before the legacy `name/title/display_name/label` fallbacks.
266
+ - `RecordDetailView` rebuilds the synthesized schema with
267
+ `detailSchema.sections` + `highlightFields` at render time so
268
+ `record:details` inherits the same field layout the legacy
269
+ `<DetailView>` would have produced.
270
+
271
+ Flag is intentionally off by default — flipping the default is a
272
+ separate explicit commit after empirical parity validation across
273
+ multiple objects. Known gaps tracked for slice 3: titleFormat
274
+ fallback for objects without `primaryField`, auto Activity / History
275
+ tabs, header-action buttons.
276
+
277
+ - 7213027: feat(detail): slotted record pages (Track 3 Phase I)
278
+
279
+ Introduce `kind: "slotted"` record pages that override one or more
280
+ named slots while letting the default-page synthesizer fill in the
281
+ rest. Authors no longer need to re-author the entire page just to
282
+ customize the header or one tab.
283
+
284
+ **Slot menu (v1):**
285
+ - `header` — replaces `page:header`
286
+ - `actions` — replaces the `record:quick_actions` action bar
287
+ - `highlights` — replaces the chips + chevron path strip
288
+ - `details` — replaces the Details tab body (other tabs stay synthesized)
289
+ - `tabs` — replaces the entire `page:tabs` node (wins over `details`)
290
+ - `discussion` — replaces the inline `record:discussion` footer
291
+
292
+ Each slot is a full replacement at the slot boundary. To compose
293
+ default + custom, call the corresponding `buildDefault*` sub-builder
294
+ (now exported from `@object-ui/plugin-detail`):
295
+ `buildDefaultHeader`, `buildDefaultActions`, `buildDefaultHighlights`,
296
+ `buildDefaultDetails`, `buildDefaultTabs`, `buildDefaultDiscussion`.
297
+
298
+ **Author shape:**
299
+
300
+ ```ts
301
+ {
302
+ type: 'record',
303
+ object: 'account',
304
+ kind: 'slotted',
305
+ slots: {
306
+ header: { type: 'page:header', properties: { ... } },
307
+ },
308
+ }
309
+ ```
310
+
311
+ **API changes:**
312
+ - `PageSchema` (in `@object-ui/types`): adds `kind?: 'full' | 'slotted'`
313
+ (default `'full'`) and `slots?: PageSlotMap`.
314
+ - `usePageAssignment` (in `@object-ui/react`): result now exposes a
315
+ `slots` field populated when the matched page has `kind === 'slotted'`.
316
+ Existing `page` field is unchanged for full pages.
317
+ - `buildDefaultPageSchema` (in `@object-ui/plugin-detail`): accepts an
318
+ `options.slots` map that overrides individual regions at synthesis time.
319
+
320
+ - 34b66bf: feat(detail): synthesize Related / Activity / History tabs + record:quick_actions header (Track 3 Phase G slice 4)
321
+ - `buildDefaultPageSchema` now accepts `headerActions`, `related`,
322
+ `showActivity`, and `history` options. When provided, the synthesizer
323
+ emits a `record:quick_actions` node after `page:header` and appends
324
+ the corresponding tabs to `page:tabs.items` in stable order
325
+ (Details / Related / Activity / History).
326
+ - New `record:history` renderer wraps the existing `HistoryTimeline`,
327
+ reading `entries` / `loading` from the schema. Host owns fetching.
328
+ - `RecordDetailView` forwards `detailSchema.actions[0].actions`,
329
+ `detailSchema.related[]` (unwrapped to `{objectName,relationshipField}`),
330
+ and `detailSchema.history` into the synthesizer call so the
331
+ `renderViaSchema` path reaches parity with the monolithic DetailView
332
+ tab strip and header action bar.
333
+ - 6 new unit tests covering headerActions emit/skip, Related tab
334
+ shape, Activity opt-in, History entries pass-through, and stable
335
+ tab ordering.
336
+
337
+ No behavior change for objects without the `renderViaSchema` opt-in.
338
+
339
+ ### Patch Changes
340
+
341
+ - f16a762: feat(plugin-detail): cross-object detail-page convergence polish (Phase J)
342
+
343
+ Two regression fixes surfaced by the Phase J browser canary across CRM
344
+ record detail pages:
345
+ 1. **`record:path` now localizes stage labels.** The renderer threads
346
+ `useSafeFieldLabel().translateOptions` against the record-context's
347
+ `objectName` + the schema's `statusField`, so picklist labels match the
348
+ active locale instead of leaking English (`New / Contacted / Qualified`)
349
+ onto zh-CN pages. Falls back to the schema's authored labels when no
350
+ i18n provider is mounted.
351
+ 2. **`deriveHighlightFields` skips system + primary fields.** Adds
352
+ `organization_id`, `workspace_id`, `tenant_id`, `created_by`,
353
+ `updated_by`, `deleted_by` to the skip set so the synthesized highlight
354
+ strip stops leaking an orphan "CRM Test's Workspace" chip with no
355
+ visible field label. Also skips the object's `primaryField` and common
356
+ title-field candidates (`name`, `full_name`, `title`, `subject`,
357
+ `display_name`) so the strip never duplicates the page H1.
358
+
359
+ `ObjectDefLike` gains an optional `primaryField` declaration to drive the
360
+ new skip behavior. No spec changes; the field is already part of the
361
+ upstream object schema.
362
+
363
+ - Updated dependencies [8930b15]
364
+ - Updated dependencies [95b6b21]
365
+ - Updated dependencies [ddb08a7]
366
+ - Updated dependencies [765d50f]
367
+ - Updated dependencies [927187a]
368
+ - Updated dependencies [bae8ba8]
369
+ - Updated dependencies [8435860]
370
+ - Updated dependencies [bb2ea48]
371
+ - Updated dependencies [b14fe09]
372
+ - Updated dependencies [a7bef6e]
373
+ - Updated dependencies [74962b0]
374
+ - Updated dependencies [3154334]
375
+ - Updated dependencies [fa4c2cb]
376
+ - Updated dependencies [7213027]
377
+ - @object-ui/components@5.0.0
378
+ - @object-ui/react@5.0.0
379
+ - @object-ui/types@5.0.0
380
+ - @object-ui/fields@5.0.0
381
+ - @object-ui/core@5.0.0
382
+ - @object-ui/permissions@5.0.0
383
+
384
+ ## 4.8.0
385
+
386
+ ### Minor Changes
387
+
388
+ - 06a4066: Mobile: render related sub-tables on record detail pages as a single-column
389
+ gallery of cards (reusing the existing `object-gallery` renderer) instead of
390
+ cramped multi-column tables. Non-first related sections start collapsed on
391
+ mobile to keep the page scannable. Desktop behavior is unchanged. Touch
392
+ targets on the section "+ 新建" button and header are enlarged on mobile.
393
+
3
394
  ## 4.7.0
4
395
 
5
396
  ## 4.6.0