@almadar/ui 6.15.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.
@@ -3462,7 +3462,7 @@ var init_Textarea = __esm({
3462
3462
  init_cn();
3463
3463
  init_useEventBus();
3464
3464
  Textarea = React89__namespace.default.forwardRef(
3465
- ({ className, error, onChange, ...props }, ref) => {
3465
+ ({ className, error, onChange, action, onKeyDown, ...props }, ref) => {
3466
3466
  const eventBus = useEventBus();
3467
3467
  const handleChange = (e) => {
3468
3468
  if (typeof onChange === "string") {
@@ -3471,11 +3471,18 @@ var init_Textarea = __esm({
3471
3471
  onChange?.(e);
3472
3472
  }
3473
3473
  };
3474
+ const handleKeyDown = (e) => {
3475
+ onKeyDown?.(e);
3476
+ if (!action || e.key !== "Enter" || !(e.metaKey || e.ctrlKey)) return;
3477
+ e.preventDefault();
3478
+ eventBus.emit(`UI:${action}`, { value: e.currentTarget.value });
3479
+ };
3474
3480
  return /* @__PURE__ */ jsxRuntime.jsx(
3475
3481
  "textarea",
3476
3482
  {
3477
3483
  ref,
3478
3484
  onChange: handleChange,
3485
+ onKeyDown: handleKeyDown,
3479
3486
  className: cn(
3480
3487
  "block w-full border-[length:var(--border-width)] shadow-sm",
3481
3488
  "px-3 py-2 text-sm text-foreground",
@@ -9010,6 +9017,29 @@ var init_useCanvasGestures = __esm({
9010
9017
  }
9011
9018
  });
9012
9019
 
9020
+ // lib/keyMapEvent.ts
9021
+ function isEditableTarget(target) {
9022
+ if (!(target instanceof HTMLElement)) return false;
9023
+ const tag = target.tagName;
9024
+ if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
9025
+ return target.isContentEditable || target.contentEditable === "true";
9026
+ }
9027
+ function keyMapCode(e) {
9028
+ let code = e.code;
9029
+ if (e.altKey) code = `Alt+${code}`;
9030
+ if (e.shiftKey) code = `Shift+${code}`;
9031
+ if (e.metaKey || e.ctrlKey) code = `Mod+${code}`;
9032
+ return code;
9033
+ }
9034
+ function resolveKeyMapEvent(map, e) {
9035
+ if (!map || isEditableTarget(e.target)) return void 0;
9036
+ return map[keyMapCode(e)] ?? map[e.code];
9037
+ }
9038
+ var init_keyMapEvent = __esm({
9039
+ "lib/keyMapEvent.ts"() {
9040
+ }
9041
+ });
9042
+
9013
9043
  // lib/imageCache.ts
9014
9044
  function startLoad(url, onReady, existing) {
9015
9045
  const img = new Image();
@@ -10935,14 +10965,14 @@ function Canvas2D({
10935
10965
  React89.useEffect(() => {
10936
10966
  if (!keyMap && !keyUpMap) return;
10937
10967
  const onDown = (e) => {
10938
- const ev = keyMap?.[e.code];
10968
+ const ev = resolveKeyMapEvent(keyMap, e);
10939
10969
  if (ev) {
10940
10970
  eventBus.emit(`UI:${ev}`, {});
10941
10971
  e.preventDefault();
10942
10972
  }
10943
10973
  };
10944
10974
  const onUp = (e) => {
10945
- const ev = keyUpMap?.[e.code];
10975
+ const ev = resolveKeyMapEvent(keyUpMap, e);
10946
10976
  if (ev) eventBus.emit(`UI:${ev}`, {});
10947
10977
  };
10948
10978
  window.addEventListener("keydown", onDown);
@@ -11066,6 +11096,7 @@ var init_Canvas2D = __esm({
11066
11096
  init_useCamera();
11067
11097
  init_useCanvasGestures();
11068
11098
  init_verificationRegistry();
11099
+ init_keyMapEvent();
11069
11100
  init_webPainter2d();
11070
11101
  init_projector();
11071
11102
  init_paintDispatch();
@@ -27504,6 +27535,40 @@ var init_DashboardLayout = __esm({
27504
27535
  NavLinkBottom.displayName = "NavLinkBottom";
27505
27536
  }
27506
27537
  });
27538
+
27539
+ // lib/relationLabel.ts
27540
+ function relationLabel(value) {
27541
+ if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
27542
+ return null;
27543
+ for (const key of ["name", "title", "label"]) {
27544
+ const candidate = value[key];
27545
+ if (typeof candidate === "string" && candidate !== "") return candidate;
27546
+ }
27547
+ const id = value.id;
27548
+ return id !== void 0 && id !== null ? String(id) : null;
27549
+ }
27550
+ function relationDisplayLabels(value, options) {
27551
+ if (value === void 0 || value === null || value === "") return [];
27552
+ if (Array.isArray(value)) {
27553
+ return value.flatMap((item) => relationDisplayLabels(item, options));
27554
+ }
27555
+ const hydrated = relationLabel(value);
27556
+ if (hydrated !== null) return [hydrated];
27557
+ const raw = String(value);
27558
+ const match = options?.find((opt) => opt.value === raw);
27559
+ return [match ? match.label : raw];
27560
+ }
27561
+ function resolveRelationCellDisplay(value, options) {
27562
+ if (value === null || value === void 0 || value === "") return void 0;
27563
+ const isObjectShaped = typeof value === "object" && !(value instanceof Date) || Array.isArray(value) && value.some((v) => v !== null && typeof v === "object" && !(v instanceof Date));
27564
+ if (!isObjectShaped && !options) return void 0;
27565
+ const labels = relationDisplayLabels(value, options);
27566
+ return labels.length > 0 ? labels.join(", ") : void 0;
27567
+ }
27568
+ var init_relationLabel = __esm({
27569
+ "lib/relationLabel.ts"() {
27570
+ }
27571
+ });
27507
27572
  function downloadItemUrl(url, label) {
27508
27573
  const a = document.createElement("a");
27509
27574
  a.href = url;
@@ -28335,7 +28400,8 @@ function DataGrid({
28335
28400
  positionEvent,
28336
28401
  dndItemIdField,
28337
28402
  dndRoot,
28338
- look = "dense"
28403
+ look = "dense",
28404
+ relationsData
28339
28405
  }) {
28340
28406
  const eventBus = useEventBus();
28341
28407
  const { t } = hooks.useTranslate();
@@ -28525,6 +28591,10 @@ function DataGrid({
28525
28591
  );
28526
28592
  }
28527
28593
  const titleValue = core.getNestedValue(itemData, titleField?.name ?? "");
28594
+ const titleDisplay = resolveRelationCellDisplay(
28595
+ titleValue,
28596
+ titleField ? relationsData?.[titleField.name] : void 0
28597
+ ) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
28528
28598
  return wrapDnd(
28529
28599
  /* @__PURE__ */ jsxRuntime.jsxs(
28530
28600
  Box,
@@ -28549,7 +28619,7 @@ function DataGrid({
28549
28619
  "img",
28550
28620
  {
28551
28621
  src: imgUrl,
28552
- alt: titleValue !== void 0 ? String(titleValue) : "",
28622
+ alt: titleDisplay ?? "",
28553
28623
  className: "w-full h-full object-cover",
28554
28624
  loading: "lazy"
28555
28625
  }
@@ -28564,18 +28634,18 @@ function DataGrid({
28564
28634
  onChange: () => toggleSelection(id),
28565
28635
  onClick: (e) => e.stopPropagation(),
28566
28636
  className: "w-4 h-4 mt-1 flex-shrink-0 accent-primary",
28567
- "aria-label": t("card.selectItem", { item: titleValue !== void 0 ? String(titleValue) : t("card.itemFallback") })
28637
+ "aria-label": t("card.selectItem", { item: titleDisplay ?? t("card.itemFallback") })
28568
28638
  }
28569
28639
  ),
28570
28640
  /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
28571
- titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center min-w-0", children: [
28641
+ titleDisplay !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center min-w-0", children: [
28572
28642
  titleField?.icon && renderIconInput(titleField.icon, { size: "sm", className: "text-primary flex-shrink-0" }),
28573
28643
  /* @__PURE__ */ jsxRuntime.jsx(
28574
28644
  Typography,
28575
28645
  {
28576
28646
  variant: titleField?.variant === "h3" ? "h3" : "h4",
28577
28647
  className: "font-semibold truncate min-w-0",
28578
- children: String(titleValue)
28648
+ children: titleDisplay
28579
28649
  }
28580
28650
  )
28581
28651
  ] }),
@@ -28584,7 +28654,7 @@ function DataGrid({
28584
28654
  if (val === void 0 || val === null || val === "") return null;
28585
28655
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
28586
28656
  field.icon && renderIconInput(field.icon, { size: "xs" }),
28587
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: humanizeEnumValue(formatValue(val, field.format)) })
28657
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: resolveBadgeVariant(field, String(val)), children: resolveRelationCellDisplay(val, relationsData?.[field.name]) ?? humanizeEnumValue(formatValue(val, field.format)) })
28588
28658
  ] }, field.name);
28589
28659
  }) })
28590
28660
  ] }),
@@ -28623,7 +28693,7 @@ function DataGrid({
28623
28693
  bodyFields.filter((f3) => f3.variant === "caption" && f3.format !== "boolean").map((field) => {
28624
28694
  const value = core.getNestedValue(itemData, field.name);
28625
28695
  if (value === void 0 || value === null || value === "") return null;
28626
- return /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", className: "line-clamp-2", children: formatValue(value, field.format) }, field.name);
28696
+ 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);
28627
28697
  }),
28628
28698
  /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "md", className: "flex-wrap gap-y-1", children: bodyFields.filter((f3) => f3.variant !== "caption" || f3.format === "boolean").map((field) => {
28629
28699
  const value = core.getNestedValue(itemData, field.name);
@@ -28638,7 +28708,7 @@ function DataGrid({
28638
28708
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center", children: [
28639
28709
  field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
28640
28710
  /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
28641
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
28711
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: resolveRelationCellDisplay(value, relationsData?.[field.name]) ?? formatValue(value, field.format) })
28642
28712
  ] }, field.name);
28643
28713
  }) })
28644
28714
  ] }) })
