@juicemantics/veloiq-ui 0.7.0 → 0.8.3

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/index.d.mts CHANGED
@@ -444,6 +444,10 @@ declare const useAllModels: () => ModelDef[];
444
444
  declare const ColorModeContext: React$1.Context<{
445
445
  mode: "light" | "dark";
446
446
  setMode: (mode: "light" | "dark") => void;
447
+ /** Increments every time the color schema (plain-color / color-coded / hex)
448
+ * changes via setColorSchemas(). Components that depend on derived tones
449
+ * use this to re-render when the schema updates. */
450
+ schemaVersion: number;
447
451
  }>;
448
452
 
449
453
  declare const ColorModeContextProvider: React.FC<PropsWithChildren>;
package/dist/index.d.ts CHANGED
@@ -444,6 +444,10 @@ declare const useAllModels: () => ModelDef[];
444
444
  declare const ColorModeContext: React$1.Context<{
445
445
  mode: "light" | "dark";
446
446
  setMode: (mode: "light" | "dark") => void;
447
+ /** Increments every time the color schema (plain-color / color-coded / hex)
448
+ * changes via setColorSchemas(). Components that depend on derived tones
449
+ * use this to re-render when the schema updates. */
450
+ schemaVersion: number;
447
451
  }>;
448
452
 
449
453
  declare const ColorModeContextProvider: React.FC<PropsWithChildren>;
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
46
46
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
47
47
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
48
48
  var ColorModeContext = React5.createContext({ mode: "light", setMode: () => {
49
- } });
49
+ }, schemaVersion: 0 });
50
50
 
51
51
  // src/utils/modelTone.ts
52
52
  var MODEL_TONES_LIGHT = [
@@ -85,6 +85,16 @@ var _modulesColorSchema = typeof localStorage !== "undefined" && localStorage.ge
85
85
  var _modelsColorSchema = typeof localStorage !== "undefined" && localStorage.getItem("jm_modelsColorSchema") || "plain-color";
86
86
  var _customPlainToneLight = null;
87
87
  var _customPlainToneDark = null;
88
+ var _colorSchemaListeners = [];
89
+ var onColorSchemaChange = (listener) => {
90
+ _colorSchemaListeners.push(listener);
91
+ return () => {
92
+ _colorSchemaListeners = _colorSchemaListeners.filter((l) => l !== listener);
93
+ };
94
+ };
95
+ var _notifyColorSchemaListeners = () => {
96
+ for (const l of [..._colorSchemaListeners]) l();
97
+ };
88
98
  var hexToRgb = (hex) => {
89
99
  const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
90
100
  if (!match) return null;
@@ -219,6 +229,7 @@ var setColorSchemas = (schemas) => {
219
229
  }
220
230
  }
221
231
  }
232
+ _notifyColorSchemaListeners();
222
233
  };
