@juicemantics/veloiq-ui 0.8.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.mjs CHANGED
@@ -19,7 +19,7 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
19
19
  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);
20
20
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
21
21
  var ColorModeContext = createContext({ mode: "light", setMode: () => {
22
- } });
22
+ }, schemaVersion: 0 });
23
23
 
24
24
  // src/utils/modelTone.ts
25
25
  var MODEL_TONES_LIGHT = [
@@ -58,6 +58,16 @@ var _modulesColorSchema = typeof localStorage !== "undefined" && localStorage.ge
58
58
  var _modelsColorSchema = typeof localStorage !== "undefined" && localStorage.getItem("jm_modelsColorSchema") || "plain-color";
59
59
  var _customPlainToneLight = null;
60
60
  var _customPlainToneDark = null;
61
+ var _colorSchemaListeners = [];
62
+ var onColorSchemaChange = (listener) => {
63
+ _colorSchemaListeners.push(listener);
64
+ return () => {
65
+ _colorSchemaListeners = _colorSchemaListeners.filter((l) => l !== listener);
66
+ };
67
+ };
68
+ var _notifyColorSchemaListeners = () => {
69
+ for (const l of [..._colorSchemaListeners]) l();
70
+ };
61
71
  var hexToRgb = (hex) => {
62
72
  const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
63
73
  if (!match) return null;
@@ -192,6 +202,7 @@ var setColorSchemas = (schemas) => {
192
202
  }
193
203
  }
194
204
  }
205
+ _notifyColorSchemaListeners();
195
206
  };
