@object-ui/plugin-detail 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +41 -41
- package/CHANGELOG.md +11 -0
- package/dist/{AddressField-C07oUOY6.js → AddressField-B1iVr404.js} +1 -1
- package/dist/{AvatarField-VThNABzo.js → AvatarField-Duw4xOLZ.js} +1 -1
- package/dist/{BooleanField-CGHKBzAi.js → BooleanField-CZ4axVeq.js} +1 -1
- package/dist/{CodeField-Co_muhRR.js → CodeField-BSz-mk2v.js} +1 -1
- package/dist/{ColorField-DLid_tFz.js → ColorField-B522ad8m.js} +1 -1
- package/dist/{CurrencyField-Bw-LqANM.js → CurrencyField-Cwr3_pow.js} +1 -1
- package/dist/{DateField-BNHAzMB2.js → DateField-DCo6dxud.js} +1 -1
- package/dist/{DateTimeField-DjAyn_DQ.js → DateTimeField-BWfBuANO.js} +1 -1
- package/dist/{EmailField-xoNcSppb.js → EmailField-CpwbdVCU.js} +1 -1
- package/dist/{FileField-DbNJwjU2.js → FileField-DVAUAJ8e.js} +1 -1
- package/dist/{GeolocationField-C1AnS6VV.js → GeolocationField-DNCKitgo.js} +1 -1
- package/dist/{GridField-DATAHIKf.js → GridField-DSblZNfp.js} +1 -1
- package/dist/{ImageField-CEKJpyJp.js → ImageField-DBAlnMon.js} +1 -1
- package/dist/{LocationField-jDWXjlpx.js → LocationField-DsHsXA6R.js} +1 -1
- package/dist/{LookupField-DQ08L9UQ.js → LookupField-CsT0QQz2.js} +1 -1
- package/dist/{MasterDetailField-Dbk529Ea.js → MasterDetailField-Db8b7Gqs.js} +1 -1
- package/dist/{NumberField-BVroN9aV.js → NumberField-0IGp7lcA.js} +1 -1
- package/dist/{ObjectField-CT3l_IHW.js → ObjectField-BLApgJtS.js} +1 -1
- package/dist/{PasswordField-DweVLEE0.js → PasswordField-pHKyNlmo.js} +1 -1
- package/dist/{PercentField-ZpWUK97K.js → PercentField-CwgKmlIb.js} +1 -1
- package/dist/{PhoneField-mw-9fqZ_.js → PhoneField-lKtbYOdN.js} +1 -1
- package/dist/{QRCodeField-Cbb9ck59.js → QRCodeField-BTTasT3w.js} +1 -1
- package/dist/{RatingField-CSqgLS6t.js → RatingField-De2X-l44.js} +1 -1
- package/dist/{RichTextField-BpfBOd99.js → RichTextField-B5QnvUOr.js} +1 -1
- package/dist/{SelectField-B9Ei-5jl.js → SelectField-C9AZRHWu.js} +1 -1
- package/dist/{SignatureField-DgGpHnQ8.js → SignatureField-BgcEmYzd.js} +1 -1
- package/dist/{SliderField-C6HvOHd8.js → SliderField-BzrttVOY.js} +1 -1
- package/dist/{TextAreaField-BK3RgzY3.js → TextAreaField-DSE_CaU6.js} +1 -1
- package/dist/{TextField-Bvzx3atT.js → TextField-DFQ4T9PR.js} +1 -1
- package/dist/{TimeField-Cuz9-Uai.js → TimeField-F0cfmsps.js} +1 -1
- package/dist/{UrlField-B6XHTV73.js → UrlField-DLXrFIH-.js} +1 -1
- package/dist/{UserField-ooTul2d6.js → UserField-PXMmxJY9.js} +1 -1
- package/dist/{index-CnlyRfY_.js → index-qQ1C-yUR.js} +21560 -21045
- package/dist/index.js +20 -18
- package/dist/index.umd.cjs +31 -31
- package/dist/plugin-detail.css +1 -1
- package/dist/src/DetailSection.d.ts +2 -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 +8 -2
- package/src/DetailView.tsx +271 -61
- package/src/HeaderHighlight.tsx +67 -0
- package/src/RelatedList.tsx +287 -21
- package/src/SectionGroup.tsx +101 -0
- package/src/__tests__/DetailSection.test.tsx +1 -1
- 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
|
@@ -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,CAwuBhD,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":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACzG,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACtH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACpF,YAAY,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACnH,YAAY,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnF,YAAY,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAChF,YAAY,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC7E,YAAY,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC9E,YAAY,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACnF,YAAY,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC5F,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC7F,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -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.1",
|
|
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/
|
|
30
|
-
"@object-ui/
|
|
31
|
-
"@object-ui/react": "3.1.
|
|
32
|
-
"@object-ui/types": "3.1.
|
|
28
|
+
"@object-ui/components": "3.1.1",
|
|
29
|
+
"@object-ui/fields": "3.1.1",
|
|
30
|
+
"@object-ui/core": "3.1.1",
|
|
31
|
+
"@object-ui/react": "3.1.1",
|
|
32
|
+
"@object-ui/types": "3.1.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^18.0.0 || ^19.0.0",
|
package/src/DetailSection.tsx
CHANGED
|
@@ -29,6 +29,7 @@ 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';
|
|
32
33
|
|
|
33
34
|
export interface DetailSectionProps {
|
|
34
35
|
section: DetailViewSectionType;
|
|
@@ -36,6 +37,8 @@ export interface DetailSectionProps {
|
|
|
36
37
|
className?: string;
|
|
37
38
|
/** Object schema from DataSource for field type enrichment */
|
|
38
39
|
objectSchema?: any;
|
|
40
|
+
/** Object name for i18n field label resolution */
|
|
41
|
+
objectName?: string;
|
|
39
42
|
/** Whether inline editing is active */
|
|
40
43
|
isEditing?: boolean;
|
|
41
44
|
/** Callback when a field value changes during inline editing */
|
|
@@ -47,12 +50,14 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
47
50
|
data,
|
|
48
51
|
className,
|
|
49
52
|
objectSchema,
|
|
53
|
+
objectName,
|
|
50
54
|
isEditing = false,
|
|
51
55
|
onFieldChange,
|
|
52
56
|
}) => {
|
|
53
57
|
const [isCollapsed, setIsCollapsed] = React.useState(section.defaultCollapsed ?? false);
|
|
54
58
|
const [copiedField, setCopiedField] = React.useState<string | null>(null);
|
|
55
59
|
const { t } = useDetailTranslation();
|
|
60
|
+
const { fieldLabel } = useSafeFieldLabel();
|
|
56
61
|
|
|
57
62
|
const handleCopyField = React.useCallback((fieldName: string, value: any) => {
|
|
58
63
|
const textValue = value !== null && value !== undefined ? String(value) : '';
|
|
@@ -91,7 +96,8 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
91
96
|
if (objectDefField.currency && !enrichedField.currency) enrichedField.currency = objectDefField.currency;
|
|
92
97
|
if (objectDefField.precision !== undefined && enrichedField.precision === undefined) enrichedField.precision = objectDefField.precision;
|
|
93
98
|
if (objectDefField.format && !enrichedField.format) enrichedField.format = objectDefField.format;
|
|
94
|
-
|
|
99
|
+
const refTarget = objectDefField.reference_to || objectDefField.reference;
|
|
100
|
+
if (refTarget && !enrichedField.reference_to) enrichedField.reference_to = refTarget;
|
|
95
101
|
if (objectDefField.reference_field && !enrichedField.reference_field) enrichedField.reference_field = objectDefField.reference_field;
|
|
96
102
|
}
|
|
97
103
|
// Use type-aware cell renderer when field type is available (explicit or enriched)
|
|
@@ -110,7 +116,7 @@ export const DetailSection: React.FC<DetailSectionProps> = ({
|
|
|
110
116
|
return (
|
|
111
117
|
<div key={field.name} className={cn("space-y-1.5 group", spanClass)}>
|
|
112
118
|
<div className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
113
|
-
{field.label || field.name}
|
|
119
|
+
{fieldLabel(objectName || '', field.name, field.label || field.name)}
|
|
114
120
|
</div>
|
|
115
121
|
{isEditing && !field.readonly ? (
|
|
116
122
|
<div className="min-h-[44px] sm:min-h-0">
|
package/src/DetailView.tsx
CHANGED
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
TooltipContent,
|
|
22
22
|
TooltipProvider,
|
|
23
23
|
TooltipTrigger,
|
|
24
|
+
Tabs,
|
|
25
|
+
TabsList,
|
|
26
|
+
TabsTrigger,
|
|
27
|
+
TabsContent,
|
|
24
28
|
} from '@object-ui/components';
|
|
25
29
|
import {
|
|
26
30
|
ArrowLeft,
|
|
@@ -40,6 +44,8 @@ import {
|
|
|
40
44
|
import { DetailSection } from './DetailSection';
|
|
41
45
|
import { DetailTabs } from './DetailTabs';
|
|
42
46
|
import { RelatedList } from './RelatedList';
|
|
47
|
+
import { SectionGroup } from './SectionGroup';
|
|
48
|
+
import { HeaderHighlight } from './HeaderHighlight';
|
|
43
49
|
import { RecordComments } from './RecordComments';
|
|
44
50
|
import { ActivityTimeline } from './ActivityTimeline';
|
|
45
51
|
import { SchemaRenderer } from '@object-ui/react';
|
|
@@ -47,6 +53,9 @@ import { buildExpandFields } from '@object-ui/core';
|
|
|
47
53
|
import type { DetailViewSchema, DataSource } from '@object-ui/types';
|
|
48
54
|
import { useDetailTranslation } from './useDetailTranslation';
|
|
49
55
|
|
|
56
|
+
/** Default page size for related lists in the detail view */
|
|
57
|
+
const DEFAULT_RELATED_PAGE_SIZE = 5;
|
|
58
|
+
|
|
50
59
|
export interface DetailViewProps {
|
|
51
60
|
schema: DetailViewSchema;
|
|
52
61
|
dataSource?: DataSource;
|
|
@@ -288,6 +297,42 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
288
297
|
return () => document.removeEventListener('keydown', handler);
|
|
289
298
|
}, [schema.recordNavigation]);
|
|
290
299
|
|
|
300
|
+
// Auto-discover related lists from objectSchema reference fields
|
|
301
|
+
const discoveredRelated = React.useMemo(() => {
|
|
302
|
+
if (!schema.autoDiscoverRelated || !objectSchema?.fields) return [];
|
|
303
|
+
// Only auto-discover when no explicit related config is provided
|
|
304
|
+
if (schema.related && schema.related.length > 0) return [];
|
|
305
|
+
const refs: Array<{ title: string; type: 'list' | 'grid' | 'table'; objectName: string; referenceField: string }> = [];
|
|
306
|
+
const fields = objectSchema.fields;
|
|
307
|
+
for (const [fieldName, fieldDef] of Object.entries<any>(fields)) {
|
|
308
|
+
const refTarget = fieldDef?.reference_to || fieldDef?.reference;
|
|
309
|
+
if (
|
|
310
|
+
fieldDef &&
|
|
311
|
+
(fieldDef.type === 'lookup' || fieldDef.type === 'master_detail') &&
|
|
312
|
+
refTarget
|
|
313
|
+
) {
|
|
314
|
+
refs.push({
|
|
315
|
+
title: fieldDef.label || fieldName.charAt(0).toUpperCase() + fieldName.slice(1),
|
|
316
|
+
type: 'table',
|
|
317
|
+
objectName: refTarget,
|
|
318
|
+
referenceField: fieldName,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return refs;
|
|
323
|
+
}, [schema.autoDiscoverRelated, schema.related, objectSchema]);
|
|
324
|
+
|
|
325
|
+
// Merge explicit and auto-discovered related lists
|
|
326
|
+
const effectiveRelated: NonNullable<DetailViewSchema['related']> = React.useMemo(() => {
|
|
327
|
+
if (schema.related && schema.related.length > 0) return schema.related;
|
|
328
|
+
return discoveredRelated.map((r) => ({
|
|
329
|
+
title: r.title,
|
|
330
|
+
type: r.type,
|
|
331
|
+
api: r.objectName,
|
|
332
|
+
data: [] as any[],
|
|
333
|
+
}));
|
|
334
|
+
}, [schema.related, discoveredRelated]);
|
|
335
|
+
|
|
291
336
|
if (loading || schema.loading) {
|
|
292
337
|
return (
|
|
293
338
|
<div className={cn('space-y-4', className)}>
|
|
@@ -427,7 +472,7 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
427
472
|
<SchemaRenderer key={index} schema={action} data={data} />
|
|
428
473
|
))}
|
|
429
474
|
|
|
430
|
-
{/* Inline Edit Toggle */}
|
|
475
|
+
{/* Inline Edit Toggle - hidden on mobile, accessible via more menu */}
|
|
431
476
|
{inlineEdit && (
|
|
432
477
|
<Tooltip>
|
|
433
478
|
<TooltipTrigger asChild>
|
|
@@ -435,7 +480,7 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
435
480
|
variant={isInlineEditing ? 'default' : 'outline'}
|
|
436
481
|
size="sm"
|
|
437
482
|
onClick={handleInlineEditToggle}
|
|
438
|
-
className="gap-2"
|
|
483
|
+
className="gap-2 hidden sm:inline-flex"
|
|
439
484
|
>
|
|
440
485
|
{isInlineEditing ? (
|
|
441
486
|
<>
|
|
@@ -456,21 +501,21 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
456
501
|
</Tooltip>
|
|
457
502
|
)}
|
|
458
503
|
|
|
459
|
-
{/* Share Button */}
|
|
504
|
+
{/* Share Button - hidden on mobile, accessible via more menu */}
|
|
460
505
|
<Tooltip>
|
|
461
506
|
<TooltipTrigger asChild>
|
|
462
|
-
<Button variant="outline" size="icon" onClick={handleShare}>
|
|
507
|
+
<Button variant="outline" size="icon" onClick={handleShare} className="hidden sm:inline-flex">
|
|
463
508
|
<Share2 className="h-4 w-4" />
|
|
464
509
|
</Button>
|
|
465
510
|
</TooltipTrigger>
|
|
466
511
|
<TooltipContent>{t('detail.share')}</TooltipContent>
|
|
467
512
|
</Tooltip>
|
|
468
513
|
|
|
469
|
-
{/* Edit Button */}
|
|
514
|
+
{/* Edit Button - hidden on mobile, accessible via more menu */}
|
|
470
515
|
{schema.showEdit && (
|
|
471
516
|
<Tooltip>
|
|
472
517
|
<TooltipTrigger asChild>
|
|
473
|
-
<Button variant="default" onClick={handleEdit} className="gap-2">
|
|
518
|
+
<Button variant="default" onClick={handleEdit} className="gap-2 hidden sm:inline-flex">
|
|
474
519
|
<Edit className="h-4 w-4" />
|
|
475
520
|
<span className="hidden sm:inline">{t('detail.edit')}</span>
|
|
476
521
|
</Button>
|
|
@@ -492,6 +537,24 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
492
537
|
<TooltipContent>{t('detail.moreActions')}</TooltipContent>
|
|
493
538
|
</Tooltip>
|
|
494
539
|
<DropdownMenuContent align="end" className="w-[calc(100vw-2rem)] sm:w-48 max-h-[60vh] overflow-y-auto">
|
|
540
|
+
{/* Mobile-only: Share, Edit, Inline Edit */}
|
|
541
|
+
<DropdownMenuItem onClick={handleShare} className="sm:hidden">
|
|
542
|
+
<Share2 className="h-4 w-4 mr-2" />
|
|
543
|
+
{t('detail.share')}
|
|
544
|
+
</DropdownMenuItem>
|
|
545
|
+
{schema.showEdit && (
|
|
546
|
+
<DropdownMenuItem onClick={handleEdit} className="sm:hidden">
|
|
547
|
+
<Edit className="h-4 w-4 mr-2" />
|
|
548
|
+
{t('detail.edit')}
|
|
549
|
+
</DropdownMenuItem>
|
|
550
|
+
)}
|
|
551
|
+
{inlineEdit && (
|
|
552
|
+
<DropdownMenuItem onClick={handleInlineEditToggle} className="sm:hidden">
|
|
553
|
+
<Edit className="h-4 w-4 mr-2" />
|
|
554
|
+
{isInlineEditing ? t('detail.save') : t('detail.editInline')}
|
|
555
|
+
</DropdownMenuItem>
|
|
556
|
+
)}
|
|
557
|
+
<DropdownMenuSeparator className="sm:hidden" />
|
|
495
558
|
<DropdownMenuItem onClick={handleDuplicate}>
|
|
496
559
|
<Copy className="h-4 w-4 mr-2" />
|
|
497
560
|
{t('detail.duplicate')}
|
|
@@ -528,70 +591,217 @@ export const DetailView: React.FC<DetailViewProps> = ({
|
|
|
528
591
|
</div>
|
|
529
592
|
)}
|
|
530
593
|
|
|
531
|
-
{/*
|
|
532
|
-
{schema.
|
|
533
|
-
<
|
|
534
|
-
|
|
594
|
+
{/* Header Highlight Area */}
|
|
595
|
+
{schema.highlightFields && schema.highlightFields.length > 0 && (
|
|
596
|
+
<HeaderHighlight fields={schema.highlightFields} data={data} objectName={schema.objectName} />
|
|
597
|
+
)}
|
|
598
|
+
|
|
599
|
+
{/* Auto Tabs mode: wrap sections, related, activity into tabs */}
|
|
600
|
+
{schema.autoTabs && !schema.tabs?.length ? (
|
|
601
|
+
<Tabs defaultValue="details" className="w-full">
|
|
602
|
+
<TabsList className="w-full justify-start border-b rounded-none bg-transparent p-0">
|
|
603
|
+
<TabsTrigger
|
|
604
|
+
value="details"
|
|
605
|
+
className="relative rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
606
|
+
>
|
|
607
|
+
{t('detail.details')}
|
|
608
|
+
</TabsTrigger>
|
|
609
|
+
{effectiveRelated.length > 0 && (
|
|
610
|
+
<TabsTrigger
|
|
611
|
+
value="related"
|
|
612
|
+
className="relative rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
613
|
+
>
|
|
614
|
+
<span className="flex items-center gap-1.5">
|
|
615
|
+
{t('detail.related')}
|
|
616
|
+
<Badge variant="secondary" className="text-xs">{effectiveRelated.length}</Badge>
|
|
617
|
+
</span>
|
|
618
|
+
</TabsTrigger>
|
|
619
|
+
)}
|
|
620
|
+
{schema.activities && schema.activities.length > 0 && (
|
|
621
|
+
<TabsTrigger
|
|
622
|
+
value="activity"
|
|
623
|
+
className="relative rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent"
|
|
624
|
+
>
|
|
625
|
+
<span className="flex items-center gap-1.5">
|
|
626
|
+
{t('detail.activity')}
|
|
627
|
+
<Badge variant="secondary" className="text-xs">{schema.activities.length}</Badge>
|
|
628
|
+
</span>
|
|
629
|
+
</TabsTrigger>
|
|
630
|
+
)}
|
|
631
|
+
</TabsList>
|
|
632
|
+
|
|
633
|
+
{/* Details Tab Content */}
|
|
634
|
+
<TabsContent value="details" className="mt-4">
|
|
635
|
+
<div className="space-y-3 sm:space-y-4">
|
|
636
|
+
{/* Section Groups */}
|
|
637
|
+
{schema.sectionGroups && schema.sectionGroups.length > 0 && (
|
|
638
|
+
schema.sectionGroups.map((group, index) => (
|
|
639
|
+
<SectionGroup
|
|
640
|
+
key={index}
|
|
641
|
+
group={group}
|
|
642
|
+
data={{ ...data, ...editedValues }}
|
|
643
|
+
objectSchema={objectSchema}
|
|
644
|
+
objectName={schema.objectName}
|
|
645
|
+
isEditing={isInlineEditing}
|
|
646
|
+
onFieldChange={handleInlineFieldChange}
|
|
647
|
+
/>
|
|
648
|
+
))
|
|
649
|
+
)}
|
|
650
|
+
{schema.sections && schema.sections.length > 0 && (
|
|
651
|
+
schema.sections.map((section, index) => (
|
|
652
|
+
<DetailSection
|
|
653
|
+
key={index}
|
|
654
|
+
section={section}
|
|
655
|
+
data={{ ...data, ...editedValues }}
|
|
656
|
+
objectSchema={objectSchema}
|
|
657
|
+
objectName={schema.objectName}
|
|
658
|
+
isEditing={isInlineEditing}
|
|
659
|
+
onFieldChange={handleInlineFieldChange}
|
|
660
|
+
/>
|
|
661
|
+
))
|
|
662
|
+
)}
|
|
663
|
+
{schema.fields && schema.fields.length > 0 && !schema.sections?.length && (
|
|
664
|
+
<DetailSection
|
|
665
|
+
section={{
|
|
666
|
+
fields: schema.fields,
|
|
667
|
+
columns: schema.columns,
|
|
668
|
+
}}
|
|
669
|
+
data={{ ...data, ...editedValues }}
|
|
670
|
+
objectSchema={objectSchema}
|
|
671
|
+
objectName={schema.objectName}
|
|
672
|
+
isEditing={isInlineEditing}
|
|
673
|
+
onFieldChange={handleInlineFieldChange}
|
|
674
|
+
/>
|
|
675
|
+
)}
|
|
676
|
+
{/* Comments in details tab */}
|
|
677
|
+
{schema.comments && (
|
|
678
|
+
<RecordComments
|
|
679
|
+
comments={schema.comments}
|
|
680
|
+
onAddComment={schema.onAddComment}
|
|
681
|
+
/>
|
|
682
|
+
)}
|
|
683
|
+
</div>
|
|
684
|
+
</TabsContent>
|
|
685
|
+
|
|
686
|
+
{/* Related Tab Content */}
|
|
687
|
+
{effectiveRelated.length > 0 && (
|
|
688
|
+
<TabsContent value="related" className="mt-4">
|
|
689
|
+
<div className="space-y-4">
|
|
690
|
+
{effectiveRelated.map((related, index) => (
|
|
691
|
+
<RelatedList
|
|
692
|
+
key={index}
|
|
693
|
+
title={related.title}
|
|
694
|
+
type={related.type}
|
|
695
|
+
api={related.api}
|
|
696
|
+
data={related.data}
|
|
697
|
+
columns={related.columns as any}
|
|
698
|
+
dataSource={dataSource}
|
|
699
|
+
objectName={related.api}
|
|
700
|
+
collapsible
|
|
701
|
+
pageSize={DEFAULT_RELATED_PAGE_SIZE}
|
|
702
|
+
/>
|
|
703
|
+
))}
|
|
704
|
+
</div>
|
|
705
|
+
</TabsContent>
|
|
706
|
+
)}
|
|
707
|
+
|
|
708
|
+
{/* Activity Tab Content */}
|
|
709
|
+
{schema.activities && schema.activities.length > 0 && (
|
|
710
|
+
<TabsContent value="activity" className="mt-4">
|
|
711
|
+
<ActivityTimeline activities={schema.activities} />
|
|
712
|
+
</TabsContent>
|
|
713
|
+
)}
|
|
714
|
+
</Tabs>
|
|
715
|
+
) : (
|
|
716
|
+
<>
|
|
717
|
+
{/* Section Groups */}
|
|
718
|
+
{schema.sectionGroups && schema.sectionGroups.length > 0 && (
|
|
719
|
+
<div className="space-y-3 sm:space-y-4">
|
|
720
|
+
{schema.sectionGroups.map((group, index) => (
|
|
721
|
+
<SectionGroup
|
|
722
|
+
key={index}
|
|
723
|
+
group={group}
|
|
724
|
+
data={{ ...data, ...editedValues }}
|
|
725
|
+
objectSchema={objectSchema}
|
|
726
|
+
objectName={schema.objectName}
|
|
727
|
+
isEditing={isInlineEditing}
|
|
728
|
+
onFieldChange={handleInlineFieldChange}
|
|
729
|
+
/>
|
|
730
|
+
))}
|
|
731
|
+
</div>
|
|
732
|
+
)}
|
|
733
|
+
|
|
734
|
+
{/* Sections */}
|
|
735
|
+
{schema.sections && schema.sections.length > 0 && (
|
|
736
|
+
<div className="space-y-3 sm:space-y-4">
|
|
737
|
+
{schema.sections.map((section, index) => (
|
|
738
|
+
<DetailSection
|
|
739
|
+
key={index}
|
|
740
|
+
section={section}
|
|
741
|
+
data={{ ...data, ...editedValues }}
|
|
742
|
+
objectSchema={objectSchema}
|
|
743
|
+
objectName={schema.objectName}
|
|
744
|
+
isEditing={isInlineEditing}
|
|
745
|
+
onFieldChange={handleInlineFieldChange}
|
|
746
|
+
/>
|
|
747
|
+
))}
|
|
748
|
+
</div>
|
|
749
|
+
)}
|
|
750
|
+
|
|
751
|
+
{/* Direct Fields (if no sections) */}
|
|
752
|
+
{schema.fields && schema.fields.length > 0 && !schema.sections?.length && (
|
|
535
753
|
<DetailSection
|
|
536
|
-
|
|
537
|
-
|
|
754
|
+
section={{
|
|
755
|
+
fields: schema.fields,
|
|
756
|
+
columns: schema.columns,
|
|
757
|
+
}}
|
|
538
758
|
data={{ ...data, ...editedValues }}
|
|
539
759
|
objectSchema={objectSchema}
|
|
760
|
+
objectName={schema.objectName}
|
|
540
761
|
isEditing={isInlineEditing}
|
|
541
762
|
onFieldChange={handleInlineFieldChange}
|
|
542
763
|
/>
|
|
543
|
-
)
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
764
|
+
)}
|
|
765
|
+
|
|
766
|
+
{/* Tabs */}
|
|
767
|
+
{schema.tabs && schema.tabs.length > 0 && (
|
|
768
|
+
<DetailTabs tabs={schema.tabs} data={data} />
|
|
769
|
+
)}
|
|
770
|
+
|
|
771
|
+
{/* Related Lists */}
|
|
772
|
+
{effectiveRelated.length > 0 && (
|
|
773
|
+
<div className="space-y-4">
|
|
774
|
+
<h2 className="text-xl font-semibold">{t('detail.related')}</h2>
|
|
775
|
+
{effectiveRelated.map((related, index) => (
|
|
776
|
+
<RelatedList
|
|
777
|
+
key={index}
|
|
778
|
+
title={related.title}
|
|
779
|
+
type={related.type}
|
|
780
|
+
api={related.api}
|
|
781
|
+
data={related.data}
|
|
782
|
+
columns={related.columns as any}
|
|
783
|
+
dataSource={dataSource}
|
|
784
|
+
objectName={related.api}
|
|
785
|
+
collapsible
|
|
786
|
+
pageSize={DEFAULT_RELATED_PAGE_SIZE}
|
|
787
|
+
/>
|
|
788
|
+
))}
|
|
789
|
+
</div>
|
|
790
|
+
)}
|
|
565
791
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
<RelatedList
|
|
572
|
-
key={index}
|
|
573
|
-
title={related.title}
|
|
574
|
-
type={related.type}
|
|
575
|
-
api={related.api}
|
|
576
|
-
data={related.data}
|
|
577
|
-
columns={related.columns as any}
|
|
578
|
-
dataSource={dataSource}
|
|
792
|
+
{/* Comments */}
|
|
793
|
+
{schema.comments && (
|
|
794
|
+
<RecordComments
|
|
795
|
+
comments={schema.comments}
|
|
796
|
+
onAddComment={schema.onAddComment}
|
|
579
797
|
/>
|
|
580
|
-
)
|
|
581
|
-
</div>
|
|
582
|
-
)}
|
|
583
|
-
|
|
584
|
-
{/* Comments */}
|
|
585
|
-
{schema.comments && (
|
|
586
|
-
<RecordComments
|
|
587
|
-
comments={schema.comments}
|
|
588
|
-
onAddComment={schema.onAddComment}
|
|
589
|
-
/>
|
|
590
|
-
)}
|
|
798
|
+
)}
|
|
591
799
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
800
|
+
{/* Activity Timeline */}
|
|
801
|
+
{schema.activities && schema.activities.length > 0 && (
|
|
802
|
+
<ActivityTimeline activities={schema.activities} />
|
|
803
|
+
)}
|
|
804
|
+
</>
|
|
595
805
|
)}
|
|
596
806
|
|
|
597
807
|
{/* Custom Footer */}
|