@object-ui/app-shell 11.4.0 → 11.5.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 +178 -0
- package/README.md +9 -0
- package/dist/chrome/KeyboardShortcutsDialog.js +2 -1
- package/dist/console/AppContent.js +145 -26
- package/dist/console/ConsoleShell.js +8 -1
- package/dist/context/CommandPaletteProvider.js +2 -1
- package/dist/hooks/useObjectActions.js +16 -4
- package/dist/layout/AppHeader.js +13 -5
- package/dist/layout/AppSidebar.js +10 -4
- package/dist/observability/sentry.d.ts +5 -0
- package/dist/observability/sentry.js +6 -1
- package/dist/preview/DraftChangesPanel.d.ts +29 -1
- package/dist/preview/DraftChangesPanel.js +141 -14
- package/dist/urlParams.d.ts +68 -0
- package/dist/urlParams.js +76 -0
- package/dist/utils/appRoute.d.ts +15 -0
- package/dist/utils/appRoute.js +22 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/pageTabsUrlSync.d.ts +32 -0
- package/dist/utils/pageTabsUrlSync.js +43 -0
- package/dist/utils/recordFormNavigation.d.ts +40 -0
- package/dist/utils/recordFormNavigation.js +30 -0
- package/dist/views/InterfaceListPage.d.ts +1 -0
- package/dist/views/InterfaceListPage.js +1 -1
- package/dist/views/ObjectDataPage.d.ts +29 -0
- package/dist/views/ObjectDataPage.js +227 -0
- package/dist/views/ObjectView.js +4 -3
- package/dist/views/RecordDetailView.js +61 -20
- package/dist/views/RelatedRecordActionsBridge.d.ts +10 -1
- package/dist/views/RelatedRecordActionsBridge.js +49 -16
- package/dist/views/metadata-admin/ResourceEditPage.js +39 -0
- package/dist/views/metadata-admin/i18n.js +214 -4
- package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +11 -4
- package/dist/views/metadata-admin/inspectors/AppNavInspector.js +141 -7
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +14 -0
- package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +76 -5
- package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +35 -19
- package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +8 -1
- package/dist/views/metadata-admin/inspectors/flow-node-config.js +3 -2
- package/dist/views/metadata-admin/inspectors/nav-target.d.ts +52 -0
- package/dist/views/metadata-admin/inspectors/nav-target.js +149 -0
- package/dist/views/metadata-admin/nav-selection.d.ts +20 -0
- package/dist/views/metadata-admin/nav-selection.js +81 -0
- package/dist/views/metadata-admin/previews/AppNavCanvas.js +9 -1
- package/dist/views/metadata-admin/previews/AppPreview.js +4 -2
- package/dist/views/studio-design/BuilderLanding.d.ts +1 -1
- package/dist/views/studio-design/BuilderLanding.js +12 -19
- package/dist/views/studio-design/ObjectFormDesigner.d.ts +5 -3
- package/dist/views/studio-design/ObjectFormDesigner.js +17 -12
- package/dist/views/studio-design/ObjectSettingsPanel.d.ts +1 -1
- package/dist/views/studio-design/ObjectSettingsPanel.js +4 -3
- package/dist/views/studio-design/ObjectValidationsPanel.js +6 -4
- package/dist/views/studio-design/PackageIdInput.d.ts +31 -0
- package/dist/views/studio-design/PackageIdInput.js +40 -0
- package/dist/views/studio-design/StudioDesignSurface.d.ts +13 -0
- package/dist/views/studio-design/StudioDesignSurface.js +227 -57
- package/dist/views/studio-design/packageSurfaces.d.ts +49 -0
- package/dist/views/studio-design/packageSurfaces.js +34 -0
- package/dist/views/studio-design/packages-io.d.ts +11 -0
- package/dist/views/studio-design/packages-io.js +12 -0
- package/dist/views/studio-design/skeletons.d.ts +16 -0
- package/dist/views/studio-design/skeletons.js +51 -0
- package/package.json +38 -38
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load the rail entries for one metadata type inside a Studio package pillar:
|
|
3
|
+
* the PUBLISHED items unioned with the pending DRAFT items, deduped by name.
|
|
4
|
+
*
|
|
5
|
+
* Why the union: `client.list(type, { packageId })` only returns
|
|
6
|
+
* published/active metadata. A freshly-authored item that hasn't been published
|
|
7
|
+
* yet (or a whole fresh writable-base package whose items are all still drafts)
|
|
8
|
+
* would therefore render an empty rail even though the author just created it —
|
|
9
|
+
* and the "N pending changes" counter would show the draft exists while the rail
|
|
10
|
+
* itself hid it. Merging `client.listDrafts({ packageId, type })` keeps the item
|
|
11
|
+
* designable between authoring and its first publish.
|
|
12
|
+
*
|
|
13
|
+
* This is the canonical form of the merge the Data / Interfaces / Access pillars
|
|
14
|
+
* already do inline; extracting it (a) fixes the Automations pillar, which was
|
|
15
|
+
* the sole rail that listed only published items and hid draft-only flows, and
|
|
16
|
+
* (b) makes the behaviour unit-testable without rendering a heavy pillar tree.
|
|
17
|
+
*
|
|
18
|
+
* Draft headers carry no label (they are light rows — no body), so a draft-only
|
|
19
|
+
* item shows its machine name until the draft body loads on selection, matching
|
|
20
|
+
* the sibling pillars.
|
|
21
|
+
*/
|
|
22
|
+
/** Minimal structural view of the metadata client this helper needs. */
|
|
23
|
+
export interface PackageSurfaceClient {
|
|
24
|
+
list(type: string, options?: {
|
|
25
|
+
packageId?: string;
|
|
26
|
+
}): Promise<unknown>;
|
|
27
|
+
listDrafts(options?: {
|
|
28
|
+
packageId?: string;
|
|
29
|
+
type?: string;
|
|
30
|
+
}): Promise<Array<{
|
|
31
|
+
name?: string | null;
|
|
32
|
+
}>>;
|
|
33
|
+
}
|
|
34
|
+
/** One rail entry — mirrors the `Surface` shape used by the pillars. */
|
|
35
|
+
export interface PackageSurface {
|
|
36
|
+
type: string;
|
|
37
|
+
name: string;
|
|
38
|
+
label: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Fetch published + pending-draft items of `type` for `packageId` and merge them
|
|
42
|
+
* into rail entries. Published rows win on name collision (their real label is
|
|
43
|
+
* kept); draft-only names are appended with the machine name as the label.
|
|
44
|
+
*
|
|
45
|
+
* `listDrafts` failures are tolerated (an older server without the drafts
|
|
46
|
+
* endpoint, or a transient error) — the rail still renders the published set
|
|
47
|
+
* rather than erroring out, matching the sibling pillars' `.catch(() => [])`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadPackageSurfaces(client: PackageSurfaceClient, type: string, packageId: string): Promise<PackageSurface[]>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
/**
|
|
3
|
+
* Fetch published + pending-draft items of `type` for `packageId` and merge them
|
|
4
|
+
* into rail entries. Published rows win on name collision (their real label is
|
|
5
|
+
* kept); draft-only names are appended with the machine name as the label.
|
|
6
|
+
*
|
|
7
|
+
* `listDrafts` failures are tolerated (an older server without the drafts
|
|
8
|
+
* endpoint, or a transient error) — the rail still renders the published set
|
|
9
|
+
* rather than erroring out, matching the sibling pillars' `.catch(() => [])`.
|
|
10
|
+
*/
|
|
11
|
+
export async function loadPackageSurfaces(client, type, packageId) {
|
|
12
|
+
const [published, draftHeaders] = await Promise.all([
|
|
13
|
+
client.list(type, { packageId }),
|
|
14
|
+
client
|
|
15
|
+
.listDrafts({ packageId, type })
|
|
16
|
+
.catch(() => []),
|
|
17
|
+
]);
|
|
18
|
+
const items = (published || [])
|
|
19
|
+
.map((o) => ({
|
|
20
|
+
type,
|
|
21
|
+
name: String(o.name ?? ''),
|
|
22
|
+
label: String(o.label ?? o.name ?? ''),
|
|
23
|
+
}))
|
|
24
|
+
.filter((o) => o.name);
|
|
25
|
+
const known = new Set(items.map((o) => o.name));
|
|
26
|
+
for (const d of draftHeaders || []) {
|
|
27
|
+
const name = String(d?.name ?? '');
|
|
28
|
+
if (name && !known.has(name)) {
|
|
29
|
+
items.push({ type, name, label: name });
|
|
30
|
+
known.add(name);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return items;
|
|
34
|
+
}
|
|
@@ -25,3 +25,14 @@ export declare function createBasePackage(id: string, name: string): Promise<voi
|
|
|
25
25
|
*/
|
|
26
26
|
export declare function duplicatePackage(sourceId: string, targetId: string, targetName?: string): Promise<void>;
|
|
27
27
|
export declare const PACKAGE_ID_RE: RegExp;
|
|
28
|
+
/**
|
|
29
|
+
* Normalize raw package-id keystrokes to the allowed alphabet, and SAY when
|
|
30
|
+
* something was dropped — the wizard used to strip illegal characters
|
|
31
|
+
* silently (`bad id!!` → `badid`), which reads as the input eating keys.
|
|
32
|
+
* The `stripped` flag drives an inline notice; PACKAGE_ID_RE stays the
|
|
33
|
+
* format authority (reverse-domain, e.g. `com.example.myapp`).
|
|
34
|
+
*/
|
|
35
|
+
export declare function sanitizePackageId(raw: string): {
|
|
36
|
+
value: string;
|
|
37
|
+
stripped: boolean;
|
|
38
|
+
};
|
|
@@ -59,3 +59,15 @@ export async function duplicatePackage(sourceId, targetId, targetName) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
export const PACKAGE_ID_RE = /^[a-z][a-z0-9_.-]*(\.[a-z0-9_-]+)+$/;
|
|
62
|
+
/**
|
|
63
|
+
* Normalize raw package-id keystrokes to the allowed alphabet, and SAY when
|
|
64
|
+
* something was dropped — the wizard used to strip illegal characters
|
|
65
|
+
* silently (`bad id!!` → `badid`), which reads as the input eating keys.
|
|
66
|
+
* The `stripped` flag drives an inline notice; PACKAGE_ID_RE stays the
|
|
67
|
+
* format authority (reverse-domain, e.g. `com.example.myapp`).
|
|
68
|
+
*/
|
|
69
|
+
export function sanitizePackageId(raw) {
|
|
70
|
+
const value = raw.toLowerCase().replace(/[^a-z0-9_.-]/g, '');
|
|
71
|
+
// Lowercasing is benign normalization; only actually-dropped characters warrant the notice.
|
|
72
|
+
return { value, stripped: value.length !== raw.length };
|
|
73
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildObjectSkeleton(name: string, label: string, nameFieldLabel: string): Record<string, unknown>;
|
|
9
|
+
export declare function buildFlowSkeleton(name: string, label: string, startLabel: string, endLabel: string): Record<string, unknown>;
|
|
10
|
+
/** An object to seed a new app's navigation with (one menu item per object). */
|
|
11
|
+
export interface AppNavSeed {
|
|
12
|
+
name: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildAppSkeleton(name: string, label: string, navObjects?: AppNavSeed[]): Record<string, unknown>;
|
|
16
|
+
export declare function buildPermissionSkeleton(name: string, label: string): Record<string, unknown>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
// Minimal-valid draft skeletons for the Studio's INLINE "New X" creators
|
|
9
|
+
// (Data → object, Automations → flow, Interfaces → app, Access → permission).
|
|
10
|
+
//
|
|
11
|
+
// These bypass the metadata-admin registry, so `createConformance.test.ts`'s
|
|
12
|
+
// registry-driven gate does NOT cover them — a future edit to one of these
|
|
13
|
+
// shapes could make its "New" button a silent dead-end (create→save 422s). They
|
|
14
|
+
// live here, pure and exported, so BOTH the pillars and the conformance gate
|
|
15
|
+
// consume the SAME source: the test can't drift from what the designer emits.
|
|
16
|
+
//
|
|
17
|
+
// Label strings are parameters (the pillars pass localized `t(...)` values); the
|
|
18
|
+
// gate passes any placeholder — the labels don't affect spec validity.
|
|
19
|
+
export function buildObjectSkeleton(name, label, nameFieldLabel) {
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
label,
|
|
23
|
+
fields: { name: { type: 'text', label: nameFieldLabel } },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function buildFlowSkeleton(name, label, startLabel, endLabel) {
|
|
27
|
+
return {
|
|
28
|
+
name,
|
|
29
|
+
label,
|
|
30
|
+
type: 'autolaunched',
|
|
31
|
+
nodes: [
|
|
32
|
+
{ id: 'start', type: 'start', label: startLabel },
|
|
33
|
+
{ id: 'end', type: 'end', label: endLabel },
|
|
34
|
+
],
|
|
35
|
+
edges: [{ id: 'e1', source: 'start', target: 'end' }],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function buildAppSkeleton(name, label, navObjects = []) {
|
|
39
|
+
return {
|
|
40
|
+
name,
|
|
41
|
+
label,
|
|
42
|
+
active: true,
|
|
43
|
+
// Seeding nav from the package's objects closes the create-app dead-end:
|
|
44
|
+
// a fresh app otherwise ships zero menu items and every object must be
|
|
45
|
+
// wired by hand in the Interfaces pillar (objectui#2262).
|
|
46
|
+
navigation: navObjects.map((o) => ({ id: `nav_${o.name}`, type: 'object', label: o.label, objectName: o.name })),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function buildPermissionSkeleton(name, label) {
|
|
50
|
+
return { name, label, objects: {}, fields: {} };
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/app-shell",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Minimal application shell for ObjectUI - framework-agnostic rendering engine",
|
|
@@ -36,36 +36,36 @@
|
|
|
36
36
|
"qrcode": "^1.5.4",
|
|
37
37
|
"sonner": "^2.0.7",
|
|
38
38
|
"zod": "^4.4.3",
|
|
39
|
-
"@object-ui/auth": "11.
|
|
40
|
-
"@object-ui/collaboration": "11.
|
|
41
|
-
"@object-ui/components": "11.
|
|
42
|
-
"@object-ui/core": "11.
|
|
43
|
-
"@object-ui/data-objectstack": "11.
|
|
44
|
-
"@object-ui/fields": "11.
|
|
45
|
-
"@object-ui/i18n": "11.
|
|
46
|
-
"@object-ui/layout": "11.
|
|
47
|
-
"@object-ui/permissions": "11.
|
|
48
|
-
"@object-ui/plugin-editor": "11.
|
|
49
|
-
"@object-ui/providers": "11.
|
|
50
|
-
"@object-ui/react": "11.
|
|
51
|
-
"@object-ui/types": "11.
|
|
39
|
+
"@object-ui/auth": "11.5.0",
|
|
40
|
+
"@object-ui/collaboration": "11.5.0",
|
|
41
|
+
"@object-ui/components": "11.5.0",
|
|
42
|
+
"@object-ui/core": "11.5.0",
|
|
43
|
+
"@object-ui/data-objectstack": "11.5.0",
|
|
44
|
+
"@object-ui/fields": "11.5.0",
|
|
45
|
+
"@object-ui/i18n": "11.5.0",
|
|
46
|
+
"@object-ui/layout": "11.5.0",
|
|
47
|
+
"@object-ui/permissions": "11.5.0",
|
|
48
|
+
"@object-ui/plugin-editor": "11.5.0",
|
|
49
|
+
"@object-ui/providers": "11.5.0",
|
|
50
|
+
"@object-ui/react": "11.5.0",
|
|
51
|
+
"@object-ui/types": "11.5.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"react": "^18.0.0 || ^19.0.0",
|
|
55
55
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
56
56
|
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
57
|
-
"@object-ui/plugin-calendar": "^11.
|
|
58
|
-
"@object-ui/plugin-charts": "^11.
|
|
59
|
-
"@object-ui/plugin-chatbot": "^11.
|
|
60
|
-
"@object-ui/plugin-dashboard": "^11.
|
|
61
|
-
"@object-ui/plugin-designer": "^11.
|
|
62
|
-
"@object-ui/plugin-detail": "^11.
|
|
63
|
-
"@object-ui/plugin-form": "^11.
|
|
64
|
-
"@object-ui/plugin-grid": "^11.
|
|
65
|
-
"@object-ui/plugin-kanban": "^11.
|
|
66
|
-
"@object-ui/plugin-list": "^11.
|
|
67
|
-
"@object-ui/plugin-report": "^11.
|
|
68
|
-
"@object-ui/plugin-view": "^11.
|
|
57
|
+
"@object-ui/plugin-calendar": "^11.5.0",
|
|
58
|
+
"@object-ui/plugin-charts": "^11.5.0",
|
|
59
|
+
"@object-ui/plugin-chatbot": "^11.5.0",
|
|
60
|
+
"@object-ui/plugin-dashboard": "^11.5.0",
|
|
61
|
+
"@object-ui/plugin-designer": "^11.5.0",
|
|
62
|
+
"@object-ui/plugin-detail": "^11.5.0",
|
|
63
|
+
"@object-ui/plugin-form": "^11.5.0",
|
|
64
|
+
"@object-ui/plugin-grid": "^11.5.0",
|
|
65
|
+
"@object-ui/plugin-kanban": "^11.5.0",
|
|
66
|
+
"@object-ui/plugin-list": "^11.5.0",
|
|
67
|
+
"@object-ui/plugin-report": "^11.5.0",
|
|
68
|
+
"@object-ui/plugin-view": "^11.5.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^26.0.1",
|
|
@@ -78,18 +78,18 @@
|
|
|
78
78
|
"sonner": "^2.0.7",
|
|
79
79
|
"typescript": "^6.0.3",
|
|
80
80
|
"vite": "^8.1.0",
|
|
81
|
-
"@object-ui/plugin-calendar": "11.
|
|
82
|
-
"@object-ui/plugin-charts": "11.
|
|
83
|
-
"@object-ui/plugin-chatbot": "11.
|
|
84
|
-
"@object-ui/plugin-dashboard": "11.
|
|
85
|
-
"@object-ui/plugin-designer": "11.
|
|
86
|
-
"@object-ui/plugin-detail": "11.
|
|
87
|
-
"@object-ui/plugin-form": "11.
|
|
88
|
-
"@object-ui/plugin-grid": "11.
|
|
89
|
-
"@object-ui/plugin-kanban": "11.
|
|
90
|
-
"@object-ui/plugin-list": "11.
|
|
91
|
-
"@object-ui/plugin-report": "11.
|
|
92
|
-
"@object-ui/plugin-view": "11.
|
|
81
|
+
"@object-ui/plugin-calendar": "11.5.0",
|
|
82
|
+
"@object-ui/plugin-charts": "11.5.0",
|
|
83
|
+
"@object-ui/plugin-chatbot": "11.5.0",
|
|
84
|
+
"@object-ui/plugin-dashboard": "11.5.0",
|
|
85
|
+
"@object-ui/plugin-designer": "11.5.0",
|
|
86
|
+
"@object-ui/plugin-detail": "11.5.0",
|
|
87
|
+
"@object-ui/plugin-form": "11.5.0",
|
|
88
|
+
"@object-ui/plugin-grid": "11.5.0",
|
|
89
|
+
"@object-ui/plugin-kanban": "11.5.0",
|
|
90
|
+
"@object-ui/plugin-list": "11.5.0",
|
|
91
|
+
"@object-ui/plugin-report": "11.5.0",
|
|
92
|
+
"@object-ui/plugin-view": "11.5.0"
|
|
93
93
|
},
|
|
94
94
|
"keywords": [
|
|
95
95
|
"objectui",
|