@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +9 -0
  3. package/dist/chrome/KeyboardShortcutsDialog.js +2 -1
  4. package/dist/console/AppContent.js +145 -26
  5. package/dist/console/ConsoleShell.js +8 -1
  6. package/dist/context/CommandPaletteProvider.js +2 -1
  7. package/dist/hooks/useObjectActions.js +16 -4
  8. package/dist/layout/AppHeader.js +13 -5
  9. package/dist/layout/AppSidebar.js +10 -4
  10. package/dist/observability/sentry.d.ts +5 -0
  11. package/dist/observability/sentry.js +6 -1
  12. package/dist/preview/DraftChangesPanel.d.ts +29 -1
  13. package/dist/preview/DraftChangesPanel.js +141 -14
  14. package/dist/urlParams.d.ts +68 -0
  15. package/dist/urlParams.js +76 -0
  16. package/dist/utils/appRoute.d.ts +15 -0
  17. package/dist/utils/appRoute.js +22 -0
  18. package/dist/utils/index.d.ts +1 -1
  19. package/dist/utils/index.js +1 -1
  20. package/dist/utils/pageTabsUrlSync.d.ts +32 -0
  21. package/dist/utils/pageTabsUrlSync.js +43 -0
  22. package/dist/utils/recordFormNavigation.d.ts +40 -0
  23. package/dist/utils/recordFormNavigation.js +30 -0
  24. package/dist/views/InterfaceListPage.d.ts +1 -0
  25. package/dist/views/InterfaceListPage.js +1 -1
  26. package/dist/views/ObjectDataPage.d.ts +29 -0
  27. package/dist/views/ObjectDataPage.js +227 -0
  28. package/dist/views/ObjectView.js +4 -3
  29. package/dist/views/RecordDetailView.js +61 -20
  30. package/dist/views/RelatedRecordActionsBridge.d.ts +10 -1
  31. package/dist/views/RelatedRecordActionsBridge.js +49 -16
  32. package/dist/views/metadata-admin/ResourceEditPage.js +39 -0
  33. package/dist/views/metadata-admin/i18n.js +214 -4
  34. package/dist/views/metadata-admin/inspectors/AppNavInspector.d.ts +11 -4
  35. package/dist/views/metadata-admin/inspectors/AppNavInspector.js +141 -7
  36. package/dist/views/metadata-admin/inspectors/FlowReferenceField.d.ts +14 -0
  37. package/dist/views/metadata-admin/inspectors/FlowReferenceField.js +76 -5
  38. package/dist/views/metadata-admin/inspectors/ObjectFieldInspector.js +35 -19
  39. package/dist/views/metadata-admin/inspectors/flow-node-config.d.ts +8 -1
  40. package/dist/views/metadata-admin/inspectors/flow-node-config.js +3 -2
  41. package/dist/views/metadata-admin/inspectors/nav-target.d.ts +52 -0
  42. package/dist/views/metadata-admin/inspectors/nav-target.js +149 -0
  43. package/dist/views/metadata-admin/nav-selection.d.ts +20 -0
  44. package/dist/views/metadata-admin/nav-selection.js +81 -0
  45. package/dist/views/metadata-admin/previews/AppNavCanvas.js +9 -1
  46. package/dist/views/metadata-admin/previews/AppPreview.js +4 -2
  47. package/dist/views/studio-design/BuilderLanding.d.ts +1 -1
  48. package/dist/views/studio-design/BuilderLanding.js +12 -19
  49. package/dist/views/studio-design/ObjectFormDesigner.d.ts +5 -3
  50. package/dist/views/studio-design/ObjectFormDesigner.js +17 -12
  51. package/dist/views/studio-design/ObjectSettingsPanel.d.ts +1 -1
  52. package/dist/views/studio-design/ObjectSettingsPanel.js +4 -3
  53. package/dist/views/studio-design/ObjectValidationsPanel.js +6 -4
  54. package/dist/views/studio-design/PackageIdInput.d.ts +31 -0
  55. package/dist/views/studio-design/PackageIdInput.js +40 -0
  56. package/dist/views/studio-design/StudioDesignSurface.d.ts +13 -0
  57. package/dist/views/studio-design/StudioDesignSurface.js +227 -57
  58. package/dist/views/studio-design/packageSurfaces.d.ts +49 -0
  59. package/dist/views/studio-design/packageSurfaces.js +34 -0
  60. package/dist/views/studio-design/packages-io.d.ts +11 -0
  61. package/dist/views/studio-design/packages-io.js +12 -0
  62. package/dist/views/studio-design/skeletons.d.ts +16 -0
  63. package/dist/views/studio-design/skeletons.js +51 -0
  64. 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.4.0",
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.4.0",
40
- "@object-ui/collaboration": "11.4.0",
41
- "@object-ui/components": "11.4.0",
42
- "@object-ui/core": "11.4.0",
43
- "@object-ui/data-objectstack": "11.4.0",
44
- "@object-ui/fields": "11.4.0",
45
- "@object-ui/i18n": "11.4.0",
46
- "@object-ui/layout": "11.4.0",
47
- "@object-ui/permissions": "11.4.0",
48
- "@object-ui/plugin-editor": "11.4.0",
49
- "@object-ui/providers": "11.4.0",
50
- "@object-ui/react": "11.4.0",
51
- "@object-ui/types": "11.4.0"
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.4.0",
58
- "@object-ui/plugin-charts": "^11.4.0",
59
- "@object-ui/plugin-chatbot": "^11.4.0",
60
- "@object-ui/plugin-dashboard": "^11.4.0",
61
- "@object-ui/plugin-designer": "^11.4.0",
62
- "@object-ui/plugin-detail": "^11.4.0",
63
- "@object-ui/plugin-form": "^11.4.0",
64
- "@object-ui/plugin-grid": "^11.4.0",
65
- "@object-ui/plugin-kanban": "^11.4.0",
66
- "@object-ui/plugin-list": "^11.4.0",
67
- "@object-ui/plugin-report": "^11.4.0",
68
- "@object-ui/plugin-view": "^11.4.0"
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.4.0",
82
- "@object-ui/plugin-charts": "11.4.0",
83
- "@object-ui/plugin-chatbot": "11.4.0",
84
- "@object-ui/plugin-dashboard": "11.4.0",
85
- "@object-ui/plugin-designer": "11.4.0",
86
- "@object-ui/plugin-detail": "11.4.0",
87
- "@object-ui/plugin-form": "11.4.0",
88
- "@object-ui/plugin-grid": "11.4.0",
89
- "@object-ui/plugin-kanban": "11.4.0",
90
- "@object-ui/plugin-list": "11.4.0",
91
- "@object-ui/plugin-report": "11.4.0",
92
- "@object-ui/plugin-view": "11.4.0"
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",