223
234
  var hashString = (input) => {
224
235
  let hash = 0;
@@ -248,7 +259,7 @@ var getModelTone = (modelLike, darkMode) => {
248
259
  return tones[hashString(seed) % tones.length];
249
260
  };
250
261
  var useModelTone = (modelLike) => {
251
- const { mode } = React5.useContext(ColorModeContext);
262
+ const { mode, schemaVersion } = React5.useContext(ColorModeContext);
252
263
  return getModelTone(modelLike, mode === "dark");
253
264
  };
254
265
  var getContrastingTextColor = (background) => isDarkColor(background) ? "#f8fafc" : "#0f172a";
@@ -303,6 +314,7 @@ function getNavEntry(navConfig, key) {
303
314
  return navConfig.find((e) => e.key === key);
304
315
  }
305
316
  function sortItemsByNavConfig(items, navConfig) {
317
+ if (!Array.isArray(items)) return [];
306
318
  return [...items].sort((a, b) => {
307
319
  const aSeq = getNavEntry(navConfig, a.key ?? a.name ?? "")?.sequence ?? 999;
308
320
  const bSeq = getNavEntry(navConfig, b.key ?? b.name ?? "")?.sequence ?? 999;
@@ -358,6 +370,7 @@ function useJourneyMenuItems() {
358
370
  return byModule;
359
371
  }
360
372
  function injectJourneyMenuItems(items, byModule) {
373
+ if (!Array.isArray(items)) return [];
361
374
  if (!byModule || Object.keys(byModule).length === 0) return items;
362
375
  const moduleNameOf = (item) => {
363
376
  let key = String(item?.key ?? item?.name ?? "");
@@ -366,16 +379,20 @@ function injectJourneyMenuItems(items, byModule) {
366
379
  if (byModule[key]) return key;
367
380
  return null;
368
381
  };
369
- const walk = (list) => list.map((item) => {
370
- const childrenWalked = Array.isArray(item?.children) && item.children.length ? walk(item.children) : item?.children;
371
- const moduleName = moduleNameOf(item);
372
- const extra = moduleName ? byModule[moduleName] : void 0;
373
- if (extra && extra.length) {
374
- return { ...item, children: [...extra, ...childrenWalked || []] };
375
- }
376
- if (childrenWalked !== item?.children) return { ...item, children: childrenWalked };
377
- return item;
378
- });
382
+ const walk = (list) => {
383
+ if (!Array.isArray(list)) return [];
384
+ return list.map((item) => {
385
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
386
+ const childrenWalked = safeChildren.length ? walk(safeChildren) : safeChildren;
387
+ const moduleName = moduleNameOf(item);
388
+ const extra = moduleName ? byModule[moduleName] : void 0;
389
+ if (extra && extra.length) {
390
+ return { ...item, children: [...extra, ...Array.isArray(childrenWalked) ? childrenWalked : []] };
391
+ }
392
+ if (childrenWalked !== item?.children) return { ...item, children: Array.isArray(childrenWalked) ? childrenWalked : item?.children };
393
+ return item;
394
+ });
395
+ };
379
396
  return walk(items);
380
397
  }
381
398
  var HorizontalMenu = ({ navConfig = [] }) => {
@@ -422,8 +439,10 @@ var HorizontalMenu = ({ navConfig = [] }) => {
422
439
  );
423
440
  };
424
441
  const transformItems = (items2, depth = 0) => {
442
+ if (!Array.isArray(items2)) return [];
425
443
  return items2.map((item) => {
426
- const hasChildren = item.children && item.children.length > 0;
444
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
445
+ const hasChildren = safeChildren.length > 0;
427
446
  return {
428
447
  key: item.key,
429
448
  label: renderLabel(item, depth, hasChildren),
@@ -494,8 +513,10 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
494
513
  );
495
514
  };
496
515
  const transformItems = (items2, depth = 0) => {
516
+ if (!Array.isArray(items2)) return [];
497
517
  return items2.map((item) => {
498
- const hasChildren = item.children && item.children.length > 0;
518
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
519
+ const hasChildren = safeChildren.length > 0;
499
520
  return {
500
521
  key: item.key,
501
522
  label: renderLabel(item, depth, hasChildren),
@@ -524,7 +545,7 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
524
545
  theme: mode === "dark" ? "dark" : "light",
525
546
  style: {
526
547
  borderRight: `1px solid ${token.colorBorderSecondary}`,
527
- background: token.colorBgContainer,
548
+ background: mode === "dark" ? token.colorBgContainer : token.colorBgLayout,
528
549
  height: "100vh",
529
550
  position: "sticky",
530
551
  top: 0,
@@ -1569,7 +1590,6 @@ function useNavModules() {
1569
1590
  const navConfig = useNavConfig();
1570
1591
  return (navConfig || []).filter((e) => e.type === "module" && String(e.key || "").startsWith("module:")).map((e) => ({ value: String(e.key).slice("module:".length), label: e.label || String(e.key).slice("module:".length) }));
1571
1592
  }
1572
- var API_URL4 = "/api";
1573
1593
  var DefaultLogo = ({ logo, appTitle, collapsed, isHeader = false, hideTitle = false }) => {
1574
1594
  const logoEl = typeof logo === "string" ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: appTitle || "App", style: { height: isHeader ? "32px" : "40px", width: "auto", marginRight: collapsed || hideTitle ? 0 : 10 } }) : logo ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginRight: collapsed || hideTitle ? 0 : 10, display: "flex", alignItems: "center" }, children: logo }) : null;
1575
1595
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: collapsed ? "center" : "flex-start", padding: isHeader ? 0 : "10px 0" }, children: [
@@ -1580,16 +1600,19 @@ var DefaultLogo = ({ logo, appTitle, collapsed, isHeader = false, hideTitle = fa
1580
1600
  var MobileMenuContent = ({ onClose }) => {
1581
1601
  const { menuItems, selectedKey } = core.useMenu();
1582
1602
  const go = core.useGo();
1583
- const transformItems = (items) => items.map((item) => ({
1584
- key: item.key,
1585
- label: item.label || item.name || item.key,
1586
- icon: item.icon,
1587
- onClick: item.children?.length ? void 0 : () => {
1588
- go({ to: item.route });
1589
- onClose();
1590
- },
1591
- children: item.children?.length ? transformItems(item.children) : void 0
1592
- }));
1603
+ const transformItems = (items) => {
1604
+ if (!Array.isArray(items)) return [];
1605
+ return items.map((item) => ({
1606
+ key: item.key,
1607
+ label: item.label || item.name || item.key,
1608
+ icon: item.icon,
1609
+ onClick: item.children?.length ? void 0 : () => {
1610
+ go({ to: item.route });
1611
+ onClose();
1612
+ },
1613
+ children: item.children?.length ? transformItems(item.children) : void 0
1614
+ }));
1615
+ };
1593
1616
  return /* @__PURE__ */ jsxRuntime.jsx(
1594
1617
  antd.Menu,
1595
1618
  {
@@ -1642,7 +1665,7 @@ var LayoutWrapper = ({
1642
1665
  const handleChangePassword = async (values) => {
1643
1666
  setPwdLoading(true);
1644
1667
  try {
1645
- const res = await authenticatedFetch(`${API_URL4}/auth/change-password`, {
1668
+ const res = await authenticatedFetch(`/auth/change-password`, {
1646
1669
  method: "PUT",
1647
1670
  headers: { "Content-Type": "application/json" },
1648
1671
  body: JSON.stringify(values)
@@ -4019,6 +4042,12 @@ var getRecordId = (record, fields) => {
4019
4042
  }
4020
4043
  return record.eid ?? record.id;
4021
4044
  };
4045
+ var isPkField = (field, model) => {
4046
+ if (field.isPk === true) return true;
4047
+ if (model?.pkField != null && field.key === model.pkField) return true;
4048
+ return false;
4049
+ };
4050
+ var isReferenceField = (field) => !!field.reference;
4022
4051
  var getListViewFields = (model, filterField) => {
4023
4052
  const baseFields = filterField ? model.fields.filter((field) => field.key !== filterField) : model.fields;
4024
4053
  return baseFields.slice(0, 6);
@@ -4489,9 +4518,14 @@ var resolveRelationFromConfig = (relations, item) => {
4489
4518
  (rel) => (rel.relationName || "").toLowerCase() === target || (rel.resource || "").toLowerCase() === target || (rel.label || "").toLowerCase() === target
4490
4519
  );
4491
4520
  if (exact) return exact;
4492
- return relations.find(
4521
+ const byVariant = relations.find(
4493
4522
  (rel) => targetVariants.has((rel.relationName || "").toLowerCase()) || targetVariants.has((rel.resource || "").toLowerCase()) || targetVariants.has((rel.label || "").toLowerCase())
4494
4523
  );
4524
+ if (byVariant) return byVariant;
4525
+ const relPathBase = (rel) => String(rel.resourcePath || "").toLowerCase().replace(/_relation$/, "");
4526
+ return relations.find(
4527
+ (rel) => relPathBase(rel) === target || targetVariants.has(relPathBase(rel))
4528
+ );
4495
4529
  };
4496
4530
  var buildConfiguredRelationKeys = (rows) => {
4497
4531
  const keys = /* @__PURE__ */ new Set();
@@ -8460,7 +8494,7 @@ function buildColumnFilterOptions({
8460
8494
  }) {
8461
8495
  const filtersMap = /* @__PURE__ */ new Map();
8462
8496
  for (const field of fields) {
8463
- if (field.key === "eid") {
8497
+ if (isPkField(field)) {
8464
8498
  const labelValues = [];
8465
8499
  for (const record of data) {
8466
8500
  const lbl = record?._label;
@@ -8567,7 +8601,7 @@ function buildColumnFilterOptions({
8567
8601
  for (const record of data) {
8568
8602
  let value = record?.[field.key];
8569
8603
  let label = value;
8570
- if (field.key === "eid" && record?._label) {
8604
+ if (isPkField(field) && record?._label) {
8571
8605
  value = record.eid;
8572
8606
  label = record._label;
8573
8607
  }
@@ -8608,7 +8642,7 @@ function matchesColumnFilterValue(field, record, value) {
8608
8642
  const recordVal = String(record?.[field.key] ?? "");
8609
8643
  return recordVal.localeCompare(lo) >= 0 && recordVal.localeCompare(hi) <= 0;
8610
8644
  }
8611
- if (field.key === "eid" && strValue.startsWith("__catrange__:")) {
8645
+ if (isPkField(field) && strValue.startsWith("__catrange__:")) {
8612
8646
  const sub = strValue.substring("__catrange__:".length);
8613
8647
  const sepIdx = sub.indexOf(":");
8614
8648
  const lo = decodeURIComponent(sub.substring(0, sepIdx));
@@ -8616,7 +8650,7 @@ function matchesColumnFilterValue(field, record, value) {
8616
8650
  const recordLabel = String(record?._label ?? "");
8617
8651
  return recordLabel.localeCompare(lo) >= 0 && recordLabel.localeCompare(hi) <= 0;
8618
8652
  }
8619
- if (field.key === "eid" && record?._label) {
8653
+ if (isPkField(field) && record?._label) {
8620
8654
  return String(record._label) === strValue || String(record.eid) === strValue;
8621
8655
  }
8622
8656
  return String(record?.[field.key]) === strValue;
@@ -12734,11 +12768,11 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
12734
12768
  }
12735
12769
  }, [apiUrl, categoryField1, categoryField2, chartType, selectedSeriesKeys, summaryFn, rankingMode, rankingFieldKey, rankingN, crosstabFilterFields, relatedModel.name, relatedModel.resource, allModels]);
12736
12770
  const categoricalFields = React5.useMemo(() => {
12737
- return relatedModel.fields.filter((field) => field.key === "eid" || (field.type !== "number" || field.reference));
12738
- }, [relatedModel.fields]);
12771
+ return relatedModel.fields.filter((field) => isPkField(field, relatedModel) || (field.type !== "number" || field.reference));
12772
+ }, [relatedModel]);
12739
12773
  const numericFields = React5.useMemo(() => {
12740
- return relatedModel.fields.filter((field) => field.key !== "eid" && field.type === "number" && !field.reference);
12741
- }, [relatedModel.fields]);
12774
+ return relatedModel.fields.filter((field) => !isPkField(field, relatedModel) && field.type === "number" && !field.reference);
12775
+ }, [relatedModel]);
12742
12776
  const resetLayoutDefaults = React5.useCallback(() => {
12743
12777
  setListVisible(true);
12744
12778
  setAnalyzeOpen(false);
@@ -13307,7 +13341,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13307
13341
  if (!rowValues) return;
13308
13342
  const payload = {};
13309
13343
  relatedModel.fields.forEach((field) => {
13310
- if (field.key === "eid") return;
13344
+ if (isPkField(field, relatedModel)) return;
13311
13345
  if (!Object.prototype.hasOwnProperty.call(rowValues, field.key)) return;
13312
13346
  const newVal = normalizeFieldValue(field, rowValues[field.key]);
13313
13347
  const oldVal = normalizeFieldValue(field, row?.[field.key]);
@@ -13408,7 +13442,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13408
13442
  const getSortValue = React5.useCallback((field, recordRow) => {
13409
13443
  const raw = recordRow?.[field.key];
13410
13444
  if (raw === void 0 || raw === null) return null;
13411
- if (field.key === "eid" && recordRow?._label) return recordRow._label;
13445
+ if (isPkField(field, relatedModel) && recordRow?._label) return recordRow._label;
13412
13446
  if (field.reference) {
13413
13447
  const cacheKey = `${field.reference}:${raw}`;
13414
13448
  return labelCache[cacheKey] ?? raw;
@@ -13684,7 +13718,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13684
13718
  if (!field) return _34("All");
13685
13719
  const raw = recordRow?.[field.key];
13686
13720
  if (raw === void 0 || raw === null) return "-";
13687
- if (field.key === "eid" && recordRow?._label) return recordRow._label;
13721
+ if (isPkField(field, relatedModel) && recordRow?._label) return recordRow._label;
13688
13722
  if (field.reference) {
13689
13723
  const cacheKey = `${field.reference}:${raw}`;
13690
13724
  return labelCache[cacheKey] || String(raw);
@@ -13704,7 +13738,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13704
13738
  return parts.filter(Boolean).join(" \u2022 ");
13705
13739
  }, [categoryField1, categoryField2, relatedModel.fields, relatedModel.label, relatedModel.name]);
13706
13740
  const chartData = React5.useMemo(() => {
13707
- const data = columnFilteredRows || [];
13741
+ const data = Array.isArray(columnFilteredRows) ? columnFilteredRows : [];
13708
13742
  const cat1Field = categoryField1 ? relatedModel.fields.find((field) => field.key === categoryField1) : void 0;
13709
13743
  const cat2Field = categoryField2 ? relatedModel.fields.find((field) => field.key === categoryField2) : void 0;
13710
13744
  const groupMap = /* @__PURE__ */ new Map();
@@ -13965,7 +13999,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13965
13999
  setSelectedSeriesKeys(value);
13966
14000
  },
13967
14001
  style: { width: "100%" },
13968
- options: relatedModel.fields.filter((field) => !field.isPk && field.key !== "eid").map((field) => ({ label: field.label, value: field.key })),
14002
+ options: relatedModel.fields.filter((field) => !isPkField(field, relatedModel)).map((field) => ({ label: field.label, value: field.key })),
13969
14003
  placeholder: _34("All numeric fields"),
13970
14004
  maxTagCount: "responsive"
13971
14005
  }
@@ -14232,9 +14266,9 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
14232
14266
  }, [columnFilteredRows, displayFields, labelCache]);
14233
14267
  const isTotalsDetailsVariant = viewVariant === "totals-details";
14234
14268
  const getDefaultTotalsSummaryFn = React5.useCallback((field) => {
14235
- if (field.key === "eid") return "count";
14269
+ if (isPkField(field, relatedModel)) return "count";
14236
14270
  return "sum";
14237
- }, []);
14271
+ }, [relatedModel]);
14238
14272
  const resolveTotalsSummaryFn = React5.useCallback((field) => {
14239
14273
  return totalsSummaryFunctions[field.key] || getDefaultTotalsSummaryFn(field);
14240
14274
  }, [getDefaultTotalsSummaryFn, totalsSummaryFunctions]);
@@ -15068,10 +15102,15 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
15068
15102
  allowInlineEdit && /* @__PURE__ */ jsxRuntime.jsx(
15069
15103
  antd.Table.Column,
15070
15104
  {
15071
- title: rel.otherKey || "Related",
15105
+ title: relatedModel.label || relatedModel.name,
15106
+ sorter: { compare: (a, b) => getRecordDisplayLabel(a).localeCompare(getRecordDisplayLabel(b)) },
15107
+ filters: Array.from(new Set((filteredRows || []).map((r) => getRecordDisplayLabel(r)))).map((label) => ({ text: label, value: label })),
15108
+ filterSearch: true,
15109
+ onFilter: (value, row) => getRecordDisplayLabel(row) === String(value),
15072
15110
  render: (_unused, row) => {
15073
15111
  const id = row?.eid ?? row?.id;
15074
- if (!id) return "-";
15112
+ const label = getRecordDisplayLabel(row);
15113
+ if (!id) return label;
15075
15114
  return /* @__PURE__ */ jsxRuntime.jsx(
15076
15115
  "a",
15077
15116
  {
@@ -15086,7 +15125,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
15086
15125
  }
15087
15126
  },
15088
15127
  style: { cursor: "pointer", color: "inherit", textDecoration: "none" },
15089
- children: String(id)
15128
+ children: label
15090
15129
  }
15091
15130
  );
15092
15131
  }
@@ -15111,15 +15150,15 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
15111
15150
  }
15112
15151
  }),
15113
15152
  onFilter: (value, recordRow) => {
15114
- if (field.key === "eid" && recordRow?._label) {
15153
+ if (isPkField(field, relatedModel) && recordRow?._label) {
15115
15154
  return String(recordRow._label) === String(value) || String(recordRow.eid) === String(value);
15116
15155
  }
15117
15156
  const recordValue = recordRow?.[field.key];
15118
15157
  return String(recordValue) === String(value);
15119
15158
  },
15120
- align: field.type === "number" && !field.reference && !["eid", "eid_from", "eid_to"].includes(field.key) ? "right" : void 0,
15159
+ align: field.type === "number" && !isReferenceField(field) && !isPkField(field, relatedModel) ? "right" : void 0,
15121
15160
  render: (value, row) => {
15122
- if (allowInlineEdit && field.key !== "eid") {
15161
+ if (allowInlineEdit && !isPkField(field, relatedModel)) {
15123
15162
  const rowId = row?.eid ?? row?.id ?? row?.__relationKey;
15124
15163
  return /* @__PURE__ */ jsxRuntime.jsx(
15125
15164
  antd.Form.Item,
@@ -15141,7 +15180,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
15141
15180
  const cacheKey = `${field.reference}:${value}`;
15142
15181
  return labelCache[cacheKey] || value;
15143
15182
  }
15144
- if (field.key === "eid" && row._label) return row._label;
15183
+ if (isPkField(field, relatedModel) && row._label) return row._label;
15145
15184
  if (field.type === "boolean") return /* @__PURE__ */ jsxRuntime.jsx(antd.Checkbox, { checked: value, disabled: true });
15146
15185
  if (field.type === "number" && !field.reference) {
15147
15186
  const formatted = formatNumberValue(value);
@@ -16676,7 +16715,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16676
16715
  const getSortValue = React5.useCallback((field, record) => {
16677
16716
  const raw = record?.[field.key];
16678
16717
  if (raw === void 0 || raw === null) return null;
16679
- if (field.key === "eid" && record?._label) return record._label;
16718
+ if (isPkField(field, model) && record?._label) return record._label;
16680
16719
  if (field.reference) {
16681
16720
  const cacheKey = `${field.reference}:${raw}`;
16682
16721
  return labelCache[cacheKey] ?? raw;
@@ -16855,7 +16894,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16855
16894
  }, [allRowsData, useLocalSearch, localSearch, model.fields, labelCache]);
16856
16895
  const isClientFiltering = allRowsLoaded && !allRowsError;
16857
16896
  const filteredDataSource = React5.useMemo(() => {
16858
- if (!isClientFiltering) return tableProps.dataSource || [];
16897
+ if (!isClientFiltering) return Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
16859
16898
  const baseRows = allRows || [];
16860
16899
  return applyFilterRules(applyGlobalSearch(baseRows));
16861
16900
  }, [allRows, applyFilterRules, applyGlobalSearch, isClientFiltering, tableProps.dataSource]);
@@ -16874,7 +16913,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16874
16913
  setGalleryPage(1);
16875
16914
  }, [localSearch, filterRules, resolvedListViewType]);
16876
16915
  const columnFilters = React5.useMemo(() => {
16877
- const data = allRowsData.length > 0 ? allRowsData : tableProps.dataSource || [];
16916
+ const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
16878
16917
  const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
16879
16918
  return buildColumnFilterOptions({ fields: displayFields, data, rangeCount });
16880
16919
  }, [allRowsData, displayFields, tableProps.dataSource, viewSettings]);
@@ -16961,10 +17000,10 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16961
17000
  };
16962
17001
  }, [handleTablePageChange, isClientFiltering, pageSize, tableProps.pagination]);
16963
17002
  const categoricalFields = React5.useMemo(() => {
16964
- return model.fields.filter((field) => field.key === "eid" || (field.type !== "number" || field.reference));
17003
+ return model.fields.filter((field) => isPkField(field, model) || (field.type !== "number" || field.reference));
16965
17004
  }, [model.fields]);
16966
17005
  const numericFields = React5.useMemo(() => {
16967
- return model.fields.filter((field) => field.key !== "eid" && field.type === "number" && !field.reference);
17006
+ return model.fields.filter((field) => !isPkField(field, model) && field.type === "number" && !field.reference);
16968
17007
  }, [model.fields]);
16969
17008
  const hasActiveRangeColumnFilter = React5.useMemo(() => {
16970
17009
  return Object.values(columnFiltersSelected).some(
@@ -17563,7 +17602,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17563
17602
  if (!field) return _36("All");
17564
17603
  const raw = record?.[field.key];
17565
17604
  if (raw === void 0 || raw === null) return "-";
17566
- if (field.key === "eid" && record?._label) return record._label;
17605
+ if (isPkField(field, model) && record?._label) return record._label;
17567
17606
  if (field.reference) {
17568
17607
  const cacheKey = `${field.reference}:${raw}`;
17569
17608
  return labelCache[cacheKey] || String(raw);
@@ -17578,7 +17617,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17578
17617
  return String(raw);
17579
17618
  }, [labelCache]);
17580
17619
  const chartData = React5.useMemo(() => {
17581
- const data = columnFilteredDataSource || [];
17620
+ const data = Array.isArray(columnFilteredDataSource) ? columnFilteredDataSource : [];
17582
17621
  const cat1Field = categoryField1 ? model.fields.find((field) => field.key === categoryField1) : void 0;
17583
17622
  const cat2Field = categoryField2 ? model.fields.find((field) => field.key === categoryField2) : void 0;
17584
17623
  const groupMap = /* @__PURE__ */ new Map();
@@ -17760,7 +17799,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17760
17799
  }, [isCrosstabView, categoryField1, categoryField2, crosstabFilterFields, allRowsData, columnFilteredDataSource, model.fields, allModels, apiUrl, handleReferenceLabel]);
17761
17800
  const crosstabFilterOptions = React5.useMemo(() => {
17762
17801
  if (crosstabFilterFields.length === 0) return /* @__PURE__ */ new Map();
17763
- const data = allRowsData.length > 0 ? allRowsData : tableProps.dataSource || [];
17802
+ const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
17764
17803
  const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
17765
17804
  const fields = crosstabFilterFields.map((k) => model.fields.find((f) => f.key === k)).filter((f) => Boolean(f));
17766
17805
  return buildColumnFilterOptions({ fields, data, rangeCount });
@@ -17833,7 +17872,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17833
17872
  setSelectedSeriesKeys(value);
17834
17873
  },
17835
17874
  style: { width: "100%" },
17836
- options: model.fields.filter((field) => !field.isPk && field.key !== "eid").map((field) => ({ label: field.label, value: field.key })),
17875
+ options: model.fields.filter((field) => !isPkField(field, model)).map((field) => ({ label: field.label, value: field.key })),
17837
17876
  placeholder: _36("All numeric fields"),
17838
17877
  maxTagCount: "responsive"
17839
17878
  }
@@ -17984,7 +18023,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17984
18023
  });
17985
18024
  }, [isTotalsDetailsView, allRows, displayFields, labelCache]);
17986
18025
  const getDefaultTotalsSummaryFn = React5.useCallback((field) => {
17987
- if (["eid", "eid_from", "eid_to"].includes(field.key)) return "count";
18026
+ if (isPkField(field, model) || isReferenceField(field)) return "count";
17988
18027
  return "sum";
17989
18028
  }, []);
17990
18029
  const resolveTotalsSummaryFn = React5.useCallback((field) => {
@@ -18281,8 +18320,8 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
18281
18320
  }
18282
18321
  const resourceName = model.isNamedQuery && model.primaryResource ? model.primaryResource : model.resource || model.name;
18283
18322
  const explicitPk = model.pkField ? record[model.pkField] : void 0;
18284
- const isPkField = model.fields?.find((f) => f.isPk)?.key;
18285
- const pkValue = explicitPk ?? (isPkField ? record[isPkField] : void 0) ?? record.eid ?? record.id ?? null;
18323
+ const isPkField2 = model.fields?.find((f) => f.isPk)?.key;
18324
+ const pkValue = explicitPk ?? (isPkField2 ? record[isPkField2] : void 0) ?? record.eid ?? record.id ?? null;
18286
18325
  if (pkValue != null) {
18287
18326
  return { resource: resourceName, id: pkValue, isLinkRow: false };
18288
18327
  }
@@ -18427,7 +18466,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
18427
18466
  getRowKeyRef.current = getRowKey;
18428
18467
  const handleBulkRowSelectionChange = React5.useCallback(
18429
18468
  (newKeys, newRowsOnPage) => {
18430
- const currentPageData = isClientFiltering ? filteredDataSource : tableProps.dataSource || [];
18469
+ const currentPageData = isClientFiltering ? filteredDataSource : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
18431
18470
  const currentPageKeys = new Set(currentPageData.map((r) => String(getRowKeyRef.current(r))));
18432
18471
  const newKeySet = new Set(newKeys.map((k) => String(k)));
18433
18472
  newRowsOnPage.forEach((row) => {
@@ -19679,7 +19718,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
19679
19718
  dataIndex: field.key,
19680
19719
  title: field.label,
19681
19720
  sorter: { compare: (a, b) => compareSortValues(field, a, b), multiple: getSortPriority(columnSort, field.key) },
19682
- align: field.type === "number" && !field.reference && !["eid", "eid_from", "eid_to"].includes(field.key) ? "right" : void 0,
19721
+ align: field.type === "number" && !isReferenceField(field) && !isPkField(field, model) ? "right" : void 0,
19683
19722
  filters: columnFilters.get(field.key),
19684
19723
  filteredValue: columnFiltersSelected[field.key] || null,
19685
19724
  sortOrder: columnSort.find((item) => item.fieldKey === field.key)?.order ?? null,
@@ -19714,7 +19753,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
19714
19753
  }
19715
19754
  );
19716
19755
  }
19717
- if (field.key === "eid" && record._label) return record._label;
19756
+ if (isPkField(field, model) && record._label) return record._label;
19718
19757
  if (field.type === "boolean") return /* @__PURE__ */ jsxRuntime.jsx(antd.Checkbox, { checked: value, disabled: true });
19719
19758
  if (field.type === "number" && !field.reference) {
19720
19759
  const formatted = formatNumberValue(value);
@@ -20866,6 +20905,10 @@ var ColorModeContextProvider = ({
20866
20905
  colorModeFromLocalStorage === "dark" || colorModeFromLocalStorage === "light" ? colorModeFromLocalStorage : systemPreference
20867
20906
  );
20868
20907
  const initializedFromServer = React5.useRef(false);
20908
+ const [schemaVersion, setSchemaVersion] = React5.useState(0);
20909
+ React5.useEffect(() => {
20910
+ return onColorSchemaChange(() => setSchemaVersion((v) => v + 1));
20911
+ }, []);
20869
20912
  React5.useEffect(() => {
20870
20913
  let cancelled = false;
20871
20914
  const load = async () => {
@@ -20907,7 +20950,7 @@ var ColorModeContextProvider = ({
20907
20950
  void saveToServer(newMode);
20908
20951
  }, [saveToServer]);
20909
20952
  const { darkAlgorithm, defaultAlgorithm } = antd.theme;
20910
- return /* @__PURE__ */ jsxRuntime.jsx(ColorModeContext.Provider, { value: { mode, setMode: setColorMode }, children: /* @__PURE__ */ jsxRuntime.jsx(
20953
+ return /* @__PURE__ */ jsxRuntime.jsx(ColorModeContext.Provider, { value: { mode, setMode: setColorMode, schemaVersion }, children: /* @__PURE__ */ jsxRuntime.jsx(
20911
20954
  antd.ConfigProvider,
20912
20955
  {
20913
20956
  theme: {