@object-ui/app-shell 4.5.0 → 4.6.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 +17 -0
- package/README.md +21 -0
- package/dist/console/AppContent.js +6 -39
- package/dist/console/ConsoleShell.js +45 -4
- package/dist/console/home/AppCard.d.ts +2 -1
- package/dist/console/home/AppCard.js +24 -5
- package/dist/console/home/HomePage.js +29 -7
- package/dist/console/home/QuickActions.js +13 -7
- package/dist/console/home/RecentApps.js +12 -5
- package/dist/console/home/StarredApps.js +12 -5
- package/dist/context/FavoritesProvider.d.ts +9 -12
- package/dist/context/FavoritesProvider.js +83 -37
- package/dist/context/RecentItemsProvider.d.ts +45 -0
- package/dist/context/RecentItemsProvider.js +139 -0
- package/dist/context/UserStateAdapters.d.ts +61 -0
- package/dist/context/UserStateAdapters.js +141 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.js +2 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useRecentItems.d.ts +9 -17
- package/dist/hooks/useRecentItems.js +9 -46
- package/dist/hooks/useTrackRouteAsRecent.d.ts +18 -0
- package/dist/hooks/useTrackRouteAsRecent.js +91 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/layout/PageHeader.d.ts +29 -2
- package/dist/layout/PageHeader.js +20 -2
- package/dist/views/ActionParamDialog.js +16 -2
- package/dist/views/ObjectView.js +63 -164
- package/dist/views/RecordDetailView.d.ts +20 -1
- package/dist/views/RecordDetailView.js +23 -9
- package/package.json +24 -24
|
@@ -47,8 +47,11 @@ const AUDIT_FIELD_NAMES = new Set(['created_at', 'created_by', 'updated_at', 'up
|
|
|
47
47
|
const HIDDEN_SYSTEM_FIELD_NAMES = new Set([
|
|
48
48
|
'organization_id', 'tenant_id', 'is_deleted', 'deleted_at',
|
|
49
49
|
]);
|
|
50
|
-
export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
51
|
-
const
|
|
50
|
+
export function RecordDetailView({ dataSource, objects, onEdit, objectNameOverride, recordIdOverride, embedded }) {
|
|
51
|
+
const params = useParams();
|
|
52
|
+
const appName = params.appName;
|
|
53
|
+
const objectName = objectNameOverride ?? params.objectName;
|
|
54
|
+
const recordId = recordIdOverride ?? params.recordId;
|
|
52
55
|
const { showDebug } = useMetadataInspector();
|
|
53
56
|
const { user } = useAuth();
|
|
54
57
|
const navigate = useNavigate();
|
|
@@ -64,8 +67,9 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
64
67
|
const [recordTitle, setRecordTitle] = useState();
|
|
65
68
|
const objectDef = objects.find((o) => o.name === objectName);
|
|
66
69
|
// Publish record title to the navigation context so the top-bar breadcrumb
|
|
67
|
-
// can display "Acme Platform Upgrade" instead of "#9U1_MmmxjiGR…".
|
|
68
|
-
|
|
70
|
+
// can display "Acme Platform Upgrade" instead of "#9U1_MmmxjiGR…". Skip
|
|
71
|
+
// when embedded (drawer/split): the parent list route owns the breadcrumb.
|
|
72
|
+
useRecordBreadcrumbTitle(embedded ? undefined : recordTitle);
|
|
69
73
|
// Use the URL recordId as-is — it contains the actual record id.
|
|
70
74
|
// Navigation code passes `record.id || record._id` directly into the URL
|
|
71
75
|
// without adding any prefix, so no stripping is needed.
|
|
@@ -734,7 +738,17 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
734
738
|
title: sec.name ? sectionLabel(objectDef.name, sec.name, sec.title || sec.name) : sec.title,
|
|
735
739
|
collapsible: sec.collapsible,
|
|
736
740
|
defaultCollapsed: sec.defaultCollapsed,
|
|
737
|
-
fields: (sec.fields || [])
|
|
741
|
+
fields: (sec.fields || [])
|
|
742
|
+
.filter((f) => {
|
|
743
|
+
// Honor `hidden: true` on a field def even when the form
|
|
744
|
+
// section explicitly lists it. Hidden fields are typically
|
|
745
|
+
// internal artifacts (e.g. database URL, environment id)
|
|
746
|
+
// that platform actions read but end-users shouldn't see.
|
|
747
|
+
const fieldName = typeof f === 'string' ? f : f.name;
|
|
748
|
+
const fieldDef = objectDef.fields?.[fieldName];
|
|
749
|
+
return !fieldDef?.hidden;
|
|
750
|
+
})
|
|
751
|
+
.map((f) => {
|
|
738
752
|
const fieldName = typeof f === 'string' ? f : f.name;
|
|
739
753
|
const fieldDef = objectDef.fields[fieldName];
|
|
740
754
|
if (!fieldDef) {
|
|
@@ -760,7 +774,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
760
774
|
// redundant "Details" heading).
|
|
761
775
|
showBorder: false,
|
|
762
776
|
fields: Object.keys(objectDef.fields || {})
|
|
763
|
-
.filter(key => !AUDIT_FIELD_NAMES.has(key) && !HIDDEN_SYSTEM_FIELD_NAMES.has(key))
|
|
777
|
+
.filter(key => !AUDIT_FIELD_NAMES.has(key) && !HIDDEN_SYSTEM_FIELD_NAMES.has(key) && !objectDef.fields[key]?.hidden)
|
|
764
778
|
.map(key => {
|
|
765
779
|
const fieldDef = objectDef.fields[key];
|
|
766
780
|
const refTarget = fieldDef.reference_to || fieldDef.reference;
|
|
@@ -954,7 +968,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
954
968
|
type: 'detail-view',
|
|
955
969
|
objectName: objectDef.name,
|
|
956
970
|
resourceId: pureRecordId,
|
|
957
|
-
showBack:
|
|
971
|
+
showBack: !embedded,
|
|
958
972
|
onBack: 'history',
|
|
959
973
|
// Hide the Edit button for objects whose lifecycle isn't user-managed
|
|
960
974
|
// (approval requests, audit logs, better-auth tables, …). The
|
|
@@ -985,7 +999,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
985
999
|
}),
|
|
986
1000
|
};
|
|
987
1001
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
988
|
-
}, [objectDef?.name, pureRecordId, childRelatedData, actionRefreshKey, appName, navigate, dataSource, t, objectLabel, objects, historyEnabled, historyEntries, historyLoading, approvals.available, approvals.processes, approvals.canSubmit, approvals.canRecall, approvals.pendingRequest, approvals.latestRequest]);
|
|
1002
|
+
}, [objectDef?.name, pureRecordId, childRelatedData, actionRefreshKey, appName, navigate, dataSource, t, objectLabel, objects, historyEnabled, historyEntries, historyLoading, approvals.available, approvals.processes, approvals.canSubmit, approvals.canRecall, approvals.pendingRequest, approvals.latestRequest, embedded]);
|
|
989
1003
|
if (isLoading) {
|
|
990
1004
|
return _jsx(SkeletonDetail, {});
|
|
991
1005
|
}
|
|
@@ -993,7 +1007,7 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
993
1007
|
return (_jsx("div", { className: "flex h-full items-center justify-center p-4", children: _jsxs(Empty, { children: [_jsx("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: _jsx(Database, { className: "h-6 w-6 text-muted-foreground" }) }), _jsx(EmptyTitle, { children: t('empty.objectNotFound') }), _jsx(EmptyDescription, { children: t('empty.objectNotFoundDescription', { name: objectName }) })] }) }));
|
|
994
1008
|
}
|
|
995
1009
|
if (assignedPage) {
|
|
996
|
-
return (_jsx(RecordContextProvider, { objectName: objectName, recordId: pureRecordId, data: pageRecord, objectSchema: objectDef, dataSource: dataSource, children: _jsx(ActionProvider, { context: { record: pageRecord || {}, objectName, user: currentUser }, onConfirm: confirmHandler, onToast: toastHandler, onNavigate: navigateHandler, onParamCollection: paramCollectionHandler, handlers: { api: apiHandler, flow: flowHandler, script: serverActionHandler, modal: serverActionHandler, approval: approvalHandler }, children: _jsx("div", { className: "bg-background p-3 sm:p-4 lg:p-6", children: _jsx(SchemaRenderer, { schema: assignedPage }) }) }) }));
|
|
1010
|
+
return (_jsx(RecordContextProvider, { objectName: objectName, recordId: pureRecordId, data: pageRecord, objectSchema: objectDef, dataSource: dataSource, embedded: embedded, children: _jsx(ActionProvider, { context: { record: pageRecord || {}, objectName, user: currentUser }, onConfirm: confirmHandler, onToast: toastHandler, onNavigate: navigateHandler, onParamCollection: paramCollectionHandler, handlers: { api: apiHandler, flow: flowHandler, script: serverActionHandler, modal: serverActionHandler, approval: approvalHandler }, children: _jsx("div", { className: "bg-background p-3 sm:p-4 lg:p-6", children: _jsx(SchemaRenderer, { schema: assignedPage }) }) }) }));
|
|
997
1011
|
}
|
|
998
1012
|
return (_jsxs("div", { className: "h-full bg-background overflow-hidden flex flex-col relative", children: [_jsxs("div", { className: "absolute top-2 sm:top-4 right-2 sm:right-4 z-50 flex items-center gap-2", children: [_jsx(ManagedByBadge, { managedBy: objectDef?.managedBy }), recordViewers.length > 0 && (_jsxs("div", { className: "flex items-center gap-1.5", title: t('recordDetail.viewersTooltip'), children: [_jsx(Users, { className: "h-3.5 w-3.5 text-muted-foreground" }), _jsx(PresenceAvatars, { users: recordViewers, size: "sm", maxVisible: 4, showStatus: true })] }))] }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-row", children: [_jsx("div", { className: "flex-1 overflow-auto p-3 sm:p-4 lg:p-6 scroll-pb-48", children: _jsx(ActionProvider, { context: { record: {}, objectName, user: currentUser }, onConfirm: confirmHandler, onToast: toastHandler, onNavigate: navigateHandler, onParamCollection: paramCollectionHandler, handlers: { api: apiHandler, flow: flowHandler, script: serverActionHandler, modal: serverActionHandler, approval: approvalHandler }, children: _jsx(DetailView, { schema: detailSchema, dataSource: dataSource, objectLabel: objectLabel({ name: objectDef.name, label: objectDef.label }), onDataLoaded: (record) => {
|
|
999
1013
|
if (!record || typeof record !== 'object')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/app-shell",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Minimal application shell for ObjectUI - framework-agnostic rendering engine",
|
|
@@ -27,34 +27,34 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"lucide-react": "^1.16.0",
|
|
29
29
|
"sonner": "^2.0.7",
|
|
30
|
-
"@object-ui/auth": "4.
|
|
31
|
-
"@object-ui/collaboration": "4.
|
|
32
|
-
"@object-ui/components": "4.
|
|
33
|
-
"@object-ui/core": "4.
|
|
34
|
-
"@object-ui/data-objectstack": "4.
|
|
35
|
-
"@object-ui/fields": "4.
|
|
36
|
-
"@object-ui/i18n": "4.
|
|
37
|
-
"@object-ui/layout": "4.
|
|
38
|
-
"@object-ui/permissions": "4.
|
|
39
|
-
"@object-ui/react": "4.
|
|
40
|
-
"@object-ui/types": "4.
|
|
30
|
+
"@object-ui/auth": "4.6.0",
|
|
31
|
+
"@object-ui/collaboration": "4.6.0",
|
|
32
|
+
"@object-ui/components": "4.6.0",
|
|
33
|
+
"@object-ui/core": "4.6.0",
|
|
34
|
+
"@object-ui/data-objectstack": "4.6.0",
|
|
35
|
+
"@object-ui/fields": "4.6.0",
|
|
36
|
+
"@object-ui/i18n": "4.6.0",
|
|
37
|
+
"@object-ui/layout": "4.6.0",
|
|
38
|
+
"@object-ui/permissions": "4.6.0",
|
|
39
|
+
"@object-ui/react": "4.6.0",
|
|
40
|
+
"@object-ui/types": "4.6.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react": "^18.0.0 || ^19.0.0",
|
|
44
44
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
45
45
|
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
46
|
-
"@object-ui/plugin-calendar": "^4.
|
|
47
|
-
"@object-ui/plugin-charts": "^4.
|
|
48
|
-
"@object-ui/plugin-chatbot": "^4.
|
|
49
|
-
"@object-ui/plugin-dashboard": "^4.
|
|
50
|
-
"@object-ui/plugin-designer": "^4.
|
|
51
|
-
"@object-ui/plugin-detail": "^4.
|
|
52
|
-
"@object-ui/plugin-form": "^4.
|
|
53
|
-
"@object-ui/plugin-grid": "^4.
|
|
54
|
-
"@object-ui/plugin-kanban": "^4.
|
|
55
|
-
"@object-ui/plugin-list": "^4.
|
|
56
|
-
"@object-ui/plugin-report": "^4.
|
|
57
|
-
"@object-ui/plugin-view": "^4.
|
|
46
|
+
"@object-ui/plugin-calendar": "^4.6.0",
|
|
47
|
+
"@object-ui/plugin-charts": "^4.6.0",
|
|
48
|
+
"@object-ui/plugin-chatbot": "^4.6.0",
|
|
49
|
+
"@object-ui/plugin-dashboard": "^4.6.0",
|
|
50
|
+
"@object-ui/plugin-designer": "^4.6.0",
|
|
51
|
+
"@object-ui/plugin-detail": "^4.6.0",
|
|
52
|
+
"@object-ui/plugin-form": "^4.6.0",
|
|
53
|
+
"@object-ui/plugin-grid": "^4.6.0",
|
|
54
|
+
"@object-ui/plugin-kanban": "^4.6.0",
|
|
55
|
+
"@object-ui/plugin-list": "^4.6.0",
|
|
56
|
+
"@object-ui/plugin-report": "^4.6.0",
|
|
57
|
+
"@object-ui/plugin-view": "^4.6.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^25.9.0",
|