@@ -28682,6 +28752,7 @@ var init_DataGrid = __esm({
28682
28752
  "use client";
28683
28753
  init_cn();
28684
28754
  init_format();
28755
+ init_relationLabel();
28685
28756
  init_getNestedValue();
28686
28757
  init_useEventBus();
28687
28758
  init_Box();
@@ -28734,7 +28805,9 @@ function statusVariant3(value) {
28734
28805
  if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
28735
28806
  return "default";
28736
28807
  }
28737
- function formatValue2(value, format, boolLabels) {
28808
+ function formatValue2(value, format, boolLabels, relationOptions) {
28809
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
28810
+ if (relationDisplay !== void 0) return relationDisplay;
28738
28811
  if (value !== void 0 && value !== null && (format === "boolean" || typeof value === "boolean")) {
28739
28812
  const isNo = value === false || value === 0 || String(value) === "false";
28740
28813
  return isNo ? boolLabels?.no ?? "No" : boolLabels?.yes ?? "Yes";
@@ -28794,7 +28867,8 @@ function DataList({
28794
28867
  positionEvent,
28795
28868
  dndItemIdField,
28796
28869
  dndRoot,
28797
- look = "dense"
28870
+ look = "dense",
28871
+ relationsData
28798
28872
  }) {
28799
28873
  const eventBus = useEventBus();
28800
28874
  const { t } = hooks.useTranslate();
@@ -28982,13 +29056,13 @@ function DataList({
28982
29056
  return f3.variant === "badge" ? (
28983
29057
  // `format` applies here too — a boolean field badged
28984
29058
  // without it renders the raw "false" instead of "No".
28985
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format) }, f3.name)
29059
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(v)), children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name]) }, f3.name)
28986
29060
  ) : /* @__PURE__ */ jsxRuntime.jsx(
28987
29061
  Typography,
28988
29062
  {
28989
29063
  variant: "caption",
28990
29064
  className: cn("text-xs", isSent ? "opacity-70" : "text-muted-foreground"),
28991
- children: formatValue2(v, f3.format)
29065
+ children: formatValue2(v, f3.format, void 0, relationsData?.[f3.name])
28992
29066
  },
28993
29067
  f3.name
28994
29068
  );