196
207
  var hashString = (input) => {
197
208
  let hash = 0;
@@ -221,7 +232,7 @@ var getModelTone = (modelLike, darkMode) => {
221
232
  return tones[hashString(seed) % tones.length];
222
233
  };
223
234
  var useModelTone = (modelLike) => {
224
- const { mode } = useContext(ColorModeContext);
235
+ const { mode, schemaVersion } = useContext(ColorModeContext);
225
236
  return getModelTone(modelLike, mode === "dark");
226
237
  };
227
238
  var getContrastingTextColor = (background) => isDarkColor(background) ? "#f8fafc" : "#0f172a";
@@ -276,6 +287,7 @@ function getNavEntry(navConfig, key) {
276
287
  return navConfig.find((e) => e.key === key);
277
288
  }
278
289
  function sortItemsByNavConfig(items, navConfig) {
290
+ if (!Array.isArray(items)) return [];
279
291
  return [...items].sort((a, b) => {
280
292
  const aSeq = getNavEntry(navConfig, a.key ?? a.name ?? "")?.sequence ?? 999;
281
293
  const bSeq = getNavEntry(navConfig, b.key ?? b.name ?? "")?.sequence ?? 999;
@@ -331,6 +343,7 @@ function useJourneyMenuItems() {
331
343
  return byModule;
332
344
  }
333
345
  function injectJourneyMenuItems(items, byModule) {
346
+ if (!Array.isArray(items)) return [];
334
347
  if (!byModule || Object.keys(byModule).length === 0) return items;
335
348
  const moduleNameOf = (item) => {
336
349
  let key = String(item?.key ?? item?.name ?? "");
@@ -339,16 +352,20 @@ function injectJourneyMenuItems(items, byModule) {
339
352
  if (byModule[key]) return key;
340
353
  return null;
341
354
  };
342
- const walk = (list) => list.map((item) => {
343
- const childrenWalked = Array.isArray(item?.children) && item.children.length ? walk(item.children) : item?.children;
344
- const moduleName = moduleNameOf(item);
345
- const extra = moduleName ? byModule[moduleName] : void 0;
346
- if (extra && extra.length) {
347
- return { ...item, children: [...extra, ...childrenWalked || []] };
348
- }
349
- if (childrenWalked !== item?.children) return { ...item, children: childrenWalked };
350
- return item;
351
- });
355
+ const walk = (list) => {
356
+ if (!Array.isArray(list)) return [];
357
+ return list.map((item) => {
358
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
359
+ const childrenWalked = safeChildren.length ? walk(safeChildren) : safeChildren;
360
+ const moduleName = moduleNameOf(item);
361
+ const extra = moduleName ? byModule[moduleName] : void 0;
362
+ if (extra && extra.length) {
363
+ return { ...item, children: [...extra, ...Array.isArray(childrenWalked) ? childrenWalked : []] };
364
+ }
365
+ if (childrenWalked !== item?.children) return { ...item, children: Array.isArray(childrenWalked) ? childrenWalked : item?.children };
366
+ return item;
367
+ });
368
+ };
352
369
  return walk(items);
353
370
  }
354
371
  var HorizontalMenu = ({ navConfig = [] }) => {
@@ -395,8 +412,10 @@ var HorizontalMenu = ({ navConfig = [] }) => {
395
412
  );
396
413
  };
397
414
  const transformItems = (items2, depth = 0) => {
415
+ if (!Array.isArray(items2)) return [];
398
416
  return items2.map((item) => {
399
- const hasChildren = item.children && item.children.length > 0;
417
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
418
+ const hasChildren = safeChildren.length > 0;
400
419
  return {
401
420
  key: item.key,
402
421
  label: renderLabel(item, depth, hasChildren),
@@ -467,8 +486,10 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
467
486
  );
468
487
  };
469
488
  const transformItems = (items2, depth = 0) => {
489
+ if (!Array.isArray(items2)) return [];
470
490
  return items2.map((item) => {
471
- const hasChildren = item.children && item.children.length > 0;
491
+ const safeChildren = Array.isArray(item?.children) ? item.children : [];
492
+ const hasChildren = safeChildren.length > 0;
472
493
  return {
473
494
  key: item.key,
474
495
  label: renderLabel(item, depth, hasChildren),
@@ -497,7 +518,7 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
497
518
  theme: mode === "dark" ? "dark" : "light",
498
519
  style: {
499
520
  borderRight: `1px solid ${token.colorBorderSecondary}`,
500
- background: token.colorBgContainer,
521
+ background: mode === "dark" ? token.colorBgContainer : token.colorBgLayout,
501
522
  height: "100vh",
502
523
  position: "sticky",
503
524
  top: 0,
@@ -1542,7 +1563,6 @@ function useNavModules() {
1542
1563
  const navConfig = useNavConfig();
1543
1564
  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) }));
1544
1565
  }
1545
- var API_URL4 = "/api";
1546
1566
  var DefaultLogo = ({ logo, appTitle, collapsed, isHeader = false, hideTitle = false }) => {
1547
1567
  const logoEl = typeof logo === "string" ? /* @__PURE__ */ jsx("img", { src: logo, alt: appTitle || "App", style: { height: isHeader ? "32px" : "40px", width: "auto", marginRight: collapsed || hideTitle ? 0 : 10 } }) : logo ? /* @__PURE__ */ jsx("span", { style: { marginRight: collapsed || hideTitle ? 0 : 10, display: "flex", alignItems: "center" }, children: logo }) : null;
1548
1568
  return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: collapsed ? "center" : "flex-start", padding: isHeader ? 0 : "10px 0" }, children: [
@@ -1553,16 +1573,19 @@ var DefaultLogo = ({ logo, appTitle, collapsed, isHeader = false, hideTitle = fa
1553
1573
  var MobileMenuContent = ({ onClose }) => {
1554
1574
  const { menuItems, selectedKey } = useMenu();
1555
1575
  const go = useGo();
1556
- const transformItems = (items) => items.map((item) => ({
1557
- key: item.key,
1558
- label: item.label || item.name || item.key,
1559
- icon: item.icon,
1560
- onClick: item.children?.length ? void 0 : () => {
1561
- go({ to: item.route });
1562
- onClose();
1563
- },
1564
- children: item.children?.length ? transformItems(item.children) : void 0
1565
- }));
1576
+ const transformItems = (items) => {
1577
+ if (!Array.isArray(items)) return [];
1578
+ return items.map((item) => ({
1579
+ key: item.key,
1580
+ label: item.label || item.name || item.key,
1581
+ icon: item.icon,
1582
+ onClick: item.children?.length ? void 0 : () => {
1583
+ go({ to: item.route });
1584
+ onClose();
1585
+ },
1586
+ children: item.children?.length ? transformItems(item.children) : void 0
1587
+ }));
1588
+ };
1566
1589
  return /* @__PURE__ */ jsx(
1567
1590
  Menu,
1568
1591
  {
@@ -1615,7 +1638,7 @@ var LayoutWrapper = ({
1615
1638
  const handleChangePassword = async (values) => {
1616
1639
  setPwdLoading(true);
1617
1640
  try {
1618
- const res = await authenticatedFetch(`${API_URL4}/auth/change-password`, {
1641
+ const res = await authenticatedFetch(`/auth/change-password`, {
1619
1642
  method: "PUT",
1620
1643
  headers: { "Content-Type": "application/json" },
1621
1644
  body: JSON.stringify(values)
@@ -13688,7 +13711,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
13688
13711
  return parts.filter(Boolean).join(" \u2022 ");
13689
13712
  }, [categoryField1, categoryField2, relatedModel.fields, relatedModel.label, relatedModel.name]);
13690
13713
  const chartData = useMemo(() => {
13691
- const data = columnFilteredRows || [];
13714
+ const data = Array.isArray(columnFilteredRows) ? columnFilteredRows : [];
13692
13715
  const cat1Field = categoryField1 ? relatedModel.fields.find((field) => field.key === categoryField1) : void 0;
13693
13716
  const cat2Field = categoryField2 ? relatedModel.fields.find((field) => field.key === categoryField2) : void 0;
13694
13717
  const groupMap = /* @__PURE__ */ new Map();
@@ -16844,7 +16867,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16844
16867
  }, [allRowsData, useLocalSearch, localSearch, model.fields, labelCache]);
16845
16868
  const isClientFiltering = allRowsLoaded && !allRowsError;
16846
16869
  const filteredDataSource = useMemo(() => {
16847
- if (!isClientFiltering) return tableProps.dataSource || [];
16870
+ if (!isClientFiltering) return Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
16848
16871
  const baseRows = allRows || [];
16849
16872
  return applyFilterRules(applyGlobalSearch(baseRows));
16850
16873
  }, [allRows, applyFilterRules, applyGlobalSearch, isClientFiltering, tableProps.dataSource]);
@@ -16863,7 +16886,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
16863
16886
  setGalleryPage(1);
16864
16887
  }, [localSearch, filterRules, resolvedListViewType]);
16865
16888
  const columnFilters = useMemo(() => {
16866
- const data = allRowsData.length > 0 ? allRowsData : tableProps.dataSource || [];
16889
+ const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
16867
16890
  const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
16868
16891
  return buildColumnFilterOptions({ fields: displayFields, data, rangeCount });
16869
16892
  }, [allRowsData, displayFields, tableProps.dataSource, viewSettings]);
@@ -17567,7 +17590,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17567
17590
  return String(raw);
17568
17591
  }, [labelCache]);
17569
17592
  const chartData = useMemo(() => {
17570
- const data = columnFilteredDataSource || [];
17593
+ const data = Array.isArray(columnFilteredDataSource) ? columnFilteredDataSource : [];
17571
17594
  const cat1Field = categoryField1 ? model.fields.find((field) => field.key === categoryField1) : void 0;
17572
17595
  const cat2Field = categoryField2 ? model.fields.find((field) => field.key === categoryField2) : void 0;
17573
17596
  const groupMap = /* @__PURE__ */ new Map();
@@ -17749,7 +17772,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
17749
17772
  }, [isCrosstabView, categoryField1, categoryField2, crosstabFilterFields, allRowsData, columnFilteredDataSource, model.fields, allModels, apiUrl, handleReferenceLabel]);
17750
17773
  const crosstabFilterOptions = useMemo(() => {
17751
17774
  if (crosstabFilterFields.length === 0) return /* @__PURE__ */ new Map();
17752
- const data = allRowsData.length > 0 ? allRowsData : tableProps.dataSource || [];
17775
+ const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
17753
17776
  const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
17754
17777
  const fields = crosstabFilterFields.map((k) => model.fields.find((f) => f.key === k)).filter((f) => Boolean(f));
17755
17778
  return buildColumnFilterOptions({ fields, data, rangeCount });
@@ -18416,7 +18439,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
18416
18439
  getRowKeyRef.current = getRowKey;
18417
18440
  const handleBulkRowSelectionChange = useCallback(
18418
18441
  (newKeys, newRowsOnPage) => {
18419
- const currentPageData = isClientFiltering ? filteredDataSource : tableProps.dataSource || [];
18442
+ const currentPageData = isClientFiltering ? filteredDataSource : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
18420
18443
  const currentPageKeys = new Set(currentPageData.map((r) => String(getRowKeyRef.current(r))));
18421
18444
  const newKeySet = new Set(newKeys.map((k) => String(k)));
18422
18445
  newRowsOnPage.forEach((row) => {
@@ -20855,6 +20878,10 @@ var ColorModeContextProvider = ({
20855
20878
  colorModeFromLocalStorage === "dark" || colorModeFromLocalStorage === "light" ? colorModeFromLocalStorage : systemPreference
20856
20879
  );
20857
20880
  const initializedFromServer = useRef(false);
20881
+ const [schemaVersion, setSchemaVersion] = useState(0);
20882
+ useEffect(() => {
20883
+ return onColorSchemaChange(() => setSchemaVersion((v) => v + 1));
20884
+ }, []);
20858
20885
  useEffect(() => {
20859
20886
  let cancelled = false;
20860
20887
  const load = async () => {
@@ -20896,7 +20923,7 @@ var ColorModeContextProvider = ({
20896
20923
  void saveToServer(newMode);
20897
20924
  }, [saveToServer]);
20898
20925
  const { darkAlgorithm, defaultAlgorithm } = theme;
20899
- return /* @__PURE__ */ jsx(ColorModeContext.Provider, { value: { mode, setMode: setColorMode }, children: /* @__PURE__ */ jsx(
20926
+ return /* @__PURE__ */ jsx(ColorModeContext.Provider, { value: { mode, setMode: setColorMode, schemaVersion }, children: /* @__PURE__ */ jsx(
20900
20927
  ConfigProvider,
20901
20928
  {
20902
20929
  theme: {