@object-ui/plugin-detail 4.8.0 → 5.0.1

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