@@ -29066,6 +29140,10 @@ function DataList({
29066
29140
  }
29067
29141
  const id = itemData.id || String(index);
29068
29142
  const titleValue = core.getNestedValue(itemData, titleField?.name ?? "");
29143
+ const titleDisplay = resolveRelationCellDisplay(
29144
+ titleValue,
29145
+ titleField ? relationsData?.[titleField.name] : void 0
29146
+ ) ?? (titleValue !== void 0 && titleValue !== null ? String(titleValue) : void 0);
29069
29147
  return wrapDnd(
29070
29148
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn(rowClickEvent && "cursor-pointer"), children: [
29071
29149
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -29090,7 +29168,7 @@ function DataList({
29090
29168
  {
29091
29169
  variant: titleField?.variant === "h3" ? "h3" : "h4",
29092
29170
  className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
29093
- children: String(titleValue)
29171
+ children: titleDisplay
29094
29172
  }
29095
29173
  ),
29096
29174
  badgeFields.map((field) => {
@@ -29098,7 +29176,7 @@ function DataList({
29098
29176
  if (val === void 0 || val === null) return null;
29099
29177
  return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
29100
29178
  field.icon && renderIconInput2(field.icon, { size: "xs" }),
29101
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format) })
29179
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant3(String(val)), children: formatValue2(val, field.format, void 0, relationsData?.[field.name]) })
29102
29180
  ] }, field.name);
