@almadar/ui 5.153.0 → 5.154.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/dist/{EntityBindingContext-CD9ZoXb4.d.cts → EntityBindingContext-BfZGeDfX.d.cts} +4 -2
- package/dist/{EntityBindingContext-CD9ZoXb4.d.ts → EntityBindingContext-BfZGeDfX.d.ts} +4 -2
- package/dist/NavStackContext-BoVV9nWb.d.cts +83 -0
- package/dist/NavStackContext-BoVV9nWb.d.ts +83 -0
- package/dist/avl/index.cjs +114 -31
- package/dist/avl/index.js +115 -32
- package/dist/components/index.cjs +44 -7
- package/dist/components/index.d.cts +20 -3
- package/dist/components/index.d.ts +20 -3
- package/dist/components/index.js +42 -9
- package/dist/hooks/index.cjs +4 -0
- package/dist/hooks/index.d.cts +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/providers/index.cjs +220 -14
- package/dist/providers/index.d.cts +2 -1
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/index.js +220 -17
- package/dist/runtime/index.cjs +113 -30
- package/dist/runtime/index.d.cts +12 -5
- package/dist/runtime/index.d.ts +12 -5
- package/dist/runtime/index.js +114 -31
- package/package.json +4 -4
|
@@ -84,7 +84,7 @@ declare function useEntitySchema(): EntitySchemaContextValue;
|
|
|
84
84
|
declare function useEntitySchemaOptional(): EntitySchemaContextValue | null;
|
|
85
85
|
|
|
86
86
|
/** Wire-format client effect tuple from the server response. */
|
|
87
|
-
type ClientEffectTuple = ['render-ui', string, AnyPatternConfig | null, ...SExpr[]] | ['navigate', string, ...SExpr[]] | ['notify', string, ...SExpr[]];
|
|
87
|
+
type ClientEffectTuple = ['render-ui', string, AnyPatternConfig | null, ...SExpr[]] | ['navigate', string, ...SExpr[]] | ['navigate-back'] | ['notify', string, ...SExpr[]];
|
|
88
88
|
interface OrbitalEventResponse {
|
|
89
89
|
success: boolean;
|
|
90
90
|
transitioned: boolean;
|
|
@@ -114,11 +114,13 @@ interface OrbitalEventResponse {
|
|
|
114
114
|
error?: string;
|
|
115
115
|
}
|
|
116
116
|
interface ServerClientEffect {
|
|
117
|
-
type: 'render-ui' | 'navigate' | 'notify';
|
|
117
|
+
type: 'render-ui' | 'navigate' | 'navigate-back' | 'notify';
|
|
118
118
|
slot?: string;
|
|
119
119
|
pattern?: AnyPatternConfig;
|
|
120
120
|
route?: string;
|
|
121
121
|
params?: EventPayload;
|
|
122
|
+
/** Nav-stack entry label carried by the navigate effect's options. */
|
|
123
|
+
crumb?: string;
|
|
122
124
|
message?: string;
|
|
123
125
|
/**
|
|
124
126
|
* Trait that emitted this effect. Used by `<TraitFrame>` to resolve
|
|
@@ -84,7 +84,7 @@ declare function useEntitySchema(): EntitySchemaContextValue;
|
|
|
84
84
|
declare function useEntitySchemaOptional(): EntitySchemaContextValue | null;
|
|
85
85
|
|
|
86
86
|
/** Wire-format client effect tuple from the server response. */
|
|
87
|
-
type ClientEffectTuple = ['render-ui', string, AnyPatternConfig | null, ...SExpr[]] | ['navigate', string, ...SExpr[]] | ['notify', string, ...SExpr[]];
|
|
87
|
+
type ClientEffectTuple = ['render-ui', string, AnyPatternConfig | null, ...SExpr[]] | ['navigate', string, ...SExpr[]] | ['navigate-back'] | ['notify', string, ...SExpr[]];
|
|
88
88
|
interface OrbitalEventResponse {
|
|
89
89
|
success: boolean;
|
|
90
90
|
transitioned: boolean;
|
|
@@ -114,11 +114,13 @@ interface OrbitalEventResponse {
|
|
|
114
114
|
error?: string;
|
|
115
115
|
}
|
|
116
116
|
interface ServerClientEffect {
|
|
117
|
-
type: 'render-ui' | 'navigate' | 'notify';
|
|
117
|
+
type: 'render-ui' | 'navigate' | 'navigate-back' | 'notify';
|
|
118
118
|
slot?: string;
|
|
119
119
|
pattern?: AnyPatternConfig;
|
|
120
120
|
route?: string;
|
|
121
121
|
params?: EventPayload;
|
|
122
|
+
/** Nav-stack entry label carried by the navigate effect's options. */
|
|
123
|
+
crumb?: string;
|
|
122
124
|
message?: string;
|
|
123
125
|
/**
|
|
124
126
|
* Trait that emitted this effect. Used by `<TraitFrame>` to resolve
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { NavStackEntry } from '@almadar/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Navigation-stack core — the pure logic behind the orbital-scoped
|
|
6
|
+
* client-session navigation stack both execution paths share.
|
|
7
|
+
*
|
|
8
|
+
* The stack is what detail-page breadcrumb bands and the `navigate-back`
|
|
9
|
+
* effect read. It lives client-side only (per browser tab): the runtime
|
|
10
|
+
* path's OrbPreview and the compiled app's App.tsx both mount
|
|
11
|
+
* `NavStackProvider` (providers/NavStackContext.tsx), which drives this
|
|
12
|
+
* module on every route change.
|
|
13
|
+
*
|
|
14
|
+
* Semantics (deterministic):
|
|
15
|
+
* - One stack per ORBITAL, keyed by the orbital owning the current page.
|
|
16
|
+
* - On route change: an entry with the same href already in the stack
|
|
17
|
+
* truncates back to it (revisit); otherwise the new entry is pushed.
|
|
18
|
+
* - Cold load (deep link): the stack seeds from the declared page-path
|
|
19
|
+
* hierarchy — every declared page whose pattern matches a strict prefix
|
|
20
|
+
* of the concrete path becomes an ancestor entry — so the trail is never
|
|
21
|
+
* empty and back always has a target on nested paths.
|
|
22
|
+
* - Entry label = the `crumb` carried by the navigate effect when one was
|
|
23
|
+
* staged for this href, else the page's declared name humanized.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/** One declared page as the nav stack needs it: path pattern + name + owning orbital. */
|
|
27
|
+
interface NavPageDecl {
|
|
28
|
+
path: string;
|
|
29
|
+
name: string;
|
|
30
|
+
orbital: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* NavStackProvider — the orbital-scoped client-session navigation stack.
|
|
35
|
+
*
|
|
36
|
+
* One provider instance per app host. Both execution paths mount it:
|
|
37
|
+
* - Runtime path: OrbPreview supplies `currentPath` + `navigate` explicitly.
|
|
38
|
+
* - Compiled path: the emitted App.tsx mounts `NavStackRouterBridge`, which
|
|
39
|
+
* reads react-router's location/navigate and renders this provider.
|
|
40
|
+
*
|
|
41
|
+
* Pure stack semantics live in lib/navStack.ts (one owner for both paths).
|
|
42
|
+
* State persists to sessionStorage (per-tab) so a compiled app's full page
|
|
43
|
+
* reload keeps the trail; every storage access is guarded with an in-memory
|
|
44
|
+
* fallback.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
interface NavStackApi {
|
|
48
|
+
/** Stack of the current page's orbital, root-first (empty when no declared page matches). */
|
|
49
|
+
entries: readonly NavStackEntry[];
|
|
50
|
+
/** True when a previous entry exists for the current page's orbital. */
|
|
51
|
+
canGoBack: boolean;
|
|
52
|
+
/** Stage the crumb label for the entry the target page will record, then call navigate yourself. */
|
|
53
|
+
beginNavigate: (href: string, crumb?: string) => void;
|
|
54
|
+
/** Pop the current orbital's stack: navigate to the previous entry (no-op without one). */
|
|
55
|
+
back: () => void;
|
|
56
|
+
/** Navigate to an arbitrary stack entry (breadcrumb click). */
|
|
57
|
+
goTo: (href: string) => void;
|
|
58
|
+
}
|
|
59
|
+
declare function useNavStack(): NavStackApi;
|
|
60
|
+
interface NavStackProviderProps {
|
|
61
|
+
pages: readonly NavPageDecl[];
|
|
62
|
+
/** Concrete current path (route params substituted), e.g. /contracts/42. */
|
|
63
|
+
currentPath: string;
|
|
64
|
+
/** Host navigation function (SPA route change). */
|
|
65
|
+
navigate: (path: string) => void;
|
|
66
|
+
/** sessionStorage key; omit to keep the stack in memory only. */
|
|
67
|
+
storageKey?: string;
|
|
68
|
+
children: React__default.ReactNode;
|
|
69
|
+
}
|
|
70
|
+
declare const NavStackProvider: React__default.FC<NavStackProviderProps>;
|
|
71
|
+
interface NavStackRouterBridgeProps {
|
|
72
|
+
pages: readonly NavPageDecl[];
|
|
73
|
+
storageKey?: string;
|
|
74
|
+
children: React__default.ReactNode;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compiled-path host: binds NavStackProvider to react-router. Must render
|
|
78
|
+
* inside a Router (the emitted App.tsx mounts it directly under
|
|
79
|
+
* BrowserRouter).
|
|
80
|
+
*/
|
|
81
|
+
declare const NavStackRouterBridge: React__default.FC<NavStackRouterBridgeProps>;
|
|
82
|
+
|
|
83
|
+
export { type NavPageDecl as N, type NavStackApi as a, NavStackProvider as b, type NavStackProviderProps as c, NavStackRouterBridge as d, type NavStackRouterBridgeProps as e, useNavStack as u };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { NavStackEntry } from '@almadar/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Navigation-stack core — the pure logic behind the orbital-scoped
|
|
6
|
+
* client-session navigation stack both execution paths share.
|
|
7
|
+
*
|
|
8
|
+
* The stack is what detail-page breadcrumb bands and the `navigate-back`
|
|
9
|
+
* effect read. It lives client-side only (per browser tab): the runtime
|
|
10
|
+
* path's OrbPreview and the compiled app's App.tsx both mount
|
|
11
|
+
* `NavStackProvider` (providers/NavStackContext.tsx), which drives this
|
|
12
|
+
* module on every route change.
|
|
13
|
+
*
|
|
14
|
+
* Semantics (deterministic):
|
|
15
|
+
* - One stack per ORBITAL, keyed by the orbital owning the current page.
|
|
16
|
+
* - On route change: an entry with the same href already in the stack
|
|
17
|
+
* truncates back to it (revisit); otherwise the new entry is pushed.
|
|
18
|
+
* - Cold load (deep link): the stack seeds from the declared page-path
|
|
19
|
+
* hierarchy — every declared page whose pattern matches a strict prefix
|
|
20
|
+
* of the concrete path becomes an ancestor entry — so the trail is never
|
|
21
|
+
* empty and back always has a target on nested paths.
|
|
22
|
+
* - Entry label = the `crumb` carried by the navigate effect when one was
|
|
23
|
+
* staged for this href, else the page's declared name humanized.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/** One declared page as the nav stack needs it: path pattern + name + owning orbital. */
|
|
27
|
+
interface NavPageDecl {
|
|
28
|
+
path: string;
|
|
29
|
+
name: string;
|
|
30
|
+
orbital: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* NavStackProvider — the orbital-scoped client-session navigation stack.
|
|
35
|
+
*
|
|
36
|
+
* One provider instance per app host. Both execution paths mount it:
|
|
37
|
+
* - Runtime path: OrbPreview supplies `currentPath` + `navigate` explicitly.
|
|
38
|
+
* - Compiled path: the emitted App.tsx mounts `NavStackRouterBridge`, which
|
|
39
|
+
* reads react-router's location/navigate and renders this provider.
|
|
40
|
+
*
|
|
41
|
+
* Pure stack semantics live in lib/navStack.ts (one owner for both paths).
|
|
42
|
+
* State persists to sessionStorage (per-tab) so a compiled app's full page
|
|
43
|
+
* reload keeps the trail; every storage access is guarded with an in-memory
|
|
44
|
+
* fallback.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
interface NavStackApi {
|
|
48
|
+
/** Stack of the current page's orbital, root-first (empty when no declared page matches). */
|
|
49
|
+
entries: readonly NavStackEntry[];
|
|
50
|
+
/** True when a previous entry exists for the current page's orbital. */
|
|
51
|
+
canGoBack: boolean;
|
|
52
|
+
/** Stage the crumb label for the entry the target page will record, then call navigate yourself. */
|
|
53
|
+
beginNavigate: (href: string, crumb?: string) => void;
|
|
54
|
+
/** Pop the current orbital's stack: navigate to the previous entry (no-op without one). */
|
|
55
|
+
back: () => void;
|
|
56
|
+
/** Navigate to an arbitrary stack entry (breadcrumb click). */
|
|
57
|
+
goTo: (href: string) => void;
|
|
58
|
+
}
|
|
59
|
+
declare function useNavStack(): NavStackApi;
|
|
60
|
+
interface NavStackProviderProps {
|
|
61
|
+
pages: readonly NavPageDecl[];
|
|
62
|
+
/** Concrete current path (route params substituted), e.g. /contracts/42. */
|
|
63
|
+
currentPath: string;
|
|
64
|
+
/** Host navigation function (SPA route change). */
|
|
65
|
+
navigate: (path: string) => void;
|
|
66
|
+
/** sessionStorage key; omit to keep the stack in memory only. */
|
|
67
|
+
storageKey?: string;
|
|
68
|
+
children: React__default.ReactNode;
|
|
69
|
+
}
|
|
70
|
+
declare const NavStackProvider: React__default.FC<NavStackProviderProps>;
|
|
71
|
+
interface NavStackRouterBridgeProps {
|
|
72
|
+
pages: readonly NavPageDecl[];
|
|
73
|
+
storageKey?: string;
|
|
74
|
+
children: React__default.ReactNode;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compiled-path host: binds NavStackProvider to react-router. Must render
|
|
78
|
+
* inside a Router (the emitted App.tsx mounts it directly under
|
|
79
|
+
* BrowserRouter).
|
|
80
|
+
*/
|
|
81
|
+
declare const NavStackRouterBridge: React__default.FC<NavStackRouterBridgeProps>;
|
|
82
|
+
|
|
83
|
+
export { type NavPageDecl as N, type NavStackApi as a, NavStackProvider as b, type NavStackProviderProps as c, NavStackRouterBridge as d, type NavStackRouterBridgeProps as e, useNavStack as u };
|
package/dist/avl/index.cjs
CHANGED
|
@@ -23665,17 +23665,27 @@ var init_Breadcrumb = __esm({
|
|
|
23665
23665
|
init_useEventBus();
|
|
23666
23666
|
Breadcrumb = ({
|
|
23667
23667
|
items,
|
|
23668
|
+
fromNavStack = false,
|
|
23669
|
+
itemEvent,
|
|
23668
23670
|
separator = "chevron-right",
|
|
23669
23671
|
maxItems,
|
|
23670
23672
|
className
|
|
23671
23673
|
}) => {
|
|
23672
23674
|
const eventBus = useEventBus();
|
|
23673
23675
|
const { t } = hooks.useTranslate();
|
|
23674
|
-
const
|
|
23675
|
-
|
|
23676
|
+
const navStack = providers.useNavStack();
|
|
23677
|
+
const sourceItems = fromNavStack ? navStack.entries.map((entry, i) => ({
|
|
23678
|
+
label: entry.label,
|
|
23679
|
+
path: entry.href,
|
|
23680
|
+
isCurrent: i === navStack.entries.length - 1,
|
|
23681
|
+
event: itemEvent
|
|
23682
|
+
})) : items ?? [];
|
|
23683
|
+
if (fromNavStack && sourceItems.length === 0) return null;
|
|
23684
|
+
const displayItems = maxItems && sourceItems.length > maxItems ? [
|
|
23685
|
+
...sourceItems.slice(0, 1),
|
|
23676
23686
|
{ label: "...", isCurrent: false },
|
|
23677
|
-
...
|
|
23678
|
-
] :
|
|
23687
|
+
...sourceItems.slice(-maxItems + 1)
|
|
23688
|
+
] : sourceItems;
|
|
23679
23689
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
23680
23690
|
"nav",
|
|
23681
23691
|
{
|
|
@@ -23685,7 +23695,7 @@ var init_Breadcrumb = __esm({
|
|
|
23685
23695
|
const isLast = index === displayItems.length - 1;
|
|
23686
23696
|
const isEllipsis = item.label === "...";
|
|
23687
23697
|
return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center gap-2", children: [
|
|
23688
|
-
isEllipsis ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", children: item.label }) : item.href || item.path ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23698
|
+
isEllipsis ? /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "muted", children: item.label }) : (item.href || item.path) && !item.event && !fromNavStack ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
23689
23699
|
"a",
|
|
23690
23700
|
{
|
|
23691
23701
|
href: item.href || item.path,
|
|
@@ -23711,7 +23721,12 @@ var init_Breadcrumb = __esm({
|
|
|
23711
23721
|
{
|
|
23712
23722
|
type: "button",
|
|
23713
23723
|
onClick: () => {
|
|
23714
|
-
|
|
23724
|
+
const href = item.path ?? item.href;
|
|
23725
|
+
if (item.event) {
|
|
23726
|
+
eventBus.emit(`UI:${item.event}`, { label: item.label, href, index });
|
|
23727
|
+
} else if (fromNavStack && href) {
|
|
23728
|
+
navStack.goTo(href);
|
|
23729
|
+
}
|
|
23715
23730
|
item.onClick?.();
|
|
23716
23731
|
},
|
|
23717
23732
|
className: cn(
|
|
@@ -44184,6 +44199,7 @@ var init_DetailPanel = __esm({
|
|
|
44184
44199
|
init_Box();
|
|
44185
44200
|
init_Stack();
|
|
44186
44201
|
init_SimpleGrid();
|
|
44202
|
+
init_Menu();
|
|
44187
44203
|
init_LoadingState();
|
|
44188
44204
|
init_ErrorState();
|
|
44189
44205
|
init_EmptyState();
|
|
@@ -44201,6 +44217,7 @@ var init_DetailPanel = __esm({
|
|
|
44201
44217
|
avatar,
|
|
44202
44218
|
sections: propSections,
|
|
44203
44219
|
actions,
|
|
44220
|
+
maxInlineActions,
|
|
44204
44221
|
backAction,
|
|
44205
44222
|
footer,
|
|
44206
44223
|
slideOver = false,
|
|
@@ -44435,7 +44452,7 @@ var init_DetailPanel = __esm({
|
|
|
44435
44452
|
}
|
|
44436
44453
|
) }),
|
|
44437
44454
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "end", align: "center", gap: "xs", children: [
|
|
44438
|
-
otherActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
44455
|
+
(maxInlineActions != null ? otherActions.slice(0, maxInlineActions) : otherActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
44439
44456
|
Button,
|
|
44440
44457
|
{
|
|
44441
44458
|
variant: action.variant || "secondary",
|
|
@@ -44450,6 +44467,22 @@ var init_DetailPanel = __esm({
|
|
|
44450
44467
|
},
|
|
44451
44468
|
idx
|
|
44452
44469
|
)),
|
|
44470
|
+
maxInlineActions != null && otherActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
|
|
44471
|
+
Menu,
|
|
44472
|
+
{
|
|
44473
|
+
position: "bottom-end",
|
|
44474
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
|
|
44475
|
+
items: otherActions.slice(maxInlineActions).map((action) => ({
|
|
44476
|
+
// ONE firing path: onClick → handleActionClick (emits with
|
|
44477
|
+
// the {id, row} payload). Passing `event` too would make
|
|
44478
|
+
// Menu emit a second, payload-less copy of the same event.
|
|
44479
|
+
label: action.label,
|
|
44480
|
+
icon: action.icon,
|
|
44481
|
+
variant: action.variant === "danger" ? "danger" : "default",
|
|
44482
|
+
onClick: () => handleActionClick(action, normalizedData)
|
|
44483
|
+
}))
|
|
44484
|
+
}
|
|
44485
|
+
),
|
|
44453
44486
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
44454
44487
|
Button,
|
|
44455
44488
|
{
|
|
@@ -55440,7 +55473,7 @@ function runTickFrame(entityId, orderedWriters, store) {
|
|
|
55440
55473
|
}
|
|
55441
55474
|
var log8 = logger.createLogger("almadar:ui:effects:client-handlers");
|
|
55442
55475
|
function createClientEffectHandlers(options) {
|
|
55443
|
-
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
55476
|
+
const { eventBus, slotSetter, navigate, navigateBack, notify, callService, liveEntity } = options;
|
|
55444
55477
|
return {
|
|
55445
55478
|
emit: (event, payload, source) => {
|
|
55446
55479
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -55490,6 +55523,9 @@ function createClientEffectHandlers(options) {
|
|
|
55490
55523
|
}
|
|
55491
55524
|
log8.warn("No navigate handler, ignoring", { path });
|
|
55492
55525
|
}),
|
|
55526
|
+
navigateBack: navigateBack ?? (() => {
|
|
55527
|
+
log8.warn("No navigate-back handler, ignoring");
|
|
55528
|
+
}),
|
|
55493
55529
|
notify: notify ?? ((msg, type) => {
|
|
55494
55530
|
log8.debug("notify", { type, message: msg });
|
|
55495
55531
|
})
|
|
@@ -55959,6 +55995,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
55959
55995
|
}
|
|
55960
55996
|
},
|
|
55961
55997
|
navigate: optionsRef.current?.navigate,
|
|
55998
|
+
navigateBack: optionsRef.current?.navigateBack,
|
|
55962
55999
|
notify: optionsRef.current?.notify,
|
|
55963
56000
|
callService: optionsRef.current?.callService,
|
|
55964
56001
|
// The canonical client `set` writes `(set @entity.X)` straight into
|
|
@@ -56020,6 +56057,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
56020
56057
|
emit: clientHandlers.emit,
|
|
56021
56058
|
renderUI: clientHandlers.renderUI,
|
|
56022
56059
|
navigate: clientHandlers.navigate,
|
|
56060
|
+
navigateBack: clientHandlers.navigateBack,
|
|
56023
56061
|
notify: clientHandlers.notify
|
|
56024
56062
|
};
|
|
56025
56063
|
}
|
|
@@ -56639,7 +56677,7 @@ function normalizeChild(child) {
|
|
|
56639
56677
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
56640
56678
|
};
|
|
56641
56679
|
}
|
|
56642
|
-
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits) {
|
|
56680
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraits, onNavigateBack) {
|
|
56643
56681
|
for (const eff of effects) {
|
|
56644
56682
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
56645
56683
|
if (eff.traitName && activeTraits && !activeTraits.has(eff.traitName)) {
|
|
@@ -56685,7 +56723,9 @@ function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, active
|
|
|
56685
56723
|
});
|
|
56686
56724
|
}
|
|
56687
56725
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
56688
|
-
onNavigate(eff.route, eff.params);
|
|
56726
|
+
onNavigate(eff.route, eff.params, eff.crumb);
|
|
56727
|
+
} else if (eff.type === "navigate-back" && onNavigateBack) {
|
|
56728
|
+
onNavigateBack();
|
|
56689
56729
|
}
|
|
56690
56730
|
}
|
|
56691
56731
|
}
|
|
@@ -56708,7 +56748,17 @@ function collectServerActiveTraits(ir, allTraits, mountedTraitNames) {
|
|
|
56708
56748
|
}
|
|
56709
56749
|
return active;
|
|
56710
56750
|
}
|
|
56711
|
-
function
|
|
56751
|
+
function NavStackRefBridge({ apiRef }) {
|
|
56752
|
+
const api = providers.useNavStack();
|
|
56753
|
+
React94.useEffect(() => {
|
|
56754
|
+
apiRef.current = api;
|
|
56755
|
+
return () => {
|
|
56756
|
+
apiRef.current = null;
|
|
56757
|
+
};
|
|
56758
|
+
}, [api, apiRef]);
|
|
56759
|
+
return null;
|
|
56760
|
+
}
|
|
56761
|
+
function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNavigate, onNavigateBack, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, serverActiveTraits, children }) {
|
|
56712
56762
|
const bridge = providers.useServerBridge();
|
|
56713
56763
|
const activeTraitNames = React94.useMemo(
|
|
56714
56764
|
() => new Set(traits2.map((b) => b.trait.name).filter((n) => !!n)),
|
|
@@ -56734,10 +56784,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
56734
56784
|
for (const name of targets) {
|
|
56735
56785
|
const { effects, meta } = await bridge.sendEvent(name, event, withActiveTraits(payload));
|
|
56736
56786
|
recordServerResponse(name, event, meta);
|
|
56737
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
56787
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
56738
56788
|
}
|
|
56739
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
56740
|
-
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
56789
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
56790
|
+
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
56741
56791
|
const { sendEvent, entityBindingSource } = useTraitStateMachine(traits2, uiSlots, opts);
|
|
56742
56792
|
const initSentRef = React94.useRef(false);
|
|
56743
56793
|
const prevTraitsRef = React94.useRef(void 0);
|
|
@@ -56796,13 +56846,13 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
56796
56846
|
effects: effectTraces,
|
|
56797
56847
|
timestamp: Date.now()
|
|
56798
56848
|
});
|
|
56799
|
-
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames);
|
|
56849
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
56800
56850
|
}
|
|
56801
56851
|
})();
|
|
56802
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|
|
56852
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits, routeParams]);
|
|
56803
56853
|
return /* @__PURE__ */ jsxRuntime.jsx(providers.EntityBindingContext.Provider, { value: entityBindingSource, children });
|
|
56804
56854
|
}
|
|
56805
|
-
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeParams, onNavigate, onLocalFallback, persistence }) {
|
|
56855
|
+
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeParams, onNavigate, onNavigateBack, onLocalFallback, persistence }) {
|
|
56806
56856
|
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
56807
56857
|
const allPageTraits = React94.useMemo(() => {
|
|
56808
56858
|
let base;
|
|
@@ -56950,6 +57000,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, routeP
|
|
|
56950
57000
|
embeddedTraits,
|
|
56951
57001
|
serverActiveTraits,
|
|
56952
57002
|
onNavigate,
|
|
57003
|
+
onNavigateBack,
|
|
56953
57004
|
onLocalFallback,
|
|
56954
57005
|
persistence,
|
|
56955
57006
|
children: /* @__PURE__ */ jsxRuntime.jsx(providers.OrbitalThemeProvider, { theme: activeOrbitalTheme, children: /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "h-full min-h-full overflow-auto p-4", children: /* @__PURE__ */ jsxRuntime.jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) }) })
|
|
@@ -57042,6 +57093,15 @@ function OrbPreview({
|
|
|
57042
57093
|
const resolved = pages.find((p) => p.page.name === activePageName)?.page.path;
|
|
57043
57094
|
return resolved ?? initialPagePath;
|
|
57044
57095
|
}, [pages, currentPage, initialPagePath]);
|
|
57096
|
+
const navPages = React94.useMemo(
|
|
57097
|
+
() => pages.filter((p) => typeof p.page.path === "string" && p.page.path.length > 0).map((p) => ({ path: p.page.path, name: p.page.name, orbital: p.orbitalName })),
|
|
57098
|
+
[pages]
|
|
57099
|
+
);
|
|
57100
|
+
const concreteCurrentPath = React94.useMemo(() => {
|
|
57101
|
+
const pattern = currentPagePath ?? "/";
|
|
57102
|
+
return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
|
|
57103
|
+
}, [currentPagePath, routeParams]);
|
|
57104
|
+
const navStackRef = React94.useRef(null);
|
|
57045
57105
|
const handleNavigate = React94.useCallback((path) => {
|
|
57046
57106
|
const hit = providers.matchPathAmong(pages, path, (entry) => entry.page.path);
|
|
57047
57107
|
const match = hit?.candidate;
|
|
@@ -57063,6 +57123,16 @@ function OrbPreview({
|
|
|
57063
57123
|
}
|
|
57064
57124
|
}
|
|
57065
57125
|
}, [pages]);
|
|
57126
|
+
const handleNavigateEffect = React94.useCallback(
|
|
57127
|
+
(path, _params, crumb) => {
|
|
57128
|
+
navStackRef.current?.beginNavigate(path, crumb);
|
|
57129
|
+
handleNavigate(path);
|
|
57130
|
+
},
|
|
57131
|
+
[handleNavigate]
|
|
57132
|
+
);
|
|
57133
|
+
const handleNavigateBack = React94.useCallback(() => {
|
|
57134
|
+
navStackRef.current?.back();
|
|
57135
|
+
}, []);
|
|
57066
57136
|
React94.useEffect(() => {
|
|
57067
57137
|
const unsubscribe = eventBus.on("UI:NAVIGATE", (event) => {
|
|
57068
57138
|
const url = event.payload?.url;
|
|
@@ -57115,20 +57185,33 @@ function OrbPreview({
|
|
|
57115
57185
|
style: { height },
|
|
57116
57186
|
children: [
|
|
57117
57187
|
localFallback && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-3 py-2 bg-[var(--color-warning)] bg-opacity-10 border-b border-[var(--color-warning)] flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", className: "text-[var(--color-warning-foreground)] flex-1", children: "Preview server unreachable \u2014 running locally. Server-side state and persistence are disabled." }) }),
|
|
57118
|
-
/* @__PURE__ */ jsxRuntime.jsx(providers.CurrentPagePathProvider, { value: currentPagePath, children: /* @__PURE__ */ jsxRuntime.
|
|
57119
|
-
|
|
57120
|
-
{
|
|
57121
|
-
|
|
57122
|
-
|
|
57123
|
-
|
|
57124
|
-
|
|
57125
|
-
|
|
57126
|
-
|
|
57127
|
-
|
|
57128
|
-
|
|
57129
|
-
|
|
57130
|
-
|
|
57131
|
-
|
|
57188
|
+
/* @__PURE__ */ jsxRuntime.jsx(providers.CurrentPagePathProvider, { value: currentPagePath, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
57189
|
+
providers.NavStackProvider,
|
|
57190
|
+
{
|
|
57191
|
+
pages: navPages,
|
|
57192
|
+
currentPath: concreteCurrentPath,
|
|
57193
|
+
navigate: handleNavigate,
|
|
57194
|
+
storageKey: `almadar:navstack:${parseResult.schema.name ?? "preview"}`,
|
|
57195
|
+
children: [
|
|
57196
|
+
/* @__PURE__ */ jsxRuntime.jsx(NavStackRefBridge, { apiRef: navStackRef }),
|
|
57197
|
+
/* @__PURE__ */ jsxRuntime.jsx(providers.OrbitalProvider, { initialData: effectiveMockData, skipTheme: true, verification: true, isolated, children: /* @__PURE__ */ jsxRuntime.jsx(context.UISlotProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
57198
|
+
SchemaRunner,
|
|
57199
|
+
{
|
|
57200
|
+
schema: parseResult.schema,
|
|
57201
|
+
serverUrl,
|
|
57202
|
+
transport,
|
|
57203
|
+
mockData: effectiveMockData,
|
|
57204
|
+
pageName: currentPage,
|
|
57205
|
+
routeParams,
|
|
57206
|
+
onNavigate: handleNavigateEffect,
|
|
57207
|
+
onNavigateBack: handleNavigateBack,
|
|
57208
|
+
onLocalFallback: handleLocalFallback,
|
|
57209
|
+
persistence
|
|
57210
|
+
}
|
|
57211
|
+
) }) })
|
|
57212
|
+
]
|
|
57213
|
+
}
|
|
57214
|
+
) })
|
|
57132
57215
|
]
|
|
57133
57216
|
}
|
|
57134
57217
|
);
|