@almadar/ui 5.158.0 → 5.160.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-Bn3ePJQC.d.cts → EntityBindingContext-0Evn_LcT.d.cts} +1 -1
- package/dist/{EntityBindingContext-Bn3ePJQC.d.ts → EntityBindingContext-0Evn_LcT.d.ts} +1 -1
- package/dist/avl/index.cjs +177 -54
- package/dist/avl/index.js +178 -55
- package/dist/components/index.cjs +225 -27
- package/dist/components/index.d.cts +8 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +226 -28
- package/dist/context/index.cjs +134 -39
- package/dist/context/index.js +92 -1
- package/dist/hooks/index.cjs +328 -233
- package/dist/hooks/index.js +93 -2
- package/dist/lib/index.cjs +92 -0
- package/dist/lib/index.d.cts +58 -1
- package/dist/lib/index.d.ts +58 -1
- package/dist/lib/index.js +62 -1
- package/dist/locales/index.cjs +3 -0
- package/dist/locales/index.js +3 -0
- package/dist/perf-DaVdsbU0.d.cts +21 -0
- package/dist/perf-DaVdsbU0.d.ts +21 -0
- package/dist/providers/index.cjs +289 -116
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +290 -117
- package/dist/runtime/index.cjs +185 -59
- package/dist/runtime/index.d.cts +5 -22
- package/dist/runtime/index.d.ts +5 -22
- package/dist/runtime/index.js +187 -60
- package/locales/ar.json +1 -0
- package/locales/en.json +1 -0
- package/locales/sl.json +1 -0
- package/package.json +5 -5
|
@@ -3,7 +3,7 @@ import { EntityRow, SExpr } from '@almadar/core';
|
|
|
3
3
|
export { ANONYMOUS_USER } from '@almadar/core';
|
|
4
4
|
import { U as UIThemeDefinition, j as UserData } from '../UserContext-g_LcDiGN.js';
|
|
5
5
|
export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as CurrentPagePathProviderProps, d as DesignThemeProvider, O as OrbitalThemeProvider, e as OrbitalThemeProviderProps, h as UserContext, i as UserContextValue, k as UserProvider, l as UserProviderProps, u as useCurrentPagePath, m as useDesignTheme, n as useHasPermission, o as useHasRole, q as useUser, r as useUserForEvaluation } from '../UserContext-g_LcDiGN.js';
|
|
6
|
-
export {
|
|
6
|
+
export { o as EntityBindingContext, E as EntityBindingSource, a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, p as SendEventResult, d as ServerBridgeContextValue, e as ServerBridgeProvider, q as ServerBridgeProviderProps, S as ServerBridgeTransport, f as ServerClientEffect, r as ServerResponseMeta, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, s as useEntityBindingSnapshot, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.js';
|
|
7
7
|
import { j as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-QUdKOj7f.js';
|
|
8
8
|
export { c as NavigationContextValue, d as NavigationProvider, e as NavigationProviderProps, f as NavigationState, k as comparePathSpecificity, m as extractRouteParams, n as findPageByName, o as findPageByPath, p as getAllPages, q as getDefaultPage, r as matchPath, s as matchPathAmong, t as pathMatches, u as useActivePage, v as useInitPayload, w as useNavigateTo, x as useNavigation, y as useNavigationId, z as useNavigationState } from '../offline-executor-QUdKOj7f.js';
|
|
9
9
|
import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.js';
|
package/dist/providers/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { useTranslate } from '@almadar/ui/hooks';
|
|
|
15
15
|
import { useUISlots, ThemeProvider, useTheme } from '@almadar/ui/context';
|
|
16
16
|
export { DesignThemeProvider, useDesignTheme } from '@almadar/ui/context';
|
|
17
17
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
18
|
-
import { wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
18
|
+
import { wrapCallbackForEvent, perfStart, perfEnd } from '@almadar/runtime/ui';
|
|
19
19
|
import { useLocation, useNavigate, Link, Outlet } from 'react-router-dom';
|
|
20
20
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
|
21
21
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
|
|
@@ -286,7 +286,16 @@ function isPlainObject(value) {
|
|
|
286
286
|
if (typeof value === "function") return false;
|
|
287
287
|
return true;
|
|
288
288
|
}
|
|
289
|
+
function isEvaluatorResolvedData(value) {
|
|
290
|
+
return evaluatorResolvedData.has(value);
|
|
291
|
+
}
|
|
292
|
+
function brandResolved(value) {
|
|
293
|
+
if (value !== null && typeof value === "object" && !React87__default.isValidElement(value) && !(value instanceof Date)) {
|
|
294
|
+
resolvedMarkerFree.add(value);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
289
297
|
function subtreeHasMarker(value) {
|
|
298
|
+
if (resolvedMarkerFree.has(value)) return false;
|
|
290
299
|
const cached = markerPresenceCache.get(value);
|
|
291
300
|
if (cached !== void 0) return cached;
|
|
292
301
|
let found = false;
|
|
@@ -308,10 +317,23 @@ function subtreeHasMarker(value) {
|
|
|
308
317
|
}
|
|
309
318
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
310
319
|
if (isRenderBindingMarker(value)) {
|
|
311
|
-
|
|
320
|
+
const cached = markerResolutionCache.get(value);
|
|
321
|
+
if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
|
|
322
|
+
return { resolved: cached.resolved, changed: false };
|
|
323
|
+
}
|
|
324
|
+
const resolved = resolveMarkerExpression(value.expression, entity, config, state);
|
|
325
|
+
markerResolutionCache.set(value, { entity, config, state, resolved });
|
|
326
|
+
if (resolved !== null && typeof resolved === "object" && !React87__default.isValidElement(resolved) && !(resolved instanceof Date)) {
|
|
327
|
+
resolvedMarkerFree.add(resolved);
|
|
328
|
+
evaluatorResolvedData.add(resolved);
|
|
329
|
+
}
|
|
330
|
+
return { resolved, changed: true };
|
|
312
331
|
}
|
|
313
332
|
if (Array.isArray(value)) {
|
|
314
|
-
if (!subtreeHasMarker(value))
|
|
333
|
+
if (!subtreeHasMarker(value)) {
|
|
334
|
+
brandResolved(value);
|
|
335
|
+
return { resolved: value, changed: false };
|
|
336
|
+
}
|
|
315
337
|
const out = [];
|
|
316
338
|
let changed = false;
|
|
317
339
|
for (const item of value) {
|
|
@@ -326,10 +348,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
326
348
|
out.push(resolved);
|
|
327
349
|
if (itemChanged) changed = true;
|
|
328
350
|
}
|
|
351
|
+
brandResolved(out);
|
|
329
352
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
330
353
|
}
|
|
331
354
|
if (isPlainObject(value)) {
|
|
332
|
-
if (!subtreeHasMarker(value))
|
|
355
|
+
if (!subtreeHasMarker(value)) {
|
|
356
|
+
brandResolved(value);
|
|
357
|
+
return { resolved: value, changed: false };
|
|
358
|
+
}
|
|
333
359
|
const sourceTrait = value._sourceTrait;
|
|
334
360
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
335
361
|
return { resolved: value, changed: false };
|
|
@@ -341,11 +367,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
341
367
|
out[key] = resolved;
|
|
342
368
|
if (itemChanged) changed = true;
|
|
343
369
|
}
|
|
370
|
+
brandResolved(out);
|
|
344
371
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
345
372
|
}
|
|
346
373
|
return { resolved: value, changed: false };
|
|
347
374
|
}
|
|
348
375
|
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
376
|
+
if (resolvedMarkerFree.has(props)) return props;
|
|
349
377
|
const out = {};
|
|
350
378
|
let changed = false;
|
|
351
379
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -353,13 +381,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
353
381
|
out[key] = resolved;
|
|
354
382
|
if (propChanged) changed = true;
|
|
355
383
|
}
|
|
384
|
+
brandResolved(out);
|
|
356
385
|
return changed ? out : props;
|
|
357
386
|
}
|
|
358
|
-
var markerPresenceCache;
|
|
387
|
+
var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
|
|
359
388
|
var init_resolve_render_bindings = __esm({
|
|
360
389
|
"lib/resolve-render-bindings.ts"() {
|
|
361
390
|
"use client";
|
|
362
391
|
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
392
|
+
markerResolutionCache = /* @__PURE__ */ new WeakMap();
|
|
393
|
+
resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
|
|
394
|
+
evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
|
|
363
395
|
}
|
|
364
396
|
});
|
|
365
397
|
function cn(...inputs) {
|
|
@@ -11793,6 +11825,10 @@ var init_molecules = __esm({
|
|
|
11793
11825
|
init_puzzleObject();
|
|
11794
11826
|
}
|
|
11795
11827
|
});
|
|
11828
|
+
var init_perf = __esm({
|
|
11829
|
+
"lib/perf.ts"() {
|
|
11830
|
+
}
|
|
11831
|
+
});
|
|
11796
11832
|
function themeBodyFont(el) {
|
|
11797
11833
|
if (typeof getComputedStyle !== "function") return "system-ui, sans-serif";
|
|
11798
11834
|
const v = getComputedStyle(el).getPropertyValue("--font-family-body").trim();
|
|
@@ -12141,6 +12177,7 @@ var init_LearningCanvas = __esm({
|
|
|
12141
12177
|
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
12142
12178
|
"use client";
|
|
12143
12179
|
init_cn();
|
|
12180
|
+
init_perf();
|
|
12144
12181
|
init_useEventBus();
|
|
12145
12182
|
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
12146
12183
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
@@ -12184,6 +12221,7 @@ var init_LearningCanvas = __esm({
|
|
|
12184
12221
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
12185
12222
|
}, [shapes, traces, readouts, width, height]);
|
|
12186
12223
|
const draw = useCallback(() => {
|
|
12224
|
+
const _perfT = perfStart("learningcanvas:paint");
|
|
12187
12225
|
const canvas = canvasRef.current;
|
|
12188
12226
|
if (!canvas) return;
|
|
12189
12227
|
const ctx = canvas.getContext("2d");
|
|
@@ -12205,6 +12243,7 @@ var init_LearningCanvas = __esm({
|
|
|
12205
12243
|
for (const shape of derivedShapes) {
|
|
12206
12244
|
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12207
12245
|
}
|
|
12246
|
+
perfEnd("learningcanvas:paint", _perfT);
|
|
12208
12247
|
}, [width, height, backgroundColor, derivedShapes]);
|
|
12209
12248
|
useEffect(() => {
|
|
12210
12249
|
draw();
|
|
@@ -26501,8 +26540,8 @@ function DataGrid({
|
|
|
26501
26540
|
}
|
|
26502
26541
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
26503
26542
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
26504
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26505
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
|
|
26543
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26544
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
26506
26545
|
] }, field.name);
|
|
26507
26546
|
}) })
|
|
26508
26547
|
] }) })
|
|
@@ -26930,7 +26969,11 @@ function DataList({
|
|
|
26930
26969
|
Box,
|
|
26931
26970
|
{
|
|
26932
26971
|
className: cn(
|
|
26933
|
-
|
|
26972
|
+
// items-start, not items-center: a multi-line row (title + meta +
|
|
26973
|
+
// progress) centred its action cluster in the vertical middle, so
|
|
26974
|
+
// the buttons floated between the meta fields instead of anchoring
|
|
26975
|
+
// to the title they act on (U-DATALIST-ACTIONS-FLOAT-MID-ROW).
|
|
26976
|
+
"group flex items-start gap-4 transition-all duration-fast",
|
|
26934
26977
|
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
26935
26978
|
"hover:bg-muted/80",
|
|
26936
26979
|
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
@@ -26961,11 +27004,19 @@ function DataList({
|
|
|
26961
27004
|
if (value === void 0 || value === null || value === "") return null;
|
|
26962
27005
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
26963
27006
|
field.icon && renderIconInput2(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
26964
|
-
/* @__PURE__ */ jsxs(
|
|
26965
|
-
|
|
26966
|
-
|
|
26967
|
-
|
|
26968
|
-
|
|
27007
|
+
/* @__PURE__ */ jsxs(
|
|
27008
|
+
Typography,
|
|
27009
|
+
{
|
|
27010
|
+
variant: "caption",
|
|
27011
|
+
color: "secondary",
|
|
27012
|
+
className: cn(field.format !== "boolean" && "sr-only"),
|
|
27013
|
+
children: [
|
|
27014
|
+
field.label ?? fieldLabel3(field.name),
|
|
27015
|
+
":"
|
|
27016
|
+
]
|
|
27017
|
+
}
|
|
27018
|
+
),
|
|
27019
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
26969
27020
|
] }, field.name);
|
|
26970
27021
|
}) }),
|
|
26971
27022
|
progressFields.map((field) => {
|
|
@@ -26984,7 +27035,7 @@ function DataList({
|
|
|
26984
27035
|
]
|
|
26985
27036
|
}
|
|
26986
27037
|
),
|
|
26987
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "
|
|
27038
|
+
(isCard || isCompact) && !isLast && /* @__PURE__ */ jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") })
|
|
26988
27039
|
] }, id)
|
|
26989
27040
|
);
|
|
26990
27041
|
};
|
|
@@ -26994,7 +27045,13 @@ function DataList({
|
|
|
26994
27045
|
{
|
|
26995
27046
|
className: cn(
|
|
26996
27047
|
isCard && "bg-card rounded-xl border border-border shadow-elevation-dialog overflow-hidden",
|
|
26997
|
-
|
|
27048
|
+
// `gap-*` is inert on a block container, and Box only emits a display
|
|
27049
|
+
// class when its `display` prop is set — so every non-card list had
|
|
27050
|
+
// been asking for a gap that CSS silently dropped. flex-col makes it
|
|
27051
|
+
// real. `compact` keeps gap-0 on purpose: it separates with the row
|
|
27052
|
+
// divider above instead, never both (Almadar_UI_Beauty.md 6).
|
|
27053
|
+
!isCard && "flex flex-col",
|
|
27054
|
+
!isCard && !isCompact && gapClass,
|
|
26998
27055
|
listLookStyles[look],
|
|
26999
27056
|
className
|
|
27000
27057
|
),
|
|
@@ -30609,6 +30666,7 @@ var init_MathCanvas = __esm({
|
|
|
30609
30666
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
30610
30667
|
"use client";
|
|
30611
30668
|
init_useEventBus();
|
|
30669
|
+
init_perf();
|
|
30612
30670
|
init_atoms();
|
|
30613
30671
|
init_Stack();
|
|
30614
30672
|
init_LearningCanvas();
|
|
@@ -30674,6 +30732,7 @@ var init_MathCanvas = __esm({
|
|
|
30674
30732
|
};
|
|
30675
30733
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30676
30734
|
const derivedShapes = useMemo(() => {
|
|
30735
|
+
const _perfT = perfStart("mathcanvas:derive");
|
|
30677
30736
|
const out = [];
|
|
30678
30737
|
const margin = 24;
|
|
30679
30738
|
const plotW = width - margin * 2;
|
|
@@ -30917,6 +30976,7 @@ var init_MathCanvas = __esm({
|
|
|
30917
30976
|
}
|
|
30918
30977
|
}
|
|
30919
30978
|
out.push(...shapes);
|
|
30979
|
+
perfEnd("mathcanvas:derive", _perfT);
|
|
30920
30980
|
return out;
|
|
30921
30981
|
}, [
|
|
30922
30982
|
width,
|
|
@@ -32180,12 +32240,12 @@ var init_MapView = __esm({
|
|
|
32180
32240
|
shadowSize: [41, 41]
|
|
32181
32241
|
});
|
|
32182
32242
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
32183
|
-
const { useEffect: useEffect67, useRef:
|
|
32243
|
+
const { useEffect: useEffect67, useRef: useRef65, useCallback: useCallback97, useState: useState95 } = React87__default;
|
|
32184
32244
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
32185
32245
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
32186
32246
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
32187
32247
|
const map = useMap();
|
|
32188
|
-
const prevRef =
|
|
32248
|
+
const prevRef = useRef65({ centerLat, centerLng, zoom });
|
|
32189
32249
|
useEffect67(() => {
|
|
32190
32250
|
const prev = prevRef.current;
|
|
32191
32251
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
@@ -37270,7 +37330,7 @@ var init_RichBlockEditor = __esm({
|
|
|
37270
37330
|
{
|
|
37271
37331
|
variant: "bordered",
|
|
37272
37332
|
padding: "none",
|
|
37273
|
-
className: cn("flex flex-col", className),
|
|
37333
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
37274
37334
|
children: [
|
|
37275
37335
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsx(
|
|
37276
37336
|
Box,
|
|
@@ -42498,6 +42558,7 @@ var init_DetailPanel = __esm({
|
|
|
42498
42558
|
"use client";
|
|
42499
42559
|
init_atoms();
|
|
42500
42560
|
init_Box();
|
|
42561
|
+
init_Input();
|
|
42501
42562
|
init_Stack();
|
|
42502
42563
|
init_SimpleGrid();
|
|
42503
42564
|
init_Menu();
|
|
@@ -42513,6 +42574,7 @@ var init_DetailPanel = __esm({
|
|
|
42513
42574
|
ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
42514
42575
|
DetailPanel = ({
|
|
42515
42576
|
title: propTitle,
|
|
42577
|
+
onTitleCommit,
|
|
42516
42578
|
subtitle,
|
|
42517
42579
|
status,
|
|
42518
42580
|
avatar,
|
|
@@ -42534,6 +42596,7 @@ var init_DetailPanel = __esm({
|
|
|
42534
42596
|
}) => {
|
|
42535
42597
|
const eventBus = useEventBus();
|
|
42536
42598
|
const { t } = useTranslate();
|
|
42599
|
+
const [titleDraft, setTitleDraft] = React87__default.useState(null);
|
|
42537
42600
|
const isFieldDefArray = (arr) => {
|
|
42538
42601
|
if (!arr || arr.length === 0) return false;
|
|
42539
42602
|
const first = arr[0];
|
|
@@ -42754,6 +42817,50 @@ var init_DetailPanel = __esm({
|
|
|
42754
42817
|
}),
|
|
42755
42818
|
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
42756
42819
|
] });
|
|
42820
|
+
const commitTitle = () => {
|
|
42821
|
+
if (!onTitleCommit) return;
|
|
42822
|
+
const next = (titleDraft ?? "").trim();
|
|
42823
|
+
setTitleDraft(null);
|
|
42824
|
+
if (!next || next === title) return;
|
|
42825
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
42826
|
+
};
|
|
42827
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsx(
|
|
42828
|
+
Input,
|
|
42829
|
+
{
|
|
42830
|
+
value: titleDraft,
|
|
42831
|
+
autoFocus: true,
|
|
42832
|
+
"aria-label": t("common.title"),
|
|
42833
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
42834
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
42835
|
+
onBlur: commitTitle,
|
|
42836
|
+
onKeyDown: (e) => {
|
|
42837
|
+
if (e.key === "Enter") {
|
|
42838
|
+
e.preventDefault();
|
|
42839
|
+
commitTitle();
|
|
42840
|
+
} else if (e.key === "Escape") {
|
|
42841
|
+
e.preventDefault();
|
|
42842
|
+
setTitleDraft(null);
|
|
42843
|
+
}
|
|
42844
|
+
},
|
|
42845
|
+
"data-testid": "detail-title-input"
|
|
42846
|
+
}
|
|
42847
|
+
) : onTitleCommit ? /* @__PURE__ */ jsx(
|
|
42848
|
+
Box,
|
|
42849
|
+
{
|
|
42850
|
+
role: "button",
|
|
42851
|
+
tabIndex: 0,
|
|
42852
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
42853
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
42854
|
+
onKeyDown: (e) => {
|
|
42855
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
42856
|
+
e.preventDefault();
|
|
42857
|
+
setTitleDraft(title ?? "");
|
|
42858
|
+
}
|
|
42859
|
+
},
|
|
42860
|
+
"data-testid": "detail-title-editable",
|
|
42861
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
42862
|
+
}
|
|
42863
|
+
) : /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
42757
42864
|
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
42758
42865
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
42759
42866
|
/* @__PURE__ */ jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -42773,7 +42880,7 @@ var init_DetailPanel = __esm({
|
|
|
42773
42880
|
avatar,
|
|
42774
42881
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
42775
42882
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
42776
|
-
|
|
42883
|
+
titleNode,
|
|
42777
42884
|
statusBadges
|
|
42778
42885
|
] }),
|
|
42779
42886
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -42873,16 +42980,11 @@ var init_DetailPanel = __esm({
|
|
|
42873
42980
|
footer
|
|
42874
42981
|
] })
|
|
42875
42982
|
] }) });
|
|
42876
|
-
|
|
42877
|
-
Box,
|
|
42878
|
-
|
|
42879
|
-
|
|
42880
|
-
|
|
42881
|
-
className
|
|
42882
|
-
),
|
|
42883
|
-
children: content
|
|
42884
|
-
}
|
|
42885
|
-
);
|
|
42983
|
+
if (!slideOver) {
|
|
42984
|
+
return /* @__PURE__ */ jsx(Box, { className, children: content });
|
|
42985
|
+
}
|
|
42986
|
+
const panel = /* @__PURE__ */ jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
|
|
42987
|
+
return typeof document === "undefined" ? panel : createPortal(panel, document.body);
|
|
42886
42988
|
};
|
|
42887
42989
|
DetailPanel.displayName = "DetailPanel";
|
|
42888
42990
|
}
|
|
@@ -43334,7 +43436,7 @@ var init_Form = __esm({
|
|
|
43334
43436
|
});
|
|
43335
43437
|
debug(
|
|
43336
43438
|
"forms",
|
|
43337
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
43439
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
43338
43440
|
);
|
|
43339
43441
|
}
|
|
43340
43442
|
});
|
|
@@ -49814,6 +49916,7 @@ function isPlainConfigObject(value) {
|
|
|
49814
49916
|
return proto === Object.prototype || proto === null;
|
|
49815
49917
|
}
|
|
49816
49918
|
function subtreeHasTraitRef(value) {
|
|
49919
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
49817
49920
|
const cached = traitRefPresenceCache.get(value);
|
|
49818
49921
|
if (cached !== void 0) return cached;
|
|
49819
49922
|
let found = false;
|
|
@@ -49886,6 +49989,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
49886
49989
|
};
|
|
49887
49990
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
49888
49991
|
} else if (Array.isArray(value)) {
|
|
49992
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
49993
|
+
rendered[key] = value;
|
|
49994
|
+
continue;
|
|
49995
|
+
}
|
|
49889
49996
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
49890
49997
|
rendered[key] = value.map((item, i) => {
|
|
49891
49998
|
const el = item;
|
|
@@ -51327,6 +51434,53 @@ function useNavigationId2() {
|
|
|
51327
51434
|
|
|
51328
51435
|
// providers/ServerBridge.tsx
|
|
51329
51436
|
init_useEventBus();
|
|
51437
|
+
|
|
51438
|
+
// lib/tick-send-relay.ts
|
|
51439
|
+
function createTickSendRelay(send) {
|
|
51440
|
+
const lanes = /* @__PURE__ */ new Map();
|
|
51441
|
+
const flush = (key, lane) => {
|
|
51442
|
+
const next = lane.pending;
|
|
51443
|
+
lane.pending = void 0;
|
|
51444
|
+
if (next === void 0) {
|
|
51445
|
+
lane.inFlight = false;
|
|
51446
|
+
return;
|
|
51447
|
+
}
|
|
51448
|
+
lane.inFlight = true;
|
|
51449
|
+
void send(key, next).catch(() => void 0).then(() => flush(key, lane));
|
|
51450
|
+
};
|
|
51451
|
+
return {
|
|
51452
|
+
send(key, value) {
|
|
51453
|
+
const lane = lanes.get(key) ?? { inFlight: false };
|
|
51454
|
+
lanes.set(key, lane);
|
|
51455
|
+
if (lane.inFlight) {
|
|
51456
|
+
lane.pending = value;
|
|
51457
|
+
return;
|
|
51458
|
+
}
|
|
51459
|
+
lane.pending = value;
|
|
51460
|
+
flush(key, lane);
|
|
51461
|
+
},
|
|
51462
|
+
clear() {
|
|
51463
|
+
for (const lane of lanes.values()) {
|
|
51464
|
+
lane.pending = void 0;
|
|
51465
|
+
}
|
|
51466
|
+
}
|
|
51467
|
+
};
|
|
51468
|
+
}
|
|
51469
|
+
|
|
51470
|
+
// lib/command-send-pump.ts
|
|
51471
|
+
function createCommandSendPump() {
|
|
51472
|
+
let tail = Promise.resolve();
|
|
51473
|
+
return {
|
|
51474
|
+
enqueue(job) {
|
|
51475
|
+
const result = tail.then(job);
|
|
51476
|
+
tail = result.then(
|
|
51477
|
+
() => void 0,
|
|
51478
|
+
() => void 0
|
|
51479
|
+
);
|
|
51480
|
+
return result;
|
|
51481
|
+
}
|
|
51482
|
+
};
|
|
51483
|
+
}
|
|
51330
51484
|
var xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
|
|
51331
51485
|
var serverBridgeLog = createLogger("almadar:ui:server-bridge");
|
|
51332
51486
|
function reEmitServerEvent(eventBus, emitted, origin) {
|
|
@@ -51461,99 +51615,118 @@ function ServerBridgeProvider({
|
|
|
51461
51615
|
async () => transport.unregister(),
|
|
51462
51616
|
[transport]
|
|
51463
51617
|
);
|
|
51618
|
+
const tickRelay = useMemo(
|
|
51619
|
+
() => createTickSendRelay(async (_key, snap) => {
|
|
51620
|
+
await transport.sendEvent(snap.orbitalName, snap.event, snap.payload, getTabClientId(), snap.tick, snap.sourceTrait);
|
|
51621
|
+
}),
|
|
51622
|
+
[transport]
|
|
51623
|
+
);
|
|
51624
|
+
useEffect(() => () => tickRelay.clear(), [tickRelay]);
|
|
51625
|
+
const commandPump = useMemo(createCommandSendPump, []);
|
|
51626
|
+
const disposedRef = useRef(false);
|
|
51627
|
+
useEffect(() => {
|
|
51628
|
+
disposedRef.current = false;
|
|
51629
|
+
return () => {
|
|
51630
|
+
disposedRef.current = true;
|
|
51631
|
+
};
|
|
51632
|
+
}, []);
|
|
51464
51633
|
const sendEvent = useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
|
|
51465
51634
|
const emptyMeta = { success: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
|
|
51466
51635
|
if (!connected) return { effects: [], meta: emptyMeta };
|
|
51467
|
-
|
|
51468
|
-
|
|
51469
|
-
|
|
51470
|
-
|
|
51471
|
-
|
|
51472
|
-
}
|
|
51473
|
-
|
|
51474
|
-
|
|
51475
|
-
|
|
51476
|
-
|
|
51477
|
-
|
|
51478
|
-
|
|
51479
|
-
|
|
51480
|
-
|
|
51481
|
-
|
|
51482
|
-
|
|
51483
|
-
|
|
51484
|
-
|
|
51485
|
-
|
|
51486
|
-
|
|
51487
|
-
|
|
51488
|
-
|
|
51489
|
-
|
|
51490
|
-
const
|
|
51491
|
-
|
|
51492
|
-
|
|
51493
|
-
const
|
|
51494
|
-
|
|
51495
|
-
|
|
51496
|
-
|
|
51497
|
-
|
|
51498
|
-
|
|
51499
|
-
|
|
51500
|
-
|
|
51501
|
-
|
|
51502
|
-
|
|
51503
|
-
|
|
51504
|
-
|
|
51505
|
-
|
|
51506
|
-
|
|
51507
|
-
|
|
51508
|
-
|
|
51509
|
-
|
|
51510
|
-
|
|
51511
|
-
|
|
51512
|
-
|
|
51513
|
-
|
|
51514
|
-
|
|
51515
|
-
|
|
51516
|
-
|
|
51517
|
-
|
|
51518
|
-
|
|
51519
|
-
|
|
51520
|
-
|
|
51521
|
-
|
|
51522
|
-
|
|
51523
|
-
|
|
51524
|
-
|
|
51525
|
-
|
|
51526
|
-
|
|
51527
|
-
|
|
51636
|
+
if (tick !== void 0) {
|
|
51637
|
+
tickRelay.send(`${orbitalName}:${event}`, { orbitalName, event, payload, tick, sourceTrait });
|
|
51638
|
+
return { effects: [], meta: { ...emptyMeta, success: true } };
|
|
51639
|
+
}
|
|
51640
|
+
return commandPump.enqueue(async () => {
|
|
51641
|
+
if (disposedRef.current) return { effects: [], meta: emptyMeta };
|
|
51642
|
+
try {
|
|
51643
|
+
const result = await transport.sendEvent(orbitalName, event, payload, getTabClientId(), tick, sourceTrait);
|
|
51644
|
+
const effects = [];
|
|
51645
|
+
const responseData = result.data || {};
|
|
51646
|
+
const dataEntities = {};
|
|
51647
|
+
for (const [entityName, records] of Object.entries(responseData)) {
|
|
51648
|
+
dataEntities[entityName] = Array.isArray(records) ? records.length : 0;
|
|
51649
|
+
}
|
|
51650
|
+
const meta = {
|
|
51651
|
+
success: !!result.success,
|
|
51652
|
+
clientEffects: result.clientEffects?.length ?? 0,
|
|
51653
|
+
dataEntities,
|
|
51654
|
+
data: responseData,
|
|
51655
|
+
emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
|
|
51656
|
+
error: result.error
|
|
51657
|
+
};
|
|
51658
|
+
if (result.success) {
|
|
51659
|
+
const tagged = result.clientEffectsByTrait;
|
|
51660
|
+
const tuples = tagged ? tagged.map((entry) => ({ effect: entry.effect, traitName: entry.traitName })) : (result.clientEffects ?? []).map((eff) => ({ effect: eff }));
|
|
51661
|
+
for (const { effect, traitName } of tuples) {
|
|
51662
|
+
const effectType = effect[0];
|
|
51663
|
+
if (effectType === "render-ui") {
|
|
51664
|
+
const slot = effect[1];
|
|
51665
|
+
const pattern = effect[2];
|
|
51666
|
+
effects.push({
|
|
51667
|
+
type: "render-ui",
|
|
51668
|
+
slot,
|
|
51669
|
+
pattern: pattern !== null && typeof pattern === "object" ? pattern : void 0,
|
|
51670
|
+
traitName
|
|
51671
|
+
});
|
|
51672
|
+
} else if (effectType === "navigate") {
|
|
51673
|
+
const route = effect[1];
|
|
51674
|
+
const rawParams = effect[2];
|
|
51675
|
+
const rawOptions = effect[3];
|
|
51676
|
+
const optionsObj = rawOptions !== null && rawOptions !== void 0 && typeof rawOptions === "object" && !Array.isArray(rawOptions) ? rawOptions : void 0;
|
|
51677
|
+
const crumb = typeof optionsObj?.crumb === "string" ? optionsObj.crumb : void 0;
|
|
51678
|
+
effects.push({
|
|
51679
|
+
type: "navigate",
|
|
51680
|
+
route,
|
|
51681
|
+
params: rawParams !== null && rawParams !== void 0 && typeof rawParams === "object" && !Array.isArray(rawParams) ? rawParams : void 0,
|
|
51682
|
+
crumb,
|
|
51683
|
+
traitName
|
|
51684
|
+
});
|
|
51685
|
+
} else if (effectType === "navigate-back") {
|
|
51686
|
+
effects.push({ type: "navigate-back", traitName });
|
|
51687
|
+
} else if (effectType === "notify") {
|
|
51688
|
+
const message = effect[1];
|
|
51689
|
+
effects.push({ type: "notify", message: typeof message === "string" ? message : void 0, traitName });
|
|
51690
|
+
}
|
|
51691
|
+
}
|
|
51692
|
+
if (result.emittedEvents) {
|
|
51693
|
+
for (const emitted of result.emittedEvents) {
|
|
51694
|
+
if (emitted.event === event) continue;
|
|
51695
|
+
reEmitServerEvent(
|
|
51696
|
+
eventBus,
|
|
51697
|
+
{ ...emitted, source: { ...emitted.source, dispatched: true } },
|
|
51698
|
+
orbitalName
|
|
51699
|
+
);
|
|
51700
|
+
}
|
|
51528
51701
|
}
|
|
51702
|
+
} else if (result.error) {
|
|
51703
|
+
xOrbitalLog.warn("response:fail", {
|
|
51704
|
+
orbital: orbitalName,
|
|
51705
|
+
event,
|
|
51706
|
+
error: result.error
|
|
51707
|
+
});
|
|
51529
51708
|
}
|
|
51530
|
-
|
|
51531
|
-
|
|
51532
|
-
|
|
51533
|
-
|
|
51534
|
-
|
|
51535
|
-
|
|
51536
|
-
|
|
51537
|
-
|
|
51538
|
-
|
|
51539
|
-
|
|
51540
|
-
|
|
51541
|
-
|
|
51542
|
-
|
|
51543
|
-
|
|
51544
|
-
|
|
51545
|
-
|
|
51546
|
-
}
|
|
51547
|
-
|
|
51548
|
-
xOrbitalLog.error("response:network", {
|
|
51549
|
-
orbital: orbitalName,
|
|
51550
|
-
event,
|
|
51551
|
-
error: msg
|
|
51552
|
-
});
|
|
51709
|
+
return { effects, meta };
|
|
51710
|
+
} catch (err) {
|
|
51711
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
51712
|
+
if (err instanceof TypeError) {
|
|
51713
|
+
xOrbitalLog.warn("response:network", {
|
|
51714
|
+
orbital: orbitalName,
|
|
51715
|
+
event,
|
|
51716
|
+
error: msg,
|
|
51717
|
+
reason: "peer endpoint unreachable (expected in standalone single-orbital mode)"
|
|
51718
|
+
});
|
|
51719
|
+
} else {
|
|
51720
|
+
xOrbitalLog.error("response:network", {
|
|
51721
|
+
orbital: orbitalName,
|
|
51722
|
+
event,
|
|
51723
|
+
error: msg
|
|
51724
|
+
});
|
|
51725
|
+
}
|
|
51726
|
+
return { effects: [], meta: { ...emptyMeta, error: msg } };
|
|
51553
51727
|
}
|
|
51554
|
-
|
|
51555
|
-
|
|
51556
|
-
}, [connected, transport, eventBus]);
|
|
51728
|
+
});
|
|
51729
|
+
}, [connected, transport, eventBus, tickRelay, commandPump]);
|
|
51557
51730
|
useEffect(() => {
|
|
51558
51731
|
if (!schema) return;
|
|
51559
51732
|
let cancelled = false;
|