@object-ui/plugin-detail 17.6.0 → 17.7.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 +6741 -0
- package/README.md +404 -71
- package/dist/ActivityTimeline.d.ts.map +1 -1
- package/dist/CommentAttachment.d.ts.map +1 -1
- package/dist/ConcurrentUpdateDialog.d.ts +17 -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.map +1 -1
- package/dist/HeaderHighlight.d.ts.map +1 -1
- package/dist/HistoryTimeline.d.ts +8 -1
- 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 +79 -6
- package/dist/InlineFieldInput.d.ts.map +1 -1
- package/dist/ReactionPicker.d.ts.map +1 -1
- package/dist/RecordActivityTimeline.d.ts +19 -4
- package/dist/RecordActivityTimeline.d.ts.map +1 -1
- package/dist/RecordChatterPanel.d.ts +6 -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 +1 -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 +44 -4
- 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 +4883 -5255
- package/dist/index.umd.cjs +2 -5
- 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 +2 -0
- package/dist/renderers/record-details.d.ts.map +1 -1
- 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 +16 -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 +37 -3
- package/dist/renderers/record-related-list.d.ts.map +1 -1
- package/dist/renderers/recordActivityFeed.d.ts +272 -20
- package/dist/renderers/recordActivityFeed.d.ts.map +1 -1
- 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 +98 -17
- package/dist/synth/buildDefaultPageSchema.d.ts.map +1 -1
- package/dist/useDetailTranslation.d.ts.map +1 -1
- package/dist/useRecordEditable.d.ts +1 -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
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { DetailViewSection } from '@object-ui/types';
|
|
2
|
+
import { DetailSectionProps } from './DetailSection.js';
|
|
3
|
+
/**
|
|
4
|
+
* ObjectUI
|
|
5
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The component the `detail-section` TAG is registered against — the seam that
|
|
12
|
+
* makes the block's declared `inputs` true (objectui#8626).
|
|
13
|
+
*
|
|
14
|
+
* ## The defect this closes
|
|
15
|
+
*
|
|
16
|
+
* `ComponentRegistry.register('detail-section', …)` declared eight FLAT inputs
|
|
17
|
+
* — `title`, `description`, `fields`, `collapsible`, `defaultCollapsed`,
|
|
18
|
+
* `columns`, `showBorder`, `headerColor`. `DetailSection` declares no such
|
|
19
|
+
* props: it takes a single `section` object and reads `section.title`,
|
|
20
|
+
* `section.fields`, `section.defaultCollapsed` and the rest off it. The two
|
|
21
|
+
* are joined by `SchemaRenderer`, which spreads a node's non-metadata keys as
|
|
22
|
+
* React props — so an authored node arrived as `title` / `fields` / … and
|
|
23
|
+
* `section` arrived as `undefined`.
|
|
24
|
+
*
|
|
25
|
+
* That is not "every input inert". MEASURED on `b775500af` by rendering an
|
|
26
|
+
* authored node through the real `SchemaRenderer` and the real registry:
|
|
27
|
+
* `DetailSection`'s first statement is `React.useState(section.defaultCollapsed
|
|
28
|
+
* ?? false)`, so the render THREW, `SchemaErrorBoundary` caught it, and the
|
|
29
|
+
* author's page showed an orange banner reading
|
|
30
|
+
* `Component "detail-section" failed to render — Cannot read properties of
|
|
31
|
+
* undefined (reading 'defaultCollapsed')`. Every authored key was lost AND the
|
|
32
|
+
* block became a visible hole.
|
|
33
|
+
*
|
|
34
|
+
* ## Why the fold, and not a re-declaration
|
|
35
|
+
*
|
|
36
|
+
* The two repairs objectui#8626 names are not symmetric, and the measurement
|
|
37
|
+
* decides between them rather than taste:
|
|
38
|
+
*
|
|
39
|
+
* - The flat inputs are the PUBLISHED surface, and the platform enforces them.
|
|
40
|
+
* `packages/components/src/renderers/layout/page.tsx` builds the JSX-page
|
|
41
|
+
* compiler's manifest from `getKnownTypes()` plus these `inputs`, and
|
|
42
|
+
* `sdui-parser`'s `validateTree` judges an authored page against it.
|
|
43
|
+
* Measured against that live manifest: the flat eight drew ZERO
|
|
44
|
+
* diagnostics, while `section` draws `unknown-prop` AND
|
|
45
|
+
* `missing-required-prop "fields"`. The validator does not merely permit
|
|
46
|
+
* the flat shape — it REFUSES the nested one.
|
|
47
|
+
* - The flat shape is authored: `packages/plugin-detail/README.md` documents
|
|
48
|
+
* a `detail-section` node inside `tabs[].content` (which `DetailTabs`
|
|
49
|
+
* renders through `SchemaRenderer`), and
|
|
50
|
+
* `__tests__/detailSectionHeaderColorEnum-6955.test.ts` pins the flat
|
|
51
|
+
* `fields` + `headerColor` surface against that same validator.
|
|
52
|
+
*
|
|
53
|
+
* Re-declaring the registration as a nested `section` object would therefore
|
|
54
|
+
* invalidate both, and would delete the surface objectui#6955 had just
|
|
55
|
+
* narrowed. Folding at the seam invalidates nothing: every authored node keeps
|
|
56
|
+
* validating and starts rendering.
|
|
57
|
+
*
|
|
58
|
+
* ## Why HERE and not inside `DetailSection`
|
|
59
|
+
*
|
|
60
|
+
* `DetailSection` is a published export with five in-repo callers
|
|
61
|
+
* (`DetailView`, `SectionGroup` and their tests), every one of which passes
|
|
62
|
+
* `section={…}` as a direct JSX child — none goes through the registry. Teaching
|
|
63
|
+
* the component two prop shapes would put a second dialect in front of all of
|
|
64
|
+
* them (AGENTS.md #0.1). The registration seam is where the translation
|
|
65
|
+
* belongs, and this package already does exactly that for
|
|
66
|
+
* `field:permission-facet-link` via `withFieldCarrier` (objectui#3307).
|
|
67
|
+
*
|
|
68
|
+
* ⇒ this adapter accepts the DECLARED surface and nothing else. It does not
|
|
69
|
+
* take a `section` prop: a node carrying one is refused by the platform
|
|
70
|
+
* validator, so honouring it here would create the second de-facto contract
|
|
71
|
+
* #0.1 exists to prevent.
|
|
72
|
+
*/
|
|
73
|
+
import * as React from 'react';
|
|
74
|
+
/**
|
|
75
|
+
* The section members an authored `detail-section` node carries as FLAT props,
|
|
76
|
+
* i.e. exactly the names the registration declares as `inputs`.
|
|
77
|
+
*
|
|
78
|
+
* THE single source for the fold, and load-bearing rather than descriptive:
|
|
79
|
+
* the component below folds by iterating THIS list, so a name removed from it
|
|
80
|
+
* is a name that stops reaching `DetailSection` — which is how the ablation
|
|
81
|
+
* for objectui#8626 reddens a per-input row.
|
|
82
|
+
* `detailSectionAuthoredNode-8626.test.tsx` additionally pins the list against
|
|
83
|
+
* the registration's own declared input names in BOTH directions, so a new
|
|
84
|
+
* input declared without a fold — the shape of the original defect — reds
|
|
85
|
+
* rather than arriving silently inert.
|
|
86
|
+
*/
|
|
87
|
+
export declare const DETAIL_SECTION_NODE_INPUTS: readonly ["title", "description", "icon", "fields", "collapsible", "defaultCollapsed", "columns", "showBorder", "headerColor", "hideEmpty"];
|
|
88
|
+
type DetailSectionNodeInput = (typeof DETAIL_SECTION_NODE_INPUTS)[number];
|
|
89
|
+
/**
|
|
90
|
+
* What an author may write on a `detail-section` node: the declared inputs
|
|
91
|
+
* (`DETAIL_SECTION_NODE_INPUTS`), flat, plus the render-context props a host
|
|
92
|
+
* supplies.
|
|
93
|
+
*/
|
|
94
|
+
export type DetailSectionNodeProps = Omit<DetailSectionProps, 'section'> & Partial<Pick<DetailViewSection, DetailSectionNodeInput>>;
|
|
95
|
+
export declare const DetailSectionNode: React.FC<DetailSectionNodeProps>;
|
|
96
|
+
export {};
|
|
97
|
+
//# sourceMappingURL=DetailSectionNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DetailSectionNode.d.ts","sourceRoot":"","sources":["../src/DetailSectionNode.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,6IAiB7B,CAAC;AAEX,KAAK,sBAAsB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,GACtE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,sBAAsB,CAAC,CAAC,CAAC;AAI3D,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAkC9D,CAAC"}
|
package/dist/DetailView.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetailView.d.ts","sourceRoot":"","sources":["../src/DetailView.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DetailView.d.ts","sourceRoot":"","sources":["../src/DetailView.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAyC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAA4B,MAAM,kBAAkB,CAAC;AAsH/F,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACrC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5C;AA8DD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAswDhD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeaderHighlight.d.ts","sourceRoot":"","sources":["../src/HeaderHighlight.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"HeaderHighlight.d.ts","sourceRoot":"","sources":["../src/HeaderHighlight.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAevD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAgT1D,CAAC"}
|
|
@@ -42,7 +42,14 @@ export interface HistoryTimelineProps {
|
|
|
42
42
|
/** Localized fallback for entries with no resolved actor name. Defaults to "Unknown user". */
|
|
43
43
|
unknownUserText?: string;
|
|
44
44
|
className?: string;
|
|
45
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* BCP-47 tag used for both the relative and the absolute time face.
|
|
47
|
+
*
|
|
48
|
+
* ⚠️ Defaults to `useDisplayLocale()` — the tenant's regional default, then
|
|
49
|
+
* the active UI language, then `'en'` — and ⛔ NOT to the browser's own
|
|
50
|
+
* locale, which is the machine's and neither of those two channels
|
|
51
|
+
* (objectui#9786). Pass this only to OVERRIDE that composition.
|
|
52
|
+
*/
|
|
46
53
|
locale?: string;
|
|
47
54
|
}
|
|
48
55
|
export declare function HistoryTimeline({ entries, loading, emptyText, unknownUserText, className, locale, }: HistoryTimelineProps): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HistoryTimeline.d.ts","sourceRoot":"","sources":["../src/HistoryTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"HistoryTimeline.d.ts","sourceRoot":"","sources":["../src/HistoryTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6FD,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,OAAO,EACP,SAAS,EACT,eAAe,EACf,SAAS,EACT,MAAM,GACP,EAAE,oBAAoB,qBA0HtB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isConcurrentUpdateError, ConcurrentUpdateConflict } from './ConcurrentUpdateDialog.js';
|
|
1
2
|
/**
|
|
2
3
|
* ObjectUI
|
|
3
4
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -25,6 +26,45 @@
|
|
|
25
26
|
* and **Cmd/Ctrl+Enter** saves — both respecting `saving`/`locked`.
|
|
26
27
|
*
|
|
27
28
|
* The bar renders nothing unless the record is actively being edited.
|
|
29
|
+
*
|
|
30
|
+
* ## Validation authority on this surface: the SERVER (objectui#6868)
|
|
31
|
+
*
|
|
32
|
+
* ⚖️ Ruled by the maintainer on 2026-08-31 (decision batch #13, on
|
|
33
|
+
* https://github.com/objectstack-ai/objectui/issues/6868). Recorded here
|
|
34
|
+
* because, until that ruling, the inline-edit surface's lack of client-side
|
|
35
|
+
* validation was an ABSENCE, and an absence and a decision look identical in
|
|
36
|
+
* code. This comment is the difference.
|
|
37
|
+
*
|
|
38
|
+
* The ruling, in its own words:
|
|
39
|
+
*
|
|
40
|
+
* 1. 正式记录:行内编辑面的校验权威是**服务端**…此前这是一个「缺席」,现在是
|
|
41
|
+
* 一个「决定」——在相应模块注释写明并指向本裁定。
|
|
42
|
+
* 2. 交付物:把服务端 `VALIDATION_FAILED` 拒绝**映射为就地字段提示**(拒绝信息
|
|
43
|
+
* 已含字段与规则,缺的只是呈现层)——用户不再看到原始服务器错误。
|
|
44
|
+
* 3. ⛔ 不抽取共享求值器。
|
|
45
|
+
* 4. ⛔ 照旧不写第二套校验实现——服务端是唯一规则源,前端只做呈现。
|
|
46
|
+
*
|
|
47
|
+
* What that means for anyone editing this module:
|
|
48
|
+
*
|
|
49
|
+
* - ⛔ Do NOT add a client-side rule evaluator here, and do NOT call
|
|
50
|
+
* `buildValidationRules` from this surface. The form surface's producer
|
|
51
|
+
* emits a react-hook-form rule DESCRIPTOR, not a verdict; RHF is the only
|
|
52
|
+
* evaluator in the repo, and this package depends on neither. Wiring one
|
|
53
|
+
* up would create a second rule source that can disagree with the server —
|
|
54
|
+
* which is precisely how AI-authored metadata gets a green form and a
|
|
55
|
+
* rejected write.
|
|
56
|
+
* - ✅ DO present what the server already decided. The refusal envelope is
|
|
57
|
+
* field-scoped: `@objectstack/objectql`'s validators throw
|
|
58
|
+
* `VALIDATION_FAILED` with `fields[]`, and `@object-ui/react`'s
|
|
59
|
+
* `extractFieldErrors` is the ONE in-repo normaliser for it (the same one
|
|
60
|
+
* `form.tsx` uses). This module reads that normaliser and renders per-field
|
|
61
|
+
* reasons; it never re-derives a rule.
|
|
62
|
+
*
|
|
63
|
+
* The rule kinds the engine refuses on this surface were measured on a real
|
|
64
|
+
* ObjectQL engine before the ruling: `required` (empty AND null), `minLength`,
|
|
65
|
+
* `maxLength`, `email`, `url`, `min`, `max` — every one a `VALIDATION_FAILED`
|
|
66
|
+
* with the prior value left in storage. So no invalid value reachable here
|
|
67
|
+
* survives the write; the only defect was the SHAPE of the refusal the user saw.
|
|
28
68
|
*/
|
|
29
69
|
import * as React from 'react';
|
|
30
70
|
export interface InlineEditSaveBarProps {
|
|
@@ -52,6 +92,34 @@ export interface InlineEditSaveBarProps {
|
|
|
52
92
|
lockedHint?: string;
|
|
53
93
|
className?: string;
|
|
54
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* The shape `isConcurrentUpdateError` narrows to, DERIVED from the predicate
|
|
97
|
+
* rather than restated here (objectui#6477).
|
|
98
|
+
*
|
|
99
|
+
* `buildConflict` below is that predicate's ONLY in-repo consumer, and it used
|
|
100
|
+
* to take `err: any` — which discarded the narrowing one line after the call
|
|
101
|
+
* site drew it, so the predicate's return type reached no typed consumer at
|
|
102
|
+
* all. objectui#6421 / PR #6474 had just made that return type honest
|
|
103
|
+
* (`code?: 'CONCURRENT_UPDATE'`, optional because the `name` limb carries no
|
|
104
|
+
* `code`); this alias is what makes something listen.
|
|
105
|
+
*
|
|
106
|
+
* Derived, not copied, on purpose: a restated literal shape is a second
|
|
107
|
+
* declaration that drifts silently, and the two disagreeing is exactly the
|
|
108
|
+
* failure this card was opened to rule out. Written this way the compiler
|
|
109
|
+
* re-checks every read in `buildConflict` against whatever the predicate
|
|
110
|
+
* currently promises, so a future narrowing that stops covering
|
|
111
|
+
* `currentRecord` / `currentVersion` is a red build here rather than a fresh
|
|
112
|
+
* `any`.
|
|
113
|
+
*/
|
|
114
|
+
type NarrowedBy<F> = F extends (arg: unknown) => arg is infer N ? N : never;
|
|
115
|
+
type ConcurrentUpdateErrorShape = NarrowedBy<typeof isConcurrentUpdateError>;
|
|
116
|
+
/**
|
|
117
|
+
* Signature of the module-local `buildConflict` callback. Exported as a TYPE
|
|
118
|
+
* only, for its pin test to reach — the callback itself stays inside the
|
|
119
|
+
* component. Deliberately NOT re-exported from `src/index.tsx`, which lists
|
|
120
|
+
* every published name explicitly, so the package surface is unchanged.
|
|
121
|
+
*/
|
|
122
|
+
export type BuildConflict = (draft: Record<string, any>, err: ConcurrentUpdateErrorShape) => ConcurrentUpdateConflict;
|
|
55
123
|
export declare const InlineEditSaveBar: React.FC<InlineEditSaveBarProps>;
|
|
56
124
|
export default InlineEditSaveBar;
|
|
57
125
|
//# sourceMappingURL=InlineEditSaveBar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineEditSaveBar.d.ts","sourceRoot":"","sources":["../src/InlineEditSaveBar.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"InlineEditSaveBar.d.ts","sourceRoot":"","sources":["../src/InlineEditSaveBar.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,EAEL,uBAAuB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,iFAAiF;IACjF,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,iFAAiF;IACjF,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,KAAK,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC5E,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,GAAG,EAAE,0BAA0B,KAC5B,wBAAwB,CAAC;AAuF9B,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAsS9D,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TEXTUAL_REF_FALLBACK_TYPES } from './fieldEnrichment';
|
|
1
|
+
import { TEXTUAL_REF_FALLBACK_TYPES } from './fieldEnrichment.js';
|
|
2
2
|
/**
|
|
3
3
|
* ObjectUI
|
|
4
4
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -8,7 +8,7 @@ import { TEXTUAL_REF_FALLBACK_TYPES } from './fieldEnrichment';
|
|
|
8
8
|
*/
|
|
9
9
|
import * as React from 'react';
|
|
10
10
|
/**
|
|
11
|
-
* Field types that carry a `
|
|
11
|
+
* Field types that carry a `reference` for relational metadata but are NOT
|
|
12
12
|
* edited via the lookup picker (they have their own dedicated inputs/renderers).
|
|
13
13
|
* Used below so the inline-edit branch doesn't hijack them into a record picker.
|
|
14
14
|
*
|
|
@@ -43,9 +43,17 @@ export declare const INLINE_PLAIN_TEXT_INPUT_TESTID = "inline-plain-text-input";
|
|
|
43
43
|
*
|
|
44
44
|
* `select` is deliberately absent: it has a routed branch (the picklist), and
|
|
45
45
|
* only its degenerate options-less SINGLE-value form reaches the terminal
|
|
46
|
-
* input — see {@link usesInlinePlainTextInput}.
|
|
47
|
-
*
|
|
48
|
-
* (
|
|
46
|
+
* input — see {@link usesInlinePlainTextInput}.
|
|
47
|
+
*
|
|
48
|
+
* `markdown` (objectui#11541) and `textarea` (objectui#11562) are absent
|
|
49
|
+
* although their values are strings: they are multi-line by type, so they are
|
|
50
|
+
* ROUTED, to the multi-line `TextAreaField`. This terminal input is a
|
|
51
|
+
* single-line `<input type="text">`, and the browser strips line breaks from
|
|
52
|
+
* the value it is seeded with — one keystroke and the flattened text is what
|
|
53
|
+
* gets written. The members left here are single-line types, which is what
|
|
54
|
+
* makes "nothing is lost" true of them. `html` / `richtext` are absent because
|
|
55
|
+
* the hosts never open an editor for them at all (they are in the fields
|
|
56
|
+
* package's shared exclusion, consulted since #4228).
|
|
49
57
|
*/
|
|
50
58
|
export declare const INLINE_PLAIN_TEXT_FIELD_TYPES: Set<string>;
|
|
51
59
|
/**
|
|
@@ -99,7 +107,7 @@ export declare function extractLookupId(value: unknown): unknown;
|
|
|
99
107
|
export interface InlineFieldInputProps {
|
|
100
108
|
/**
|
|
101
109
|
* Enriched field metadata — `type` plus any objectSchema enrichment (options,
|
|
102
|
-
* currency, precision, format,
|
|
110
|
+
* currency, precision, format, reference, widget…). The caller owns
|
|
103
111
|
* enrichment so read-mode and edit-mode agree on the same resolved field
|
|
104
112
|
* shape. Kept as a loose bag (matching the widgets' `field` props) since the
|
|
105
113
|
* exact key set varies by field type.
|
|
@@ -113,6 +121,41 @@ export interface InlineFieldInputProps {
|
|
|
113
121
|
dataSource?: any;
|
|
114
122
|
/** Auto-focus the underlying input on mount (wired to the entered field). */
|
|
115
123
|
autoFocus?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* The SERVER's reason for refusing this field on the last save, or undefined
|
|
126
|
+
* (objectui#6868). Forwarded to the widget's published objectui#3222 `error`
|
|
127
|
+
* slot, which marks `aria-invalid` — it does NOT render text, on this surface
|
|
128
|
+
* or on the form one, so the visible hint is drawn by the HOST beside this
|
|
129
|
+
* input (see `DetailSection` / `HeaderHighlight`).
|
|
130
|
+
*
|
|
131
|
+
* ⚠️ Never a client-side verdict. The ruling on objectui#6868 makes the
|
|
132
|
+
* server the validation authority here; this prop only carries what the
|
|
133
|
+
* server already decided.
|
|
134
|
+
*/
|
|
135
|
+
error?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The record this field belongs to, as the edit session sees it — the saved
|
|
138
|
+
* record overlaid with the inline draft (objectui#7190). Forwarded unchanged
|
|
139
|
+
* to every widget that scopes itself by a record: `LookupField` / `UserField`
|
|
140
|
+
* (a `dependsOn` lookup gates on it and filters its query by it),
|
|
141
|
+
* `SelectField` (a `dependsOn` gate plus per-option `visibleWhen`, through
|
|
142
|
+
* `useCascadingOptions`), and `FieldEditWidget`, which hands it on to the
|
|
143
|
+
* option widgets it renders. Same spelling and shape as the widgets' own
|
|
144
|
+
* `dependentValues` prop.
|
|
145
|
+
*
|
|
146
|
+
* ⚠️ It is the ONLY channel. The widgets resolve `dependentValues ?? {}`:
|
|
147
|
+
* there is no context fallback (objectui#7206 retired the one that was
|
|
148
|
+
* documented and never fired), so a host that omits it renders every
|
|
149
|
+
* `dependsOn` field permanently gated — "Select region first" beside a
|
|
150
|
+
* filled `region`. The two in-repo hosts, `DetailSection` and
|
|
151
|
+
* `HeaderHighlight`, both pass it.
|
|
152
|
+
*
|
|
153
|
+
* STAGED, not saved: a parent edited in the same session re-scopes the child
|
|
154
|
+
* before anything is written, and clearing it re-gates the child — the grid
|
|
155
|
+
* inline editor's `pendingRow ?? row` (objectui#7188) and the form's live
|
|
156
|
+
* watched record.
|
|
157
|
+
*/
|
|
158
|
+
dependentValues?: Record<string, unknown>;
|
|
116
159
|
}
|
|
117
160
|
/**
|
|
118
161
|
* The single inline-edit input for a record field, extracted from
|
|
@@ -130,6 +173,36 @@ export interface InlineFieldInputProps {
|
|
|
130
173
|
* Editability GATING (computed types, `readonly`, system fields, object
|
|
131
174
|
* lifecycle) stays with the host — this component only renders the editor once
|
|
132
175
|
* the host has decided the field is editable.
|
|
176
|
+
*
|
|
177
|
+
* ## Why there is no validation in this component (objectui#6868)
|
|
178
|
+
*
|
|
179
|
+
* ⚖️ This is a DECISION, not an omission. The maintainer ruled on 2026-08-31
|
|
180
|
+
* (decision batch #13, on
|
|
181
|
+
* https://github.com/objectstack-ai/objectui/issues/6868) that **the server is
|
|
182
|
+
* the validation authority on the inline-edit surface**. Recorded here because
|
|
183
|
+
* this component is where the question gets asked: it imports from
|
|
184
|
+
* `@object-ui/fields` but never calls `buildValidationRules`, and it takes no
|
|
185
|
+
* `error` prop — which for two years read as an oversight and is now a ruling.
|
|
186
|
+
*
|
|
187
|
+
* ⛔ Do NOT "fix" that by adding rules here. The ruling refuses both an
|
|
188
|
+
* extracted shared evaluator and a second validation implementation on this
|
|
189
|
+
* surface: the server is the only rule source, and the front end only presents
|
|
190
|
+
* its verdict. Every rule kind reachable through this component was measured
|
|
191
|
+
* against a real ObjectQL engine and refused server-side with
|
|
192
|
+
* `VALIDATION_FAILED` (`required` empty and null, `minLength`, `maxLength`,
|
|
193
|
+
* `email`, `url`, `min`, `max`), with the prior value left in storage.
|
|
194
|
+
*
|
|
195
|
+
* ✅ The presentation half lives in `<InlineEditSaveBar>`, which turns the
|
|
196
|
+
* server's field-scoped refusal into a reason per field. See that module's
|
|
197
|
+
* header for the ruling in full.
|
|
198
|
+
*
|
|
199
|
+
* ⚠️ One measured caveat for anyone extending this later: the widgets'
|
|
200
|
+
* published `error` slot (objectui#3222) marks `aria-invalid` — it does NOT
|
|
201
|
+
* render the message. Measured at 2c3cd1b: `NumberField` given `error` sets
|
|
202
|
+
* `aria-invalid="true"` and renders no text, exactly as on the form surface
|
|
203
|
+
* where `form.tsx` — not the widget — draws the visible message. So threading
|
|
204
|
+
* `error` through here would buy the a11y marking, and the visible hint would
|
|
205
|
+
* still be this package's markup to render.
|
|
133
206
|
*/
|
|
134
207
|
export declare const InlineFieldInput: React.FC<InlineFieldInputProps>;
|
|
135
208
|
//# sourceMappingURL=InlineFieldInput.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineFieldInput.d.ts","sourceRoot":"","sources":["../src/InlineFieldInput.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"InlineFieldInput.d.ts","sourceRoot":"","sources":["../src/InlineFieldInput.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA2B/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;;;;;;GASG;AACH,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,6BAA6B,aAKxC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,yBAAyB,aAuCpC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAK5E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQvD;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,iFAAiF;IACjF,KAAK,EAAE,GAAG,CAAC;IACX,oEAAoE;IACpE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAqS5D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactionPicker.d.ts","sourceRoot":"","sources":["../src/ReactionPicker.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,mBAAmB;IAClC,0CAA0C;IAC1C,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ReactionPicker.d.ts","sourceRoot":"","sources":["../src/ReactionPicker.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,mBAAmB;IAClC,0CAA0C;IAC1C,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAkFxD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FeedItem, RecordActivityComponentProps, RecordSubscription } from '@object-ui/types';
|
|
2
2
|
import { FeedFilterMode } from '@objectstack/spec/data';
|
|
3
|
-
import { Attachment } from './CommentAttachment';
|
|
3
|
+
import { Attachment } from './CommentAttachment.js';
|
|
4
4
|
/**
|
|
5
5
|
* ObjectUI
|
|
6
6
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -41,9 +41,13 @@ export interface RecordActivityTimelineProps {
|
|
|
41
41
|
* screen yet, the timeline shows a loading row instead of the empty state
|
|
42
42
|
* — "still fetching" is not "no activity" (objectui#3205). */
|
|
43
43
|
loading?: boolean;
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Called when a comment is submitted. A returned promise that REJECTS means
|
|
46
|
+
* the comment was not written: the composer keeps the draft, and reporting
|
|
47
|
+
* the failure is the host's job.
|
|
48
|
+
*/
|
|
45
49
|
onAddComment?: (text: string, attachments?: Attachment[]) => void | Promise<void>;
|
|
46
|
-
/** Called when a reply is submitted */
|
|
50
|
+
/** Called when a reply is submitted — a rejection keeps the reply draft, as above. */
|
|
47
51
|
onAddReply?: (parentId: string | number, text: string) => void | Promise<void>;
|
|
48
52
|
/** Called when user toggles a reaction */
|
|
49
53
|
onToggleReaction?: (itemId: string | number, emoji: string) => void | Promise<void>;
|
|
@@ -62,10 +66,21 @@ export interface RecordActivityTimelineProps {
|
|
|
62
66
|
/** Optional uploader for comment attachments. When provided, the composer
|
|
63
67
|
* exposes a drag-and-drop file panel. */
|
|
64
68
|
onUploadAttachments?: (files: FileList) => Promise<Attachment[]>;
|
|
65
|
-
/** Override the panel title (defaults to t('detail.activity'))
|
|
69
|
+
/** Override the panel title (defaults to t('detail.activity')). It is both
|
|
70
|
+
* the visible heading's title and the panel landmark's accessible name
|
|
71
|
+
* (objectui#9998). */
|
|
66
72
|
titleLabel?: string;
|
|
67
73
|
/** Override the empty state copy (defaults to t('detail.noActivity')) */
|
|
68
74
|
emptyLabel?: string;
|
|
75
|
+
/**
|
|
76
|
+
* The feed's activity read was REFUSED (401 / 403, or a permission
|
|
77
|
+
* envelope). The timeline then says the reader may not see the activity,
|
|
78
|
+
* instead of claiming there is none (objectui#11195). The host that owns the
|
|
79
|
+
* read decides this; the timeline never guesses it.
|
|
80
|
+
*/
|
|
81
|
+
activityDenied?: boolean;
|
|
82
|
+
/** The same, for the feed's comment read. */
|
|
83
|
+
commentsDenied?: boolean;
|
|
69
84
|
className?: string;
|
|
70
85
|
}
|
|
71
86
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordActivityTimeline.d.ts","sourceRoot":"","sources":["../src/RecordActivityTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EAAE,QAAQ,EAAgB,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACjH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAM7D,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"RecordActivityTimeline.d.ts","sourceRoot":"","sources":["../src/RecordActivityTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EAAE,QAAQ,EAAgB,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACjH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAM7D,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAIzE;;;;;;;;;;;;;GAaG;AACH,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,WAAW,2BAA2B;IAC1C,4BAA4B;IAC5B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,4BAA4B,CAAC;IACtC,mCAAmC;IACnC,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,sCAAsC;IACtC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC;;mEAE+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF,sFAAsF;IACtF,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,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,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,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;8CAC0C;IAC1C,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACjE;;2BAEuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuGD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAicxE,CAAC"}
|
|
@@ -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.
|
|
@@ -52,6 +52,11 @@ export interface RecordChatterPanelProps {
|
|
|
52
52
|
url?: string;
|
|
53
53
|
thumbnailUrl?: string;
|
|
54
54
|
}>>;
|
|
55
|
+
/** The feed's activity read was refused; forwarded to the timeline, which
|
|
56
|
+
* shows a no-permission state for it (objectui#11195). */
|
|
57
|
+
activityDenied?: boolean;
|
|
58
|
+
/** The same, for the feed's comment read. */
|
|
59
|
+
commentsDenied?: boolean;
|
|
55
60
|
className?: string;
|
|
56
61
|
}
|
|
57
62
|
/**
|
|
@@ -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,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,CA6LhE,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"}
|