@object-ui/app-shell 3.3.2 → 4.0.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/CHANGELOG.md +89 -0
- package/dist/layout/AppHeader.js +28 -9
- package/dist/layout/UnifiedSidebar.js +4 -4
- package/dist/providers/MetadataProvider.js +42 -2
- package/dist/utils/getIcon.js +2 -37
- package/dist/utils/index.d.ts +7 -4
- package/dist/utils/index.js +44 -12
- package/dist/views/CreateViewDialog.d.ts +44 -0
- package/dist/views/CreateViewDialog.js +149 -0
- package/dist/views/DashboardView.js +31 -9
- package/dist/views/ObjectView.js +435 -64
- package/dist/views/RecordDetailView.js +8 -11
- package/dist/views/ViewConfigPanel.d.ts +7 -5
- package/dist/views/ViewConfigPanel.js +9 -6
- package/dist/views/index.d.ts +1 -0
- package/dist/views/index.js +1 -0
- package/package.json +28 -26
- package/src/styles.css +16 -0
|
@@ -20,6 +20,7 @@ import { SkeletonDetail } from '../skeletons';
|
|
|
20
20
|
import { ActionConfirmDialog } from './ActionConfirmDialog';
|
|
21
21
|
import { ActionParamDialog } from './ActionParamDialog';
|
|
22
22
|
import { useRecordBreadcrumbTitle } from '../context/NavigationContext';
|
|
23
|
+
import { getRecordDisplayName } from '../utils';
|
|
23
24
|
const FALLBACK_USER = { id: 'current-user', name: 'Demo User' };
|
|
24
25
|
export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
25
26
|
const { objectName, recordId } = useParams();
|
|
@@ -477,17 +478,13 @@ export function RecordDetailView({ dataSource, objects, onEdit }) {
|
|
|
477
478
|
return (_jsxs("div", { className: "h-full bg-background overflow-hidden flex flex-col relative", children: [_jsx("div", { className: "absolute top-2 sm:top-4 right-2 sm:right-4 z-50 flex items-center gap-2", children: recordViewers.length > 0 && (_jsxs("div", { className: "flex items-center gap-1.5", title: "Users viewing this record", 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 }, children: _jsx(DetailView, { schema: detailSchema, dataSource: dataSource, objectLabel: objectDef.label, onDataLoaded: (record) => {
|
|
478
479
|
if (!record || typeof record !== 'object')
|
|
479
480
|
return;
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
];
|
|
488
|
-
const next = candidates.find((v) => typeof v === 'string' && v.trim().length > 0);
|
|
489
|
-
if (next && next !== recordTitle)
|
|
490
|
-
setRecordTitle(next);
|
|
481
|
+
// Resolve the same way DetailView's header does, so the
|
|
482
|
+
// breadcrumb matches the on-page title (e.g. "David Kim"
|
|
483
|
+
// instead of "#lead-1778…").
|
|
484
|
+
const resolved = getRecordDisplayName(objectDef, record);
|
|
485
|
+
if (resolved && resolved !== recordTitle && resolved !== 'Untitled') {
|
|
486
|
+
setRecordTitle(resolved);
|
|
487
|
+
}
|
|
491
488
|
}, onEdit: () => {
|
|
492
489
|
onEdit({ id: pureRecordId });
|
|
493
490
|
}, discussionSlot: _jsx(RecordChatterPanel, { config: {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ViewConfigPanel —
|
|
2
|
+
* ViewConfigPanel — Airtable-style simplified configuration panel.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Renders a focused, opinionated set of sections (Page / Data /
|
|
5
|
+
* Appearance / Toolbar / User actions / Navigation / Advanced) — matching
|
|
6
|
+
* Airtable's Interface designer right rail. Power-user sections (records,
|
|
7
|
+
* sharing, accessibility) are intentionally excluded to keep the panel
|
|
8
|
+
* approachable; they can be re-introduced later as a dedicated "advanced"
|
|
9
|
+
* settings dialog if needed.
|
|
8
10
|
*
|
|
9
11
|
* All changes are buffered in a local draft state. Clicking Save commits
|
|
10
12
|
* the draft via onSave; Discard resets to the original activeView.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* ViewConfigPanel —
|
|
3
|
+
* ViewConfigPanel — Airtable-style simplified configuration panel.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Renders a focused, opinionated set of sections (Page / Data /
|
|
6
|
+
* Appearance / Toolbar / User actions / Navigation / Advanced) — matching
|
|
7
|
+
* Airtable's Interface designer right rail. Power-user sections (records,
|
|
8
|
+
* sharing, accessibility) are intentionally excluded to keep the panel
|
|
9
|
+
* approachable; they can be re-introduced later as a dedicated "advanced"
|
|
10
|
+
* settings dialog if needed.
|
|
9
11
|
*
|
|
10
12
|
* All changes are buffered in a local draft state. Clicking Save commits
|
|
11
13
|
* the draft via onSave; Discard resets to the original activeView.
|
|
@@ -51,7 +53,7 @@ export function ViewConfigPanel({ open, onClose, mode = 'edit', activeView, obje
|
|
|
51
53
|
// Bridge: filter/sort → builder format
|
|
52
54
|
const filterGroupValue = useMemo(() => toFilterGroup(draft.filter), [draft.filter]);
|
|
53
55
|
const sortItemsValue = useMemo(() => toSortItems(draft.sort), [draft.sort]);
|
|
54
|
-
// Build schema
|
|
56
|
+
// Build schema — always essentials-only (Airtable-style focused layout).
|
|
55
57
|
const schema = useMemo(() => buildViewConfigSchema({
|
|
56
58
|
t,
|
|
57
59
|
fieldOptions,
|
|
@@ -59,6 +61,7 @@ export function ViewConfigPanel({ open, onClose, mode = 'edit', activeView, obje
|
|
|
59
61
|
updateField,
|
|
60
62
|
filterGroupValue,
|
|
61
63
|
sortItemsValue,
|
|
64
|
+
essentialOnly: true,
|
|
62
65
|
}), [t, fieldOptions, objectDef, updateField, filterGroupValue, sortItemsValue]);
|
|
63
66
|
// Override breadcrumb with dynamic view type
|
|
64
67
|
const viewType = draft.type || 'grid';
|
package/dist/views/index.d.ts
CHANGED
|
@@ -8,4 +8,5 @@ export { ActionConfirmDialog } from './ActionConfirmDialog';
|
|
|
8
8
|
export { ActionParamDialog } from './ActionParamDialog';
|
|
9
9
|
export { MetadataToggle, MetadataPanel } from './MetadataInspector';
|
|
10
10
|
export { ViewConfigPanel } from './ViewConfigPanel';
|
|
11
|
+
export { CreateViewDialog } from './CreateViewDialog';
|
|
11
12
|
export { DesignDrawer } from './DesignDrawer';
|
package/dist/views/index.js
CHANGED
|
@@ -8,4 +8,5 @@ export { ActionConfirmDialog } from './ActionConfirmDialog';
|
|
|
8
8
|
export { ActionParamDialog } from './ActionParamDialog';
|
|
9
9
|
export { MetadataToggle, MetadataPanel } from './MetadataInspector';
|
|
10
10
|
export { ViewConfigPanel } from './ViewConfigPanel';
|
|
11
|
+
export { CreateViewDialog } from './CreateViewDialog';
|
|
11
12
|
export { DesignDrawer } from './DesignDrawer';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/app-shell",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Minimal application shell for ObjectUI - framework-agnostic rendering engine",
|
|
@@ -21,39 +21,40 @@
|
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
22
|
"import": "./dist/index.js",
|
|
23
23
|
"default": "./dist/index.js"
|
|
24
|
-
}
|
|
24
|
+
},
|
|
25
|
+
"./styles.css": "./src/styles.css"
|
|
25
26
|
},
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"lucide-react": "^
|
|
28
|
+
"lucide-react": "^1.14.0",
|
|
28
29
|
"sonner": "^2.0.7",
|
|
29
|
-
"@object-ui/auth": "
|
|
30
|
-
"@object-ui/collaboration": "
|
|
31
|
-
"@object-ui/components": "
|
|
32
|
-
"@object-ui/core": "
|
|
33
|
-
"@object-ui/data-objectstack": "
|
|
34
|
-
"@object-ui/fields": "
|
|
35
|
-
"@object-ui/i18n": "
|
|
36
|
-
"@object-ui/layout": "
|
|
37
|
-
"@object-ui/permissions": "
|
|
38
|
-
"@object-ui/react": "
|
|
39
|
-
"@object-ui/types": "
|
|
30
|
+
"@object-ui/auth": "4.0.1",
|
|
31
|
+
"@object-ui/collaboration": "4.0.1",
|
|
32
|
+
"@object-ui/components": "4.0.1",
|
|
33
|
+
"@object-ui/core": "4.0.1",
|
|
34
|
+
"@object-ui/data-objectstack": "4.0.1",
|
|
35
|
+
"@object-ui/fields": "4.0.1",
|
|
36
|
+
"@object-ui/i18n": "4.0.1",
|
|
37
|
+
"@object-ui/layout": "4.0.1",
|
|
38
|
+
"@object-ui/permissions": "4.0.1",
|
|
39
|
+
"@object-ui/react": "4.0.1",
|
|
40
|
+
"@object-ui/types": "4.0.1"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"react": "^18.0.0 || ^19.0.0",
|
|
43
44
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
44
45
|
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
45
|
-
"@object-ui/plugin-calendar": "
|
|
46
|
-
"@object-ui/plugin-charts": "
|
|
47
|
-
"@object-ui/plugin-chatbot": "
|
|
48
|
-
"@object-ui/plugin-dashboard": "
|
|
49
|
-
"@object-ui/plugin-designer": "
|
|
50
|
-
"@object-ui/plugin-detail": "
|
|
51
|
-
"@object-ui/plugin-form": "
|
|
52
|
-
"@object-ui/plugin-grid": "
|
|
53
|
-
"@object-ui/plugin-kanban": "
|
|
54
|
-
"@object-ui/plugin-list": "
|
|
55
|
-
"@object-ui/plugin-report": "
|
|
56
|
-
"@object-ui/plugin-view": "
|
|
46
|
+
"@object-ui/plugin-calendar": "4.0.1",
|
|
47
|
+
"@object-ui/plugin-charts": "4.0.1",
|
|
48
|
+
"@object-ui/plugin-chatbot": "4.0.1",
|
|
49
|
+
"@object-ui/plugin-dashboard": "4.0.1",
|
|
50
|
+
"@object-ui/plugin-designer": "4.0.1",
|
|
51
|
+
"@object-ui/plugin-detail": "4.0.1",
|
|
52
|
+
"@object-ui/plugin-form": "4.0.1",
|
|
53
|
+
"@object-ui/plugin-grid": "4.0.1",
|
|
54
|
+
"@object-ui/plugin-kanban": "4.0.1",
|
|
55
|
+
"@object-ui/plugin-list": "4.0.1",
|
|
56
|
+
"@object-ui/plugin-report": "4.0.1",
|
|
57
|
+
"@object-ui/plugin-view": "4.0.1"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@types/node": "^25.6.0",
|
|
@@ -84,6 +85,7 @@
|
|
|
84
85
|
},
|
|
85
86
|
"files": [
|
|
86
87
|
"dist",
|
|
88
|
+
"src/styles.css",
|
|
87
89
|
"README.md",
|
|
88
90
|
"CHANGELOG.md",
|
|
89
91
|
"LICENSE"
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @object-ui/app-shell shared Tailwind v4 styles.
|
|
3
|
+
*
|
|
4
|
+
* Import once per consumer right after `@import 'tailwindcss';`:
|
|
5
|
+
*
|
|
6
|
+
* @import 'tailwindcss';
|
|
7
|
+
* @import '@object-ui/app-shell/styles.css';
|
|
8
|
+
*
|
|
9
|
+
* Centralizing here keeps every host app (console, runner, starter, custom
|
|
10
|
+
* shells) on the same theming/variant contract.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/* Bind Tailwind's `dark:` variant to the `.dark` class on <html> (or any
|
|
14
|
+
* ancestor) instead of the OS `prefers-color-scheme`. Required so the
|
|
15
|
+
* in-app theme toggle fully controls light/dark UI under Tailwind v4. */
|
|
16
|
+
@custom-variant dark (&:where(.dark, .dark *));
|