@object-ui/plugin-detail 17.6.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 +7755 -0
- package/README.md +557 -71
- package/dist/ActivityTimeline.d.ts.map +1 -1
- package/dist/CommentAttachment.d.ts.map +1 -1
- package/dist/CommentAuthorControls.d.ts +40 -0
- package/dist/CommentAuthorControls.d.ts.map +1 -0
- package/dist/ConcurrentUpdateDialog.d.ts +16 -1
- package/dist/ConcurrentUpdateDialog.d.ts.map +1 -1
- package/dist/DetailSection.d.ts.map +1 -1
- package/dist/DetailSectionNode.d.ts +97 -0
- package/dist/DetailSectionNode.d.ts.map +1 -0
- package/dist/DetailView.d.ts +13 -0
- package/dist/DetailView.d.ts.map +1 -1
- package/dist/HeaderHighlight.d.ts.map +1 -1
- package/dist/HistoryTimeline.d.ts +21 -4
- package/dist/HistoryTimeline.d.ts.map +1 -1
- package/dist/InlineEditSaveBar.d.ts +68 -0
- package/dist/InlineEditSaveBar.d.ts.map +1 -1
- package/dist/InlineFieldInput.d.ts +80 -7
- package/dist/InlineFieldInput.d.ts.map +1 -1
- package/dist/ReactionPicker.d.ts.map +1 -1
- package/dist/RecordActivityTimeline.d.ts +32 -4
- package/dist/RecordActivityTimeline.d.ts.map +1 -1
- package/dist/RecordChatterPanel.d.ts +10 -1
- package/dist/RecordChatterPanel.d.ts.map +1 -1
- package/dist/RecordComments.d.ts +1 -0
- package/dist/RecordComments.d.ts.map +1 -1
- package/dist/RecordDetailDrawer.d.ts +20 -6
- package/dist/RecordDetailDrawer.d.ts.map +1 -1
- package/dist/RecordDetailPanel.d.ts +101 -0
- package/dist/RecordDetailPanel.d.ts.map +1 -0
- package/dist/RecordMetaFooter.d.ts +1 -1
- package/dist/RecordMetaFooter.d.ts.map +1 -1
- package/dist/RelatedList.d.ts +83 -10
- package/dist/RelatedList.d.ts.map +1 -1
- package/dist/ThreadedReplies.d.ts +9 -1
- package/dist/ThreadedReplies.d.ts.map +1 -1
- package/dist/emptiness.d.ts +142 -0
- package/dist/emptiness.d.ts.map +1 -0
- package/dist/fieldEnrichment.d.ts +46 -5
- package/dist/fieldEnrichment.d.ts.map +1 -1
- package/dist/headerColor.d.ts +20 -0
- package/dist/headerColor.d.ts.map +1 -0
- package/dist/index.d.ts +94 -77
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5693 -5487
- package/dist/index.umd.cjs +2 -5
- package/dist/recordPageProvenance.d.ts +39 -0
- package/dist/recordPageProvenance.d.ts.map +1 -0
- package/dist/renderers/record-activity.d.ts.map +1 -1
- package/dist/renderers/record-alert.d.ts +23 -3
- package/dist/renderers/record-alert.d.ts.map +1 -1
- package/dist/renderers/record-alert.readProps.d.ts +40 -0
- package/dist/renderers/record-alert.readProps.d.ts.map +1 -0
- package/dist/renderers/record-chatter.d.ts.map +1 -1
- package/dist/renderers/record-details.d.ts +12 -0
- package/dist/renderers/record-details.d.ts.map +1 -1
- package/dist/renderers/record-highlights.d.ts +10 -0
- package/dist/renderers/record-highlights.d.ts.map +1 -1
- package/dist/renderers/record-history.d.ts +1 -1
- package/dist/renderers/record-history.d.ts.map +1 -1
- package/dist/renderers/record-path.d.ts.map +1 -1
- package/dist/renderers/record-quick-actions.d.ts +26 -6
- package/dist/renderers/record-quick-actions.d.ts.map +1 -1
- package/dist/renderers/record-reference-rail.d.ts +40 -0
- package/dist/renderers/record-reference-rail.d.ts.map +1 -1
- package/dist/renderers/record-related-list.d.ts +51 -7
- package/dist/renderers/record-related-list.d.ts.map +1 -1
- package/dist/renderers/recordActivityFeed.d.ts +343 -33
- package/dist/renderers/recordActivityFeed.d.ts.map +1 -1
- package/dist/renderers/recordBinding.d.ts +180 -0
- package/dist/renderers/recordBinding.d.ts.map +1 -0
- package/dist/renderers/recordComponentAria.d.ts +44 -0
- package/dist/renderers/recordComponentAria.d.ts.map +1 -0
- package/dist/renderers/relatedListActions.d.ts +102 -0
- package/dist/renderers/relatedListActions.d.ts.map +1 -0
- package/dist/summaryChipPercent.d.ts +83 -0
- package/dist/summaryChipPercent.d.ts.map +1 -0
- package/dist/summaryChipRenderers.d.ts +83 -0
- package/dist/summaryChipRenderers.d.ts.map +1 -0
- package/dist/synth/buildDefaultPageSchema.d.ts +188 -21
- package/dist/synth/buildDefaultPageSchema.d.ts.map +1 -1
- package/dist/useDetailTranslation.d.ts.map +1 -1
- package/dist/useRecordEditable.d.ts +4 -1
- package/dist/useRecordEditable.d.ts.map +1 -1
- package/package.json +19 -18
- package/dist/CommentInput.d.ts +0 -24
- package/dist/CommentInput.d.ts.map +0 -1
- package/dist/DiffView.d.ts +0 -24
- package/dist/DiffView.d.ts.map +0 -1
- package/dist/InlineCreateRelated.d.ts +0 -32
- package/dist/InlineCreateRelated.d.ts.map +0 -1
- package/dist/MentionAutocomplete.d.ts +0 -43
- package/dist/MentionAutocomplete.d.ts.map +0 -1
- package/dist/PointInTimeRestore.d.ts +0 -28
- package/dist/PointInTimeRestore.d.ts.map +0 -1
- package/dist/RecordNavigationEnhanced.d.ts +0 -18
- package/dist/RecordNavigationEnhanced.d.ts.map +0 -1
- package/dist/RelationshipGraph.d.ts +0 -23
- package/dist/RelationshipGraph.d.ts.map +0 -1
- package/dist/renderers/PermissionFacetLink.d.ts +0 -38
- package/dist/renderers/PermissionFacetLink.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RecordChatterComponentProps, FeedItem, RecordSubscription } from '@object-ui/types';
|
|
2
|
-
import { FeedFilterMode } from './RecordActivityTimeline';
|
|
2
|
+
import { FeedFilterMode } from './RecordActivityTimeline.js';
|
|
3
3
|
/**
|
|
4
4
|
* ObjectUI
|
|
5
5
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -25,6 +25,10 @@ export interface RecordChatterPanelProps {
|
|
|
25
25
|
onAddReply?: (parentId: string | number, text: string) => void | Promise<void>;
|
|
26
26
|
/** Called when user toggles a reaction */
|
|
27
27
|
onToggleReaction?: (itemId: string | number, emoji: string) => void | Promise<void>;
|
|
28
|
+
/** Edits a comment the viewer wrote; forwarded to the timeline (objectui#12268). */
|
|
29
|
+
onEditComment?: (itemId: string | number, text: string) => void | Promise<void>;
|
|
30
|
+
/** Deletes a comment the viewer wrote; forwarded to the timeline (objectui#12268). */
|
|
31
|
+
onDeleteComment?: (itemId: string | number) => void | Promise<void>;
|
|
28
32
|
/** Subscription state */
|
|
29
33
|
subscription?: RecordSubscription;
|
|
30
34
|
/** Called when user toggles subscription */
|
|
@@ -52,6 +56,11 @@ export interface RecordChatterPanelProps {
|
|
|
52
56
|
url?: string;
|
|
53
57
|
thumbnailUrl?: string;
|
|
54
58
|
}>>;
|
|
59
|
+
/** The feed's activity read was refused; forwarded to the timeline, which
|
|
60
|
+
* shows a no-permission state for it (objectui#11195). */
|
|
61
|
+
activityDenied?: boolean;
|
|
62
|
+
/** The same, for the feed's comment read. */
|
|
63
|
+
commentsDenied?: boolean;
|
|
55
64
|
className?: string;
|
|
56
65
|
}
|
|
57
66
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordChatterPanel.d.ts","sourceRoot":"","sources":["../src/RecordChatterPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElG,OAAO,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"RecordChatterPanel.d.ts","sourceRoot":"","sources":["../src/RecordChatterPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,2BAA2B,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAElG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,qDAAqD;IACrD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,oBAAoB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yCAAyC;IACzC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,uCAAuC;IACvC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpF,oFAAoF;IACpF,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,sFAAsF;IACtF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,yBAAyB;IACzB,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,4CAA4C;IAC5C,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,kBAAkB;IAClB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,iCAAiC;IACjC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;sDACkD;IAClD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9E;oEACgE;IAChE,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,KAAK,CAAC;QACvD,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC,CAAC;IACJ;+DAC2D;IAC3D,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAmMhE,CAAC"}
|
package/dist/RecordComments.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { CommentEntry } from '@object-ui/types';
|
|
|
9
9
|
import * as React from 'react';
|
|
10
10
|
export interface RecordCommentsProps {
|
|
11
11
|
comments: CommentEntry[];
|
|
12
|
+
/** A rejection means the comment was not written: the composer keeps the draft. */
|
|
12
13
|
onAddComment?: (text: string) => void | Promise<void>;
|
|
13
14
|
/** Callback to toggle pin/star on a comment */
|
|
14
15
|
onTogglePin?: (commentId: string | number) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordComments.d.ts","sourceRoot":"","sources":["../src/RecordComments.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"RecordComments.d.ts","sourceRoot":"","sources":["../src/RecordComments.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIrD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,mFAAmF;IACnF,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,+CAA+C;IAC/C,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IACnD,iDAAiD;IACjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAwCD,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgLxD,CAAC"}
|
|
@@ -28,6 +28,21 @@ export interface RecordDetailDrawerProps {
|
|
|
28
28
|
* `min(960px, 60vw)` which fills ~60% of typical desktop viewports
|
|
29
29
|
* (the prior `max-w-2xl` cap felt cramped on wide screens).
|
|
30
30
|
*
|
|
31
|
+
* That default is the single code home of the literal repo-wide: the
|
|
32
|
+
* gantt, kanban and calendar renderers deliberately spell no width and
|
|
33
|
+
* let `undefined` fall through to here. Converging it on the `size: 'lg'`
|
|
34
|
+
* bucket (`min(92vw, 960px)` — up to 53% wider below a 1600px viewport)
|
|
35
|
+
* was RULED AGAINST: objectui#6584, 2026-08-27 — stays on the CSS
|
|
36
|
+
* literal; no bucket convergence. The question is CLOSED, not open. A
|
|
37
|
+
* future move to the bucket is a fresh ruling, with visual-regression
|
|
38
|
+
* evidence across all four surfaces in one stroke.
|
|
39
|
+
*
|
|
40
|
+
* ⚠️ Pixels are unchanged by objectui#9299's shell delegation: the shell
|
|
41
|
+
* treats an authored width as a floor via
|
|
42
|
+
* `max(WIDTH, min(60vw, 880px))`, and for this default that expression
|
|
43
|
+
* reduces to `min(60vw, 960px)` at every viewport — the same value the
|
|
44
|
+
* inline style used to set.
|
|
45
|
+
*
|
|
31
46
|
* Note: when `resizable` is true (the default), this is only used
|
|
32
47
|
* as the initial width — the user's drag-resized width takes over
|
|
33
48
|
* and is persisted to localStorage keyed by `objectName`.
|
|
@@ -57,22 +72,21 @@ export interface RecordDetailDrawerProps {
|
|
|
57
72
|
resizable?: boolean;
|
|
58
73
|
/**
|
|
59
74
|
* Optional URL to the full record page. When provided, the drawer
|
|
60
|
-
* shows an "Open in new tab"
|
|
61
|
-
* URL in a new browser tab. The drawer itself stays open.
|
|
75
|
+
* shows an "Open in new tab" entry in the record header's overflow menu.
|
|
62
76
|
* Typically `/console/apps/{appName}/{objectName}/record/{recordId}`.
|
|
63
77
|
*/
|
|
64
78
|
fullPageHref?: string;
|
|
65
79
|
}
|
|
66
|
-
/** Right-side drawer wrapping {@link
|
|
80
|
+
/** Right-side drawer wrapping {@link RecordDetailPanel} for a single record. */
|
|
67
81
|
export declare function RecordDetailDrawer({ open, onClose, title, record, objectName, recordId, dataSource, objectSchema, width, columns, systemFields, onFieldSave, onDelete, resizable, fullPageHref, }: RecordDetailDrawerProps): React.JSX.Element;
|
|
68
82
|
export default RecordDetailDrawer;
|
|
69
83
|
/**
|
|
70
84
|
* Derive a full record-page URL from the current browser location.
|
|
71
85
|
*
|
|
72
86
|
* Used by plugin-gantt / plugin-calendar / plugin-kanban to populate
|
|
73
|
-
* `
|
|
74
|
-
*
|
|
75
|
-
*
|
|
87
|
+
* `fullPageHref` without each plugin needing direct access to the router.
|
|
88
|
+
* Strips any `/view/{viewId}` suffix so the resulting URL points at the
|
|
89
|
+
* canonical record page.
|
|
76
90
|
*
|
|
77
91
|
* @param objectName - The object name segment in the URL
|
|
78
92
|
* (e.g. `campaign`, `lead`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordDetailDrawer.d.ts","sourceRoot":"","sources":["../src/RecordDetailDrawer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH
|
|
1
|
+
{"version":3,"file":"RecordDetailDrawer.d.ts","sourceRoot":"","sources":["../src/RecordDetailDrawer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,MAAM,WAAW,uBAAuB;IACtC,4CAA4C;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,oFAAoF;IACpF,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAoC,EACpC,OAAW,EACX,YAAoC,EACpC,WAAW,EACX,QAAQ,EACR,SAAgB,EAChB,YAAY,GACb,EAAE,uBAAuB,qBAiCzB;AAED,eAAe,kBAAkB,CAAC;AAElC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAQjG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { DataSource } from '@object-ui/types';
|
|
3
|
+
/**
|
|
4
|
+
* Field names hidden from the quick-look overlay / inline edit form.
|
|
5
|
+
*
|
|
6
|
+
* Scope: this is the OVERLAY allow-list — used to keep the slim panel UI
|
|
7
|
+
* focused on author-defined business fields. The full record detail page
|
|
8
|
+
* (`RecordDetailView`) surfaces audit fields via a compact
|
|
9
|
+
* `<RecordMetaFooter>` (single-line, muted) rather than a heavy panel, so
|
|
10
|
+
* users can still see who/when created or last touched a record.
|
|
11
|
+
*
|
|
12
|
+
* Derived from the shared `SYSTEM_MANAGED_FIELD_NAMES` — the same set the grid's
|
|
13
|
+
* default-column derivation uses — so it stays in lockstep with the fields
|
|
14
|
+
* `applySystemFields` injects (audit `*_at`/`*_by`, the ownership/tenant FKs,
|
|
15
|
+
* soft-delete bookkeeping). Callers can still override via the `systemFields` prop.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_SYSTEM_FIELDS: Set<string>;
|
|
18
|
+
export interface RecordDetailPanelProps {
|
|
19
|
+
/** The record being displayed. */
|
|
20
|
+
record: Record<string, any>;
|
|
21
|
+
/** Logical object name used by the data source. */
|
|
22
|
+
objectName: string;
|
|
23
|
+
/** Record id (string-coerced before issuing update/delete). */
|
|
24
|
+
recordId: string | number;
|
|
25
|
+
/** Active data source — used for inline updates and deletion. */
|
|
26
|
+
dataSource?: DataSource;
|
|
27
|
+
/**
|
|
28
|
+
* Optional objectSchema (as returned by `dataSource.getObjectSchema`).
|
|
29
|
+
* When provided the panel infers field types so dates / picklists /
|
|
30
|
+
* currency render with their proper widgets.
|
|
31
|
+
*/
|
|
32
|
+
objectSchema?: {
|
|
33
|
+
fields?: Record<string, any>;
|
|
34
|
+
} | null;
|
|
35
|
+
/** Number of columns the field grid should use. Default `2`. */
|
|
36
|
+
columns?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Optional override for the SYSTEM_FIELDS filter. Defaults to a
|
|
39
|
+
* standard set (id, timestamps, audit fields).
|
|
40
|
+
*/
|
|
41
|
+
systemFields?: Set<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Persist an inline field edit. Plugins usually update local state
|
|
44
|
+
* here so the panel stays in sync after the network round-trip.
|
|
45
|
+
*/
|
|
46
|
+
onFieldSave?: (field: string, value: unknown) => void | Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Persist record deletion. Plugins are expected to remove the record
|
|
49
|
+
* from their local state; the host is asked to close via `onClose`
|
|
50
|
+
* after this resolves.
|
|
51
|
+
*/
|
|
52
|
+
onDelete?: () => void | Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Dismiss the overlay. Called after a successful delete. The shell owns
|
|
55
|
+
* every other way of closing.
|
|
56
|
+
*/
|
|
57
|
+
onClose?: () => void;
|
|
58
|
+
/**
|
|
59
|
+
* Optional URL to the full record page. When provided, the panel adds an
|
|
60
|
+
* "Open in new tab" entry to `DetailView`'s header overflow menu.
|
|
61
|
+
* Typically `/console/apps/{appName}/{objectName}/record/{recordId}`.
|
|
62
|
+
*/
|
|
63
|
+
fullPageHref?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build `DetailView`'s typed field list from an object schema.
|
|
67
|
+
*
|
|
68
|
+
* Exported because the derivation — not just the JSX — is what the five
|
|
69
|
+
* renderers share; a second hand-written copy is exactly the fork this card
|
|
70
|
+
* exists to remove.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildRecordDetailFields(record: Record<string, any>, objectSchema: {
|
|
73
|
+
fields?: Record<string, any>;
|
|
74
|
+
} | null | undefined, systemFields: Set<string>): Array<Record<string, any>>;
|
|
75
|
+
/**
|
|
76
|
+
* The default overlay width, and the single code home of this literal
|
|
77
|
+
* repo-wide.
|
|
78
|
+
*
|
|
79
|
+
* The gantt, kanban and calendar renderers deliberately spell no `width` of
|
|
80
|
+
* their own and let an unauthored `navigation.width` fall through to this
|
|
81
|
+
* value. Converging it on the `size: 'lg'` bucket (`min(92vw, 960px)` — up to
|
|
82
|
+
* 53% wider below a 1600px viewport) was RULED AGAINST: objectui#6584,
|
|
83
|
+
* 2026-08-27 — stays on the CSS literal; no bucket convergence. The question is
|
|
84
|
+
* CLOSED, not open.
|
|
85
|
+
*
|
|
86
|
+
* ⚠️ It became an EXPORT with objectui#9299. Before that it was
|
|
87
|
+
* `RecordDetailDrawer`'s default parameter, reached by passing `undefined`;
|
|
88
|
+
* the renderers no longer go through that component, so they read the constant
|
|
89
|
+
* instead. ⛔ Do not re-spell the literal at a call site — four copies of a
|
|
90
|
+
* ruled-on number is how the four surfaces drift apart.
|
|
91
|
+
*
|
|
92
|
+
* `NavigationOverlay` treats an authored width as a FLOOR
|
|
93
|
+
* (`max(WIDTH, min(60vw, 880px))`), and for this value that expression reduces
|
|
94
|
+
* to `min(60vw, 960px)` at every viewport — i.e. the same pixels the old
|
|
95
|
+
* inline style set.
|
|
96
|
+
*/
|
|
97
|
+
export declare const RECORD_OVERLAY_DEFAULT_WIDTH = "min(960px, 60vw)";
|
|
98
|
+
/** The record overlay payload — shell-free by construction. */
|
|
99
|
+
export declare function RecordDetailPanel({ record, objectName, recordId, dataSource, objectSchema, columns, systemFields, onFieldSave, onDelete, onClose, fullPageHref, }: RecordDetailPanelProps): React.JSX.Element;
|
|
100
|
+
export default RecordDetailPanel;
|
|
101
|
+
//# sourceMappingURL=RecordDetailPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordDetailPanel.d.ts","sourceRoot":"","sources":["../src/RecordDetailPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,aAAsC,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EACjE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAkG5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAE/D,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAW,EACX,YAAoC,EACpC,WAAW,EACX,QAAQ,EACR,OAAO,EACP,YAAY,GACb,EAAE,sBAAsB,qBAqFxB;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -9,7 +9,7 @@ import * as React from 'react';
|
|
|
9
9
|
export interface RecordMetaFooterProps {
|
|
10
10
|
/** The current record data; expected to contain audit fields when available. */
|
|
11
11
|
data: Record<string, any> | null | undefined;
|
|
12
|
-
/** Resolved object schema (used to read
|
|
12
|
+
/** Resolved object schema (used to read `reference` for created_by/updated_by). */
|
|
13
13
|
objectSchema?: any;
|
|
14
14
|
/** Object name for future i18n hooks (currently unused). */
|
|
15
15
|
objectName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordMetaFooter.d.ts","sourceRoot":"","sources":["../src/RecordMetaFooter.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RecordMetaFooter.d.ts","sourceRoot":"","sources":["../src/RecordMetaFooter.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,mFAAmF;IACnF,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsKD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiE5D,CAAC"}
|
package/dist/RelatedList.d.ts
CHANGED
|
@@ -64,11 +64,27 @@ export interface RelatedListProps {
|
|
|
64
64
|
linkField?: string;
|
|
65
65
|
label?: string;
|
|
66
66
|
};
|
|
67
|
-
/** Callback when a row is clicked (opens record detail) */
|
|
68
|
-
onRowClick?: (row: any) => void;
|
|
69
67
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
* Callback when a row is clicked (opens record detail).
|
|
69
|
+
*
|
|
70
|
+
* TWO parameters since objectui#9357, and the second is not decoration: this
|
|
71
|
+
* prop reaches `useNavigationOverlay` as its `onRowClick`, and `handleClick`
|
|
72
|
+
* invokes it as `onRowClick(record, event)` — the modifier payload a host
|
|
73
|
+
* needs to implement Cmd/Ctrl/middle-click for itself. Declaring one
|
|
74
|
+
* parameter hid the second on the ONE line a host reads. Spelled `any` and
|
|
75
|
+
* not `HandleClickModifiers` for the reason objectui#9341 measured on
|
|
76
|
+
* `ObjectKanbanSchema.onCardClick`: that interface lives in
|
|
77
|
+
* `@object-ui/react`, the published twins in `@object-ui/types` may not name
|
|
78
|
+
* it, and a host that discovered the payload from the implementation
|
|
79
|
+
* annotated it `React.MouseEvent` — which a narrower declaration refuses
|
|
80
|
+
* contravariantly. `BaseSchema`'s own `onClick` / `onChange` / `onSubmit`
|
|
81
|
+
* already use this spelling for exactly this situation.
|
|
82
|
+
*/
|
|
83
|
+
onRowClick?: (row: any, event?: any) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Child-object row actions (`locations` `list_item`, or `record_related`
|
|
86
|
+
* inside a parent record — objectui#11270), already localized by the host.
|
|
87
|
+
* Rendered in each row's overflow menu alongside Edit/Delete.
|
|
72
88
|
*/
|
|
73
89
|
rowActions?: RelatedRowActionDef[];
|
|
74
90
|
/** Execute one of {@link rowActions} against the clicked row. */
|
|
@@ -81,6 +97,26 @@ export interface RelatedListProps {
|
|
|
81
97
|
toolbarActions?: RelatedRowActionDef[];
|
|
82
98
|
/** Execute one of {@link toolbarActions} (no row context). */
|
|
83
99
|
onToolbarAction?: (action: RelatedRowActionDef) => void | Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Field names this list must never show, whatever decided its columns
|
|
102
|
+
* (objectui#9053).
|
|
103
|
+
*
|
|
104
|
+
* The block-level authoring preference `record:related_list` reads as
|
|
105
|
+
* `redactFields`, pushed down to the component that actually decides
|
|
106
|
+
* columns. It used to be applied only where the block could apply it — over
|
|
107
|
+
* the AUTHORED `columns` array — and this component has two more paths that
|
|
108
|
+
* decide columns on their own (`highlightFields` prominence and the
|
|
109
|
+
* heuristic field walk), which that list never reached. Redacting EVERY
|
|
110
|
+
* authored column therefore emptied the array, the empty array read as "no
|
|
111
|
+
* columns were authored", and the derived set brought the redacted field
|
|
112
|
+
* straight back: applying the control maximally switched it off.
|
|
113
|
+
*
|
|
114
|
+
* ⚠️ This is an AUTHORING preference, not the permission boundary. Field
|
|
115
|
+
* security is enforced independently and unconditionally through
|
|
116
|
+
* `perms.checkField(..., 'read')` on every path below; a field that must be
|
|
117
|
+
* unreachable belongs in FLS, not here.
|
|
118
|
+
*/
|
|
119
|
+
redactFields?: string[];
|
|
84
120
|
/** Maximum number of columns to auto-generate. Default 6. */
|
|
85
121
|
maxColumns?: number;
|
|
86
122
|
/** Page size for pagination (enables pagination when set) */
|
|
@@ -104,6 +140,9 @@ export interface RelatedListProps {
|
|
|
104
140
|
* since objectui#3106 they sort the collection rather than the page, so the
|
|
105
141
|
* button row above them would be a second control over the same order.
|
|
106
142
|
*
|
|
143
|
+
* A masked column (a `password` / `secret` field, or any column while the
|
|
144
|
+
* object's field types are still unknown) gets no button (objectui#10728).
|
|
145
|
+
*
|
|
107
146
|
* @default false
|
|
108
147
|
*/
|
|
109
148
|
sortable?: boolean;
|
|
@@ -130,7 +169,12 @@ export interface RelatedListProps {
|
|
|
130
169
|
* second conversion dialect appears.
|
|
131
170
|
*/
|
|
132
171
|
filter?: ViewFilterRule[] | FilterNode;
|
|
133
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
* Enable text filtering. The box keeps a row when a column the list shows
|
|
174
|
+
* contains the term; a masked column (a `password` / `secret` field, or any
|
|
175
|
+
* column while the object's field types are still unknown) and a field no
|
|
176
|
+
* column shows are not searched (objectui#10728).
|
|
177
|
+
*/
|
|
134
178
|
filterable?: boolean;
|
|
135
179
|
/** Whether the card is collapsible */
|
|
136
180
|
collapsible?: boolean;
|
|
@@ -140,15 +184,32 @@ export interface RelatedListProps {
|
|
|
140
184
|
* Foreign-key field name on child records pointing back to the parent.
|
|
141
185
|
* The renderer hides this column from the table and from the schema-derived
|
|
142
186
|
* column list, since the parent record is already implicit context.
|
|
143
|
-
* Used in combination with `parentId` to scope the auto-fetch query
|
|
187
|
+
* Used in combination with `parentId` to scope the auto-fetch query — its
|
|
188
|
+
* ARITY on the child object decides how that condition is compiled, see
|
|
189
|
+
* `parentId` below.
|
|
144
190
|
*/
|
|
145
191
|
referenceField?: string;
|
|
146
192
|
/**
|
|
147
193
|
* Primary-key value of the parent record. When both `parentId` and
|
|
148
|
-
* `referenceField` are set, the auto-fetch query is scoped
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
194
|
+
* `referenceField` are set, the auto-fetch query is scoped to this parent's
|
|
195
|
+
* children so only true children are returned. Without this scope the list
|
|
196
|
+
* would dump the entire target object table.
|
|
197
|
+
*
|
|
198
|
+
* The condition is compiled to match the relationship field's ARITY on the
|
|
199
|
+
* child object (objectui#7299), because the two arities are two different
|
|
200
|
+
* questions about the stored value:
|
|
201
|
+
*
|
|
202
|
+
* - single-valued → `$filter: { [referenceField]: parentId }` — equality,
|
|
203
|
+
* byte for byte what this component has always sent;
|
|
204
|
+
* - `multiple: true` → `$filter: { [referenceField]: { $contains: parentId } }`
|
|
205
|
+
* — MEMBERSHIP, because the stored value is an ARRAY of ids and equality
|
|
206
|
+
* asks whether the whole array IS one id.
|
|
207
|
+
*
|
|
208
|
+
* The verdict is `@objectstack/spec/data`'s own `isMultiValueField`, not a
|
|
209
|
+
* local rule, and it is reached through `@object-ui/core`'s
|
|
210
|
+
* {@link composeParentScopeFilter} — the ONE compiler of this condition,
|
|
211
|
+
* shared with the tab-badge count probe that used to carry a second one
|
|
212
|
+
* (objectui#8882).
|
|
152
213
|
*/
|
|
153
214
|
parentId?: string | number;
|
|
154
215
|
/** Lucide icon name (kebab-case) to render next to the section title. */
|
|
@@ -168,6 +229,18 @@ export interface RelatedListProps {
|
|
|
168
229
|
* `invite_user` (`visible: "features.organization != false"`) hides when its
|
|
169
230
|
* predicate is false. `features`/`user` resolve from the ambient
|
|
170
231
|
* ExpressionProvider scope.
|
|
232
|
+
*
|
|
233
|
+
* The verdict fails CLOSED on a predicate that FAULTS (`throwOnError`), as
|
|
234
|
+
* every action `visible` leg does (objectui#11212, Rider 1 of objectui#4421):
|
|
235
|
+
* a precondition that cannot be evaluated — `current_user.can(…)` before the
|
|
236
|
+
* permissions payload has loaded, an unbound root — hides the button and is
|
|
237
|
+
* reported once, instead of showing an action whose guard is broken. This leg
|
|
238
|
+
* used to fail SOFT to `true`.
|
|
239
|
+
*
|
|
240
|
+
* Whether a gate is DECLARED at all is asked with `hasDeclaredVisibilityGate`,
|
|
241
|
+
* as every other member of the action family asks it (objectui#3812,
|
|
242
|
+
* objectui#11244), never by truthiness: `visible: false` is a declared gate and
|
|
243
|
+
* hides the button, while a blank predicate (`''`, whitespace) is no gate.
|
|
171
244
|
*/
|
|
172
245
|
export declare const RelatedToolbarButton: React.FC<{
|
|
173
246
|
action: RelatedRowActionDef;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RelatedList.d.ts","sourceRoot":"","sources":["../src/RelatedList.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RelatedList.d.ts","sourceRoot":"","sources":["../src/RelatedList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,18 @@ export interface ThreadedRepliesProps {
|
|
|
12
12
|
parentItem: FeedItem;
|
|
13
13
|
/** Reply feed items (children) */
|
|
14
14
|
replies: FeedItem[];
|
|
15
|
-
/** Called when a reply is submitted */
|
|
15
|
+
/** Called when a reply is submitted. A rejection means it was not written: the draft is kept. */
|
|
16
16
|
onAddReply?: (parentId: string | number, text: string) => void | Promise<void>;
|
|
17
17
|
/** Whether to show the reply input */
|
|
18
18
|
showReplyInput?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Stores a new text for a reply the viewer wrote (objectui#12268): a reply
|
|
21
|
+
* is a comment too, and offers its author the same Edit as a root comment,
|
|
22
|
+
* on a reply whose `authoredByViewer` the host set. A rejection keeps the draft.
|
|
23
|
+
*/
|
|
24
|
+
onEditComment?: (itemId: string | number, text: string) => void | Promise<void>;
|
|
25
|
+
/** Deletes a reply the viewer wrote, on the same replies; the host confirms first. */
|
|
26
|
+
onDeleteComment?: (itemId: string | number) => void | Promise<void>;
|
|
19
27
|
className?: string;
|
|
20
28
|
}
|
|
21
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadedReplies.d.ts","sourceRoot":"","sources":["../src/ThreadedReplies.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ThreadedReplies.d.ts","sourceRoot":"","sources":["../src/ThreadedReplies.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKjD,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,UAAU,EAAE,QAAQ,CAAC;IACrB,kCAAkC;IAClC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,iGAAiG;IACjG,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,sFAAsF;IACtF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAmI1D,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Does this cell have anything to render? **THE** definition of emptiness on
|
|
10
|
+
* the `record:details` page (objectui#8376, widened to the whole package by
|
|
11
|
+
* objectui#8394).
|
|
12
|
+
*
|
|
13
|
+
* ## Readers
|
|
14
|
+
*
|
|
15
|
+
* Every band of the record page that draws a placeholder instead of a value, or
|
|
16
|
+
* omits a slot because there is no value, asks THIS — never its own
|
|
17
|
+
* `null | undefined | ''`:
|
|
18
|
+
*
|
|
19
|
+
* - `DetailSection` — `isEmptyValue` (the row filter behind `emptyCount`, the
|
|
20
|
+
* "Show N empty fields" toggle and the auto-hide heuristic), the `isEmpty`
|
|
21
|
+
* branch of `displayValue` (the muted em-dash + `No value` affordance), and
|
|
22
|
+
* `canCopy` (a row that says `No value` must not offer to copy it);
|
|
23
|
+
* - `HeaderHighlight` — the ADR-0085 highlight strip's `isEmpty`, the same
|
|
24
|
+
* em-dash affordance one band higher on the same screen;
|
|
25
|
+
* - `DetailView` — the `summaryFields` chips beside the page H1, BOTH the
|
|
26
|
+
* auto-detection that picks which field becomes a chip and the render that
|
|
27
|
+
* skips a valueless one. Those two must agree or the derivation spends the
|
|
28
|
+
* one status slot on a field the render then drops, and no chip appears;
|
|
29
|
+
* - `HistoryTimeline` — `formatDiffValue`'s `'—'` placeholder for an audit
|
|
30
|
+
* value;
|
|
31
|
+
* - `RecordMetaFooter` — whether `created_by` / `updated_by` is an actor at
|
|
32
|
+
* all (see the note at its call site: the footer normalizes at the READ,
|
|
33
|
+
* because the label, the `·` separator and the renderer are three consumers
|
|
34
|
+
* of one answer).
|
|
35
|
+
*
|
|
36
|
+
* They MUST agree. Before objectui#8350 / #8376 / #8394 each spelled the test
|
|
37
|
+
* out for itself, none trimmed, and the page contradicted itself in one
|
|
38
|
+
* screenful: the H1 called a whitespace-only field empty, the body grid painted
|
|
39
|
+
* a blank cell, the strip between them painted a blank chip. Raw tests that
|
|
40
|
+
* happen to agree can stop agreeing; one definition cannot.
|
|
41
|
+
*
|
|
42
|
+
* ## Why the scalar half DELEGATES (objectui#8350's authority)
|
|
43
|
+
*
|
|
44
|
+
* None of those tests TRIMMED, so `' '` counted as FILLED while
|
|
45
|
+
* `@object-ui/core`'s `recordDisplayValueAt` — the definition the page H1 and
|
|
46
|
+
* the `record:details` dedupe ladder both read — calls it EMPTY. The
|
|
47
|
+
* consequences were not cosmetic: a row painted a visually blank cell (the exact
|
|
48
|
+
* UI the em-dash exists to prevent), it escaped `emptyCount` so the toggle read
|
|
49
|
+
* one too low, and because `shouldAutoHideEmpty` only needs `filledCount > 0`
|
|
50
|
+
* ONE such value suppressed the all-empty skeleton and hid every genuinely empty
|
|
51
|
+
* row in its section. So the scalar answer is not re-spelled here: it is the
|
|
52
|
+
* authority's, and a `.trim()` written at a call site would be the second
|
|
53
|
+
* implementation that drifts next.
|
|
54
|
+
*
|
|
55
|
+
* ## Why the OBJECT half does NOT delegate — measured, not assumed
|
|
56
|
+
*
|
|
57
|
+
* `recordDisplayValueAt` answers "does this resolve to a NAME", so an object
|
|
58
|
+
* value goes through `displayNameOfEmbeddedObject` and is EMPTY whenever that
|
|
59
|
+
* Salesforce-style chain yields nothing. That is right for a title and WRONG for
|
|
60
|
+
* a cell: here an object value is handed to a TYPE-AWARE renderer that knows how
|
|
61
|
+
* to draw it. `{ latitude, longitude }` renders as coordinates
|
|
62
|
+
* (`LocationCellRenderer`), `{ street, city, … }` as a formatted postal address
|
|
63
|
+
* (`AddressCellRenderer`, objectui#4037), `['alpha','beta']` as select badges,
|
|
64
|
+
* an expanded `{ id, name }` reference through `LookupCellRenderer`'s own
|
|
65
|
+
* display chain, any other object as JSON — none of which carries a name-ish key
|
|
66
|
+
* in the general case, so delegating this half would replace populated cells
|
|
67
|
+
* with `No value`, drop them out of `filledCount`, and let auto-hide bury them.
|
|
68
|
+
* A POPULATED object is therefore a VALUE here.
|
|
69
|
+
*
|
|
70
|
+
* ## The one object shape that is NOT a value: `[]` (objectui#8474)
|
|
71
|
+
*
|
|
72
|
+
* That member now arrives from the SHARED FLOOR rather than from a clause
|
|
73
|
+
* written here — `isEmptyValue` in `@object-ui/core` (objectui#8496). The
|
|
74
|
+
* reasoning below is what MEASURED it, and it is kept because it is the reason
|
|
75
|
+
* the floor may be asked here at all; the four members themselves are no longer
|
|
76
|
+
* this file's to spell.
|
|
77
|
+
*
|
|
78
|
+
* Every example above is a POPULATED object. `typeof [] === 'object'`, so until
|
|
79
|
+
* objectui#8474 an EMPTY array took the same branch and was a value — and there
|
|
80
|
+
* the reasoning stops holding, because the type-aware renderer has nothing to
|
|
81
|
+
* draw. `SelectCellRenderer` tests `value == null || value === ''`, which `[]`
|
|
82
|
+
* passes, and then maps it over zero entries: the cell renders as
|
|
83
|
+
* `<div class="flex flex-wrap gap-1"></div>`, a visually blank cell — the exact
|
|
84
|
+
* UI the em-dash exists to prevent, reached through the function that exists to
|
|
85
|
+
* prevent it. And it brought the whole objectui#8376 triple with it: the row
|
|
86
|
+
* escaped `emptyCount` so the toggle read one too low, `canCopy` offered to copy
|
|
87
|
+
* it, and because `shouldAutoHideEmpty` only needs `filledCount > 0` a section
|
|
88
|
+
* whose one non-null value was `[]` auto-hid every genuinely empty row around it
|
|
89
|
+
* and rendered a lone label over a blank.
|
|
90
|
+
*
|
|
91
|
+
* ⚠️ The declared cost, measured rather than waved past: a `json`-family field
|
|
92
|
+
* holding `[]` used to render the literal two-character text `[]` through
|
|
93
|
+
* `JsonCellRenderer`, and now draws the `No value` placeholder. That is
|
|
94
|
+
* intended — "no items" is what the placeholder says — but it IS a render
|
|
95
|
+
* change, and it is pinned as one.
|
|
96
|
+
*
|
|
97
|
+
* ## Why `{}` is NOT included — measured on this surface, not argued by symmetry
|
|
98
|
+
*
|
|
99
|
+
* `{}` is a VALUE here, and that is a measurement rather than an oversight.
|
|
100
|
+
* Rendered in a real `DetailSection`, `{}` on a `json`, an `object` and a
|
|
101
|
+
* `location` field all draw the literal `{}` through `JsonCellRenderer`
|
|
102
|
+
* (`location` falls back to it when the lat/lng chain yields nothing) — a terse
|
|
103
|
+
* cell, but a DRAWN one. There is no blank cell, so there is no defect of the
|
|
104
|
+
* kind above to fix, and turning a visible `{}` into an em-dash would be a taste
|
|
105
|
+
* change dressed up as a bug fix.
|
|
106
|
+
*
|
|
107
|
+
* ⛔ And the shape that would sweep `{}` in is actively unsafe here:
|
|
108
|
+
* `Object.keys(value).length === 0` is ALSO true of `new Date(0)`, of a
|
|
109
|
+
* populated `Map`, of a populated `Set`, and of any class instance whose state
|
|
110
|
+
* sits behind getters (all four measured). Widening that way would call those
|
|
111
|
+
* EMPTY — a false-empty on values that render, strictly worse than the bug it
|
|
112
|
+
* set out to fix. So this function moves whitespace-only strings and empty
|
|
113
|
+
* arrays, and nothing else.
|
|
114
|
+
*
|
|
115
|
+
* ## Agreement with `RelatedList`'s local predicate (objectui#8459)
|
|
116
|
+
*
|
|
117
|
+
* `RelatedList.isValueEmpty` has drawn this finer line for some time, and
|
|
118
|
+
* objectui#8459 / PR #8476 measured it as the better-shaped answer for a grid,
|
|
119
|
+
* declining to delegate here BECAUSE of this hole. After objectui#8474 the two
|
|
120
|
+
* agree on every probe measured (`[]` empty; `{}`, `[1]`, `{ a: 1 }`, `0` and a
|
|
121
|
+
* `Date` all values). ⛔ Note the DIRECTION: the SHARED authority moved toward
|
|
122
|
+
* the local predicate. `RelatedList.isValueEmpty` is untouched and must stay
|
|
123
|
+
* that way — a grid column and a record row ask this at two granularities, and
|
|
124
|
+
* the local one is pinned in its own file.
|
|
125
|
+
*
|
|
126
|
+
* ## Not every emptiness question on this page is THIS question
|
|
127
|
+
*
|
|
128
|
+
* ⛔ Do not widen the reader list by pattern-matching on the shape of a test.
|
|
129
|
+
* `ConcurrentUpdateDialog`'s `formatValue` deliberately renders `''` as `""`
|
|
130
|
+
* rather than as a placeholder — a conflict dialog is reporting what is STORED,
|
|
131
|
+
* where "empty string" and "absent" are different facts the reader must be able
|
|
132
|
+
* to tell apart. Converging it would delete information rather than add it.
|
|
133
|
+
*
|
|
134
|
+
* Pinned end-to-end (DOM, not predicate) in
|
|
135
|
+
* `__tests__/DetailSection.emptinessAuthority-8376.test.tsx`,
|
|
136
|
+
* `__tests__/detailPage.emptinessAuthority-8394.test.tsx` and
|
|
137
|
+
* `__tests__/DetailSection.emptyArray-8474.test.tsx`, whose NON-REGRESSION
|
|
138
|
+
* cases are red for a wholesale delegation and red for an emptiness test that
|
|
139
|
+
* answers EMPTY for everything.
|
|
140
|
+
*/
|
|
141
|
+
export declare function hasCellValue(value: unknown): boolean;
|
|
142
|
+
//# sourceMappingURL=emptiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptiness.d.ts","sourceRoot":"","sources":["../src/emptiness.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0BpD"}
|