@almadar/ui 6.14.0 → 6.16.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-BMz9xiBa.d.cts → EntityBindingContext-Dglbi9ks.d.cts} +8 -1
- package/dist/{EntityBindingContext-BMz9xiBa.d.ts → EntityBindingContext-Dglbi9ks.d.ts} +8 -1
- package/dist/avl/index.cjs +140 -80
- package/dist/avl/index.js +140 -80
- package/dist/{avl-schema-parser-B25PL-a8.d.cts → avl-schema-parser-dGHC5jUf.d.cts} +5 -5
- package/dist/{avl-schema-parser-CM0pQo8E.d.ts → avl-schema-parser-tzl7qXDY.d.ts} +5 -5
- package/dist/components/index.cjs +118 -57
- package/dist/components/index.d.cts +49 -19
- package/dist/components/index.d.ts +49 -19
- package/dist/components/index.js +118 -57
- package/dist/lib/drawable/three/index.cjs +25 -5
- package/dist/lib/drawable/three/index.d.cts +2 -2
- package/dist/lib/drawable/three/index.d.ts +2 -2
- package/dist/lib/drawable/three/index.js +25 -5
- package/dist/lib/index.cjs +22 -0
- package/dist/lib/index.d.cts +10 -2
- package/dist/lib/index.d.ts +10 -2
- package/dist/lib/index.js +20 -1
- package/dist/providers/index.cjs +153 -67
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +153 -67
- package/dist/runtime/index.cjs +138 -78
- package/dist/runtime/index.d.cts +7 -3
- package/dist/runtime/index.d.ts +7 -3
- package/dist/runtime/index.js +138 -78
- package/package.json +4 -4
|
@@ -140,6 +140,13 @@ interface ServerClientEffect {
|
|
|
140
140
|
/** Metadata about what the server returned, for debugger logging */
|
|
141
141
|
interface ServerResponseMeta {
|
|
142
142
|
success: boolean;
|
|
143
|
+
/** `OrbitalEventResponse.transitioned` — whether any arm accepted the event. */
|
|
144
|
+
transitioned: boolean;
|
|
145
|
+
/** Server-side emits with their evaluated payloads (`ServerResponseTrace.emitted`). */
|
|
146
|
+
emitted?: ReadonlyArray<{
|
|
147
|
+
event: string;
|
|
148
|
+
payload?: EventPayload;
|
|
149
|
+
}>;
|
|
143
150
|
clientEffects: number;
|
|
144
151
|
dataEntities: Record<string, number>;
|
|
145
152
|
/** Raw entity data from server response (for EntityStore advancement) */
|
|
@@ -155,7 +162,7 @@ interface SendEventResult {
|
|
|
155
162
|
}
|
|
156
163
|
interface ServerBridgeContextValue {
|
|
157
164
|
connected: boolean;
|
|
158
|
-
sendEvent: (orbitalName: string, event: string, payload?: EventPayload, tick?: string, sourceTrait?: string) => Promise<SendEventResult>;
|
|
165
|
+
sendEvent: (orbitalName: string, event: string, payload?: EventPayload, tick?: string, sourceTrait?: string, locallyEmitted?: readonly string[]) => Promise<SendEventResult>;
|
|
159
166
|
}
|
|
160
167
|
/**
|
|
161
168
|
* Transport adapter for ServerBridgeProvider. Decouples the bridge's
|
|
@@ -140,6 +140,13 @@ interface ServerClientEffect {
|
|
|
140
140
|
/** Metadata about what the server returned, for debugger logging */
|
|
141
141
|
interface ServerResponseMeta {
|
|
142
142
|
success: boolean;
|
|
143
|
+
/** `OrbitalEventResponse.transitioned` — whether any arm accepted the event. */
|
|
144
|
+
transitioned: boolean;
|
|
145
|
+
/** Server-side emits with their evaluated payloads (`ServerResponseTrace.emitted`). */
|
|
146
|
+
emitted?: ReadonlyArray<{
|
|
147
|
+
event: string;
|
|
148
|
+
payload?: EventPayload;
|
|
149
|
+
}>;
|
|
143
150
|
clientEffects: number;
|
|
144
151
|
dataEntities: Record<string, number>;
|
|
145
152
|
/** Raw entity data from server response (for EntityStore advancement) */
|
|
@@ -155,7 +162,7 @@ interface SendEventResult {
|
|
|
155
162
|
}
|
|
156
163
|
interface ServerBridgeContextValue {
|
|
157
164
|
connected: boolean;
|
|
158
|
-
sendEvent: (orbitalName: string, event: string, payload?: EventPayload, tick?: string, sourceTrait?: string) => Promise<SendEventResult>;
|
|
165
|
+
sendEvent: (orbitalName: string, event: string, payload?: EventPayload, tick?: string, sourceTrait?: string, locallyEmitted?: readonly string[]) => Promise<SendEventResult>;
|
|
159
166
|
}
|
|
160
167
|
/**
|
|
161
168
|
* Transport adapter for ServerBridgeProvider. Decouples the bridge's
|
package/dist/avl/index.cjs
CHANGED
|
@@ -7283,7 +7283,7 @@ var init_Textarea = __esm({
|
|
|
7283
7283
|
init_cn();
|
|
7284
7284
|
init_useEventBus();
|
|
7285
7285
|
Textarea = React96__namespace.default.forwardRef(
|
|
7286
|
-
({ className, error, onChange, ...props }, ref) => {
|
|
7286
|
+
({ className, error, onChange, action, onKeyDown, ...props }, ref) => {
|
|
7287
7287
|
const eventBus = useEventBus();
|
|
7288
7288
|
const handleChange = (e) => {
|
|
7289
7289
|
if (typeof onChange === "string") {
|
|
@@ -7292,11 +7292,18 @@ var init_Textarea = __esm({
|
|
|
7292
7292
|
onChange?.(e);
|
|
7293
7293
|
}
|
|
7294
7294
|
};
|
|
7295
|
+
const handleKeyDown = (e) => {
|
|
7296
|
+
onKeyDown?.(e);
|
|
7297
|
+
if (!action || e.key !== "Enter" || !(e.metaKey || e.ctrlKey)) return;
|
|
7298
|
+
e.preventDefault();
|
|
7299
|
+
eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
|
|
7300
|
+
};
|
|
7295
7301
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7296
7302
|
"textarea",
|
|
7297
7303
|
{
|
|
7298
7304
|
ref,
|
|
7299
7305
|
onChange: handleChange,
|
|
7306
|
+
onKeyDown: handleKeyDown,
|
|
7300
7307
|
className: cn(
|
|
7301
7308
|
"block w-full border-[length:var(--border-width)] shadow-sm",
|
|
7302
7309
|
"px-3 py-2 text-sm text-foreground",
|
|
@@ -12746,6 +12753,29 @@ var init_useCanvasGestures = __esm({
|
|
|
12746
12753
|
}
|
|
12747
12754
|
});
|
|
12748
12755
|
|
|
12756
|
+
// lib/keyMapEvent.ts
|
|
12757
|
+
function isEditableTarget(target) {
|
|
12758
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
12759
|
+
const tag = target.tagName;
|
|
12760
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
12761
|
+
return target.isContentEditable || target.contentEditable === "true";
|
|
12762
|
+
}
|
|
12763
|
+
function keyMapCode(e) {
|
|
12764
|
+
let code = e.code;
|
|
12765
|
+
if (e.altKey) code = `Alt+${code}`;
|
|
12766
|
+
if (e.shiftKey) code = `Shift+${code}`;
|
|
12767
|
+
if (e.metaKey || e.ctrlKey) code = `Mod+${code}`;
|
|
12768
|
+
return code;
|
|
12769
|
+
}
|
|
12770
|
+
function resolveKeyMapEvent(map, e) {
|
|
12771
|
+
if (!map || isEditableTarget(e.target)) return void 0;
|
|
12772
|
+
return map[keyMapCode(e)] ?? map[e.code];
|
|
12773
|
+
}
|
|
12774
|
+
var init_keyMapEvent = __esm({
|
|
12775
|
+
"lib/keyMapEvent.ts"() {
|
|
12776
|
+
}
|
|
12777
|
+
});
|
|
12778
|
+
|
|
12749
12779
|
// lib/imageCache.ts
|
|
12750
12780
|
function startLoad(url, onReady, existing) {
|
|
12751
12781
|
const img = new Image();
|
|
@@ -14671,14 +14701,14 @@ function Canvas2D({
|
|
|
14671
14701
|
React96.useEffect(() => {
|
|
14672
14702
|
if (!keyMap && !keyUpMap) return;
|
|
14673
14703
|
const onDown = (e) => {
|
|
14674
|
-
const ev = keyMap
|
|
14704
|
+
const ev = resolveKeyMapEvent(keyMap, e);
|
|
14675
14705
|
if (ev) {
|
|
14676
14706
|
eventBus.emit(`UI:${ev}`, {});
|
|
14677
14707
|
e.preventDefault();
|
|
14678
14708
|
}
|
|
14679
14709
|
};
|
|
14680
14710
|
const onUp = (e) => {
|
|
14681
|
-
const ev = keyUpMap
|
|
14711
|
+
const ev = resolveKeyMapEvent(keyUpMap, e);
|
|
14682
14712
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
14683
14713
|
};
|
|
14684
14714
|
window.addEventListener("keydown", onDown);
|
|
@@ -14802,6 +14832,7 @@ var init_Canvas2D = __esm({
|
|
|
14802
14832
|
init_useCamera();
|
|
14803
14833
|
init_useCanvasGestures();
|
|
14804
14834
|
init_verificationRegistry();
|
|
14835
|
+
init_keyMapEvent();
|
|
14805
14836
|
init_webPainter2d();
|
|
14806
14837
|
init_projector();
|
|
14807
14838
|
init_paintDispatch();
|
|
@@ -30055,6 +30086,40 @@ var init_DashboardLayout = __esm({
|
|
|
30055
30086
|
NavLinkBottom.displayName = "NavLinkBottom";
|
|
30056
30087
|
}
|
|
30057
30088
|
});
|
|
30089
|
+
|
|
30090
|
+
// lib/relationLabel.ts
|
|
30091
|
+
function relationLabel(value) {
|
|
30092
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
|
|
30093
|
+
return null;
|
|
30094
|
+
for (const key of ["name", "title", "label"]) {
|
|
30095
|
+
const candidate = value[key];
|
|
30096
|
+
if (typeof candidate === "string" && candidate !== "") return candidate;
|
|
30097
|
+
}
|
|
30098
|
+
const id = value.id;
|
|
30099
|
+
return id !== void 0 && id !== null ? String(id) : null;
|
|
30100
|
+
}
|
|
30101
|
+
function relationDisplayLabels(value, options) {
|
|
30102
|
+
if (value === void 0 || value === null || value === "") return [];
|
|
30103
|
+
if (Array.isArray(value)) {
|
|
30104
|
+
return value.flatMap((item) => relationDisplayLabels(item, options));
|
|
30105
|
+
}
|
|
30106
|
+
const hydrated = relationLabel(value);
|
|
30107
|
+
if (hydrated !== null) return [hydrated];
|
|
30108
|
+
const raw = String(value);
|
|
30109
|
+
const match = options?.find((opt) => opt.value === raw);
|
|
30110
|
+
return [match ? match.label : raw];
|
|
30111
|
+
}
|
|
30112
|
+
function resolveRelationCellDisplay(value, options) {
|
|
30113
|
+
if (value === null || value === void 0 || value === "") return void 0;
|
|
30114
|
+
const isObjectShaped = typeof value === "object" && !(value instanceof Date) || Array.isArray(value) && value.some((v) => v !== null && typeof v === "object" && !(v instanceof Date));
|
|
30115
|
+
if (!isObjectShaped && !options) return void 0;
|
|
30116
|
+
const labels = relationDisplayLabels(value, options);
|
|
30117
|
+
return labels.length > 0 ? labels.join(", ") : void 0;
|
|
30118
|
+
}
|
|
30119
|
+
var init_relationLabel = __esm({
|
|
30120
|
+
"lib/relationLabel.ts"() {
|
|
30121
|
+
}
|
|
30122
|
+
});
|
|
30058
30123
|
function downloadItemUrl(url, label) {
|
|
30059
30124
|
const a = document.createElement("a");
|
|
30060
30125
|
a.href = url;
|
|
@@ -30886,7 +30951,8 @@ function DataGrid({
|
|
|
30886
30951
|
positionEvent,
|
|
30887
30952
|
dndItemIdField,
|
|
30888
30953
|
dndRoot,
|
|
30889
|
-
look = "dense"
|
|
30954
|
+
look = "dense",
|
|
30955
|
+
relationsData
|
|
30890
30956
|
}) {
|
|
30891
30957
|
const eventBus = useEventBus();
|
|
30892
30958
|
const { t } = hooks.useTranslate();
|
|
@@ -31076,6 +31142,10 @@ function DataGrid({
|
|
|
31076
31142
|
);
|
|
31077
31143
|
}
|
|
31078
31144
|
const titleValue = core.getNestedValue(itemData, titleField?.name ?? "");
|
|
31145
|
+
const titleDisplay = resolveRelationCellDisplay(
|
|
31146
|
+
titleValue,
|
|
31147
|
+
titleField ? relationsData?.[titleField.name] : void 0
|
|
31148
|
+
) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
|
|
31079
31149
|
return wrapDnd(
|
|
31080
31150
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
31081
31151
|
Box,
|
|
@@ -31100,7 +31170,7 @@ function DataGrid({
|
|
|
31100
31170
|
"img",
|
|
31101
31171
|
{
|
|
31102
31172
|
src: imgUrl,
|
|
31103
|
-
alt:
|
|
31173
|
+
alt: titleDisplay ?? "",
|
|
31104
31174
|
className: "w-full h-full object-cover",
|
|
31105
31175
|
loading: "lazy"
|
|
31106
31176
|
}
|
|
@@ -31115,18 +31185,18 @@ function DataGrid({
|
|
|
31115
31185
|
onChange: () => toggleSelection(id),
|
|
31116
31186
|
onClick: (e) => e.stopPropagation(),
|
|
31117
31187
|
className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
|
|
31118
|
-
"aria-label": t("card.selectItem", { item:
|
|
31188
|
+
"aria-label": t("card.selectItem", { item: titleDisplay ?? t("card.itemFallback") })
|
|
31119
31189
|
}
|
|
31120
31190
|
),
|
|
31121
31191
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
31122
|
-
|
|
31192
|
+
titleDisplay !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center min-w-0", children: [
|
|
31123
31193
|
titleField?.icon && renderIconInput(titleField.icon, { size: "sm", className: "text-primary flex-shrink-0" }),
|
|
31124
31194
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
31125
31195
|
Typography,
|
|
31126
31196
|
{
|
|
31127
31197
|
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
31128
31198
|
className: "font-semibold truncate min-w-0",
|
|
31129
|
-
children:
|
|
31199
|
+
children: titleDisplay
|
|
31130
31200
|
}
|
|
31131
31201
|
)
|
|
31132
31202
|
] }),
|
|
@@ -31135,7 +31205,7 @@ function DataGrid({
|
|
|
31135
31205
|
if (val === void 0 || val === null || val === "") return null;
|
|
31136
31206
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
31137
31207
|
field.icon && renderIconInput(field.icon, { size: "xs" }),
|
|
31138
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: humanizeEnumValue(formatValue(val, field.format)) })
|
|
31208
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: resolveRelationCellDisplay(val, relationsData?.[field.name]) ?? humanizeEnumValue(formatValue(val, field.format)) })
|
|
31139
31209
|
] }, field.name);
|
|
31140
31210
|
}) })
|
|
31141
31211
|
] }),
|
|
@@ -31174,7 +31244,7 @@ function DataGrid({
|
|
|
31174
31244
|
bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
|
|
31175
31245
|
const value = core.getNestedValue(itemData, field.name);
|
|
31176
31246
|
if (value === void 0 || value === null || value === "") return null;
|
|
31177
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
|
|
31247
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: resolveRelationCellDisplay(value, relationsData?.[field.name]) ?? formatValue(value, field.format) }, field.name);
|
|
31178
31248
|
}),
|
|
31179
31249
|
/* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
|
|
31180
31250
|
const value = core.getNestedValue(itemData, field.name);
|
|
@@ -31189,7 +31259,7 @@ function DataGrid({
|
|
|
31189
31259
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
31190
31260
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
31191
31261
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
31192
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
31262
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: resolveRelationCellDisplay(value, relationsData?.[field.name]) ?? formatValue(value, field.format) })
|
|
31193
31263
|
] }, field.name);
|
|
31194
31264
|
}) })
|
|
31195
31265
|
] }) })
|
|
@@ -31233,6 +31303,7 @@ var init_DataGrid = __esm({
|
|
|
31233
31303
|
"use client";
|
|
31234
31304
|
init_cn();
|
|
31235
31305
|
init_format();
|
|
31306
|
+
init_relationLabel();
|
|
31236
31307
|
init_getNestedValue();
|
|
31237
31308
|
init_useEventBus();
|
|
31238
31309
|
init_Box();
|
|
@@ -31285,7 +31356,9 @@ function statusVariant3(value) {
|
|
|
31285
31356
|
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
31286
31357
|
return "default";
|
|
31287
31358
|
}
|
|
31288
|
-
function formatValue2(value, format, boolLabels) {
|
|
31359
|
+
function formatValue2(value, format, boolLabels, relationOptions) {
|
|
31360
|
+
const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
|
|
31361
|
+
if (relationDisplay !== void 0) return relationDisplay;
|
|
31289
31362
|
if (value !== void 0 && value !== null && (format === "boolean" || typeof value === "boolean")) {
|
|
31290
31363
|
const isNo = value === false || value === 0 || String(value) === "false";
|
|
31291
31364
|
return isNo ? boolLabels?.no ?? "No" : boolLabels?.yes ?? "Yes";
|
|
@@ -31345,7 +31418,8 @@ function DataList({
|
|
|
31345
31418
|
positionEvent,
|
|
31346
31419
|
dndItemIdField,
|
|
31347
31420
|
dndRoot,
|
|
31348
|
-
look = "dense"
|
|
31421
|
+
look = "dense",
|
|
31422
|
+
relationsData
|
|
31349
31423
|
}) {
|
|
31350
31424
|
const eventBus = useEventBus();
|
|
31351
31425
|
const { t } = hooks.useTranslate();
|
|
@@ -31533,13 +31607,13 @@ function DataList({
|
|
|
31533
31607
|
return f3.variant === "badge" ? (
|
|
31534
31608
|
// `format` applies here too — a boolean field badged
|
|
31535
31609
|
// without it renders the raw "false" instead of "No".
|
|
31536
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
|
|
31610
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name]) }, f3.name)
|
|
31537
31611
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
31538
31612
|
Typography,
|
|
31539
31613
|
{
|
|
31540
31614
|
variant: "caption",
|
|
31541
31615
|
className: cn("text-xs", isSent ? "opacity-70" : "text-muted-foreground"),
|
|
31542
|
-
children: formatValue2(v, f3.format)
|
|
31616
|
+
children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name])
|
|
31543
31617
|
},
|
|
31544
31618
|
f3.name
|
|
31545
31619
|
);
|
|
@@ -31617,6 +31691,10 @@ function DataList({
|
|
|
31617
31691
|
}
|
|
31618
31692
|
const id = itemData.id || String(index);
|
|
31619
31693
|
const titleValue = core.getNestedValue(itemData, titleField?.name ?? "");
|
|
31694
|
+
const titleDisplay = resolveRelationCellDisplay(
|
|
31695
|
+
titleValue,
|
|
31696
|
+
titleField ? relationsData?.[titleField.name] : void 0
|
|
31697
|
+
) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
|
|
31620
31698
|
return wrapDnd(
|
|
31621
31699
|
/* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn(rowClickEvent && "cursor-pointer"), children: [
|
|
31622
31700
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -31641,7 +31719,7 @@ function DataList({
|
|
|
31641
31719
|
{
|
|
31642
31720
|
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
31643
31721
|
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
31644
|
-
children:
|
|
31722
|
+
children: titleDisplay
|
|
31645
31723
|
}
|
|
31646
31724
|
),
|
|
31647
31725
|
badgeFields.map((field) => {
|
|
@@ -31649,7 +31727,7 @@ function DataList({
|
|
|
31649
31727
|
if (val === void 0 || val === null) return null;
|
|
31650
31728
|
return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
31651
31729
|
field.icon && renderIconInput2(field.icon, { size: "xs" }),
|
|
31652
|
-
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
|
|
31730
|
+
/* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format, void 0, relationsData?.[field.name]) })
|
|
31653
31731
|
] }, field.name);
|
|
31654
31732
|
})
|
|
31655
31733
|
] }),
|
|
@@ -31670,7 +31748,7 @@ function DataList({
|
|
|
31670
31748
|
]
|
|
31671
31749
|
}
|
|
31672
31750
|
),
|
|
31673
|
-
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
31751
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }, relationsData?.[field.name]) })
|
|
31674
31752
|
] }, field.name);
|
|
31675
31753
|
}) }),
|
|
31676
31754
|
progressFields.map((field) => {
|
|
@@ -31750,6 +31828,7 @@ var init_DataList = __esm({
|
|
|
31750
31828
|
"use client";
|
|
31751
31829
|
init_cn();
|
|
31752
31830
|
init_format();
|
|
31831
|
+
init_relationLabel();
|
|
31753
31832
|
init_getNestedValue();
|
|
31754
31833
|
init_useEventBus();
|
|
31755
31834
|
init_Box();
|
|
@@ -35594,6 +35673,7 @@ var init_MathCanvas = __esm({
|
|
|
35594
35673
|
"use client";
|
|
35595
35674
|
init_useEventBus();
|
|
35596
35675
|
init_perf();
|
|
35676
|
+
init_keyMapEvent();
|
|
35597
35677
|
init_atoms();
|
|
35598
35678
|
init_Stack();
|
|
35599
35679
|
init_gameFonts();
|
|
@@ -35647,14 +35727,14 @@ var init_MathCanvas = __esm({
|
|
|
35647
35727
|
React96.useEffect(() => {
|
|
35648
35728
|
if (!stableKeyMap && !stableKeyUpMap) return;
|
|
35649
35729
|
const onDown = (e) => {
|
|
35650
|
-
const ev = stableKeyMap
|
|
35730
|
+
const ev = resolveKeyMapEvent(stableKeyMap, e);
|
|
35651
35731
|
if (ev) {
|
|
35652
35732
|
eventBus.emit(`UI:${ev}`, {});
|
|
35653
35733
|
e.preventDefault();
|
|
35654
35734
|
}
|
|
35655
35735
|
};
|
|
35656
35736
|
const onUp = (e) => {
|
|
35657
|
-
const ev = stableKeyUpMap
|
|
35737
|
+
const ev = resolveKeyMapEvent(stableKeyUpMap, e);
|
|
35658
35738
|
if (ev) eventBus.emit(`UI:${ev}`, {});
|
|
35659
35739
|
};
|
|
35660
35740
|
window.addEventListener("keydown", onDown);
|
|
@@ -38070,33 +38150,6 @@ var init_Lightbox = __esm({
|
|
|
38070
38150
|
Lightbox.displayName = "Lightbox";
|
|
38071
38151
|
}
|
|
38072
38152
|
});
|
|
38073
|
-
|
|
38074
|
-
// lib/relationLabel.ts
|
|
38075
|
-
function relationLabel(value) {
|
|
38076
|
-
if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
|
|
38077
|
-
return null;
|
|
38078
|
-
for (const key of ["name", "title", "label"]) {
|
|
38079
|
-
const candidate = value[key];
|
|
38080
|
-
if (typeof candidate === "string" && candidate !== "") return candidate;
|
|
38081
|
-
}
|
|
38082
|
-
const id = value.id;
|
|
38083
|
-
return id !== void 0 && id !== null ? String(id) : null;
|
|
38084
|
-
}
|
|
38085
|
-
function relationDisplayLabels(value, options) {
|
|
38086
|
-
if (value === void 0 || value === null || value === "") return [];
|
|
38087
|
-
if (Array.isArray(value)) {
|
|
38088
|
-
return value.flatMap((item) => relationDisplayLabels(item, options));
|
|
38089
|
-
}
|
|
38090
|
-
const hydrated = relationLabel(value);
|
|
38091
|
-
if (hydrated !== null) return [hydrated];
|
|
38092
|
-
const raw = String(value);
|
|
38093
|
-
const match = options?.find((opt) => opt.value === raw);
|
|
38094
|
-
return [match ? match.label : raw];
|
|
38095
|
-
}
|
|
38096
|
-
var init_relationLabel = __esm({
|
|
38097
|
-
"lib/relationLabel.ts"() {
|
|
38098
|
-
}
|
|
38099
|
-
});
|
|
38100
38153
|
function renderIconInput3(icon, props) {
|
|
38101
38154
|
return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
|
|
38102
38155
|
}
|
|
@@ -38160,7 +38213,8 @@ function TableView({
|
|
|
38160
38213
|
reorderEvent,
|
|
38161
38214
|
positionEvent,
|
|
38162
38215
|
dndItemIdField,
|
|
38163
|
-
dndRoot
|
|
38216
|
+
dndRoot,
|
|
38217
|
+
relationsData
|
|
38164
38218
|
}) {
|
|
38165
38219
|
const eventBus = useEventBus();
|
|
38166
38220
|
const { t } = hooks.useTranslate();
|
|
@@ -38245,7 +38299,7 @@ function TableView({
|
|
|
38245
38299
|
const colFloors = React96__namespace.default.useMemo(
|
|
38246
38300
|
() => colDefs.map((col) => {
|
|
38247
38301
|
const longest = data.reduce((widest, row) => {
|
|
38248
|
-
const cell = formatCell(asFieldValue(core.getNestedValue(row, col.field ?? col.key)), col.format);
|
|
38302
|
+
const cell = formatCell(asFieldValue(core.getNestedValue(row, col.field ?? col.key)), col.format, relationsData?.[col.field ?? col.key]);
|
|
38249
38303
|
return Math.max(widest, cell.length);
|
|
38250
38304
|
}, columnLabel(col).length);
|
|
38251
38305
|
const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
|
|
@@ -38345,9 +38399,11 @@ function TableView({
|
|
|
38345
38399
|
col.className
|
|
38346
38400
|
);
|
|
38347
38401
|
if (col.format === "badge" && raw != null && raw !== "") {
|
|
38348
|
-
|
|
38402
|
+
const relationDisplay = resolveRelationCellDisplay(raw, relationsData?.[col.field ?? col.key]);
|
|
38403
|
+
const label = relationDisplay ?? humanizeEnumValue(String(raw));
|
|
38404
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: label }) }, col.key);
|
|
38349
38405
|
}
|
|
38350
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
|
|
38406
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format, relationsData?.[col.field ?? col.key]) }) }, col.key);
|
|
38351
38407
|
}),
|
|
38352
38408
|
hasActions && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38353
38409
|
HStack,
|
|
@@ -38449,11 +38505,9 @@ var init_TableView = __esm({
|
|
|
38449
38505
|
init_Menu();
|
|
38450
38506
|
init_useDataDnd();
|
|
38451
38507
|
tableViewLog = logger.createLogger("almadar:ui:table-view");
|
|
38452
|
-
formatCell = (value, format) => {
|
|
38453
|
-
|
|
38454
|
-
|
|
38455
|
-
if (labels.length > 0) return labels.join(", ");
|
|
38456
|
-
}
|
|
38508
|
+
formatCell = (value, format, relationOptions) => {
|
|
38509
|
+
const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
|
|
38510
|
+
if (relationDisplay !== void 0) return relationDisplay;
|
|
38457
38511
|
return formatValue(value, format);
|
|
38458
38512
|
};
|
|
38459
38513
|
MAX_MEASURED_COL_CH = 32;
|
|
@@ -46754,7 +46808,8 @@ function DataTable({
|
|
|
46754
46808
|
headerActions,
|
|
46755
46809
|
showTotal = true,
|
|
46756
46810
|
className,
|
|
46757
|
-
look = "dense"
|
|
46811
|
+
look = "dense",
|
|
46812
|
+
relationsData
|
|
46758
46813
|
}) {
|
|
46759
46814
|
const [openActionMenu, setOpenActionMenu] = React96.useState(
|
|
46760
46815
|
null
|
|
@@ -47049,6 +47104,11 @@ function DataTable({
|
|
|
47049
47104
|
"data-column": String(col.key),
|
|
47050
47105
|
className: "px-4 py-3 text-sm text-foreground whitespace-nowrap sm:whitespace-normal",
|
|
47051
47106
|
children: col.render ? col.render(cellValue, row, rowIndex) : (() => {
|
|
47107
|
+
const relationDisplay = resolveRelationCellDisplay(
|
|
47108
|
+
cellValue,
|
|
47109
|
+
relationsData?.[String(col.key)]
|
|
47110
|
+
);
|
|
47111
|
+
if (relationDisplay !== void 0) return relationDisplay;
|
|
47052
47112
|
const boolVal = asBooleanValue2(cellValue);
|
|
47053
47113
|
if (boolVal !== null) {
|
|
47054
47114
|
return boolVal ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "success", children: t("common.yes") }) : /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "neutral", children: t("common.no") });
|
|
@@ -47137,6 +47197,7 @@ var init_DataTable = __esm({
|
|
|
47137
47197
|
init_cn();
|
|
47138
47198
|
init_format();
|
|
47139
47199
|
init_getNestedValue();
|
|
47200
|
+
init_relationLabel();
|
|
47140
47201
|
init_atoms();
|
|
47141
47202
|
init_Box();
|
|
47142
47203
|
init_Stack();
|
|
@@ -59043,7 +59104,7 @@ function runTickFrame(entityId, orderedWriters, store) {
|
|
|
59043
59104
|
}
|
|
59044
59105
|
var log9 = logger.createLogger("almadar:ui:effects:client-handlers");
|
|
59045
59106
|
function createClientEffectHandlers(options) {
|
|
59046
|
-
const { eventBus, slotSetter, navigate, navigateBack, callService, liveEntity, persistDelegated } = options;
|
|
59107
|
+
const { eventBus, slotSetter, navigate, navigateBack, callService, liveEntity, persistDelegated, callServiceDelegated } = options;
|
|
59047
59108
|
return {
|
|
59048
59109
|
emit: (event, payload, source) => {
|
|
59049
59110
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -59056,6 +59117,7 @@ function createClientEffectHandlers(options) {
|
|
|
59056
59117
|
// carries its outcome — tell the executor so the placeholder above is
|
|
59057
59118
|
// never read as a denial (see `EffectHandlers.persistDelegated`).
|
|
59058
59119
|
...persistDelegated === true ? { persistDelegated: true } : {},
|
|
59120
|
+
...callServiceDelegated === true ? { callServiceDelegated: true } : {},
|
|
59059
59121
|
// @almadar/runtime EffectHandlers.set types value:unknown — should be FieldValue (upstream fix queued)
|
|
59060
59122
|
set: ((_entityId, field, value) => {
|
|
59061
59123
|
if (!liveEntity) {
|
|
@@ -59459,7 +59521,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
59459
59521
|
}, [traitStates]);
|
|
59460
59522
|
const traitSnapshotDataRef = React96.useRef(/* @__PURE__ */ new Map());
|
|
59461
59523
|
const traitFieldStatesRef = React96.useRef(/* @__PURE__ */ new Map());
|
|
59462
|
-
const bridgeEchoPendingRef = React96.useRef(/* @__PURE__ */ new Map());
|
|
59463
59524
|
const bindingSnapshotsRef = React96.useRef(/* @__PURE__ */ new Map());
|
|
59464
59525
|
const bindingListenersRef = React96.useRef(/* @__PURE__ */ new Map());
|
|
59465
59526
|
const publishBindingSnapshot = React96.useCallback((traitName, row) => {
|
|
@@ -59620,7 +59681,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
59620
59681
|
// No local persistence adapter (bridge mode, or a syncOnly tick):
|
|
59621
59682
|
// nothing persists client-side, the server owns the write and
|
|
59622
59683
|
// reports it — never read the placeholder as a denial.
|
|
59623
|
-
persistDelegated: (syncOnly ? void 0 : optionsRef.current?.persistence) === void 0
|
|
59684
|
+
persistDelegated: (syncOnly ? void 0 : optionsRef.current?.persistence) === void 0,
|
|
59685
|
+
// Bridge mode with no consumer-supplied callService: the server
|
|
59686
|
+
// runs every call-service and its cascade carries the result —
|
|
59687
|
+
// the client's mock must not also run one.
|
|
59688
|
+
callServiceDelegated: optionsRef.current?.callService === void 0 && (syncOnly ? void 0 : optionsRef.current?.persistence) === void 0
|
|
59624
59689
|
});
|
|
59625
59690
|
const persistence = syncOnly ? void 0 : optionsRef.current?.persistence;
|
|
59626
59691
|
let handlers = clientHandlers;
|
|
@@ -59936,6 +60001,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
59936
60001
|
const _perfT0 = ui.perfStart("processEvent:total");
|
|
59937
60002
|
const bindings = traitBindingsRef.current;
|
|
59938
60003
|
const currentManager = managerRef.current;
|
|
60004
|
+
if (sourceTrait === void 0 && tick === void 0) {
|
|
60005
|
+
for (const snap of traitSnapshotDataRef.current.values()) {
|
|
60006
|
+
snap.cascadeReceived = [];
|
|
60007
|
+
}
|
|
60008
|
+
}
|
|
59939
60009
|
crossTraitLog.debug("processEvent:enter", () => ({
|
|
59940
60010
|
event: normalizedEvent,
|
|
59941
60011
|
payload: JSON.stringify(payload ?? null),
|
|
@@ -59974,7 +60044,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
59974
60044
|
});
|
|
59975
60045
|
const emittedByTrait = /* @__PURE__ */ new Map();
|
|
59976
60046
|
const serverEffectResultsByTrait = /* @__PURE__ */ new Map();
|
|
59977
|
-
bridgeEchoPendingRef.current.clear();
|
|
59978
60047
|
for (const { traitName, result } of results) {
|
|
59979
60048
|
const binding = bindingMap.get(traitName);
|
|
59980
60049
|
const traitState = currentManager.getState(traitName);
|
|
@@ -60032,12 +60101,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60032
60101
|
ui.perfEnd("processEvent:executeAll", _perfT2);
|
|
60033
60102
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
60034
60103
|
serverEffectResultsByTrait.set(traitName, transitionServerEffectResults);
|
|
60035
|
-
for (const emittedKey of emittedDuringExec) {
|
|
60036
|
-
bridgeEchoPendingRef.current.set(
|
|
60037
|
-
emittedKey,
|
|
60038
|
-
(bridgeEchoPendingRef.current.get(emittedKey) ?? 0) + 1
|
|
60039
|
-
);
|
|
60040
|
-
}
|
|
60041
60104
|
await reRenderCallsiteCaptureChildren(traitName, payload ?? {}, entityByTrait, stateLog);
|
|
60042
60105
|
} else if (!result.executed) {
|
|
60043
60106
|
if (result.guardResult === false) {
|
|
@@ -60111,6 +60174,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60111
60174
|
// the verifier reads emittedEvents only.
|
|
60112
60175
|
orbitalName: "",
|
|
60113
60176
|
success: true,
|
|
60177
|
+
transitioned: true,
|
|
60114
60178
|
clientEffects: effectTraces.length,
|
|
60115
60179
|
dataEntities: {},
|
|
60116
60180
|
emittedEvents,
|
|
@@ -60132,7 +60196,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60132
60196
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
60133
60197
|
}
|
|
60134
60198
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
60135
|
-
|
|
60199
|
+
const locallyEmitted = Array.from(emittedByTrait.values()).flat();
|
|
60200
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait, locallyEmitted);
|
|
60136
60201
|
}
|
|
60137
60202
|
ui.perfEnd("processEvent:total", _perfT0);
|
|
60138
60203
|
ui.perfEnd(`event:${normalizedEvent}`, _perfT0);
|
|
@@ -60199,14 +60264,9 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60199
60264
|
subscribedBusKeys.add(selfBusKey);
|
|
60200
60265
|
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
60201
60266
|
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
60202
|
-
if (event.source
|
|
60203
|
-
|
|
60204
|
-
|
|
60205
|
-
bridgeEchoPendingRef.current.set(eventKey, pendingEchoes - 1);
|
|
60206
|
-
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
60207
|
-
return;
|
|
60208
|
-
}
|
|
60209
|
-
crossTraitLog.debug("self:fire-server-cascade", { traitName, busKey: selfBusKey, eventKey });
|
|
60267
|
+
if (event.source?.dispatched) {
|
|
60268
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
60269
|
+
return;
|
|
60210
60270
|
}
|
|
60211
60271
|
crossTraitLog.debug("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
60212
60272
|
enqueueAndDrain(eventKey, event.payload, traitName, event.source?.tick, event.source?.trait);
|
|
@@ -60472,7 +60532,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60472
60532
|
[serverActiveTraits]
|
|
60473
60533
|
);
|
|
60474
60534
|
const uiSlots = context.useUISlots();
|
|
60475
|
-
const onEventProcessed = React96.useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
60535
|
+
const onEventProcessed = React96.useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait, locallyEmitted) => {
|
|
60476
60536
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
60477
60537
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
60478
60538
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -60486,7 +60546,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
60486
60546
|
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
60487
60547
|
continue;
|
|
60488
60548
|
}
|
|
60489
|
-
void bridge.sendEvent(name, event, withActiveTraits(payload)).then(({ effects, meta }) => {
|
|
60549
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload), void 0, void 0, locallyEmitted).then(({ effects, meta }) => {
|
|
60490
60550
|
recordServerResponse(name, event, { ...meta, effectResults: effectResultsToTraces(meta.effectResults) });
|
|
60491
60551
|
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
60492
60552
|
});
|
|
@@ -63425,6 +63485,7 @@ TraitCardNode.displayName = "TraitCardNode";
|
|
|
63425
63485
|
|
|
63426
63486
|
// components/avl/organisms/FlowCanvas.tsx
|
|
63427
63487
|
init_useEventBus();
|
|
63488
|
+
init_keyMapEvent();
|
|
63428
63489
|
init_perf();
|
|
63429
63490
|
var flowCanvasLog = logger.createLogger("almadar:ui:flow-canvas");
|
|
63430
63491
|
var NODE_TYPES = {
|
|
@@ -63664,8 +63725,7 @@ function FlowCanvasInner({
|
|
|
63664
63725
|
setExpandedOrbital(void 0);
|
|
63665
63726
|
}
|
|
63666
63727
|
} else if (e.key === "Delete" || e.key === "Backspace") {
|
|
63667
|
-
|
|
63668
|
-
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) return;
|
|
63728
|
+
if (isEditableTarget(e.target)) return;
|
|
63669
63729
|
if (selectedPattern && selectedPattern.nodeData) {
|
|
63670
63730
|
onPatternDelete?.({ patternId: selectedPattern.patternId ?? "", nodeData: selectedPattern.nodeData });
|
|
63671
63731
|
setSelectedPattern(null);
|