29103
29181
  })
29104
29182
  ] }),
@@ -29119,7 +29197,7 @@ function DataList({
29119
29197
  ]
29120
29198
  }
29121
29199
  ),
29122
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
29200
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }, relationsData?.[field.name]) })
29123
29201
  ] }, field.name);
29124
29202
  }) }),
29125
29203
  progressFields.map((field) => {
@@ -29199,6 +29277,7 @@ var init_DataList = __esm({
29199
29277
  "use client";
29200
29278
  init_cn();
29201
29279
  init_format();
29280
+ init_relationLabel();
29202
29281
  init_getNestedValue();
29203
29282
  init_useEventBus();
29204
29283
  init_Box();
@@ -33043,6 +33122,7 @@ var init_MathCanvas = __esm({
33043
33122
  "use client";
33044
33123
  init_useEventBus();
33045
33124
  init_perf();
33125
+ init_keyMapEvent();
33046
33126
  init_atoms();
33047
33127
  init_Stack();
33048
33128
  init_gameFonts();
@@ -33096,14 +33176,14 @@ var init_MathCanvas = __esm({
33096
33176
  React89.useEffect(() => {
33097
33177
  if (!stableKeyMap && !stableKeyUpMap) return;
33098
33178
  const onDown = (e) => {
33099
- const ev = stableKeyMap?.[e.code];
33179
+ const ev = resolveKeyMapEvent(stableKeyMap, e);
33100
33180
  if (ev) {
33101
33181
  eventBus.emit(`UI:${ev}`, {});
33102
33182
  e.preventDefault();
33103
33183
  }
33104
33184
  };
33105
33185
  const onUp = (e) => {
33106
- const ev = stableKeyUpMap?.[e.code];
33186
+ const ev = resolveKeyMapEvent(stableKeyUpMap, e);
33107
33187
  if (ev) eventBus.emit(`UI:${ev}`, {});
33108
33188
  };
33109
33189
  window.addEventListener("keydown", onDown);
@@ -35519,33 +35599,6 @@ var init_Lightbox = __esm({
35519
35599
  Lightbox.displayName = "Lightbox";
35520
35600
  }
35521
35601
  });
35522
-
35523
- // lib/relationLabel.ts
35524
- function relationLabel(value) {
35525
- if (value === null || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
35526
- return null;
35527
- for (const key of ["name", "title", "label"]) {
35528
- const candidate = value[key];
35529
- if (typeof candidate === "string" && candidate !== "") return candidate;
35530
- }
35531
- const id = value.id;
35532
- return id !== void 0 && id !== null ? String(id) : null;
35533
- }
35534
- function relationDisplayLabels(value, options) {
35535
- if (value === void 0 || value === null || value === "") return [];
35536
- if (Array.isArray(value)) {
35537
- return value.flatMap((item) => relationDisplayLabels(item, options));
35538
- }
35539
- const hydrated = relationLabel(value);
35540
- if (hydrated !== null) return [hydrated];
35541
- const raw = String(value);
35542
- const match = options?.find((opt) => opt.value === raw);
35543
- return [match ? match.label : raw];
35544
- }
35545
- var init_relationLabel = __esm({
35546
- "lib/relationLabel.ts"() {
35547
- }
35548
- });
35549
35602
  function renderIconInput3(icon, props) {
35550
35603
  return typeof icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: icon, ...props }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { icon, ...props });
35551
35604
  }
@@ -35609,7 +35662,8 @@ function TableView({
35609
35662
  reorderEvent,
35610
35663
  positionEvent,
35611
35664
  dndItemIdField,
35612
- dndRoot
35665
+ dndRoot,
35666
+ relationsData
35613
35667
  }) {
35614
35668
  const eventBus = useEventBus();
35615
35669
  const { t } = hooks.useTranslate();
@@ -35694,7 +35748,7 @@ function TableView({
35694
35748
  const colFloors = React89__namespace.default.useMemo(
35695
35749
  () => colDefs.map((col) => {
35696
35750
  const longest = data.reduce((widest, row) => {
35697
- const cell = formatCell(asFieldValue(core.getNestedValue(row, col.field ?? col.key)), col.format);
35751
+ const cell = formatCell(asFieldValue(core.getNestedValue(row, col.field ?? col.key)), col.format, relationsData?.[col.field ?? col.key]);
35698
35752
  return Math.max(widest, cell.length);
35699
35753
  }, columnLabel(col).length);
35700
35754
  const chrome = col.format === "badge" ? BADGE_CHROME_CH : 0;
@@ -35794,9 +35848,11 @@ function TableView({
35794
35848
  col.className
35795
35849
  );
35796
35850
  if (col.format === "badge" && raw != null && raw !== "") {
35797
- return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: statusVariant4(String(raw)), size: "sm", className: "whitespace-nowrap", children: humanizeEnumValue(String(raw)) }) }, col.key);
35851
+ const relationDisplay = resolveRelationCellDisplay(raw, relationsData?.[col.field ?? col.key]);
35852
+ const label = relationDisplay ?? humanizeEnumValue(String(raw));
35853
+ 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);
35798
35854
  }
35799
- 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);
35855
+ 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);
35800
35856
  }),
35801
35857
  hasActions && /* @__PURE__ */ jsxRuntime.jsxs(
35802
35858
  HStack,
@@ -35898,11 +35954,9 @@ var init_TableView = __esm({
35898
35954
  init_Menu();
35899
35955
  init_useDataDnd();
35900
35956
  tableViewLog = logger.createLogger("almadar:ui:table-view");
35901
- formatCell = (value, format) => {
35902
- if (value !== null && value !== void 0 && typeof value === "object" && !(value instanceof Date)) {
35903
- const labels = relationDisplayLabels(value);
35904
- if (labels.length > 0) return labels.join(", ");
35905
- }
35957
+ formatCell = (value, format, relationOptions) => {
35958
+ const relationDisplay = resolveRelationCellDisplay(value, relationOptions);
35959
+ if (relationDisplay !== void 0) return relationDisplay;
35906
35960
  return formatValue(value, format);
35907
35961
  };
35908
35962
  MAX_MEASURED_COL_CH = 32;
@@ -44612,7 +44666,8 @@ function DataTable({
44612
44666
  headerActions,
44613
44667
  showTotal = true,
44614
44668
  className,
44615
- look = "dense"
44669
+ look = "dense",
44670
+ relationsData
44616
44671
  }) {
44617
44672
  const [openActionMenu, setOpenActionMenu] = React89.useState(
44618
44673
  null
@@ -44907,6 +44962,11 @@ function DataTable({
44907
44962
  "data-column": String(col.key),
44908
44963
  className: "px-4 py-3 text-sm text-foreground whitespace-nowrap sm:whitespace-normal",
44909
44964
  children: col.render ? col.render(cellValue, row, rowIndex) : (() => {
44965
+ const relationDisplay = resolveRelationCellDisplay(
44966
+ cellValue,
44967
+ relationsData?.[String(col.key)]
44968
+ );
44969
+ if (relationDisplay !== void 0) return relationDisplay;
44910
44970
  const boolVal = asBooleanValue2(cellValue);
44911
44971
  if (boolVal !== null) {
44912
44972
  return boolVal ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "success", children: t("common.yes") }) : /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "neutral", children: t("common.no") });
@@ -44995,6 +45055,7 @@ var init_DataTable = __esm({
44995
45055
  init_cn();
44996
45056
  init_format();
44997
45057
  init_getNestedValue();
45058
+ init_relationLabel();
44998
45059
  init_atoms();
44999
45060
  init_Box();
45000
45061
  init_Stack();
@@ -54441,6 +54502,26 @@ function createCommandSendPump() {
54441
54502
  }
54442
54503
  };
54443
54504
  }
54505
+
54506
+ // lib/cascadeEcho.ts
54507
+ function stampLocallyDeliveredEchoes(dispatchedEvent, emitted, locallyEmitted) {
54508
+ const remainingLocal = /* @__PURE__ */ new Map();
54509
+ for (const name of locallyEmitted) {
54510
+ remainingLocal.set(name, (remainingLocal.get(name) ?? 0) + 1);
54511
+ }
54512
+ const result = [];
54513
+ for (const entry of emitted) {
54514
+ if (entry.event === dispatchedEvent) continue;
54515
+ const remaining = remainingLocal.get(entry.event) ?? 0;
54516
+ if (remaining > 0) {
54517
+ remainingLocal.set(entry.event, remaining - 1);
54518
+ result.push({ ...entry, source: { ...entry.source, dispatched: true } });
54519
+ } else {
54520
+ result.push(entry);
54521
+ }
54522
+ }
54523
+ return result;
54524
+ }
54444
54525
  var xOrbitalLog = logger.createLogger("almadar:runtime:cross-orbital");
54445
54526
  var serverBridgeLog = logger.createLogger("almadar:ui:server-bridge");
54446
54527
  function reEmitServerEvent(eventBus, emitted, origin) {
@@ -54597,7 +54678,7 @@ function ServerBridgeProvider({
54597
54678
  disposedRef.current = true;
54598
54679
  };
54599
54680
  }, []);
54600
- const sendEvent = React89.useCallback(async (orbitalName, event, payload, tick, sourceTrait) => {
54681
+ const sendEvent = React89.useCallback(async (orbitalName, event, payload, tick, sourceTrait, locallyEmitted) => {
54601
54682
  const emptyMeta = { success: false, transitioned: false, clientEffects: 0, dataEntities: {}, emittedEvents: [] };
54602
54683
  if (!connected) return { effects: [], meta: emptyMeta };
54603
54684
  if (tick !== void 0) {
@@ -54657,13 +54738,8 @@ function ServerBridgeProvider({
54657
54738
  }
54658
54739
  }
54659
54740
  if (result.emittedEvents) {
54660
- for (const emitted of result.emittedEvents) {
54661
- if (emitted.event === event) continue;
54662
- reEmitServerEvent(
54663
- eventBus,
54664
- { ...emitted, source: { ...emitted.source, dispatched: true } },
54665
- orbitalName
54666
- );
54741
+ for (const emitted of stampLocallyDeliveredEchoes(event, result.emittedEvents, locallyEmitted ?? [])) {
54742
+ reEmitServerEvent(eventBus, emitted, orbitalName);
54667
54743
  }
54668
54744
  }
54669
54745
  } else if (result.error) {
@@ -6,7 +6,7 @@ export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as Current
6
6
  import { b as UserData } from '../UserContext-D566nfWA.cjs';
7
7
  export { U as UserContext, a as UserContextValue, c as UserProvider, d as UserProviderProps, u as useHasPermission, e as useHasRole, f as useUser, g as useUserForEvaluation } from '../UserContext-D566nfWA.cjs';
8
8
  import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.cjs';
9
- export { A as AccessTokenProvider, E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-EJoTtuTR.cjs';
9
+ export { A as AccessTokenProvider, E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Dglbi9ks.cjs';
10
10
  import { i as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-DdV2o0Zu.cjs';
11
11
  export { N as NavigationContextValue, c as NavigationProvider, d as NavigationProviderProps, e as NavigationState, j as comparePathSpecificity, l as extractRouteParams, m as findPageByName, n as findPageByPath, o as getAllPages, p as getDefaultPage, q as matchPath, r as matchPathAmong, s as pathMatches, u as useActivePage, t as useInitPayload, v as useNavigateTo, w as useNavigation, x as useNavigationId, y as useNavigationState } from '../offline-executor-DdV2o0Zu.cjs';
12
12
  import '../verificationRegistry-DTrKDRoa.cjs';
@@ -6,7 +6,7 @@ export { a as CurrentPagePathContext, b as CurrentPagePathProvider, c as Current
6
6
  import { b as UserData } from '../UserContext-D566nfWA.js';
7
7
  export { U as UserContext, a as UserContextValue, c as UserProvider, d as UserProviderProps, u as useHasPermission, e as useHasRole, f as useUser, g as useUserForEvaluation } from '../UserContext-D566nfWA.js';
8
8
  import { E as EventBusContextType } from '../event-bus-types-Bl78kokd.js';
9
- export { A as AccessTokenProvider, E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-EJoTtuTR.js';
9
+ export { A as AccessTokenProvider, E as EntityBindingContext, a as EntityBindingSource, b as EntitySchemaContextValue, c as EntitySchemaProvider, d as EntitySchemaProviderProps, S as SendEventResult, e as ServerBridgeContextValue, f as ServerBridgeProvider, g as ServerBridgeProviderProps, h as ServerBridgeTransport, i as ServerClientEffect, j as ServerResponseMeta, T as TraitContext, k as TraitContextValue, l as TraitInstance, m as TraitProvider, n as TraitProviderProps, u as useEntityBindingSnapshot, o as useEntitySchema, p as useEntitySchemaOptional, q as useServerBridge, r as useTrait, s as useTraitContext } from '../EntityBindingContext-Dglbi9ks.js';
10
10
  import { i as UseOfflineExecutorResult, U as UseOfflineExecutorOptions } from '../offline-executor-DdV2o0Zu.js';
11
11
  export { N as NavigationContextValue, c as NavigationProvider, d as NavigationProviderProps, e as NavigationState, j as comparePathSpecificity, l as extractRouteParams, m as findPageByName, n as findPageByPath, o as getAllPages, p as getDefaultPage, q as matchPath, r as matchPathAmong, s as pathMatches, u as useActivePage, t as useInitPayload, v as useNavigateTo, w as useNavigation, x as useNavigationId, y as useNavigationState } from '../offline-executor-DdV2o0Zu.js';
12
12
  import '../verificationRegistry-Cwa52VyK.js';