@object-ui/plugin-detail 3.1.0 → 3.1.2
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/.turbo/turbo-build.log +41 -41
- package/CHANGELOG.md +21 -0
- package/dist/{AddressField-C07oUOY6.js → AddressField-QBIlXCFl.js} +1 -1
- package/dist/{AvatarField-VThNABzo.js → AvatarField-BEZuQTAH.js} +1 -1
- package/dist/{BooleanField-CGHKBzAi.js → BooleanField-doa93aFX.js} +1 -1
- package/dist/{CodeField-Co_muhRR.js → CodeField-jVV-hIXg.js} +1 -1
- package/dist/{ColorField-DLid_tFz.js → ColorField-B53qKQGW.js} +1 -1
- package/dist/{CurrencyField-Bw-LqANM.js → CurrencyField-og0NJ2ax.js} +1 -1
- package/dist/{DateField-BNHAzMB2.js → DateField-BFx64AtG.js} +1 -1
- package/dist/{DateTimeField-DjAyn_DQ.js → DateTimeField-Cxs2Rx2f.js} +1 -1
- package/dist/{EmailField-xoNcSppb.js → EmailField-BfcpzRe7.js} +1 -1
- package/dist/{FileField-DbNJwjU2.js → FileField-KarqvhYm.js} +1 -1
- package/dist/{GeolocationField-C1AnS6VV.js → GeolocationField-B5SKZaqn.js} +1 -1
- package/dist/{GridField-DATAHIKf.js → GridField-DOotrUTo.js} +1 -1
- package/dist/{ImageField-CEKJpyJp.js → ImageField-Ddotp4u-.js} +1 -1
- package/dist/{LocationField-jDWXjlpx.js → LocationField-tOkQaPIM.js} +1 -1
- package/dist/{LookupField-DQ08L9UQ.js → LookupField-DF36GvIP.js} +1 -1
- package/dist/{MasterDetailField-Dbk529Ea.js → MasterDetailField-CpHw3nTE.js} +1 -1
- package/dist/{NumberField-BVroN9aV.js → NumberField-CzBb2a28.js} +1 -1
- package/dist/{ObjectField-CT3l_IHW.js → ObjectField-BoL-JqE4.js} +1 -1
- package/dist/{PasswordField-DweVLEE0.js → PasswordField-DrTzkYgj.js} +1 -1
- package/dist/{PercentField-ZpWUK97K.js → PercentField-B9ZUQ3zE.js} +1 -1
- package/dist/{PhoneField-mw-9fqZ_.js → PhoneField-Bf9lhpdu.js} +1 -1
- package/dist/{QRCodeField-Cbb9ck59.js → QRCodeField-PzMpdBKd.js} +1 -1
- package/dist/{RatingField-CSqgLS6t.js → RatingField-CeBMFe8o.js} +1 -1
- package/dist/{RichTextField-BpfBOd99.js → RichTextField-Ch7CHSQ0.js} +1 -1
- package/dist/{SelectField-B9Ei-5jl.js → SelectField-f5Nbi02x.js} +1 -1
- package/dist/{SignatureField-DgGpHnQ8.js → SignatureField-CpxTX2tR.js} +1 -1
- package/dist/{SliderField-C6HvOHd8.js → SliderField-BoZtzgcr.js} +1 -1
- package/dist/{TextAreaField-BK3RgzY3.js → TextAreaField-rT1DLnV2.js} +1 -1
- package/dist/{TextField-Bvzx3atT.js → TextField-CflRxusu.js} +1 -1
- package/dist/{TimeField-Cuz9-Uai.js → TimeField-DeVeCpRu.js} +1 -1
- package/dist/{UrlField-B6XHTV73.js → UrlField-UWKfhP9T.js} +1 -1
- package/dist/{UserField-ooTul2d6.js → UserField-Cp2zQDjz.js} +1 -1
- package/dist/index-V_WBvcaA.js +100249 -0
- package/dist/index.js +20 -18
- package/dist/index.umd.cjs +117 -46
- package/dist/plugin-detail.css +1 -1
- package/dist/src/DetailSection.d.ts +11 -0
- package/dist/src/DetailSection.d.ts.map +1 -1
- package/dist/src/DetailView.d.ts.map +1 -1
- package/dist/src/HeaderHighlight.d.ts +18 -0
- package/dist/src/HeaderHighlight.d.ts.map +1 -0
- package/dist/src/RelatedList.d.ts +16 -0
- package/dist/src/RelatedList.d.ts.map +1 -1
- package/dist/src/SectionGroup.d.ts +21 -0
- package/dist/src/SectionGroup.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/useDetailTranslation.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/DetailSection.tsx +50 -26
- package/src/DetailView.tsx +286 -69
- package/src/HeaderHighlight.tsx +67 -0
- package/src/RelatedList.tsx +287 -21
- package/src/SectionGroup.tsx +101 -0
- package/src/__tests__/DetailSection.test.tsx +111 -2
- package/src/__tests__/DetailView.test.tsx +31 -0
- package/src/__tests__/HeaderHighlight.test.tsx +68 -0
- package/src/__tests__/RelatedList.test.tsx +101 -7
- package/src/__tests__/SectionGroup.test.tsx +101 -0
- package/src/__tests__/roadmap-features.test.tsx +478 -0
- package/src/index.tsx +4 -0
- package/src/useDetailTranslation.ts +11 -0
- package/dist/index-CnlyRfY_.js +0 -59461
- package/src/registration.test.tsx +0 -18
|
@@ -7,12 +7,23 @@ import { DetailViewSection as DetailViewSectionType } from '../../types/src';
|
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
9
|
import * as React from 'react';
|
|
10
|
+
/**
|
|
11
|
+
* Compute responsive col-span classes so that col-span never exceeds the
|
|
12
|
+
* visible column count at each Tailwind breakpoint.
|
|
13
|
+
*
|
|
14
|
+
* For columns=1: no span class (always single column)
|
|
15
|
+
* For columns=2: md:col-span-{min(span,2)}
|
|
16
|
+
* For columns>=3: md:col-span-{min(span,2)} lg:col-span-{min(span,3)}
|
|
17
|
+
*/
|
|
18
|
+
export declare function getResponsiveSpanClass(span: number | undefined, columns: number): string;
|
|
10
19
|
export interface DetailSectionProps {
|
|
11
20
|
section: DetailViewSectionType;
|
|
12
21
|
data?: any;
|
|
13
22
|
className?: string;
|
|
14
23
|
/** Object schema from DataSource for field type enrichment */
|
|
15
24
|
objectSchema?: any;
|
|
25
|
+
/** Object name for i18n field label resolution */
|
|
26
|
+
objectName?: string;
|
|
16
27
|
/** Whether inline editing is active */
|
|
17
28
|
isEditing?: boolean;
|
|
18
29
|
/** Callback when a field value changes during inline editing */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetailSection.d.ts","sourceRoot":"","sources":["../../src/DetailSection.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoB/B,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAkC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"DetailSection.d.ts","sourceRoot":"","sources":["../../src/DetailSection.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAoB/B,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAkC,MAAM,kBAAkB,CAAC;AAKnH;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAYxF;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACrD;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuOtD,CAAC"}
|
|
@@ -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;AA4C/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMrE,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,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChF;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA+uBhD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { HighlightField } from '../../types/src';
|
|
2
|
+
/**
|
|
3
|
+
* ObjectUI
|
|
4
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
import * as React from 'react';
|
|
10
|
+
export interface HeaderHighlightProps {
|
|
11
|
+
fields: HighlightField[];
|
|
12
|
+
data?: any;
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Object name for i18n field label resolution */
|
|
15
|
+
objectName?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const HeaderHighlight: React.FC<HeaderHighlightProps>;
|
|
18
|
+
//# sourceMappingURL=HeaderHighlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeaderHighlight.d.ts","sourceRoot":"","sources":["../../src/HeaderHighlight.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD,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;CACrB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA6C1D,CAAC"}
|
|
@@ -16,10 +16,26 @@ export interface RelatedListProps {
|
|
|
16
16
|
columns?: any[];
|
|
17
17
|
className?: string;
|
|
18
18
|
dataSource?: DataSource;
|
|
19
|
+
/** Object name for i18n field label resolution */
|
|
20
|
+
objectName?: string;
|
|
19
21
|
/** Callback when "New" button is clicked */
|
|
20
22
|
onNew?: () => void;
|
|
21
23
|
/** Callback when "View All" button is clicked */
|
|
22
24
|
onViewAll?: () => void;
|
|
25
|
+
/** Callback when a row Edit action is clicked */
|
|
26
|
+
onRowEdit?: (row: any) => void;
|
|
27
|
+
/** Callback when a row Delete action is clicked */
|
|
28
|
+
onRowDelete?: (row: any) => void;
|
|
29
|
+
/** Page size for pagination (enables pagination when set) */
|
|
30
|
+
pageSize?: number;
|
|
31
|
+
/** Enable column sorting */
|
|
32
|
+
sortable?: boolean;
|
|
33
|
+
/** Enable text filtering */
|
|
34
|
+
filterable?: boolean;
|
|
35
|
+
/** Whether the card is collapsible */
|
|
36
|
+
collapsible?: boolean;
|
|
37
|
+
/** Whether the card starts collapsed (requires collapsible=true) */
|
|
38
|
+
defaultCollapsed?: boolean;
|
|
23
39
|
}
|
|
24
40
|
export declare const RelatedList: React.FC<RelatedListProps>;
|
|
25
41
|
//# sourceMappingURL=RelatedList.d.ts.map
|
|
@@ -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":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAKlE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;IACnB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,mDAAmD;IACnD,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2VlD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SectionGroup as SectionGroupType } from '../../types/src';
|
|
2
|
+
/**
|
|
3
|
+
* ObjectUI
|
|
4
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
import * as React from 'react';
|
|
10
|
+
export interface SectionGroupProps {
|
|
11
|
+
group: SectionGroupType;
|
|
12
|
+
data?: any;
|
|
13
|
+
className?: string;
|
|
14
|
+
objectSchema?: any;
|
|
15
|
+
/** Object name for i18n field label resolution */
|
|
16
|
+
objectName?: string;
|
|
17
|
+
isEditing?: boolean;
|
|
18
|
+
onFieldChange?: (field: string, value: any) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare const SectionGroup: React.FC<SectionGroupProps>;
|
|
21
|
+
//# sourceMappingURL=SectionGroup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionGroup.d.ts","sourceRoot":"","sources":["../../src/SectionGroup.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,gBAAgB,CAAC;IACxB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACrD;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsEpD,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { DetailSection } from './DetailSection';
|
|
|
3
3
|
import { DetailTabs } from './DetailTabs';
|
|
4
4
|
import { RelatedList } from './RelatedList';
|
|
5
5
|
export { DetailView, DetailSection, DetailTabs, RelatedList };
|
|
6
|
+
export { SectionGroup } from './SectionGroup';
|
|
7
|
+
export { HeaderHighlight } from './HeaderHighlight';
|
|
6
8
|
export { inferDetailColumns, isWideFieldType, applyAutoSpan, applyDetailAutoLayout } from './autoLayout';
|
|
7
9
|
export { useDetailTranslation, DETAIL_DEFAULT_TRANSLATIONS, createSafeTranslationHook } from './useDetailTranslation';
|
|
8
10
|
export { RecordComments } from './RecordComments';
|
|
@@ -26,6 +28,8 @@ export type { DetailViewProps } from './DetailView';
|
|
|
26
28
|
export type { DetailSectionProps } from './DetailSection';
|
|
27
29
|
export type { DetailTabsProps } from './DetailTabs';
|
|
28
30
|
export type { RelatedListProps } from './RelatedList';
|
|
31
|
+
export type { SectionGroupProps } from './SectionGroup';
|
|
32
|
+
export type { HeaderHighlightProps } from './HeaderHighlight';
|
|
29
33
|
export type { RecordCommentsProps } from './RecordComments';
|
|
30
34
|
export type { ActivityTimelineProps, ActivityFilterType } from './ActivityTimeline';
|
|
31
35
|
export type { InlineCreateRelatedProps, RelatedFieldDefinition, RelatedRecordOption } from './InlineCreateRelated';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDetailTranslation.d.ts","sourceRoot":"","sources":["../../src/useDetailTranslation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,OAAO,EAAE,MAAM;aAQE,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;EA0B3D;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useDetailTranslation.d.ts","sourceRoot":"","sources":["../../src/useDetailTranslation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,OAAO,EAAE,MAAM;aAQE,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;EA0B3D;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA6C9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB;aAnFd,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;CAsF3D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-detail",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "DetailView plugin for Object UI - comprehensive detail page with sections, tabs, and related lists",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"lucide-react": "^0.576.0",
|
|
28
|
-
"@object-ui/components": "3.1.
|
|
29
|
-
"@object-ui/core": "3.1.
|
|
30
|
-
"@object-ui/fields": "3.1.
|
|
31
|
-
"@object-ui/
|
|
32
|
-
"@object-ui/
|
|
28
|
+
"@object-ui/components": "3.1.2",
|
|
29
|
+
"@object-ui/core": "3.1.2",
|
|
30
|
+
"@object-ui/fields": "3.1.2",
|
|
31
|
+
"@object-ui/types": "3.1.2",
|
|
32
|
+
"@object-ui/react": "3.1.2"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^18.0.0 || ^19.0.0",
|
package/src/DetailSection.tsx
CHANGED
|
@@ -29,6 +29,29 @@ import { getCellRenderer } from '@object-ui/fields';
|
|
|
29
29
|
import type { DetailViewSection as DetailViewSectionType, DetailViewField, FieldMetadata } from '@object-ui/types';
|
|
30
30
|
import { applyDetailAutoLayout } from './autoLayout';
|
|
31
31
|
import { useDetailTranslation } from './useDetailTranslation';
|
|
32
|
+
import { useSafeFieldLabel } from '@object-ui/react';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Compute responsive col-span classes so that col-span never exceeds the
|
|
36
|
+
* visible column count at each Tailwind breakpoint.
|
|
37
|
+
*
|
|
38
|
+
* For columns=1: no span class (always single column)
|
|
39
|
+
* For columns=2: md:col-span-{min(span,2)}
|
|
40
|
+
* For columns>=3: md:col-span-{min(span,2)} lg:col-span-{min(span,3)}
|
|
41
|
+
*/
|
|
42
|
+
export function getResponsiveSpanClass(span: number | undefined, columns: number): string {
|
|
43
|
+
if (!span || span <= 1 || columns <= 1) return '';
|
|
44
|
+
|
|
45
|
+
if (columns === 2) {
|
|
46
|
+
return span >= 2 ? 'md:col-span-2' : '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// columns >= 3: grid-cols-1 md:grid-cols-2 lg:grid-cols-3
|
|
50
|
+
if (span === 2) return 'md:col-span-2';
|
|
51
|
+
if (span >= 3) return 'md:col-span-2 lg:col-span-3';
|
|
52
|
+
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
32
55
|
|
|
33
56
|
export interface DetailSectionProps {
|
|
34
57
|
section: DetailViewSectionType;
|
|
@@ -36,6 +59,8 @@ export interface DetailSectionProps {
|
|
|
36
59
|
className?: string;
|
|
37
60
|
/** Object schema from DataSource for field type enrichment */
|
|
38
61
|
objectSchema?: any;
|
|
62
|
+
/** Object name for i18n field label resolution */
|
|
63
|
+
objectName?: string;
|
|
39
64
|
/** Whether inline editing is active */
|
|
40
65
|
isEditing?: boolean;
|
|
41
66
|
/** Callback when a field value changes during inline editing */
|
|
@@ -47,12 +72,14 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
47
72
|
data,
|
|
48
73
|
className,
|
|
49
74
|
objectSchema,
|
|
75
|
+
objectName,
|
|
50
76
|
isEditing = false,
|
|
51
77
|
onFieldChange,
|
|
52
78
|
}) => {
|
|
53
79
|
const [isCollapsed, setIsCollapsed] = React.useState(section.defaultCollapsed ?? false);
|
|
54
80
|
const [copiedField, setCopiedField] = React.useState<string | null>(null);
|
|
55
81
|
const { t } = useDetailTranslation();
|
|
82
|
+
const { fieldLabel } = useSafeFieldLabel();
|
|
56
83
|
|
|
57
84
|
const handleCopyField = React.useCallback((fieldName: string, value: any) => {
|
|
58
85
|
const textValue = value !== null && value !== undefined ? String(value) : '';
|
|
@@ -62,6 +89,23 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
62
89
|
});
|
|
63
90
|
}, []);
|
|
64
91
|
|
|
92
|
+
// Filter out empty fields when hideEmpty is set
|
|
93
|
+
const visibleFields = section.hideEmpty
|
|
94
|
+
? section.fields.filter((field) => {
|
|
95
|
+
const value = data?.[field.name] ?? field.value;
|
|
96
|
+
return value !== null && value !== undefined && value !== '';
|
|
97
|
+
})
|
|
98
|
+
: section.fields;
|
|
99
|
+
|
|
100
|
+
// Hide entire section when all fields are empty
|
|
101
|
+
if (visibleFields.length === 0) return null;
|
|
102
|
+
|
|
103
|
+
// Apply auto-layout: infer columns and auto-span wide fields
|
|
104
|
+
const { fields: layoutFields, columns: effectiveColumns } = applyDetailAutoLayout(
|
|
105
|
+
visibleFields,
|
|
106
|
+
section.columns
|
|
107
|
+
);
|
|
108
|
+
|
|
65
109
|
const renderField = (field: DetailViewField) => {
|
|
66
110
|
const value = data?.[field.name] ?? field.value;
|
|
67
111
|
|
|
@@ -70,13 +114,9 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
70
114
|
return <SchemaRenderer schema={field.render} data={{ ...data, value }} />;
|
|
71
115
|
}
|
|
72
116
|
|
|
73
|
-
// Calculate span class
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
field.span === 3 ? 'col-span-3' :
|
|
77
|
-
field.span === 4 ? 'col-span-4' :
|
|
78
|
-
field.span === 5 ? 'col-span-5' :
|
|
79
|
-
field.span === 6 ? 'col-span-6' : '';
|
|
117
|
+
// Calculate responsive span class so col-span never exceeds the visible
|
|
118
|
+
// column count at each breakpoint, preventing implicit columns on mobile.
|
|
119
|
+
const spanClass = getResponsiveSpanClass(field.span, effectiveColumns);
|
|
80
120
|
|
|
81
121
|
const displayValue = (() => {
|
|
82
122
|
if (value === null || value === undefined) return <span className="text-muted-foreground/50 text-xs italic">—</span>;
|
|
@@ -91,7 +131,8 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
91
131
|
if (objectDefField.currency && !enrichedField.currency) enrichedField.currency = objectDefField.currency;
|
|
92
132
|
if (objectDefField.precision !== undefined && enrichedField.precision === undefined) enrichedField.precision = objectDefField.precision;
|
|
93
133
|
if (objectDefField.format && !enrichedField.format) enrichedField.format = objectDefField.format;
|
|
94
|
-
|
|
134
|
+
const refTarget = objectDefField.reference_to || objectDefField.reference;
|
|
135
|
+
if (refTarget && !enrichedField.reference_to) enrichedField.reference_to = refTarget;
|
|
95
136
|
if (objectDefField.reference_field && !enrichedField.reference_field) enrichedField.reference_field = objectDefField.reference_field;
|
|
96
137
|
}
|
|
97
138
|
// Use type-aware cell renderer when field type is available (explicit or enriched)
|
|
@@ -110,7 +151,7 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
110
151
|
return (
|
|
111
152
|
<div key={field.name} className={cn("space-y-1.5 group", spanClass)}>
|
|
112
153
|
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
113
|
-
{field.label || field.name}
|
|
154
|
+
{fieldLabel(objectName || '', field.name, field.label || field.name)}
|
|
114
155
|
</div>
|
|
115
156
|
{isEditing && !field.readonly ? (
|
|
116
157
|
<div className="min-h-[44px] sm:min-h-0">
|
|
@@ -172,23 +213,6 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
172
213
|
);
|
|
173
214
|
};
|
|
174
215
|
|
|
175
|
-
// Filter out empty fields when hideEmpty is set
|
|
176
|
-
const visibleFields = section.hideEmpty
|
|
177
|
-
? section.fields.filter((field) => {
|
|
178
|
-
const value = data?.[field.name] ?? field.value;
|
|
179
|
-
return value !== null && value !== undefined && value !== '';
|
|
180
|
-
})
|
|
181
|
-
: section.fields;
|
|
182
|
-
|
|
183
|
-
// Hide entire section when all fields are empty
|
|
184
|
-
if (visibleFields.length === 0) return null;
|
|
185
|
-
|
|
186
|
-
// Apply auto-layout: infer columns and auto-span wide fields
|
|
187
|
-
const { fields: layoutFields, columns: effectiveColumns } = applyDetailAutoLayout(
|
|
188
|
-
visibleFields,
|
|
189
|
-
section.columns
|
|
190
|
-
);
|
|
191
|
-
|
|
192
216
|
const content = (
|
|
193
217
|
<div
|
|
194
218
|
className={cn(
|