@juicemantics/veloiq-ui 0.9.0 → 0.9.2
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.js +839 -788
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React6 = require('react');
|
|
4
4
|
var antd$1 = require('@refinedev/antd');
|
|
5
5
|
var core = require('@refinedev/core');
|
|
6
6
|
var antd = require('antd');
|
|
@@ -32,7 +32,7 @@ function _interopNamespace(e) {
|
|
|
32
32
|
return Object.freeze(n);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
var
|
|
35
|
+
var React6__default = /*#__PURE__*/_interopDefault(React6);
|
|
36
36
|
var AntDIcons2__namespace = /*#__PURE__*/_interopNamespace(AntDIcons2);
|
|
37
37
|
var dayjs9__default = /*#__PURE__*/_interopDefault(dayjs9);
|
|
38
38
|
var relativeTime2__default = /*#__PURE__*/_interopDefault(relativeTime2);
|
|
@@ -45,10 +45,8 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
|
|
|
45
45
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
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
|
-
var ColorModeContext =
|
|
48
|
+
var ColorModeContext = React6.createContext({ mode: "light", setMode: () => {
|
|
49
49
|
}, schemaVersion: 0 });
|
|
50
|
-
|
|
51
|
-
// src/utils/modelTone.ts
|
|
52
50
|
var MODEL_TONES_LIGHT = [
|
|
53
51
|
{ solid: "#2563eb", soft: "#dbeafe", softer: "#eff6ff", text: "#1e3a8a", border: "#93c5fd", shadow: "rgba(37, 99, 235, 0.22)" },
|
|
54
52
|
{ solid: "#0f766e", soft: "#ccfbf1", softer: "#f0fdfa", text: "#115e59", border: "#5eead4", shadow: "rgba(15, 118, 110, 0.22)" },
|
|
@@ -165,6 +163,10 @@ var setColorSchemas = (schemas) => {
|
|
|
165
163
|
const darkBgContent = `rgb(${shade(r, 0.06)}, ${shade(g, 0.06)}, ${shade(b, 0.06)})`;
|
|
166
164
|
const darkBgElements = `rgb(${shade(r, 0.11)}, ${shade(g, 0.11)}, ${shade(b, 0.11)})`;
|
|
167
165
|
const darkBgHover = `rgb(${shade(r, 0.16)}, ${shade(g, 0.16)}, ${shade(b, 0.16)})`;
|
|
166
|
+
const sidebarLightBg = hex;
|
|
167
|
+
const sidebarLightText = isDarkColor(hex) ? "#ffffff" : "#0f172a";
|
|
168
|
+
const sidebarDarkBg = lightBgElements;
|
|
169
|
+
const sidebarDarkText = "#0f172a";
|
|
168
170
|
styleEl.innerHTML = `
|
|
169
171
|
/* --- LIGHT MODE OVERRIDES --- */
|
|
170
172
|
body.jm-light .ant-layout,
|
|
@@ -178,7 +180,31 @@ var setColorSchemas = (schemas) => {
|
|
|
178
180
|
body.jm-light .ant-menu,
|
|
179
181
|
body.jm-light .ant-menu-submenu,
|
|
180
182
|
body.jm-light .ant-menu-submenu-title,
|
|
181
|
-
body.jm-light .ant-layout-header
|
|
183
|
+
body.jm-light .ant-layout-header {
|
|
184
|
+
background-color: ${sidebarLightBg} !important;
|
|
185
|
+
color: ${sidebarLightText} !important;
|
|
186
|
+
}
|
|
187
|
+
body.jm-light .ant-layout-sider *:not(input):not(textarea):not(.ant-input):not(.ant-select-selector):not(.ant-select-selection-item):not(.ant-select-selection-search-input),
|
|
188
|
+
body.jm-light .ant-layout-header *:not(input):not(textarea):not(.ant-input):not(.ant-select-selector):not(.ant-select-selection-item):not(.ant-select-selection-search-input) {
|
|
189
|
+
color: ${sidebarLightText} !important;
|
|
190
|
+
}
|
|
191
|
+
body.jm-light .ant-layout-sider .ant-menu-item-selected,
|
|
192
|
+
body.jm-light .ant-layout-sider .ant-menu-item-selected *,
|
|
193
|
+
body.jm-light .ant-layout-sider .ant-menu-item:hover,
|
|
194
|
+
body.jm-light .ant-layout-sider .ant-menu-item:hover *,
|
|
195
|
+
body.jm-light .ant-layout-header .ant-menu-item-selected,
|
|
196
|
+
body.jm-light .ant-layout-header .ant-menu-item-selected *,
|
|
197
|
+
body.jm-light .ant-layout-header .ant-menu-item:hover,
|
|
198
|
+
body.jm-light .ant-layout-header .ant-menu-item:hover * {
|
|
199
|
+
color: revert !important;
|
|
200
|
+
}
|
|
201
|
+
body.jm-light .ant-menu-submenu-popup {
|
|
202
|
+
background-color: ${sidebarLightBg} !important;
|
|
203
|
+
}
|
|
204
|
+
body.jm-light .ant-menu-submenu-popup .ant-menu-item:not(.ant-menu-item-selected),
|
|
205
|
+
body.jm-light .ant-menu-submenu-popup .ant-menu-submenu-title:not(.ant-menu-submenu-selected) {
|
|
206
|
+
color: ${sidebarLightText} !important;
|
|
207
|
+
}
|
|
182
208
|
body.jm-light .ant-card,
|
|
183
209
|
body.jm-light .ant-table-wrapper .ant-table,
|
|
184
210
|
body.jm-light .ant-table-thead > tr > th,
|
|
@@ -208,7 +234,31 @@ var setColorSchemas = (schemas) => {
|
|
|
208
234
|
body.jm-dark .ant-menu,
|
|
209
235
|
body.jm-dark .ant-menu-submenu,
|
|
210
236
|
body.jm-dark .ant-menu-submenu-title,
|
|
211
|
-
body.jm-dark .ant-layout-header
|
|
237
|
+
body.jm-dark .ant-layout-header {
|
|
238
|
+
background-color: ${sidebarDarkBg} !important;
|
|
239
|
+
color: ${sidebarDarkText} !important;
|
|
240
|
+
}
|
|
241
|
+
body.jm-dark .ant-layout-sider *:not(input):not(textarea):not(.ant-input):not(.ant-select-selector):not(.ant-select-selection-item):not(.ant-select-selection-search-input),
|
|
242
|
+
body.jm-dark .ant-layout-header *:not(input):not(textarea):not(.ant-input):not(.ant-select-selector):not(.ant-select-selection-item):not(.ant-select-selection-search-input) {
|
|
243
|
+
color: ${sidebarDarkText} !important;
|
|
244
|
+
}
|
|
245
|
+
body.jm-dark .ant-layout-sider .ant-menu-item-selected,
|
|
246
|
+
body.jm-dark .ant-layout-sider .ant-menu-item-selected *,
|
|
247
|
+
body.jm-dark .ant-layout-sider .ant-menu-item:hover,
|
|
248
|
+
body.jm-dark .ant-layout-sider .ant-menu-item:hover *,
|
|
249
|
+
body.jm-dark .ant-layout-header .ant-menu-item-selected,
|
|
250
|
+
body.jm-dark .ant-layout-header .ant-menu-item-selected *,
|
|
251
|
+
body.jm-dark .ant-layout-header .ant-menu-item:hover,
|
|
252
|
+
body.jm-dark .ant-layout-header .ant-menu-item:hover * {
|
|
253
|
+
color: revert !important;
|
|
254
|
+
}
|
|
255
|
+
body.jm-dark .ant-menu-submenu-popup {
|
|
256
|
+
background-color: ${sidebarDarkBg} !important;
|
|
257
|
+
}
|
|
258
|
+
body.jm-dark .ant-menu-submenu-popup .ant-menu-item:not(.ant-menu-item-selected),
|
|
259
|
+
body.jm-dark .ant-menu-submenu-popup .ant-menu-submenu-title:not(.ant-menu-submenu-selected) {
|
|
260
|
+
color: ${sidebarDarkText} !important;
|
|
261
|
+
}
|
|
212
262
|
body.jm-dark .ant-card,
|
|
213
263
|
body.jm-dark .ant-table-wrapper .ant-table,
|
|
214
264
|
body.jm-dark .ant-table-thead > tr > th,
|
|
@@ -259,7 +309,7 @@ var getModelTone = (modelLike, darkMode) => {
|
|
|
259
309
|
return tones[hashString(seed) % tones.length];
|
|
260
310
|
};
|
|
261
311
|
var useModelTone = (modelLike) => {
|
|
262
|
-
const { mode, schemaVersion } =
|
|
312
|
+
const { mode, schemaVersion } = React6.useContext(ColorModeContext);
|
|
263
313
|
return getModelTone(modelLike, mode === "dark");
|
|
264
314
|
};
|
|
265
315
|
var getContrastingTextColor = (background) => isDarkColor(background) ? "#f8fafc" : "#0f172a";
|
|
@@ -308,7 +358,7 @@ function guessIcon(text, isModule = false) {
|
|
|
308
358
|
function resolveIcon(iconName) {
|
|
309
359
|
const registry = AntDIcons2__namespace;
|
|
310
360
|
const IconCls = registry[iconName];
|
|
311
|
-
return IconCls ?
|
|
361
|
+
return IconCls ? React6__default.default.createElement(IconCls) : React6__default.default.createElement(registry["TableOutlined"]);
|
|
312
362
|
}
|
|
313
363
|
function getNavEntry(navConfig, key) {
|
|
314
364
|
return navConfig.find((e) => e.key === key);
|
|
@@ -339,8 +389,8 @@ var authenticatedFetch = (url, options = {}) => {
|
|
|
339
389
|
var API_URL = "/api";
|
|
340
390
|
var JOURNEY_ICON_NAME = "NodeIndexOutlined";
|
|
341
391
|
function useJourneyMenuItems() {
|
|
342
|
-
const [byModule, setByModule] =
|
|
343
|
-
|
|
392
|
+
const [byModule, setByModule] = React6.useState({});
|
|
393
|
+
React6.useEffect(() => {
|
|
344
394
|
let cancelled = false;
|
|
345
395
|
(async () => {
|
|
346
396
|
var _a;
|
|
@@ -396,6 +446,7 @@ function injectJourneyMenuItems(items, byModule) {
|
|
|
396
446
|
return walk(items);
|
|
397
447
|
}
|
|
398
448
|
var HorizontalMenu = ({ navConfig = [] }) => {
|
|
449
|
+
const { mode } = React6.useContext(ColorModeContext);
|
|
399
450
|
const { menuItems, selectedKey } = core.useMenu();
|
|
400
451
|
const go = core.useGo();
|
|
401
452
|
const journeysByModule = useJourneyMenuItems();
|
|
@@ -421,7 +472,7 @@ var HorizontalMenu = ({ navConfig = [] }) => {
|
|
|
421
472
|
const renderLabel = (item, depth, hasChildren) => {
|
|
422
473
|
const label = String(item?.label || item?.name || item?.key || "");
|
|
423
474
|
const isModule = depth === 0 || hasChildren;
|
|
424
|
-
|
|
475
|
+
isModule ? getModelTone(`module:${item?.key || label}`) : getModelTone(resolveModelSeed(item));
|
|
425
476
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
426
477
|
"span",
|
|
427
478
|
{
|
|
@@ -431,7 +482,7 @@ var HorizontalMenu = ({ navConfig = [] }) => {
|
|
|
431
482
|
padding: isModule ? "2px 5px" : "1px 5px",
|
|
432
483
|
borderRadius: 8,
|
|
433
484
|
background: "transparent",
|
|
434
|
-
color:
|
|
485
|
+
color: "inherit",
|
|
435
486
|
fontWeight: 400
|
|
436
487
|
},
|
|
437
488
|
children: label
|
|
@@ -457,6 +508,7 @@ var HorizontalMenu = ({ navConfig = [] }) => {
|
|
|
457
508
|
antd.Menu,
|
|
458
509
|
{
|
|
459
510
|
mode: "horizontal",
|
|
511
|
+
theme: mode === "dark" ? "light" : "dark",
|
|
460
512
|
selectedKeys: [selectedKey],
|
|
461
513
|
items,
|
|
462
514
|
style: {
|
|
@@ -469,7 +521,7 @@ var HorizontalMenu = ({ navConfig = [] }) => {
|
|
|
469
521
|
};
|
|
470
522
|
var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
|
|
471
523
|
const { token } = antd.theme.useToken();
|
|
472
|
-
const { mode } =
|
|
524
|
+
const { mode } = React6.useContext(ColorModeContext);
|
|
473
525
|
const { menuItems, selectedKey } = core.useMenu();
|
|
474
526
|
const go = core.useGo();
|
|
475
527
|
const journeysByModule = useJourneyMenuItems();
|
|
@@ -495,7 +547,7 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
|
|
|
495
547
|
const renderLabel = (item, depth, hasChildren) => {
|
|
496
548
|
const label = String(item?.label || item?.name || item?.key || "");
|
|
497
549
|
const isModule = depth === 0 || hasChildren;
|
|
498
|
-
|
|
550
|
+
isModule ? getModelTone(`module:${item?.key || label}`) : getModelTone(resolveModelSeed(item));
|
|
499
551
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
500
552
|
"span",
|
|
501
553
|
{
|
|
@@ -505,7 +557,7 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
|
|
|
505
557
|
padding: isModule ? "3px 8px" : "2px 8px",
|
|
506
558
|
borderRadius: 8,
|
|
507
559
|
background: "transparent",
|
|
508
|
-
color:
|
|
560
|
+
color: "inherit",
|
|
509
561
|
fontWeight: 400
|
|
510
562
|
},
|
|
511
563
|
children: label
|
|
@@ -526,15 +578,15 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
|
|
|
526
578
|
};
|
|
527
579
|
});
|
|
528
580
|
};
|
|
529
|
-
const sortedMenuItems =
|
|
581
|
+
const sortedMenuItems = React6.useMemo(
|
|
530
582
|
() => navConfig.length > 0 ? sortItemsByNavConfig(menuItems, navConfig) : menuItems,
|
|
531
583
|
[menuItems, navConfig]
|
|
532
584
|
);
|
|
533
|
-
const withJourneys =
|
|
585
|
+
const withJourneys = React6.useMemo(
|
|
534
586
|
() => injectJourneyMenuItems(sortedMenuItems, journeysByModule),
|
|
535
587
|
[sortedMenuItems, journeysByModule]
|
|
536
588
|
);
|
|
537
|
-
const items =
|
|
589
|
+
const items = React6.useMemo(() => transformItems(withJourneys), [withJourneys, mode, navConfig]);
|
|
538
590
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
539
591
|
antd.Layout.Sider,
|
|
540
592
|
{
|
|
@@ -611,30 +663,30 @@ var CustomSider = ({ collapsed, logo, appTitle, navConfig = [] }) => {
|
|
|
611
663
|
}
|
|
612
664
|
);
|
|
613
665
|
};
|
|
614
|
-
var AllModelsContext =
|
|
666
|
+
var AllModelsContext = React6.createContext([]);
|
|
615
667
|
var AllModelsProvider = ({
|
|
616
668
|
models,
|
|
617
669
|
children
|
|
618
670
|
}) => /* @__PURE__ */ jsxRuntime.jsx(AllModelsContext.Provider, { value: models, children });
|
|
619
|
-
var useAllModels = () =>
|
|
671
|
+
var useAllModels = () => React6.useContext(AllModelsContext);
|
|
620
672
|
|
|
621
673
|
// src/hooks/useRecordSearch.ts
|
|
622
674
|
var API_URL2 = "/api";
|
|
623
675
|
function useRecordSearch() {
|
|
624
676
|
const allSystemModels = useAllModels();
|
|
625
|
-
const [searchConfig, setSearchConfig] =
|
|
626
|
-
const [results, setResults] =
|
|
627
|
-
const [searching, setSearching] =
|
|
628
|
-
const debounceRef =
|
|
629
|
-
const abortRef =
|
|
630
|
-
|
|
677
|
+
const [searchConfig, setSearchConfig] = React6.useState(null);
|
|
678
|
+
const [results, setResults] = React6.useState([]);
|
|
679
|
+
const [searching, setSearching] = React6.useState(false);
|
|
680
|
+
const debounceRef = React6.useRef(null);
|
|
681
|
+
const abortRef = React6.useRef(null);
|
|
682
|
+
React6.useEffect(() => {
|
|
631
683
|
authenticatedFetch(`${API_URL2}/config/search`).then((r) => {
|
|
632
684
|
if (!r.ok) throw new Error("unavailable");
|
|
633
685
|
return r.json();
|
|
634
686
|
}).then((d) => setSearchConfig(d)).catch(() => {
|
|
635
687
|
});
|
|
636
688
|
}, []);
|
|
637
|
-
const searchableModels =
|
|
689
|
+
const searchableModels = React6.useMemo(() => {
|
|
638
690
|
if (!searchConfig) return [];
|
|
639
691
|
const entityTypesLower = searchConfig.entity_types.map((e) => e.toLowerCase());
|
|
640
692
|
const preferredFields = searchConfig.attribute_types;
|
|
@@ -667,7 +719,7 @@ function useRecordSearch() {
|
|
|
667
719
|
};
|
|
668
720
|
}).filter((m) => m.searchFields.length > 0);
|
|
669
721
|
}, [allSystemModels, searchConfig]);
|
|
670
|
-
const search =
|
|
722
|
+
const search = React6.useCallback(
|
|
671
723
|
(query) => {
|
|
672
724
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
673
725
|
if (abortRef.current) abortRef.current.abort();
|
|
@@ -728,7 +780,7 @@ function useRecordSearch() {
|
|
|
728
780
|
},
|
|
729
781
|
[searchableModels]
|
|
730
782
|
);
|
|
731
|
-
const clear =
|
|
783
|
+
const clear = React6.useCallback(() => {
|
|
732
784
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
733
785
|
if (abortRef.current) abortRef.current.abort();
|
|
734
786
|
setResults([]);
|
|
@@ -756,10 +808,11 @@ var flattenMenuItems = (items, parentLabel = "") => {
|
|
|
756
808
|
var GlobalSearch = () => {
|
|
757
809
|
const { menuItems } = core.useMenu();
|
|
758
810
|
const navigate = reactRouterDom.useNavigate();
|
|
759
|
-
const [searchText, setSearchText] =
|
|
811
|
+
const [searchText, setSearchText] = React6.useState("");
|
|
760
812
|
const { results: backendResults, searching, search, clear } = useRecordSearch();
|
|
761
|
-
const
|
|
762
|
-
const
|
|
813
|
+
const { token } = antd.theme.useToken();
|
|
814
|
+
const searchableResources = React6.useMemo(() => flattenMenuItems(menuItems), [menuItems]);
|
|
815
|
+
const resourceResults = React6.useMemo(() => {
|
|
763
816
|
const q2 = searchText.toLowerCase().trim();
|
|
764
817
|
if (!q2) return [];
|
|
765
818
|
const matches = searchableResources.filter(
|
|
@@ -780,7 +833,7 @@ var GlobalSearch = () => {
|
|
|
780
833
|
}
|
|
781
834
|
];
|
|
782
835
|
}, [searchText, searchableResources]);
|
|
783
|
-
const backendGroups =
|
|
836
|
+
const backendGroups = React6.useMemo(
|
|
784
837
|
() => backendResults.map((result) => ({
|
|
785
838
|
label: /* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { type: "secondary", strong: true, style: { fontSize: 11 }, children: result.modelLabel }),
|
|
786
839
|
options: result.records.map((record) => ({
|
|
@@ -791,14 +844,14 @@ var GlobalSearch = () => {
|
|
|
791
844
|
})),
|
|
792
845
|
[backendResults]
|
|
793
846
|
);
|
|
794
|
-
const onSearch =
|
|
847
|
+
const onSearch = React6.useCallback(
|
|
795
848
|
(value) => {
|
|
796
849
|
setSearchText(value);
|
|
797
850
|
search(value);
|
|
798
851
|
},
|
|
799
852
|
[search]
|
|
800
853
|
);
|
|
801
|
-
const onSelect =
|
|
854
|
+
const onSelect = React6.useCallback(
|
|
802
855
|
(value) => {
|
|
803
856
|
const path = value.replace(/^(nav:|record:)/, "");
|
|
804
857
|
navigate(path);
|
|
@@ -807,13 +860,13 @@ var GlobalSearch = () => {
|
|
|
807
860
|
},
|
|
808
861
|
[navigate, clear]
|
|
809
862
|
);
|
|
810
|
-
const options =
|
|
863
|
+
const options = React6.useMemo(
|
|
811
864
|
() => [...resourceResults, ...backendGroups],
|
|
812
865
|
[resourceResults, backendGroups]
|
|
813
866
|
);
|
|
814
|
-
const [focused, setFocused] =
|
|
815
|
-
const inputRef =
|
|
816
|
-
|
|
867
|
+
const [focused, setFocused] = React6.useState(false);
|
|
868
|
+
const inputRef = React6.useRef(null);
|
|
869
|
+
React6.useEffect(() => {
|
|
817
870
|
const handler = (e) => {
|
|
818
871
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
|
|
819
872
|
e.preventDefault();
|
|
@@ -847,7 +900,7 @@ var GlobalSearch = () => {
|
|
|
847
900
|
suffix: !focused ? /* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { type: "secondary", style: { fontSize: 9 }, children: "\u2303K" }) : void 0,
|
|
848
901
|
allowClear: true,
|
|
849
902
|
size: "small",
|
|
850
|
-
style: !focused ? { paddingInline: 2 } :
|
|
903
|
+
style: !focused ? { paddingInline: 2, color: token.colorText } : { color: token.colorText }
|
|
851
904
|
}
|
|
852
905
|
)
|
|
853
906
|
}
|
|
@@ -859,9 +912,9 @@ var API_URL3 = "/api";
|
|
|
859
912
|
|
|
860
913
|
// src/pages/dashboard/hooks/useRecentActivity.ts
|
|
861
914
|
function useRecentActivity(days) {
|
|
862
|
-
const [data, setData] =
|
|
863
|
-
const [loading, setLoading] =
|
|
864
|
-
const load =
|
|
915
|
+
const [data, setData] = React6.useState(null);
|
|
916
|
+
const [loading, setLoading] = React6.useState(true);
|
|
917
|
+
const load = React6.useCallback(async () => {
|
|
865
918
|
setLoading(true);
|
|
866
919
|
try {
|
|
867
920
|
const params = days !== void 0 ? `?days=${days}` : "";
|
|
@@ -872,7 +925,7 @@ function useRecentActivity(days) {
|
|
|
872
925
|
setLoading(false);
|
|
873
926
|
}
|
|
874
927
|
}, [days]);
|
|
875
|
-
|
|
928
|
+
React6.useEffect(() => {
|
|
876
929
|
load();
|
|
877
930
|
}, [load]);
|
|
878
931
|
return { data, loading, reload: load };
|
|
@@ -903,9 +956,9 @@ function relativeTime(iso) {
|
|
|
903
956
|
return d < 30 ? `${d}d ago` : new Date(iso).toLocaleDateString();
|
|
904
957
|
}
|
|
905
958
|
function usePinnedGroups() {
|
|
906
|
-
const [groups, setGroups] =
|
|
907
|
-
const [loading, setLoading] =
|
|
908
|
-
const load =
|
|
959
|
+
const [groups, setGroups] = React6.useState([]);
|
|
960
|
+
const [loading, setLoading] = React6.useState(false);
|
|
961
|
+
const load = React6.useCallback(async () => {
|
|
909
962
|
setLoading(true);
|
|
910
963
|
try {
|
|
911
964
|
const res = await authenticatedFetch(`${API_URL3}/dashboard/pinned-records`);
|
|
@@ -974,22 +1027,22 @@ var CommandCenterPortal = ({
|
|
|
974
1027
|
}) => {
|
|
975
1028
|
const { menuItems: rawMenuItems } = core.useMenu();
|
|
976
1029
|
const journeysByModule = useJourneyMenuItems();
|
|
977
|
-
const menuItems =
|
|
1030
|
+
const menuItems = React6.useMemo(
|
|
978
1031
|
() => injectJourneyMenuItems(rawMenuItems, journeysByModule),
|
|
979
1032
|
[rawMenuItems, journeysByModule]
|
|
980
1033
|
);
|
|
981
1034
|
const go = core.useGo();
|
|
982
|
-
const searchRef =
|
|
983
|
-
const [query, setQuery] =
|
|
984
|
-
const [activeIdx, setActiveIdx] =
|
|
985
|
-
const [colW, setColW] =
|
|
986
|
-
const colWRef =
|
|
1035
|
+
const searchRef = React6.useRef(null);
|
|
1036
|
+
const [query, setQuery] = React6.useState("");
|
|
1037
|
+
const [activeIdx, setActiveIdx] = React6.useState(-1);
|
|
1038
|
+
const [colW, setColW] = React6.useState([220, 220]);
|
|
1039
|
+
const colWRef = React6.useRef([220, 220]);
|
|
987
1040
|
colWRef.current = colW;
|
|
988
|
-
const dragRef =
|
|
1041
|
+
const dragRef = React6.useRef(null);
|
|
989
1042
|
const { results: backendResults, searching, search, clear } = useRecordSearch();
|
|
990
1043
|
const { groups: pinnedGroups, loading: pinnedLoading, load: loadPinned } = usePinnedGroups();
|
|
991
1044
|
const { data: recentData, reload: reloadRecent } = useRecentActivity(30);
|
|
992
|
-
|
|
1045
|
+
React6.useEffect(() => {
|
|
993
1046
|
if (open) {
|
|
994
1047
|
setQuery("");
|
|
995
1048
|
setActiveIdx(-1);
|
|
@@ -1000,9 +1053,9 @@ var CommandCenterPortal = ({
|
|
|
1000
1053
|
return () => clearTimeout(t);
|
|
1001
1054
|
}
|
|
1002
1055
|
}, [open, clear, loadPinned, reloadRecent]);
|
|
1003
|
-
const navItemIdsRef =
|
|
1004
|
-
const activeIdxRef =
|
|
1005
|
-
|
|
1056
|
+
const navItemIdsRef = React6.useRef([]);
|
|
1057
|
+
const activeIdxRef = React6.useRef(-1);
|
|
1058
|
+
React6.useEffect(() => {
|
|
1006
1059
|
if (!open) return;
|
|
1007
1060
|
const handler = (e) => {
|
|
1008
1061
|
if (e.key === "Escape") {
|
|
@@ -1030,33 +1083,33 @@ var CommandCenterPortal = ({
|
|
|
1030
1083
|
window.addEventListener("keydown", handler);
|
|
1031
1084
|
return () => window.removeEventListener("keydown", handler);
|
|
1032
1085
|
}, [open, onClose]);
|
|
1033
|
-
const parsedCommand =
|
|
1034
|
-
|
|
1086
|
+
const parsedCommand = React6.useMemo(() => parseCommand(query.toLowerCase().trim()), [query]);
|
|
1087
|
+
React6.useEffect(() => {
|
|
1035
1088
|
if (parsedCommand) {
|
|
1036
1089
|
clear();
|
|
1037
1090
|
} else {
|
|
1038
1091
|
search(query.toLowerCase().trim());
|
|
1039
1092
|
}
|
|
1040
1093
|
}, [query, parsedCommand, search, clear]);
|
|
1041
|
-
const allModelChildren =
|
|
1094
|
+
const allModelChildren = React6.useMemo(
|
|
1042
1095
|
() => menuItems.flatMap(
|
|
1043
1096
|
(m) => (m.children || []).filter((c) => !c.meta?.hide).map((c) => ({ ...c, moduleLabel: String(m.label || m.name || "") }))
|
|
1044
1097
|
),
|
|
1045
1098
|
[menuItems]
|
|
1046
1099
|
);
|
|
1047
|
-
const commandSuggestions =
|
|
1100
|
+
const commandSuggestions = React6.useMemo(() => {
|
|
1048
1101
|
if (!parsedCommand) return [];
|
|
1049
1102
|
const mq = parsedCommand.modelQuery;
|
|
1050
1103
|
const children = mq ? allModelChildren.filter((c) => (c.label || "").toLowerCase().includes(mq) || (c.name || "").toLowerCase().includes(mq)) : allModelChildren;
|
|
1051
1104
|
return (navConfig.length > 0 ? sortItemsByNavConfig(children, navConfig) : children).slice(0, 8);
|
|
1052
1105
|
}, [parsedCommand, allModelChildren, navConfig]);
|
|
1053
|
-
const searchPlaceholder =
|
|
1106
|
+
const searchPlaceholder = React6.useMemo(() => {
|
|
1054
1107
|
const labels = allModelChildren.slice(0, 2).map((c) => String(c.label || c.name || "").toLowerCase()).filter(Boolean);
|
|
1055
1108
|
if (labels.length === 0) return `Search modules, models, records\u2026`;
|
|
1056
1109
|
const [a, b] = labels;
|
|
1057
1110
|
return b && b !== a ? `Search modules, models, records\u2026 or "list ${a}", "create ${b}"` : `Search modules, models, records\u2026 or "list ${a}", "create ${a}"`;
|
|
1058
1111
|
}, [allModelChildren]);
|
|
1059
|
-
const modules =
|
|
1112
|
+
const modules = React6.useMemo(() => {
|
|
1060
1113
|
const q2 = parsedCommand ? parsedCommand.modelQuery : query.toLowerCase().trim();
|
|
1061
1114
|
const visibleModules = menuItems.filter((item) => item.children && item.children.length > 0).map((item) => ({ ...item, children: (item.children || []).filter((c) => !c.meta?.hide) })).filter((item) => item.children && item.children.length > 0);
|
|
1062
1115
|
const sorted = navConfig.length > 0 ? sortItemsByNavConfig(visibleModules, navConfig) : visibleModules;
|
|
@@ -1070,7 +1123,7 @@ var CommandCenterPortal = ({
|
|
|
1070
1123
|
return moduleMatch ? module : { ...module, children: filteredChildren };
|
|
1071
1124
|
}).filter((m) => m !== null);
|
|
1072
1125
|
}, [menuItems, query, parsedCommand, navConfig]);
|
|
1073
|
-
const pinnedItems =
|
|
1126
|
+
const pinnedItems = React6.useMemo(
|
|
1074
1127
|
() => pinnedGroups.flatMap((g) => g.records.map((r) => ({
|
|
1075
1128
|
resource: g.resource,
|
|
1076
1129
|
modelName: g.model_name,
|
|
@@ -1079,7 +1132,7 @@ var CommandCenterPortal = ({
|
|
|
1079
1132
|
}))),
|
|
1080
1133
|
[pinnedGroups]
|
|
1081
1134
|
);
|
|
1082
|
-
const recentItems =
|
|
1135
|
+
const recentItems = React6.useMemo(() => {
|
|
1083
1136
|
if (!recentData?.groups) return [];
|
|
1084
1137
|
return recentData.groups.flatMap((g) => g.records.map((r) => ({
|
|
1085
1138
|
resource: g.resource,
|
|
@@ -1090,7 +1143,7 @@ var CommandCenterPortal = ({
|
|
|
1090
1143
|
isNew: Boolean(r.created_at && (!r.updated_at || r.updated_at === r.created_at))
|
|
1091
1144
|
}))).sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
1092
1145
|
}, [recentData]);
|
|
1093
|
-
const navItemIds =
|
|
1146
|
+
const navItemIds = React6.useMemo(() => {
|
|
1094
1147
|
const ids = [];
|
|
1095
1148
|
if (parsedCommand) {
|
|
1096
1149
|
for (const child of commandSuggestions)
|
|
@@ -1111,10 +1164,10 @@ var CommandCenterPortal = ({
|
|
|
1111
1164
|
}, [parsedCommand, commandSuggestions, query, pinnedItems, recentItems, backendResults, modules, navConfig]);
|
|
1112
1165
|
navItemIdsRef.current = navItemIds;
|
|
1113
1166
|
activeIdxRef.current = activeIdx;
|
|
1114
|
-
|
|
1167
|
+
React6.useEffect(() => {
|
|
1115
1168
|
setActiveIdx(-1);
|
|
1116
1169
|
}, [navItemIds]);
|
|
1117
|
-
|
|
1170
|
+
React6.useEffect(() => {
|
|
1118
1171
|
if (activeIdx < 0) return;
|
|
1119
1172
|
const id = navItemIds[activeIdx];
|
|
1120
1173
|
if (id) document.querySelector(`[data-navid="${id}"]`)?.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
@@ -1303,7 +1356,7 @@ var CommandCenterPortal = ({
|
|
|
1303
1356
|
/* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { style: SECTION_LABEL_STYLE, children: "Pinned" }),
|
|
1304
1357
|
pinnedLoading && /* @__PURE__ */ jsxRuntime.jsx(antd.Spin, { size: "small", style: { marginLeft: "auto" } })
|
|
1305
1358
|
] }),
|
|
1306
|
-
pinnedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", overflowY: "auto", maxHeight: 400 }, children: pinnedItems.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1359
|
+
pinnedItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", overflowY: "auto", maxHeight: 400 }, children: pinnedItems.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1307
1360
|
idx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.04)" } }),
|
|
1308
1361
|
renderRow(
|
|
1309
1362
|
`pin-${item.resource}-${item.id}`,
|
|
@@ -1326,7 +1379,7 @@ var CommandCenterPortal = ({
|
|
|
1326
1379
|
/* @__PURE__ */ jsxRuntime.jsx(AntDIcons2.ClockCircleOutlined, { style: { color: "rgba(255,255,255,0.45)", fontSize: 12 } }),
|
|
1327
1380
|
/* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { style: SECTION_LABEL_STYLE, children: "Recent" })
|
|
1328
1381
|
] }),
|
|
1329
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", overflowY: "auto", maxHeight: 400 }, children: recentItems.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1382
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", overflowY: "auto", maxHeight: 400 }, children: recentItems.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1330
1383
|
idx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.04)" } }),
|
|
1331
1384
|
renderRow(
|
|
1332
1385
|
`recent-${item.resource}-${item.id}`,
|
|
@@ -1355,7 +1408,7 @@ var CommandCenterPortal = ({
|
|
|
1355
1408
|
const moduleLabel = String(module.label || module.name || "");
|
|
1356
1409
|
const tone = getModelTone(moduleKey);
|
|
1357
1410
|
const children = navConfig.length > 0 ? sortItemsByNavConfig(module.children || [], navConfig) : module.children || [];
|
|
1358
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1411
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1359
1412
|
modIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "5px 0", borderColor: "rgba(255,255,255,0.06)" } }),
|
|
1360
1413
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, padding: "4px 8px 2px" }, children: [
|
|
1361
1414
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: tone.solid, fontSize: 12, display: "flex", alignItems: "center" }, children: getItemIcon(moduleKey, moduleLabel, true) }),
|
|
@@ -1366,7 +1419,7 @@ var CommandCenterPortal = ({
|
|
|
1366
1419
|
const childLabel = String(child.label || child.name || "");
|
|
1367
1420
|
const childTone = getModelTone(childKey);
|
|
1368
1421
|
const childIcon = getItemIcon(childKey, childLabel, false, child.icon);
|
|
1369
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1422
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1370
1423
|
idx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.04)" } }),
|
|
1371
1424
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1372
1425
|
"div",
|
|
@@ -1418,7 +1471,7 @@ var CommandCenterPortal = ({
|
|
|
1418
1471
|
const moduleLabel = child.moduleLabel || "";
|
|
1419
1472
|
const navId = `cmd-${childKey}`;
|
|
1420
1473
|
const active = isActive(navId);
|
|
1421
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1474
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1422
1475
|
idx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.05)" } }),
|
|
1423
1476
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1424
1477
|
"div",
|
|
@@ -1462,13 +1515,13 @@ var CommandCenterPortal = ({
|
|
|
1462
1515
|
] }),
|
|
1463
1516
|
backendResults.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px" }, children: backendResults.map((modelResult, modelIdx) => {
|
|
1464
1517
|
const tone = getModelTone(modelResult.resource);
|
|
1465
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1518
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1466
1519
|
modelIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "4px 0", borderColor: "rgba(255,255,255,0.05)" } }),
|
|
1467
1520
|
/* @__PURE__ */ jsxRuntime.jsx(antd.Typography.Text, { style: { color: "rgba(255,255,255,0.35)", fontSize: 10, textTransform: "uppercase", letterSpacing: "0.07em", display: "block", padding: "4px 10px 2px" }, children: modelResult.modelLabel }),
|
|
1468
1521
|
modelResult.records.map((record, recIdx) => {
|
|
1469
1522
|
const navId = `record-${modelResult.resource}-${record.id}`;
|
|
1470
1523
|
const active = isActive(navId);
|
|
1471
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1524
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1472
1525
|
recIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.04)" } }),
|
|
1473
1526
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1474
1527
|
"div",
|
|
@@ -1550,7 +1603,7 @@ var CommandCenterPortal = ({
|
|
|
1550
1603
|
const childLabel = String(child.label || child.name || "");
|
|
1551
1604
|
const childTone = getModelTone(childKey);
|
|
1552
1605
|
const childIcon = getItemIcon(childKey, childLabel, false, child.icon);
|
|
1553
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1606
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React6__default.default.Fragment, { children: [
|
|
1554
1607
|
idx > 0 && /* @__PURE__ */ jsxRuntime.jsx(antd.Divider, { style: { margin: "2px 0", borderColor: "rgba(255,255,255,0.05)" } }),
|
|
1555
1608
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1556
1609
|
"div",
|
|
@@ -1584,8 +1637,8 @@ var CommandCenterPortal = ({
|
|
|
1584
1637
|
}
|
|
1585
1638
|
) });
|
|
1586
1639
|
};
|
|
1587
|
-
var NavConfigContext =
|
|
1588
|
-
var useNavConfig = () =>
|
|
1640
|
+
var NavConfigContext = React6.createContext([]);
|
|
1641
|
+
var useNavConfig = () => React6.useContext(NavConfigContext);
|
|
1589
1642
|
function useNavModules() {
|
|
1590
1643
|
const navConfig = useNavConfig();
|
|
1591
1644
|
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) }));
|
|
@@ -1630,24 +1683,24 @@ var LayoutWrapper = ({
|
|
|
1630
1683
|
extraUserMenuItems = [],
|
|
1631
1684
|
navConfig = []
|
|
1632
1685
|
}) => {
|
|
1633
|
-
const [layoutMode, setLayoutMode] =
|
|
1686
|
+
const [layoutMode, setLayoutMode] = React6.useState(
|
|
1634
1687
|
() => localStorage.getItem("layoutMode") || "vertical"
|
|
1635
1688
|
);
|
|
1636
1689
|
const screens = antd.Grid.useBreakpoint();
|
|
1637
1690
|
const isMobile = !screens.md;
|
|
1638
|
-
const { mode, setMode } =
|
|
1691
|
+
const { mode, setMode } = React6.useContext(ColorModeContext);
|
|
1639
1692
|
const { token } = antd.theme.useToken();
|
|
1640
1693
|
const { data: identity } = core.useGetIdentity();
|
|
1641
1694
|
const { mutate: logout } = core.useLogout();
|
|
1642
1695
|
core.useGo();
|
|
1643
1696
|
const displayName = identity ? [identity.first_name, identity.last_name].filter(Boolean).join(" ") || identity.username || "User" : "User";
|
|
1644
|
-
const [siderCollapsed, setSiderCollapsed] =
|
|
1645
|
-
const [pwdModalOpen, setPwdModalOpen] =
|
|
1646
|
-
const [pwdLoading, setPwdLoading] =
|
|
1697
|
+
const [siderCollapsed, setSiderCollapsed] = React6.useState(() => localStorage.getItem("siderCollapsed") === "true");
|
|
1698
|
+
const [pwdModalOpen, setPwdModalOpen] = React6.useState(false);
|
|
1699
|
+
const [pwdLoading, setPwdLoading] = React6.useState(false);
|
|
1647
1700
|
const [pwdForm] = antd.Form.useForm();
|
|
1648
|
-
const [drawerOpen, setDrawerOpen] =
|
|
1649
|
-
const [portalOpen, setPortalOpen] =
|
|
1650
|
-
|
|
1701
|
+
const [drawerOpen, setDrawerOpen] = React6.useState(false);
|
|
1702
|
+
const [portalOpen, setPortalOpen] = React6.useState(false);
|
|
1703
|
+
React6.useEffect(() => {
|
|
1651
1704
|
const handler = (e) => {
|
|
1652
1705
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "g") {
|
|
1653
1706
|
e.preventDefault();
|
|
@@ -1833,8 +1886,8 @@ var LayoutWrapper = ({
|
|
|
1833
1886
|
] });
|
|
1834
1887
|
};
|
|
1835
1888
|
var PANE_TOOLBAR_HEIGHT = 28;
|
|
1836
|
-
var PaneNavigationContext =
|
|
1837
|
-
var usePaneNavigation = () =>
|
|
1889
|
+
var PaneNavigationContext = React6.createContext(null);
|
|
1890
|
+
var usePaneNavigation = () => React6.useContext(PaneNavigationContext);
|
|
1838
1891
|
function gt(e, t) {
|
|
1839
1892
|
const n = getComputedStyle(e), o = parseFloat(n.fontSize);
|
|
1840
1893
|
return t * o;
|
|
@@ -3350,19 +3403,19 @@ function Vt(e) {
|
|
|
3350
3403
|
};
|
|
3351
3404
|
}
|
|
3352
3405
|
function Bt() {
|
|
3353
|
-
const [e, t] =
|
|
3406
|
+
const [e, t] = React6.useState({}), n = React6.useCallback(() => t({}), []);
|
|
3354
3407
|
return [e, n];
|
|
3355
3408
|
}
|
|
3356
3409
|
function Le(e) {
|
|
3357
|
-
const t =
|
|
3410
|
+
const t = React6.useId();
|
|
3358
3411
|
return `${e ?? t}`;
|
|
3359
3412
|
}
|
|
3360
|
-
var q = typeof window < "u" ?
|
|
3413
|
+
var q = typeof window < "u" ? React6.useLayoutEffect : React6.useEffect;
|
|
3361
3414
|
function se(e) {
|
|
3362
|
-
const t =
|
|
3415
|
+
const t = React6.useRef(e);
|
|
3363
3416
|
return q(() => {
|
|
3364
3417
|
t.current = e;
|
|
3365
|
-
}, [e]),
|
|
3418
|
+
}, [e]), React6.useCallback(
|
|
3366
3419
|
(...n) => t.current?.(...n),
|
|
3367
3420
|
[t]
|
|
3368
3421
|
);
|
|
@@ -3385,19 +3438,19 @@ function Ce(...e) {
|
|
|
3385
3438
|
});
|
|
3386
3439
|
}
|
|
3387
3440
|
function Re(e) {
|
|
3388
|
-
const t =
|
|
3441
|
+
const t = React6.useRef({ ...e });
|
|
3389
3442
|
return q(() => {
|
|
3390
3443
|
for (const n in e)
|
|
3391
3444
|
t.current[n] = e[n];
|
|
3392
3445
|
}, [e]), t.current;
|
|
3393
3446
|
}
|
|
3394
|
-
var lt =
|
|
3447
|
+
var lt = React6.createContext(null);
|
|
3395
3448
|
function Wt(e, t) {
|
|
3396
|
-
const n =
|
|
3449
|
+
const n = React6.useRef({
|
|
3397
3450
|
getLayout: () => ({}),
|
|
3398
3451
|
setLayout: Ft
|
|
3399
3452
|
});
|
|
3400
|
-
|
|
3453
|
+
React6.useImperativeHandle(t, () => n.current, []), q(() => {
|
|
3401
3454
|
Object.assign(
|
|
3402
3455
|
n.current,
|
|
3403
3456
|
nt({ groupId: e })
|
|
@@ -3423,14 +3476,14 @@ function Ut({
|
|
|
3423
3476
|
style: d,
|
|
3424
3477
|
...S
|
|
3425
3478
|
}) {
|
|
3426
|
-
const z =
|
|
3479
|
+
const z = React6.useRef({
|
|
3427
3480
|
onLayoutChange: {},
|
|
3428
3481
|
onLayoutChanged: {}
|
|
3429
3482
|
}), c = se((x) => {
|
|
3430
3483
|
W(z.current.onLayoutChange, x) || (z.current.onLayoutChange = x, s?.(x));
|
|
3431
3484
|
}), p = se((x) => {
|
|
3432
3485
|
W(z.current.onLayoutChanged, x) || (z.current.onLayoutChanged = x, l?.(x));
|
|
3433
|
-
}), m = Le(a), v =
|
|
3486
|
+
}), m = Le(a), v = React6.useRef(null), [b, y] = Bt(), g = React6.useRef({
|
|
3434
3487
|
lastExpandedPanelSizes: {},
|
|
3435
3488
|
layouts: {},
|
|
3436
3489
|
panels: [],
|
|
@@ -3464,7 +3517,7 @@ function Ut({
|
|
|
3464
3517
|
), w = Re({
|
|
3465
3518
|
defaultLayout: n,
|
|
3466
3519
|
disableCursor: o
|
|
3467
|
-
}), G =
|
|
3520
|
+
}), G = React6.useMemo(
|
|
3468
3521
|
() => ({
|
|
3469
3522
|
get disableCursor() {
|
|
3470
3523
|
return !!w.disableCursor;
|
|
@@ -3516,7 +3569,7 @@ function Ut({
|
|
|
3516
3569
|
}
|
|
3517
3570
|
}),
|
|
3518
3571
|
[M, m, y, u, w]
|
|
3519
|
-
), N =
|
|
3572
|
+
), N = React6.useRef(null);
|
|
3520
3573
|
return q(() => {
|
|
3521
3574
|
const x = v.current;
|
|
3522
3575
|
if (x === null)
|
|
@@ -3582,7 +3635,7 @@ function Ut({
|
|
|
3582
3635
|
u,
|
|
3583
3636
|
b,
|
|
3584
3637
|
w
|
|
3585
|
-
]),
|
|
3638
|
+
]), React6.useEffect(() => {
|
|
3586
3639
|
const x = N.current;
|
|
3587
3640
|
x && (x.mutableState.defaultLayout = n, x.mutableState.disableCursor = !!o);
|
|
3588
3641
|
}), /* @__PURE__ */ jsxRuntime.jsx(lt.Provider, { value: G, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3614,14 +3667,14 @@ function Ut({
|
|
|
3614
3667
|
}
|
|
3615
3668
|
Ut.displayName = "Group";
|
|
3616
3669
|
function Me() {
|
|
3617
|
-
const e =
|
|
3670
|
+
const e = React6.useContext(lt);
|
|
3618
3671
|
return C(
|
|
3619
3672
|
e,
|
|
3620
3673
|
"Group Context not found; did you render a Panel or Separator outside of a Group?"
|
|
3621
3674
|
), e;
|
|
3622
3675
|
}
|
|
3623
3676
|
function qt(e, t) {
|
|
3624
|
-
const { id: n } = Me(), o =
|
|
3677
|
+
const { id: n } = Me(), o = React6.useRef({
|
|
3625
3678
|
collapse: ye,
|
|
3626
3679
|
expand: ye,
|
|
3627
3680
|
getSize: () => ({
|
|
@@ -3631,7 +3684,7 @@ function qt(e, t) {
|
|
|
3631
3684
|
isCollapsed: () => false,
|
|
3632
3685
|
resize: ye
|
|
3633
3686
|
});
|
|
3634
|
-
|
|
3687
|
+
React6.useImperativeHandle(t, () => o.current, []), q(() => {
|
|
3635
3688
|
Object.assign(
|
|
3636
3689
|
o.current,
|
|
3637
3690
|
tt({ groupId: n, panelId: e })
|
|
@@ -3657,7 +3710,7 @@ function Yt({
|
|
|
3657
3710
|
}) {
|
|
3658
3711
|
const c = !!s, p = Le(s), m = Re({
|
|
3659
3712
|
disabled: r
|
|
3660
|
-
}), v =
|
|
3713
|
+
}), v = React6.useRef(null), b = Ce(v, f), {
|
|
3661
3714
|
getPanelStyles: y,
|
|
3662
3715
|
id: g,
|
|
3663
3716
|
orientation: P,
|
|
@@ -3705,14 +3758,14 @@ function Yt({
|
|
|
3705
3758
|
N,
|
|
3706
3759
|
M,
|
|
3707
3760
|
m
|
|
3708
|
-
]),
|
|
3761
|
+
]), React6.useEffect(() => {
|
|
3709
3762
|
w(p, { disabled: r });
|
|
3710
3763
|
}, [r, p, w]), qt(p, d);
|
|
3711
3764
|
const x = () => {
|
|
3712
3765
|
const R = y(g, p);
|
|
3713
3766
|
if (R)
|
|
3714
3767
|
return JSON.stringify(R);
|
|
3715
|
-
}, L =
|
|
3768
|
+
}, L = React6.useSyncExternalStore(
|
|
3716
3769
|
(R) => ze(g, R),
|
|
3717
3770
|
x,
|
|
3718
3771
|
x
|
|
@@ -3826,7 +3879,7 @@ function Qt({
|
|
|
3826
3879
|
const s = Le(r), l = Re({
|
|
3827
3880
|
disabled: n,
|
|
3828
3881
|
disableDoubleClick: o
|
|
3829
|
-
}), [u, h] =
|
|
3882
|
+
}), [u, h] = React6.useState({}), [d, S] = React6.useState("inactive"), [z, c] = React6.useState(false), p = React6.useRef(null), m = Ce(p, i), {
|
|
3830
3883
|
disableCursor: v,
|
|
3831
3884
|
id: b,
|
|
3832
3885
|
orientation: y,
|
|
@@ -3870,7 +3923,7 @@ function Qt({
|
|
|
3870
3923
|
k(), R(), L();
|
|
3871
3924
|
};
|
|
3872
3925
|
}
|
|
3873
|
-
}, [b, s, g, l]),
|
|
3926
|
+
}, [b, s, g, l]), React6.useEffect(() => {
|
|
3874
3927
|
P(s, { disabled: n, disableDoubleClick: o });
|
|
3875
3928
|
}, [n, o, s, P]);
|
|
3876
3929
|
let w;
|
|
@@ -3924,10 +3977,10 @@ Qt.displayName = "Separator";
|
|
|
3924
3977
|
var _3 = window._ || ((text) => text);
|
|
3925
3978
|
var NARROW_BREAKPOINT = 768;
|
|
3926
3979
|
var useIsNarrow = (breakpoint = NARROW_BREAKPOINT) => {
|
|
3927
|
-
const [narrow, setNarrow] =
|
|
3980
|
+
const [narrow, setNarrow] = React6.useState(
|
|
3928
3981
|
() => typeof window !== "undefined" ? window.innerWidth < breakpoint : false
|
|
3929
3982
|
);
|
|
3930
|
-
|
|
3983
|
+
React6.useEffect(() => {
|
|
3931
3984
|
const handler = () => setNarrow(window.innerWidth < breakpoint);
|
|
3932
3985
|
window.addEventListener("resize", handler);
|
|
3933
3986
|
return () => window.removeEventListener("resize", handler);
|
|
@@ -3950,8 +4003,8 @@ var ActionsButtonStack = ({ direction, children }) => /* @__PURE__ */ jsxRuntime
|
|
|
3950
4003
|
var VerticalActionsLayout = ({ position, onBarMount, children }) => {
|
|
3951
4004
|
const { token } = antd.theme.useToken();
|
|
3952
4005
|
const narrow = useIsNarrow();
|
|
3953
|
-
const [drawerOpen, setDrawerOpen] =
|
|
3954
|
-
const mountRef =
|
|
4006
|
+
const [drawerOpen, setDrawerOpen] = React6.useState(false);
|
|
4007
|
+
const mountRef = React6.useCallback(
|
|
3955
4008
|
(el) => onBarMount(el),
|
|
3956
4009
|
[onBarMount]
|
|
3957
4010
|
);
|
|
@@ -4280,9 +4333,9 @@ var splitRelations = (relations = []) => {
|
|
|
4280
4333
|
};
|
|
4281
4334
|
var useViewConfigurations = (modelName, viewType) => {
|
|
4282
4335
|
const apiUrl = core.useApiUrl();
|
|
4283
|
-
const [rows, setRows] =
|
|
4284
|
-
const [loading, setLoading] =
|
|
4285
|
-
|
|
4336
|
+
const [rows, setRows] = React6.useState([]);
|
|
4337
|
+
const [loading, setLoading] = React6.useState(!!modelName);
|
|
4338
|
+
React6.useEffect(() => {
|
|
4286
4339
|
if (!modelName) {
|
|
4287
4340
|
setLoading(false);
|
|
4288
4341
|
return;
|
|
@@ -4318,9 +4371,9 @@ var normalizeActionsPosition = (raw) => {
|
|
|
4318
4371
|
};
|
|
4319
4372
|
var useViewSettings = () => {
|
|
4320
4373
|
const apiUrl = core.useApiUrl();
|
|
4321
|
-
const [settings, setSettings] =
|
|
4322
|
-
const [loading, setLoading] =
|
|
4323
|
-
|
|
4374
|
+
const [settings, setSettings] = React6.useState(null);
|
|
4375
|
+
const [loading, setLoading] = React6.useState(true);
|
|
4376
|
+
React6.useEffect(() => {
|
|
4324
4377
|
let cancelled = false;
|
|
4325
4378
|
const fetchSettings = async () => {
|
|
4326
4379
|
try {
|
|
@@ -4675,7 +4728,7 @@ var extractButtonLabel = (node) => {
|
|
|
4675
4728
|
}
|
|
4676
4729
|
return null;
|
|
4677
4730
|
}
|
|
4678
|
-
if (
|
|
4731
|
+
if (React6__default.default.isValidElement(node)) {
|
|
4679
4732
|
return extractButtonLabel(node.props?.children);
|
|
4680
4733
|
}
|
|
4681
4734
|
return null;
|
|
@@ -4692,14 +4745,14 @@ var renderIconOnlyButtons = (nodes) => {
|
|
|
4692
4745
|
const enhanceNode = (node, index) => {
|
|
4693
4746
|
if (node === null || node === void 0 || typeof node === "boolean") return node;
|
|
4694
4747
|
if (Array.isArray(node)) return node.map((child, childIndex) => enhanceNode(child, childIndex));
|
|
4695
|
-
if (!
|
|
4748
|
+
if (!React6__default.default.isValidElement(node)) return node;
|
|
4696
4749
|
const componentName = node.type?.displayName || node.type?.name;
|
|
4697
4750
|
if (componentName === "RefreshButton") return null;
|
|
4698
4751
|
const fallbackLabel = componentName ? fallbackLabels[componentName] : null;
|
|
4699
4752
|
const nodeProps = node.props;
|
|
4700
4753
|
if (fallbackLabel) {
|
|
4701
4754
|
const label = extractButtonLabel(nodeProps?.children) || fallbackLabel;
|
|
4702
|
-
const element =
|
|
4755
|
+
const element = React6__default.default.cloneElement(node, {
|
|
4703
4756
|
...nodeProps,
|
|
4704
4757
|
hideText: true,
|
|
4705
4758
|
children: null
|
|
@@ -4710,7 +4763,7 @@ var renderIconOnlyButtons = (nodes) => {
|
|
|
4710
4763
|
if (nodeProps?.icon) {
|
|
4711
4764
|
const label = extractButtonLabel(nodeProps?.children);
|
|
4712
4765
|
if (label) {
|
|
4713
|
-
const element =
|
|
4766
|
+
const element = React6__default.default.cloneElement(node, {
|
|
4714
4767
|
...nodeProps,
|
|
4715
4768
|
children: null
|
|
4716
4769
|
});
|
|
@@ -4718,15 +4771,15 @@ var renderIconOnlyButtons = (nodes) => {
|
|
|
4718
4771
|
}
|
|
4719
4772
|
}
|
|
4720
4773
|
if (nodeProps?.children) {
|
|
4721
|
-
const mappedChildren =
|
|
4722
|
-
return
|
|
4774
|
+
const mappedChildren = React6__default.default.Children.map(nodeProps.children, (child, childIndex) => enhanceNode(child, childIndex));
|
|
4775
|
+
return React6__default.default.cloneElement(node, {
|
|
4723
4776
|
...nodeProps,
|
|
4724
4777
|
children: mappedChildren
|
|
4725
4778
|
});
|
|
4726
4779
|
}
|
|
4727
4780
|
return node;
|
|
4728
4781
|
};
|
|
4729
|
-
return
|
|
4782
|
+
return React6__default.default.Children.map(nodes, (child, index) => enhanceNode(child, index));
|
|
4730
4783
|
};
|
|
4731
4784
|
var ResponsiveHeaderButtons = ({ children }) => {
|
|
4732
4785
|
const screens = antd.Grid.useBreakpoint();
|
|
@@ -4777,7 +4830,7 @@ var extractButtonLabel2 = (node) => {
|
|
|
4777
4830
|
}
|
|
4778
4831
|
return null;
|
|
4779
4832
|
}
|
|
4780
|
-
if (
|
|
4833
|
+
if (React6__default.default.isValidElement(node)) {
|
|
4781
4834
|
return extractButtonLabel2(node.props?.children);
|
|
4782
4835
|
}
|
|
4783
4836
|
return null;
|
|
@@ -4795,12 +4848,12 @@ var renderIconOnlyButtons2 = (nodes) => {
|
|
|
4795
4848
|
const enhanceNode = (node, index) => {
|
|
4796
4849
|
if (node === null || node === void 0 || typeof node === "boolean") return node;
|
|
4797
4850
|
if (Array.isArray(node)) return node.map((child, childIndex) => enhanceNode(child, childIndex));
|
|
4798
|
-
if (!
|
|
4851
|
+
if (!React6__default.default.isValidElement(node)) return node;
|
|
4799
4852
|
const componentName = node.type?.displayName || node.type?.name;
|
|
4800
4853
|
const fallbackLabel = componentName ? fallbackLabels[componentName] : null;
|
|
4801
4854
|
if (fallbackLabel) {
|
|
4802
4855
|
const label = extractButtonLabel2(node.props?.children) || fallbackLabel;
|
|
4803
|
-
const element =
|
|
4856
|
+
const element = React6__default.default.cloneElement(node, {
|
|
4804
4857
|
...node.props,
|
|
4805
4858
|
hideText: true,
|
|
4806
4859
|
children: null
|
|
@@ -4811,7 +4864,7 @@ var renderIconOnlyButtons2 = (nodes) => {
|
|
|
4811
4864
|
if (node.props?.icon) {
|
|
4812
4865
|
const label = extractButtonLabel2(node.props?.children);
|
|
4813
4866
|
if (label) {
|
|
4814
|
-
const element =
|
|
4867
|
+
const element = React6__default.default.cloneElement(node, {
|
|
4815
4868
|
...node.props,
|
|
4816
4869
|
children: null
|
|
4817
4870
|
});
|
|
@@ -4819,15 +4872,15 @@ var renderIconOnlyButtons2 = (nodes) => {
|
|
|
4819
4872
|
}
|
|
4820
4873
|
}
|
|
4821
4874
|
if (node.props?.children) {
|
|
4822
|
-
const mappedChildren =
|
|
4823
|
-
return
|
|
4875
|
+
const mappedChildren = React6__default.default.Children.map(node.props.children, (child, childIndex) => enhanceNode(child, childIndex));
|
|
4876
|
+
return React6__default.default.cloneElement(node, {
|
|
4824
4877
|
...node.props,
|
|
4825
4878
|
children: mappedChildren
|
|
4826
4879
|
});
|
|
4827
4880
|
}
|
|
4828
4881
|
return node;
|
|
4829
4882
|
};
|
|
4830
|
-
return
|
|
4883
|
+
return React6__default.default.Children.map(nodes, (child, index) => enhanceNode(child, index));
|
|
4831
4884
|
};
|
|
4832
4885
|
var renderStandardShowHeaderButtons = ({
|
|
4833
4886
|
listButtonProps,
|
|
@@ -4848,8 +4901,8 @@ var useActionsWrapping = (headerButtons) => {
|
|
|
4848
4901
|
const isInMultiPane = Boolean(paneNav);
|
|
4849
4902
|
const isDetailPane = Boolean(paneNav && paneNav.paneIndex > 0);
|
|
4850
4903
|
const actionsPosition = viewSettings?.generalActionsButtonPosition || "top-right";
|
|
4851
|
-
const [verticalBarEl, setVerticalBarEl] =
|
|
4852
|
-
const [topRightEl, setTopRightEl] =
|
|
4904
|
+
const [verticalBarEl, setVerticalBarEl] = React6.useState(null);
|
|
4905
|
+
const [topRightEl, setTopRightEl] = React6.useState(null);
|
|
4853
4906
|
const wrappedHeaderButtons = (ctx) => {
|
|
4854
4907
|
const raw = typeof headerButtons === "function" ? headerButtons(ctx) : headerButtons;
|
|
4855
4908
|
if (actionsPosition === "top-right") {
|
|
@@ -4955,7 +5008,7 @@ var StandardCreate = ({ headerButtons, ...props }) => {
|
|
|
4955
5008
|
] });
|
|
4956
5009
|
};
|
|
4957
5010
|
function useKeyboardShortcuts(shortcuts) {
|
|
4958
|
-
|
|
5011
|
+
React6.useEffect(() => {
|
|
4959
5012
|
const handler = (e) => {
|
|
4960
5013
|
for (const shortcut of shortcuts) {
|
|
4961
5014
|
const keyMatch = e.key.toLowerCase() === shortcut.key.toLowerCase();
|
|
@@ -4991,7 +5044,7 @@ var wrappedPageTitleStyle2 = {
|
|
|
4991
5044
|
};
|
|
4992
5045
|
var renderWrappedPageTitle = (title) => {
|
|
4993
5046
|
if (title === null || title === void 0 || title === false) return title;
|
|
4994
|
-
return
|
|
5047
|
+
return React6__default.default.createElement("div", { style: wrappedPageTitleStyle2 }, title);
|
|
4995
5048
|
};
|
|
4996
5049
|
var numberFormatter = new Intl.NumberFormat(void 0, { maximumFractionDigits: 0 });
|
|
4997
5050
|
var decimalFormatter = new Intl.NumberFormat(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
@@ -5109,8 +5162,8 @@ var getSortPriority = (columnSort, fieldKey) => {
|
|
|
5109
5162
|
};
|
|
5110
5163
|
var _TOKEN_KEY = "jm_access_token";
|
|
5111
5164
|
function useAuthenticatedFileUrl(rawUrl) {
|
|
5112
|
-
const [src, setSrc] =
|
|
5113
|
-
|
|
5165
|
+
const [src, setSrc] = React6.useState("");
|
|
5166
|
+
React6.useEffect(() => {
|
|
5114
5167
|
if (!rawUrl) {
|
|
5115
5168
|
setSrc("");
|
|
5116
5169
|
return;
|
|
@@ -5571,7 +5624,7 @@ var ReferenceField = ({ id, resource, onLabel }) => {
|
|
|
5571
5624
|
const go = core.useGo();
|
|
5572
5625
|
const paneNav = usePaneNavigation();
|
|
5573
5626
|
const { token } = antd.theme.useToken();
|
|
5574
|
-
|
|
5627
|
+
React6.useEffect(() => {
|
|
5575
5628
|
if (onLabel && !isLoading && label !== void 0 && label !== null) {
|
|
5576
5629
|
onLabel(String(label));
|
|
5577
5630
|
}
|
|
@@ -5598,8 +5651,8 @@ var ReferenceField = ({ id, resource, onLabel }) => {
|
|
|
5598
5651
|
};
|
|
5599
5652
|
dayjs9__default.default.extend(relativeTime2__default.default);
|
|
5600
5653
|
var _8 = window._ || ((text) => text);
|
|
5601
|
-
var ReactMarkdown =
|
|
5602
|
-
var QRCodeSVG =
|
|
5654
|
+
var ReactMarkdown = React6.lazy(() => import('react-markdown').then((m) => ({ default: m.default })));
|
|
5655
|
+
var QRCodeSVG = React6.lazy(() => import('qrcode.react').then((m) => ({ default: m.QRCodeSVG })));
|
|
5603
5656
|
function formatDuration(totalSeconds) {
|
|
5604
5657
|
const h = Math.floor(totalSeconds / 3600);
|
|
5605
5658
|
const m = Math.floor(totalSeconds % 3600 / 60);
|
|
@@ -5635,7 +5688,7 @@ var renderFieldViewTypeReadOnly = (token, value, inTable) => {
|
|
|
5635
5688
|
}
|
|
5636
5689
|
);
|
|
5637
5690
|
case "read-only-markdown":
|
|
5638
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5691
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(antd.Skeleton.Input, { active: true, size: "small", style: { width: 200 } }), children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown, { children: str }) });
|
|
5639
5692
|
case "read-only-json": {
|
|
5640
5693
|
let formatted = str;
|
|
5641
5694
|
try {
|
|
@@ -5682,7 +5735,7 @@ var renderFieldViewTypeReadOnly = (token, value, inTable) => {
|
|
|
5682
5735
|
case "read-only-image-url":
|
|
5683
5736
|
return /* @__PURE__ */ jsxRuntime.jsx("a", { href: str, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: str, alt: "", style: { maxWidth: "100%", maxHeight: 200, objectFit: "contain", borderRadius: 4, display: "block" } }) });
|
|
5684
5737
|
case "read-only-qrcode":
|
|
5685
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5738
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(antd.Skeleton.Input, { active: true, size: "small", style: { width: 128 } }), children: /* @__PURE__ */ jsxRuntime.jsx(QRCodeSVG, { value: str, size: 128 }) });
|
|
5686
5739
|
case "read-only-relative": {
|
|
5687
5740
|
const parsed = dayjs9__default.default(str);
|
|
5688
5741
|
if (!parsed.isValid()) return str || "-";
|
|
@@ -5756,23 +5809,23 @@ var CrosstabTable = ({
|
|
|
5756
5809
|
editable
|
|
5757
5810
|
}) => {
|
|
5758
5811
|
const { token } = antd.theme.useToken();
|
|
5759
|
-
const modelField =
|
|
5812
|
+
const modelField = React6.useCallback(
|
|
5760
5813
|
(key) => key ? allFields.find((field) => field.key === key) : void 0,
|
|
5761
5814
|
[allFields]
|
|
5762
5815
|
);
|
|
5763
5816
|
const activeSeriesKeys = cellFieldKeys.length > 0 ? cellFieldKeys : [COUNT_KEY];
|
|
5764
|
-
const seriesLabel =
|
|
5817
|
+
const seriesLabel = React6.useCallback(
|
|
5765
5818
|
(seriesKey) => {
|
|
5766
5819
|
if (seriesKey === COUNT_KEY) return _9("Count");
|
|
5767
5820
|
return cellFieldLabels?.[seriesKey] || modelField(seriesKey)?.label || seriesKey;
|
|
5768
5821
|
},
|
|
5769
5822
|
[cellFieldLabels, modelField]
|
|
5770
5823
|
);
|
|
5771
|
-
const recordId =
|
|
5824
|
+
const recordId = React6.useCallback(
|
|
5772
5825
|
(record) => record?.[editable?.pkField || "eid"] ?? record?.eid ?? record?.id,
|
|
5773
5826
|
[editable?.pkField]
|
|
5774
5827
|
);
|
|
5775
|
-
const effectiveValue =
|
|
5828
|
+
const effectiveValue = React6.useCallback(
|
|
5776
5829
|
(record, fieldKey) => {
|
|
5777
5830
|
if (fieldKey === COUNT_KEY) return 1;
|
|
5778
5831
|
const staged = editable?.getStagedValue?.(recordId(record), fieldKey);
|
|
@@ -5783,7 +5836,7 @@ var CrosstabTable = ({
|
|
|
5783
5836
|
},
|
|
5784
5837
|
[editable, recordId]
|
|
5785
5838
|
);
|
|
5786
|
-
const summarize =
|
|
5839
|
+
const summarize = React6.useCallback(
|
|
5787
5840
|
(values) => {
|
|
5788
5841
|
if (values.length === 0) return 0;
|
|
5789
5842
|
switch (summaryFn) {
|
|
@@ -5811,7 +5864,7 @@ var CrosstabTable = ({
|
|
|
5811
5864
|
const rowFieldDef = modelField(rowField);
|
|
5812
5865
|
const hasColDimension = Boolean(colField);
|
|
5813
5866
|
const hasRowDimension = Boolean(rowField);
|
|
5814
|
-
const pivot =
|
|
5867
|
+
const pivot = React6.useMemo(() => {
|
|
5815
5868
|
const rowLabels2 = [];
|
|
5816
5869
|
const colLabels2 = [];
|
|
5817
5870
|
const cellRecords2 = /* @__PURE__ */ new Map();
|
|
@@ -5831,32 +5884,32 @@ var CrosstabTable = ({
|
|
|
5831
5884
|
return { rowLabels: rowLabels2, colLabels: colLabels2, cellRecords: cellRecords2 };
|
|
5832
5885
|
}, [rows, rowFieldDef, colFieldDef, hasColDimension, formatCategoryValue, activeSeriesKeys]);
|
|
5833
5886
|
const { rowLabels, colLabels, cellRecords } = pivot;
|
|
5834
|
-
const isAggregatedField =
|
|
5887
|
+
const isAggregatedField = React6.useCallback((seriesKey) => {
|
|
5835
5888
|
if (seriesKey === COUNT_KEY) return true;
|
|
5836
5889
|
const field = modelField(seriesKey);
|
|
5837
5890
|
return Boolean(field && field.type === "number" && !field.reference);
|
|
5838
5891
|
}, [modelField]);
|
|
5839
|
-
const cellAllRecords =
|
|
5892
|
+
const cellAllRecords = React6.useCallback(
|
|
5840
5893
|
(rowLabel, colLabel, seriesKey) => {
|
|
5841
5894
|
return cellRecords.get(`${rowLabel}::${colLabel}`)?.get(seriesKey) || [];
|
|
5842
5895
|
},
|
|
5843
5896
|
[cellRecords]
|
|
5844
5897
|
);
|
|
5845
|
-
const contributingRecords =
|
|
5898
|
+
const contributingRecords = React6.useCallback(
|
|
5846
5899
|
(rowLabel, colLabel, seriesKey) => {
|
|
5847
5900
|
const records = cellRecords.get(`${rowLabel}::${colLabel}`)?.get(seriesKey) || [];
|
|
5848
5901
|
return records.filter((rec) => effectiveValue(rec, seriesKey) !== null);
|
|
5849
5902
|
},
|
|
5850
5903
|
[cellRecords, effectiveValue]
|
|
5851
5904
|
);
|
|
5852
|
-
const cellAggregate =
|
|
5905
|
+
const cellAggregate = React6.useCallback(
|
|
5853
5906
|
(rowLabel, colLabel, seriesKey) => {
|
|
5854
5907
|
const values = contributingRecords(rowLabel, colLabel, seriesKey).map((rec) => effectiveValue(rec, seriesKey));
|
|
5855
5908
|
return values.length > 0 ? summarize(values) : null;
|
|
5856
5909
|
},
|
|
5857
5910
|
[contributingRecords, effectiveValue, summarize]
|
|
5858
5911
|
);
|
|
5859
|
-
const seriesMaxes =
|
|
5912
|
+
const seriesMaxes = React6.useMemo(() => {
|
|
5860
5913
|
return activeSeriesKeys.reduce((acc, seriesKey) => {
|
|
5861
5914
|
let maxForSeries = 0;
|
|
5862
5915
|
rowLabels.forEach((rowLabel) => {
|
|
@@ -5869,10 +5922,10 @@ var CrosstabTable = ({
|
|
|
5869
5922
|
return acc;
|
|
5870
5923
|
}, {});
|
|
5871
5924
|
}, [activeSeriesKeys, rowLabels, colLabels, cellAggregate]);
|
|
5872
|
-
const inputRefs =
|
|
5925
|
+
const inputRefs = React6.useRef(/* @__PURE__ */ new Map());
|
|
5873
5926
|
const cellAddr = (r, c) => `${r}:${c}`;
|
|
5874
5927
|
const editableColumns = colLabels.length * activeSeriesKeys.length;
|
|
5875
|
-
const focusCell =
|
|
5928
|
+
const focusCell = React6.useCallback((r, c) => {
|
|
5876
5929
|
if (r < 0 || c < 0 || r >= rowLabels.length || c >= editableColumns) return;
|
|
5877
5930
|
const el = inputRefs.current.get(cellAddr(r, c));
|
|
5878
5931
|
if (el) {
|
|
@@ -5880,7 +5933,7 @@ var CrosstabTable = ({
|
|
|
5880
5933
|
el.select?.();
|
|
5881
5934
|
}
|
|
5882
5935
|
}, [rowLabels.length, editableColumns]);
|
|
5883
|
-
const isSeriesEditable =
|
|
5936
|
+
const isSeriesEditable = React6.useCallback(
|
|
5884
5937
|
(rowLabel, colLabel, seriesKey) => {
|
|
5885
5938
|
if (!editable || seriesKey === COUNT_KEY || !isAggregatedField(seriesKey)) return false;
|
|
5886
5939
|
const n = contributingRecords(rowLabel, colLabel, seriesKey).length;
|
|
@@ -5890,7 +5943,7 @@ var CrosstabTable = ({
|
|
|
5890
5943
|
},
|
|
5891
5944
|
[editable, contributingRecords, summaryFn, isAggregatedField]
|
|
5892
5945
|
);
|
|
5893
|
-
const computeProration =
|
|
5946
|
+
const computeProration = React6.useCallback(
|
|
5894
5947
|
(records, seriesKey, newAggregate) => {
|
|
5895
5948
|
const round2 = (v) => Math.round((v + Number.EPSILON) * 100) / 100;
|
|
5896
5949
|
const n = records.length;
|
|
@@ -5922,7 +5975,7 @@ var CrosstabTable = ({
|
|
|
5922
5975
|
},
|
|
5923
5976
|
[recordId, effectiveValue, summaryFn]
|
|
5924
5977
|
);
|
|
5925
|
-
const commitCellEdit =
|
|
5978
|
+
const commitCellEdit = React6.useCallback(
|
|
5926
5979
|
(rowLabel, colLabel, seriesKey, newAggregate) => {
|
|
5927
5980
|
if (!editable || newAggregate === null || Number.isNaN(newAggregate)) return;
|
|
5928
5981
|
const records = contributingRecords(rowLabel, colLabel, seriesKey);
|
|
@@ -7378,25 +7431,25 @@ var ExecutableHtml = ({
|
|
|
7378
7431
|
inheritTabRowBackground = false,
|
|
7379
7432
|
fontSizeOverride
|
|
7380
7433
|
}) => {
|
|
7381
|
-
const htmlRef =
|
|
7382
|
-
const iframeRef =
|
|
7383
|
-
const observerRef =
|
|
7384
|
-
const appendedChunksRef =
|
|
7385
|
-
const scriptIdRef =
|
|
7386
|
-
const syncHeightTimerRef =
|
|
7387
|
-
const lastSetHeightRef =
|
|
7388
|
-
const [fontFamily, setFontFamily] =
|
|
7389
|
-
const [fontSize, setFontSize] =
|
|
7390
|
-
const [lineHeight, setLineHeight] =
|
|
7391
|
-
const [tabRowBackground, setTabRowBackground] =
|
|
7392
|
-
const { mode: colorMode } =
|
|
7434
|
+
const htmlRef = React6.useRef(null);
|
|
7435
|
+
const iframeRef = React6.useRef(null);
|
|
7436
|
+
const observerRef = React6.useRef(null);
|
|
7437
|
+
const appendedChunksRef = React6.useRef(0);
|
|
7438
|
+
const scriptIdRef = React6.useRef(0);
|
|
7439
|
+
const syncHeightTimerRef = React6.useRef(null);
|
|
7440
|
+
const lastSetHeightRef = React6.useRef(0);
|
|
7441
|
+
const [fontFamily, setFontFamily] = React6.useState("Arial, sans-serif");
|
|
7442
|
+
const [fontSize, setFontSize] = React6.useState("14px");
|
|
7443
|
+
const [lineHeight, setLineHeight] = React6.useState("1.5715");
|
|
7444
|
+
const [tabRowBackground, setTabRowBackground] = React6.useState("#fafafa");
|
|
7445
|
+
const { mode: colorMode } = React6.useContext(ColorModeContext);
|
|
7393
7446
|
const isDark = colorMode === "dark";
|
|
7394
|
-
|
|
7395
|
-
const instanceId =
|
|
7396
|
-
const htmlRefForEffect =
|
|
7447
|
+
React6.useRef(performance.now());
|
|
7448
|
+
const instanceId = React6.useRef(Math.random().toString(36).slice(2, 6));
|
|
7449
|
+
const htmlRefForEffect = React6.useRef(html);
|
|
7397
7450
|
htmlRefForEffect.current = html;
|
|
7398
7451
|
traceLog("ExecutableHtml", `[${instanceId.current}] mount mode=${mode} title=${title} htmlLen=${(html || "").length}`);
|
|
7399
|
-
const executeScriptNodesSequentially =
|
|
7452
|
+
const executeScriptNodesSequentially = React6.useCallback(async (doc, scriptNodes, isCancelled) => {
|
|
7400
7453
|
for (const oldScript of scriptNodes) {
|
|
7401
7454
|
if (isCancelled?.()) return;
|
|
7402
7455
|
const newScript = doc.createElement("script");
|
|
@@ -7418,7 +7471,7 @@ var ExecutableHtml = ({
|
|
|
7418
7471
|
});
|
|
7419
7472
|
}
|
|
7420
7473
|
}, []);
|
|
7421
|
-
|
|
7474
|
+
React6.useEffect(() => {
|
|
7422
7475
|
if (mode !== "inline") return;
|
|
7423
7476
|
const container = htmlRef.current;
|
|
7424
7477
|
if (!container || !html) return;
|
|
@@ -7429,7 +7482,7 @@ var ExecutableHtml = ({
|
|
|
7429
7482
|
cancelled = true;
|
|
7430
7483
|
};
|
|
7431
7484
|
}, [html, mode, executeScriptNodesSequentially]);
|
|
7432
|
-
|
|
7485
|
+
React6.useEffect(() => {
|
|
7433
7486
|
if (mode !== "iframe") return;
|
|
7434
7487
|
if (!inheritTypography && !inheritTabRowBackground) return;
|
|
7435
7488
|
if (typeof window === "undefined") return;
|
|
@@ -7455,7 +7508,7 @@ var ExecutableHtml = ({
|
|
|
7455
7508
|
if (resolvedBg) setTabRowBackground(resolvedBg);
|
|
7456
7509
|
}
|
|
7457
7510
|
}, [inheritTabRowBackground, inheritTypography, mode]);
|
|
7458
|
-
const htmlShell =
|
|
7511
|
+
const htmlShell = React6.useMemo(() => `<!doctype html>
|
|
7459
7512
|
<html>
|
|
7460
7513
|
<head>
|
|
7461
7514
|
<meta charset="utf-8" />
|
|
@@ -7486,7 +7539,7 @@ body, table, th, td, input, button, select, textarea, div, span, p, li, ul, ol {
|
|
|
7486
7539
|
</head>
|
|
7487
7540
|
<body></body>
|
|
7488
7541
|
</html>`, [fontFamily, fontSize, lineHeight, tabRowBackground, isDark]);
|
|
7489
|
-
const syncHeight =
|
|
7542
|
+
const syncHeight = React6.useCallback(() => {
|
|
7490
7543
|
if (syncHeightTimerRef.current) clearTimeout(syncHeightTimerRef.current);
|
|
7491
7544
|
syncHeightTimerRef.current = setTimeout(() => {
|
|
7492
7545
|
syncHeightTimerRef.current = null;
|
|
@@ -7504,7 +7557,7 @@ body, table, th, td, input, button, select, textarea, div, span, p, li, ul, ol {
|
|
|
7504
7557
|
iframe.style.height = `${nextHeight}px`;
|
|
7505
7558
|
}, 100);
|
|
7506
7559
|
}, [minHeight]);
|
|
7507
|
-
const appendHtmlChunk =
|
|
7560
|
+
const appendHtmlChunk = React6.useCallback(async (chunk) => {
|
|
7508
7561
|
const doc = iframeRef.current?.contentDocument;
|
|
7509
7562
|
if (!doc || !doc.body || !chunk) return false;
|
|
7510
7563
|
const host = doc.createElement("div");
|
|
@@ -7525,7 +7578,7 @@ body, table, th, td, input, button, select, textarea, div, span, p, li, ul, ol {
|
|
|
7525
7578
|
syncHeight();
|
|
7526
7579
|
return true;
|
|
7527
7580
|
}, [syncHeight, executeScriptNodesSequentially]);
|
|
7528
|
-
|
|
7581
|
+
React6.useEffect(() => {
|
|
7529
7582
|
if (mode !== "iframe") return;
|
|
7530
7583
|
const iframe = iframeRef.current;
|
|
7531
7584
|
if (!iframe) return;
|
|
@@ -7568,7 +7621,7 @@ body, table, th, td, input, button, select, textarea, div, span, p, li, ul, ol {
|
|
|
7568
7621
|
iframe.removeEventListener("load", onLoad);
|
|
7569
7622
|
};
|
|
7570
7623
|
}, [htmlShell, resetToken, appendHtmlChunk, syncHeight, mode]);
|
|
7571
|
-
|
|
7624
|
+
React6.useEffect(() => {
|
|
7572
7625
|
if (mode !== "iframe") return;
|
|
7573
7626
|
if (!htmlChunks || htmlChunks.length <= appendedChunksRef.current) return;
|
|
7574
7627
|
const nextChunks = htmlChunks.slice(appendedChunksRef.current);
|
|
@@ -7580,14 +7633,14 @@ body, table, th, td, input, button, select, textarea, div, span, p, li, ul, ol {
|
|
|
7580
7633
|
appendedChunksRef.current += appendedCount;
|
|
7581
7634
|
})();
|
|
7582
7635
|
}, [htmlChunks, appendHtmlChunk, mode]);
|
|
7583
|
-
|
|
7636
|
+
React6.useEffect(() => {
|
|
7584
7637
|
return () => {
|
|
7585
7638
|
if (observerRef.current) observerRef.current.disconnect();
|
|
7586
7639
|
observerRef.current = null;
|
|
7587
7640
|
if (syncHeightTimerRef.current) clearTimeout(syncHeightTimerRef.current);
|
|
7588
7641
|
};
|
|
7589
7642
|
}, []);
|
|
7590
|
-
const inlineHtml =
|
|
7643
|
+
const inlineHtml = React6.useMemo(
|
|
7591
7644
|
() => (html || "").replace(
|
|
7592
7645
|
/<script\b[^>]*\bsrc=["']?[^"'>]*cdn\.plot\.ly[^"'>]*["']?[^>]*><\/script>/gi,
|
|
7593
7646
|
""
|
|
@@ -7671,23 +7724,23 @@ var MetadataModal = ({ model, allModels, open, onClose }) => {
|
|
|
7671
7724
|
const apiUrl = core.useApiUrl();
|
|
7672
7725
|
const tone = useModelTone(model);
|
|
7673
7726
|
const modelLabel = getModelLabel(model);
|
|
7674
|
-
const [nestedModel, setNestedModel] =
|
|
7675
|
-
const [activeTab, setActiveTab] =
|
|
7676
|
-
const [graphHtml, setGraphHtml] =
|
|
7677
|
-
const [graphLoading, setGraphLoading] =
|
|
7678
|
-
const [graphError, setGraphError] =
|
|
7679
|
-
|
|
7727
|
+
const [nestedModel, setNestedModel] = React6.useState(null);
|
|
7728
|
+
const [activeTab, setActiveTab] = React6.useState("fields");
|
|
7729
|
+
const [graphHtml, setGraphHtml] = React6.useState(null);
|
|
7730
|
+
const [graphLoading, setGraphLoading] = React6.useState(false);
|
|
7731
|
+
const [graphError, setGraphError] = React6.useState(null);
|
|
7732
|
+
React6.useEffect(() => {
|
|
7680
7733
|
setGraphHtml(null);
|
|
7681
7734
|
setGraphError(null);
|
|
7682
7735
|
}, [model.name]);
|
|
7683
|
-
const findRelatedModel =
|
|
7736
|
+
const findRelatedModel = React6.useCallback((name) => {
|
|
7684
7737
|
if (!name || !allModels) return void 0;
|
|
7685
7738
|
const lower = name.toLowerCase();
|
|
7686
7739
|
return allModels.find(
|
|
7687
7740
|
(m) => (m.name || "").toLowerCase() === lower || (m.resource || "").toLowerCase() === lower
|
|
7688
7741
|
);
|
|
7689
7742
|
}, [allModels]);
|
|
7690
|
-
const loadGraph =
|
|
7743
|
+
const loadGraph = React6.useCallback(async () => {
|
|
7691
7744
|
if (graphHtml !== null || graphLoading) return;
|
|
7692
7745
|
setGraphLoading(true);
|
|
7693
7746
|
setGraphError(null);
|
|
@@ -7723,13 +7776,13 @@ var MetadataModal = ({ model, allModels, open, onClose }) => {
|
|
|
7723
7776
|
setGraphLoading(false);
|
|
7724
7777
|
}
|
|
7725
7778
|
}, [apiUrl, model, modelLabel, graphHtml, graphLoading, findRelatedModel]);
|
|
7726
|
-
|
|
7779
|
+
React6.useEffect(() => {
|
|
7727
7780
|
if (activeTab === "knowledge_graph") {
|
|
7728
7781
|
loadGraph();
|
|
7729
7782
|
}
|
|
7730
7783
|
}, [activeTab, loadGraph]);
|
|
7731
7784
|
const navigate = reactRouterDom.useNavigate();
|
|
7732
|
-
|
|
7785
|
+
React6.useEffect(() => {
|
|
7733
7786
|
const handler = (e) => {
|
|
7734
7787
|
if (e.data?.action === "metadata_graph_navigate" && e.data?.url) {
|
|
7735
7788
|
onClose();
|
|
@@ -7969,7 +8022,7 @@ var MetadataModal = ({ model, allModels, open, onClose }) => {
|
|
|
7969
8022
|
};
|
|
7970
8023
|
var _13 = window._ || ((text) => text);
|
|
7971
8024
|
var useMetadataModal = (model, allModels) => {
|
|
7972
|
-
const [metadataOpen, setMetadataOpen] =
|
|
8025
|
+
const [metadataOpen, setMetadataOpen] = React6.useState(false);
|
|
7973
8026
|
const metadataButton = /* @__PURE__ */ jsxRuntime.jsx(antd.Tooltip, { title: _13("Metadata"), children: /* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", icon: /* @__PURE__ */ jsxRuntime.jsx(AntDIcons2.InfoCircleOutlined, {}), onClick: () => setMetadataOpen(true) }) });
|
|
7974
8027
|
const metadataModal = /* @__PURE__ */ jsxRuntime.jsx(MetadataModal, { model, allModels, open: metadataOpen, onClose: () => setMetadataOpen(false) });
|
|
7975
8028
|
return { metadataButton, metadataModal };
|
|
@@ -7989,7 +8042,7 @@ var useShowEditableForm = (resource, id) => {
|
|
|
7989
8042
|
});
|
|
7990
8043
|
const record = queryResult?.data?.data;
|
|
7991
8044
|
const recordId = record?.eid ?? record?.id ?? id;
|
|
7992
|
-
useKeyboardShortcuts(
|
|
8045
|
+
useKeyboardShortcuts(React6.useMemo(() => [
|
|
7993
8046
|
{ key: "s", ctrl: true, handler: () => formProps?.form?.submit() },
|
|
7994
8047
|
{ key: "Escape", handler: () => navigate(-1) }
|
|
7995
8048
|
], [formProps?.form, navigate]));
|
|
@@ -8057,7 +8110,7 @@ var renderModelHeading = ({
|
|
|
8057
8110
|
paddingLeft: 10,
|
|
8058
8111
|
paddingRight: 10
|
|
8059
8112
|
},
|
|
8060
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minWidth: 0, fontSize:
|
|
8113
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minWidth: 0, fontSize: 18, fontWeight: 700, color: tone.solid, padding: "2px 8px" }, children: title })
|
|
8061
8114
|
}
|
|
8062
8115
|
);
|
|
8063
8116
|
};
|
|
@@ -8198,14 +8251,14 @@ var RelationsExplorer = ({ model, record, allModels, isActive = true }) => {
|
|
|
8198
8251
|
const apiUrl = core.useApiUrl();
|
|
8199
8252
|
const go = core.useGo();
|
|
8200
8253
|
const paneNav = usePaneNavigation();
|
|
8201
|
-
const [reverseTreeData, setReverseTreeData] =
|
|
8202
|
-
const [forwardTreeData, setForwardTreeData] =
|
|
8203
|
-
const [loading, setLoading] =
|
|
8254
|
+
const [reverseTreeData, setReverseTreeData] = React6.useState([]);
|
|
8255
|
+
const [forwardTreeData, setForwardTreeData] = React6.useState([]);
|
|
8256
|
+
const [loading, setLoading] = React6.useState(true);
|
|
8204
8257
|
const isReverse = (rel) => {
|
|
8205
8258
|
if (rel.relationName && rel.relationName.endsWith("_reverse")) return true;
|
|
8206
8259
|
return !rel.otherResource;
|
|
8207
8260
|
};
|
|
8208
|
-
|
|
8261
|
+
React6.useEffect(() => {
|
|
8209
8262
|
if (!isActive) {
|
|
8210
8263
|
setLoading(false);
|
|
8211
8264
|
return;
|
|
@@ -8375,9 +8428,9 @@ var RelationsExplorer = ({ model, record, allModels, isActive = true }) => {
|
|
|
8375
8428
|
] });
|
|
8376
8429
|
};
|
|
8377
8430
|
function usePinRecord(resource, recordId) {
|
|
8378
|
-
const [pinned, setPinned] =
|
|
8379
|
-
const [loading, setLoading] =
|
|
8380
|
-
|
|
8431
|
+
const [pinned, setPinned] = React6.useState(null);
|
|
8432
|
+
const [loading, setLoading] = React6.useState(false);
|
|
8433
|
+
React6.useEffect(() => {
|
|
8381
8434
|
if (!resource || recordId === void 0 || recordId === null || recordId === "") return;
|
|
8382
8435
|
let cancelled = false;
|
|
8383
8436
|
authenticatedFetch(
|
|
@@ -8391,7 +8444,7 @@ function usePinRecord(resource, recordId) {
|
|
|
8391
8444
|
cancelled = true;
|
|
8392
8445
|
};
|
|
8393
8446
|
}, [resource, recordId]);
|
|
8394
|
-
const pin =
|
|
8447
|
+
const pin = React6.useCallback(async () => {
|
|
8395
8448
|
if (!resource || recordId === void 0) return;
|
|
8396
8449
|
setLoading(true);
|
|
8397
8450
|
try {
|
|
@@ -8405,7 +8458,7 @@ function usePinRecord(resource, recordId) {
|
|
|
8405
8458
|
setLoading(false);
|
|
8406
8459
|
}
|
|
8407
8460
|
}, [resource, recordId]);
|
|
8408
|
-
const unpin =
|
|
8461
|
+
const unpin = React6.useCallback(async () => {
|
|
8409
8462
|
if (!resource || recordId === void 0) return;
|
|
8410
8463
|
setLoading(true);
|
|
8411
8464
|
try {
|
|
@@ -8418,7 +8471,7 @@ function usePinRecord(resource, recordId) {
|
|
|
8418
8471
|
setLoading(false);
|
|
8419
8472
|
}
|
|
8420
8473
|
}, [resource, recordId]);
|
|
8421
|
-
const toggle =
|
|
8474
|
+
const toggle = React6.useCallback(() => pinned ? unpin() : pin(), [pinned, pin, unpin]);
|
|
8422
8475
|
return { pinned, loading, pin, unpin, toggle };
|
|
8423
8476
|
}
|
|
8424
8477
|
async function unpinRecords(resource, recordIds) {
|
|
@@ -8434,17 +8487,17 @@ async function unpinRecords(resource, recordIds) {
|
|
|
8434
8487
|
var _17 = window._ || ((text) => text);
|
|
8435
8488
|
var useShowActionsPreferences = (model, allModels, record, saveButtonProps, configureLayoutButtonRef, saveLayoutRef) => {
|
|
8436
8489
|
const apiUrl = core.useApiUrl();
|
|
8437
|
-
const allModelsList =
|
|
8438
|
-
const [showRelationActions, setShowRelationActions] =
|
|
8439
|
-
const [showRelationCreate, setShowRelationCreate] =
|
|
8440
|
-
const [isSavingActionsPrefs, setIsSavingActionsPrefs] =
|
|
8441
|
-
const actionsPrefsTouchedRef =
|
|
8442
|
-
const actionsPrefsLoadedRef =
|
|
8443
|
-
const actionsPrefsResourceRef =
|
|
8444
|
-
const markActionsPrefsTouched =
|
|
8490
|
+
const allModelsList = React6.useMemo(() => allModels || [], [allModels]);
|
|
8491
|
+
const [showRelationActions, setShowRelationActions] = React6.useState(DEFAULT_SHOW_RELATION_ROW_ACTIONS);
|
|
8492
|
+
const [showRelationCreate, setShowRelationCreate] = React6.useState(DEFAULT_RELATION_CREATE_ACTIONS);
|
|
8493
|
+
const [isSavingActionsPrefs, setIsSavingActionsPrefs] = React6.useState(false);
|
|
8494
|
+
const actionsPrefsTouchedRef = React6.useRef(false);
|
|
8495
|
+
const actionsPrefsLoadedRef = React6.useRef(false);
|
|
8496
|
+
const actionsPrefsResourceRef = React6.useRef(null);
|
|
8497
|
+
const markActionsPrefsTouched = React6.useCallback(() => {
|
|
8445
8498
|
actionsPrefsTouchedRef.current = true;
|
|
8446
8499
|
}, []);
|
|
8447
|
-
const saveActionsPreferences =
|
|
8500
|
+
const saveActionsPreferences = React6.useCallback(async () => {
|
|
8448
8501
|
const resourceKey = resolveResourcePath(model.resource || model.name, allModelsList);
|
|
8449
8502
|
const preferences = {
|
|
8450
8503
|
showActions: showRelationActions,
|
|
@@ -8467,7 +8520,7 @@ var useShowActionsPreferences = (model, allModels, record, saveButtonProps, conf
|
|
|
8467
8520
|
setIsSavingActionsPrefs(false);
|
|
8468
8521
|
}
|
|
8469
8522
|
}, [apiUrl, allModelsList, model.name, model.resource, showRelationActions, showRelationCreate]);
|
|
8470
|
-
|
|
8523
|
+
React6.useEffect(() => {
|
|
8471
8524
|
const resourceKey = resolveResourcePath(model.resource || model.name, allModelsList);
|
|
8472
8525
|
if (actionsPrefsResourceRef.current !== resourceKey) {
|
|
8473
8526
|
actionsPrefsLoadedRef.current = false;
|
|
@@ -8552,7 +8605,7 @@ var useShowActionsPreferences = (model, allModels, record, saveButtonProps, conf
|
|
|
8552
8605
|
const resource = model.resource || model.name;
|
|
8553
8606
|
const { pinned, loading: pinLoading, toggle: togglePin } = usePinRecord(resource, recordId);
|
|
8554
8607
|
const { metadataButton, metadataModal } = useMetadataModal(model, allModels);
|
|
8555
|
-
const [exploreOpen, setExploreOpen] =
|
|
8608
|
+
const [exploreOpen, setExploreOpen] = React6.useState(false);
|
|
8556
8609
|
const headerButtons = ({ defaultButtons }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8557
8610
|
metadataButton,
|
|
8558
8611
|
metadataModal,
|
|
@@ -8589,7 +8642,7 @@ var useShowActionsPreferences = (model, allModels, record, saveButtonProps, conf
|
|
|
8589
8642
|
headerButtons
|
|
8590
8643
|
};
|
|
8591
8644
|
};
|
|
8592
|
-
var PrimaryShowContext =
|
|
8645
|
+
var PrimaryShowContext = React6__default.default.createContext(null);
|
|
8593
8646
|
|
|
8594
8647
|
// src/components/DynamicResource/utils/columnFilters.ts
|
|
8595
8648
|
var truncateLabel = (s) => s.length > 15 ? s.substring(0, 15) + "\u2026" : s;
|
|
@@ -8812,8 +8865,8 @@ function filterFieldsByRole(fields, userRoles) {
|
|
|
8812
8865
|
});
|
|
8813
8866
|
}
|
|
8814
8867
|
function useRoleFilteredModel(model) {
|
|
8815
|
-
const userRoles =
|
|
8816
|
-
return
|
|
8868
|
+
const userRoles = React6.useMemo(() => getCurrentUserRoles(), []);
|
|
8869
|
+
return React6.useMemo(() => {
|
|
8817
8870
|
const filtered = filterFieldsByRole(model.fields, userRoles);
|
|
8818
8871
|
if (filtered.length === model.fields.length) return model;
|
|
8819
8872
|
return { ...model, fields: filtered };
|
|
@@ -8824,7 +8877,7 @@ var DynamicShow = ({ model: modelProp, allModels, idOverride, embedded, beforeTa
|
|
|
8824
8877
|
const model = useRoleFilteredModel(modelProp);
|
|
8825
8878
|
applyI18nLabelsToModel(model);
|
|
8826
8879
|
applyI18nLabelsToModels(allModels);
|
|
8827
|
-
const allModelsList =
|
|
8880
|
+
const allModelsList = React6.useMemo(() => allModels || [], [allModels]);
|
|
8828
8881
|
const modelTone = useModelTone(model);
|
|
8829
8882
|
const modelDisplayLabel = asDisplayText(model.label, asDisplayText(model.name, "Record"));
|
|
8830
8883
|
const { id: routeId } = reactRouterDom.useParams();
|
|
@@ -8832,9 +8885,9 @@ var DynamicShow = ({ model: modelProp, allModels, idOverride, embedded, beforeTa
|
|
|
8832
8885
|
const { formProps, saveButtonProps, record, recordId } = useShowEditableForm(model.resource || model.name, id);
|
|
8833
8886
|
const { formProps: showFormProps, effectiveFields } = buildShowTabFormOptions(formProps, model, allModels);
|
|
8834
8887
|
const pageTitle = record?._label ? asDisplayText(record._label, `${_19("Show")} ${modelDisplayLabel}`) : `${_19("Show")} ${modelDisplayLabel}`;
|
|
8835
|
-
const saveLayoutRef =
|
|
8888
|
+
const saveLayoutRef = React6.useRef(() => {
|
|
8836
8889
|
});
|
|
8837
|
-
const configureLayoutButtonRef =
|
|
8890
|
+
const configureLayoutButtonRef = React6.useRef(null);
|
|
8838
8891
|
const wrappedSaveButtonProps = saveButtonProps ? {
|
|
8839
8892
|
...saveButtonProps,
|
|
8840
8893
|
onClick: (e) => {
|
|
@@ -8845,7 +8898,7 @@ var DynamicShow = ({ model: modelProp, allModels, idOverride, embedded, beforeTa
|
|
|
8845
8898
|
const { data: canLayoutData } = core.useCan({ resource: "veloiq_layout", action: "configure_layout" });
|
|
8846
8899
|
const canConfigureLayout = canLayoutData?.can !== false;
|
|
8847
8900
|
const { actionsState, headerButtons } = useShowActionsPreferences(model, allModels, record, wrappedSaveButtonProps, configureLayoutButtonRef, saveLayoutRef);
|
|
8848
|
-
const [activeTabKey, setActiveTabKey] =
|
|
8901
|
+
const [activeTabKey, setActiveTabKey] = React6.useState("details");
|
|
8849
8902
|
const { tabs: items, layoutConfig } = useStandardShowTabs(
|
|
8850
8903
|
model,
|
|
8851
8904
|
record,
|
|
@@ -8866,12 +8919,12 @@ var DynamicShow = ({ model: modelProp, allModels, idOverride, embedded, beforeTa
|
|
|
8866
8919
|
}
|
|
8867
8920
|
)
|
|
8868
8921
|
] }) : null;
|
|
8869
|
-
|
|
8922
|
+
React6.useEffect(() => {
|
|
8870
8923
|
if (!items.find((item) => item.key === activeTabKey)) {
|
|
8871
8924
|
setActiveTabKey(items[0]?.key || "details");
|
|
8872
8925
|
}
|
|
8873
8926
|
}, [activeTabKey, items]);
|
|
8874
|
-
const lazyItems =
|
|
8927
|
+
const lazyItems = React6.useMemo(
|
|
8875
8928
|
() => items.map((item) => ({
|
|
8876
8929
|
...item,
|
|
8877
8930
|
children: item.key === activeTabKey ? item.children : null
|
|
@@ -8934,7 +8987,7 @@ var RelationSelect = ({ field, value, onChange, allModels, multiple, serverSearc
|
|
|
8934
8987
|
const resolvedResource = resourceName && allModels ? resolveResourcePath(resourceName, allModels) : resourceName;
|
|
8935
8988
|
const referencedModel = resourceName ? findModelByName(allModels, resourceName) : void 0;
|
|
8936
8989
|
const resolvedOptionValue = field.optionValue || referencedModel?.pkField || "eid";
|
|
8937
|
-
const [loadAll, setLoadAll] =
|
|
8990
|
+
const [loadAll, setLoadAll] = React6__default.default.useState(false);
|
|
8938
8991
|
const pageSize = loadAll ? 999999 : RELATION_SELECT_DEFAULT_PAGE_SIZE;
|
|
8939
8992
|
const { selectProps, queryResult } = antd$1.useSelect({
|
|
8940
8993
|
resource: resolvedResource,
|
|
@@ -8951,8 +9004,8 @@ var RelationSelect = ({ field, value, onChange, allModels, multiple, serverSearc
|
|
|
8951
9004
|
const loadedCount = filteredOptions?.length ?? 0;
|
|
8952
9005
|
const isCapped = !loadAll && serverTotal > loadedCount && loadedCount > 0;
|
|
8953
9006
|
const normalizeSearch = (val) => String(val ?? "").toLowerCase();
|
|
8954
|
-
const selectedSet =
|
|
8955
|
-
const [searchValue, setSearchValue] =
|
|
9007
|
+
const selectedSet = React6__default.default.useMemo(() => new Set(Array.isArray(value) ? value : value !== void 0 && value !== null ? [value] : []), [value]);
|
|
9008
|
+
const [searchValue, setSearchValue] = React6__default.default.useState("");
|
|
8956
9009
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8957
9010
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8958
9011
|
antd.Select,
|
|
@@ -8999,8 +9052,8 @@ var RelationSelect = ({ field, value, onChange, allModels, multiple, serverSearc
|
|
|
8999
9052
|
var _21 = window._ || ((text) => text);
|
|
9000
9053
|
var FileUploadInput = ({ value: _value, onChange: _onChange }) => {
|
|
9001
9054
|
const form = antd.Form.useFormInstance();
|
|
9002
|
-
const [uploading, setUploading] =
|
|
9003
|
-
const [fileName, setFileName] =
|
|
9055
|
+
const [uploading, setUploading] = React6.useState(false);
|
|
9056
|
+
const [fileName, setFileName] = React6.useState(null);
|
|
9004
9057
|
const currentDataName = antd.Form.useWatch("data_name", form);
|
|
9005
9058
|
const handleUpload = async (file) => {
|
|
9006
9059
|
const recordId = form.getFieldValue("eid") ?? form.getFieldValue("id");
|
|
@@ -9066,9 +9119,9 @@ var AsyncSelectInput = ({
|
|
|
9066
9119
|
onChange
|
|
9067
9120
|
}) => {
|
|
9068
9121
|
const apiUrl = core.useApiUrl();
|
|
9069
|
-
const [options, setOptions] =
|
|
9070
|
-
const [loading, setLoading] =
|
|
9071
|
-
|
|
9122
|
+
const [options, setOptions] = React6.useState([]);
|
|
9123
|
+
const [loading, setLoading] = React6.useState(false);
|
|
9124
|
+
React6.useEffect(() => {
|
|
9072
9125
|
let cancelled = false;
|
|
9073
9126
|
setLoading(true);
|
|
9074
9127
|
const fetchOptions = async () => {
|
|
@@ -9125,9 +9178,9 @@ var AsyncSelectInput = ({
|
|
|
9125
9178
|
);
|
|
9126
9179
|
};
|
|
9127
9180
|
var _23 = window._ || ((text) => text);
|
|
9128
|
-
var ReactMarkdown2 =
|
|
9181
|
+
var ReactMarkdown2 = React6.lazy(() => import('react-markdown').then((m) => ({ default: m.default })));
|
|
9129
9182
|
var MarkdownEditor = ({ value = "", onChange }) => {
|
|
9130
|
-
const [activeTab, setActiveTab] =
|
|
9183
|
+
const [activeTab, setActiveTab] = React6.useState("edit");
|
|
9131
9184
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9132
9185
|
antd.Tabs,
|
|
9133
9186
|
{
|
|
@@ -9152,14 +9205,14 @@ var MarkdownEditor = ({ value = "", onChange }) => {
|
|
|
9152
9205
|
{
|
|
9153
9206
|
key: "preview",
|
|
9154
9207
|
label: _23("Preview"),
|
|
9155
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 60, padding: "4px 0" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9208
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: 60, padding: "4px 0" }, children: /* @__PURE__ */ jsxRuntime.jsx(React6.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(antd.Skeleton.Input, { active: true, size: "small", style: { width: 200 } }), children: /* @__PURE__ */ jsxRuntime.jsx(ReactMarkdown2, { children: value }) }) })
|
|
9156
9209
|
}
|
|
9157
9210
|
]
|
|
9158
9211
|
}
|
|
9159
9212
|
);
|
|
9160
9213
|
};
|
|
9161
9214
|
var JsonEditor = ({ value = "", onChange }) => {
|
|
9162
|
-
const [error, setError] =
|
|
9215
|
+
const [error, setError] = React6.useState(null);
|
|
9163
9216
|
const handleChange = (e) => {
|
|
9164
9217
|
const raw = e.target.value;
|
|
9165
9218
|
onChange?.(raw);
|
|
@@ -9326,7 +9379,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9326
9379
|
const { token } = antd.theme.useToken();
|
|
9327
9380
|
const modelTone = useModelTone(model);
|
|
9328
9381
|
const { settings: viewSettings, loading: viewSettingsLoading } = useViewSettings();
|
|
9329
|
-
const allModelsList =
|
|
9382
|
+
const allModelsList = React6.useMemo(() => allModels || [], [allModels]);
|
|
9330
9383
|
const { rows: editConfigRows, loading: editConfigLoading } = useViewConfigurations(model.name, "AutomaticEntityForm");
|
|
9331
9384
|
const { rows: fallbackConfigRows, loading: fallbackConfigLoading } = useViewConfigurations(model.name, "PrimaryView");
|
|
9332
9385
|
const valueBackground = isDarkColor2(token.colorBgBase || token.colorBgContainer) ? token.colorFillQuaternary : "#F9FFFF";
|
|
@@ -9340,12 +9393,12 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9340
9393
|
const relateOtherKey = searchParams.get("relate_other_key");
|
|
9341
9394
|
const relateTargetId = searchParams.get("relate_target_id");
|
|
9342
9395
|
const canAutoRelate = Boolean(relateResource && relateTargetKey && relateOtherKey && relateTargetId);
|
|
9343
|
-
const [createdRecord, setCreatedRecord] =
|
|
9344
|
-
const [showRelationActions, setShowRelationActions] =
|
|
9345
|
-
const [showRelationCreate, setShowRelationCreate] =
|
|
9346
|
-
const [activeTabKey, setActiveTabKey] =
|
|
9396
|
+
const [createdRecord, setCreatedRecord] = React6.useState(null);
|
|
9397
|
+
const [showRelationActions, setShowRelationActions] = React6.useState(DEFAULT_EDIT_RELATION_ROW_ACTIONS);
|
|
9398
|
+
const [showRelationCreate, setShowRelationCreate] = React6.useState(DEFAULT_RELATION_CREATE_ACTIONS);
|
|
9399
|
+
const [activeTabKey, setActiveTabKey] = React6.useState("main_data");
|
|
9347
9400
|
const isPostCreate = createdRecord !== null;
|
|
9348
|
-
const relationViewTypeDefaults =
|
|
9401
|
+
const relationViewTypeDefaults = React6.useMemo(
|
|
9349
9402
|
() => ({
|
|
9350
9403
|
show: normalizeRelationViewType(viewSettings?.showViewType || "") || "totals-details",
|
|
9351
9404
|
edit: normalizeRelationViewType(viewSettings?.editViewType || "") || "editable-table"
|
|
@@ -9353,11 +9406,11 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9353
9406
|
[viewSettings?.showViewType, viewSettings?.editViewType]
|
|
9354
9407
|
);
|
|
9355
9408
|
const modelDisplayLabel = asDisplayText(model.label, asDisplayText(model.name, "Record"));
|
|
9356
|
-
const isLinkModel =
|
|
9409
|
+
const isLinkModel = React6.useMemo(() => {
|
|
9357
9410
|
const fieldKeys = model.fields.map((f) => f.key);
|
|
9358
9411
|
return fieldKeys.includes("eid_from") && fieldKeys.includes("eid_to") && searchParams.has("eid_from");
|
|
9359
9412
|
}, [model.fields, searchParams]);
|
|
9360
|
-
const [serverDefaults, setServerDefaults] =
|
|
9413
|
+
const [serverDefaults, setServerDefaults] = React6.useState({});
|
|
9361
9414
|
const { formProps, saveButtonProps } = antd$1.useForm({
|
|
9362
9415
|
resource: formResource,
|
|
9363
9416
|
redirect: false,
|
|
@@ -9406,14 +9459,14 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9406
9459
|
type: "success"
|
|
9407
9460
|
})
|
|
9408
9461
|
});
|
|
9409
|
-
useKeyboardShortcuts(
|
|
9462
|
+
useKeyboardShortcuts(React6.useMemo(() => [
|
|
9410
9463
|
{ key: "s", ctrl: true, handler: () => {
|
|
9411
9464
|
if (!isPostCreate) formProps?.form?.submit();
|
|
9412
9465
|
} },
|
|
9413
9466
|
{ key: "Escape", handler: () => journeyCallbacks?.onCancel ? journeyCallbacks.onCancel() : navigate(-1) }
|
|
9414
9467
|
], [formProps?.form, navigate, isPostCreate, journeyCallbacks]));
|
|
9415
|
-
const effectiveFields =
|
|
9416
|
-
const fieldByKey =
|
|
9468
|
+
const effectiveFields = React6.useMemo(() => applyRelationFieldOverrides(model, allModelsList), [model, allModelsList]);
|
|
9469
|
+
const fieldByKey = React6.useMemo(
|
|
9417
9470
|
() => new Map(effectiveFields.map((field) => [field.key, field])),
|
|
9418
9471
|
[effectiveFields]
|
|
9419
9472
|
);
|
|
@@ -9425,7 +9478,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9425
9478
|
if (["false", "0", "no", "n", "off"].includes(normalized)) return false;
|
|
9426
9479
|
return value;
|
|
9427
9480
|
};
|
|
9428
|
-
const normalizeFieldValue =
|
|
9481
|
+
const normalizeFieldValue = React6.useCallback((field, rawValue) => {
|
|
9429
9482
|
if (rawValue === void 0 || rawValue === null || rawValue === "") return rawValue;
|
|
9430
9483
|
if (field.type === "number") {
|
|
9431
9484
|
const parsed = Number(rawValue);
|
|
@@ -9434,7 +9487,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9434
9487
|
if (field.type === "boolean") return parseBooleanValue(rawValue);
|
|
9435
9488
|
return rawValue;
|
|
9436
9489
|
}, []);
|
|
9437
|
-
|
|
9490
|
+
React6.useEffect(() => {
|
|
9438
9491
|
let cancelled = false;
|
|
9439
9492
|
const loadDefaults = async () => {
|
|
9440
9493
|
try {
|
|
@@ -9457,7 +9510,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9457
9510
|
cancelled = true;
|
|
9458
9511
|
};
|
|
9459
9512
|
}, [apiUrl, effectiveFields, formResource, normalizeFieldValue]);
|
|
9460
|
-
const { initialValues, hiddenFields } =
|
|
9513
|
+
const { initialValues, hiddenFields } = React6.useMemo(() => {
|
|
9461
9514
|
const defaults = {};
|
|
9462
9515
|
const fromQuery = {};
|
|
9463
9516
|
const hidden = [];
|
|
@@ -9498,13 +9551,13 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9498
9551
|
const configLoading = editConfigLoading || fallbackConfigLoading || viewSettingsLoading;
|
|
9499
9552
|
const hasConfig = configRows.length > 0;
|
|
9500
9553
|
const configSections = groupConfigRowsBySection(configRows);
|
|
9501
|
-
const { embedded, tabbed } =
|
|
9502
|
-
const allRelations =
|
|
9503
|
-
const configuredRelationKeys =
|
|
9504
|
-
const configuredResolvedRelationKeys =
|
|
9505
|
-
const configuredRelationDisplayKeys =
|
|
9554
|
+
const { embedded, tabbed } = React6.useMemo(() => splitRelations(model.relations), [model.relations]);
|
|
9555
|
+
const allRelations = React6.useMemo(() => [...embedded, ...tabbed], [embedded, tabbed]);
|
|
9556
|
+
const configuredRelationKeys = React6.useMemo(() => buildConfiguredRelationKeys(configRows), [configRows]);
|
|
9557
|
+
const configuredResolvedRelationKeys = React6.useMemo(() => buildConfiguredResolvedRelationKeys(model.relations, configRows), [model.relations, configRows]);
|
|
9558
|
+
const configuredRelationDisplayKeys = React6.useMemo(() => buildConfiguredRelationDisplayKeys(model.relations, configRows), [model.relations, configRows]);
|
|
9506
9559
|
const hasConfiguredDetailRelations = configuredResolvedRelationKeys.size > 0 || configuredRelationKeys.size > 0;
|
|
9507
|
-
|
|
9560
|
+
React6.useEffect(() => {
|
|
9508
9561
|
const formInstance = formProps?.form;
|
|
9509
9562
|
if (!formInstance) return;
|
|
9510
9563
|
const untouchedDefaults = Object.fromEntries(
|
|
@@ -9513,7 +9566,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9513
9566
|
if (Object.keys(untouchedDefaults).length === 0) return;
|
|
9514
9567
|
formInstance.setFieldsValue(untouchedDefaults);
|
|
9515
9568
|
}, [formProps, initialValues]);
|
|
9516
|
-
const handleDone =
|
|
9569
|
+
const handleDone = React6.useCallback(() => {
|
|
9517
9570
|
const createdId = getRecordId(createdRecord, model.fields);
|
|
9518
9571
|
if (returnTo) {
|
|
9519
9572
|
navigate(returnTo);
|
|
@@ -9523,7 +9576,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9523
9576
|
navigate(-1);
|
|
9524
9577
|
}
|
|
9525
9578
|
}, [createdRecord, returnTo, navigate, formResource]);
|
|
9526
|
-
const handleGoToEdit =
|
|
9579
|
+
const handleGoToEdit = React6.useCallback(() => {
|
|
9527
9580
|
const createdId = getRecordId(createdRecord, model.fields);
|
|
9528
9581
|
if (createdId != null) {
|
|
9529
9582
|
go({ to: { resource: model.resource || model.name, action: "edit", id: createdId } });
|
|
@@ -9535,7 +9588,7 @@ var DynamicCreate = ({ model: modelProp, allModels, journeyCallbacks, injectedVa
|
|
|
9535
9588
|
/* @__PURE__ */ jsxRuntime.jsx(antd.Button, { size: "small", type: "primary", icon: /* @__PURE__ */ jsxRuntime.jsx(AntDIcons2.CheckCircleOutlined, {}), onClick: handleDone, children: _24("Done") })
|
|
9536
9589
|
] });
|
|
9537
9590
|
const addTabsForNonConfiguredRelations = viewSettings?.addTabsForNonConfiguredRelations !== false;
|
|
9538
|
-
const relationTabEntries =
|
|
9591
|
+
const relationTabEntries = React6.useMemo(() => {
|
|
9539
9592
|
if (!allModels) return [];
|
|
9540
9593
|
const groups = /* @__PURE__ */ new Map();
|
|
9541
9594
|
allRelations.forEach((rel) => {
|
|
@@ -9876,7 +9929,7 @@ var nextGridPosition = (cells) => {
|
|
|
9876
9929
|
};
|
|
9877
9930
|
var CellConfigDrawer = ({ open, cell, tabId, config, onClose, onSave }) => {
|
|
9878
9931
|
const [form] = antd.Form.useForm();
|
|
9879
|
-
|
|
9932
|
+
React6.useEffect(() => {
|
|
9880
9933
|
if (!cell || !tabId) return;
|
|
9881
9934
|
const tab = config.tabs.find((t) => t.id === tabId);
|
|
9882
9935
|
form.setFieldsValue({
|
|
@@ -10022,7 +10075,7 @@ var CellConfigDrawer = ({ open, cell, tabId, config, onClose, onSave }) => {
|
|
|
10022
10075
|
};
|
|
10023
10076
|
var SectionCell = ({ cell, isConfiguring, isMaximized, isMinimized, onConfigure, onMaximize, onMinimize, onMove, onResize, children }) => {
|
|
10024
10077
|
const { token } = antd.theme.useToken();
|
|
10025
|
-
const cellRef =
|
|
10078
|
+
const cellRef = React6.useRef(null);
|
|
10026
10079
|
const cellStyle = {
|
|
10027
10080
|
position: "relative",
|
|
10028
10081
|
border: `1px solid ${token.colorBorderSecondary}`,
|
|
@@ -10051,7 +10104,7 @@ var SectionCell = ({ cell, isConfiguring, isMaximized, isMinimized, onConfigure,
|
|
|
10051
10104
|
minHeight: 32,
|
|
10052
10105
|
position: "relative"
|
|
10053
10106
|
};
|
|
10054
|
-
const startResize =
|
|
10107
|
+
const startResize = React6.useCallback((e, dir) => {
|
|
10055
10108
|
e.preventDefault();
|
|
10056
10109
|
e.stopPropagation();
|
|
10057
10110
|
const el = cellRef.current;
|
|
@@ -10131,20 +10184,20 @@ var SectionCell = ({ cell, isConfiguring, isMaximized, isMinimized, onConfigure,
|
|
|
10131
10184
|
] });
|
|
10132
10185
|
};
|
|
10133
10186
|
var SectionsGrid = ({ cells, config, tabId, renderContent, onConfigChange, isConfiguring = false }) => {
|
|
10134
|
-
const [maximizedCellId, setMaximizedCellId] =
|
|
10135
|
-
const [minimizedCellIds, setMinimizedCellIds] =
|
|
10136
|
-
const [drawerCellId, setDrawerCellId] =
|
|
10137
|
-
const handleMaximize =
|
|
10187
|
+
const [maximizedCellId, setMaximizedCellId] = React6.useState(null);
|
|
10188
|
+
const [minimizedCellIds, setMinimizedCellIds] = React6.useState(/* @__PURE__ */ new Set());
|
|
10189
|
+
const [drawerCellId, setDrawerCellId] = React6.useState(null);
|
|
10190
|
+
const handleMaximize = React6.useCallback((cellId) => {
|
|
10138
10191
|
setMaximizedCellId((prev) => prev === cellId ? null : cellId);
|
|
10139
10192
|
}, []);
|
|
10140
|
-
const handleMinimize =
|
|
10193
|
+
const handleMinimize = React6.useCallback((cellId) => {
|
|
10141
10194
|
setMinimizedCellIds((prev) => {
|
|
10142
10195
|
const next = new Set(prev);
|
|
10143
10196
|
next.has(cellId) ? next.delete(cellId) : next.add(cellId);
|
|
10144
10197
|
return next;
|
|
10145
10198
|
});
|
|
10146
10199
|
}, []);
|
|
10147
|
-
const handleMove =
|
|
10200
|
+
const handleMove = React6.useCallback((cellId, direction) => {
|
|
10148
10201
|
const nextTabs = config.tabs.map((tab) => {
|
|
10149
10202
|
if (tab.id !== tabId) return tab;
|
|
10150
10203
|
const cell = tab.cells.find((c) => c.id === cellId);
|
|
@@ -10167,7 +10220,7 @@ var SectionsGrid = ({ cells, config, tabId, renderContent, onConfigChange, isCon
|
|
|
10167
10220
|
});
|
|
10168
10221
|
onConfigChange({ ...config, tabs: nextTabs });
|
|
10169
10222
|
}, [config, tabId, onConfigChange]);
|
|
10170
|
-
const handleResize =
|
|
10223
|
+
const handleResize = React6.useCallback((cellId, minWidth, minHeight) => {
|
|
10171
10224
|
const nextTabs = config.tabs.map((tab) => {
|
|
10172
10225
|
if (tab.id !== tabId) return tab;
|
|
10173
10226
|
return {
|
|
@@ -10184,15 +10237,15 @@ var SectionsGrid = ({ cells, config, tabId, renderContent, onConfigChange, isCon
|
|
|
10184
10237
|
});
|
|
10185
10238
|
onConfigChange({ ...config, tabs: nextTabs });
|
|
10186
10239
|
}, [config, tabId, onConfigChange]);
|
|
10187
|
-
const numCols =
|
|
10240
|
+
const numCols = React6.useMemo(() => {
|
|
10188
10241
|
if (!cells.length) return 1;
|
|
10189
10242
|
return Math.max(...cells.map((c) => c.col)) + 1;
|
|
10190
10243
|
}, [cells]);
|
|
10191
|
-
const numRows =
|
|
10244
|
+
const numRows = React6.useMemo(() => {
|
|
10192
10245
|
if (!cells.length) return 1;
|
|
10193
10246
|
return Math.max(...cells.map((c) => c.row)) + 1;
|
|
10194
10247
|
}, [cells]);
|
|
10195
|
-
const soloRows =
|
|
10248
|
+
const soloRows = React6.useMemo(() => {
|
|
10196
10249
|
const counts = /* @__PURE__ */ new Map();
|
|
10197
10250
|
for (const c of cells) counts.set(c.row, (counts.get(c.row) ?? 0) + 1);
|
|
10198
10251
|
const solo = /* @__PURE__ */ new Set();
|
|
@@ -10269,8 +10322,8 @@ function parseInlineStyle2(cssText) {
|
|
|
10269
10322
|
}
|
|
10270
10323
|
var _25 = window._ || ((text) => text);
|
|
10271
10324
|
var ReadAndEditReference = ({ value, onChange, field, allModels, model, currentId }) => {
|
|
10272
|
-
const [editing, setEditing] =
|
|
10273
|
-
const [draft, setDraft] =
|
|
10325
|
+
const [editing, setEditing] = React6.useState(false);
|
|
10326
|
+
const [draft, setDraft] = React6.useState(void 0);
|
|
10274
10327
|
const form = antd.Form.useFormInstance();
|
|
10275
10328
|
const resource = field.referencePath ? field.referencePath : field.reference ? resolveResourcePath(field.reference, allModels) : "";
|
|
10276
10329
|
const modelResource = model ? resolveResourcePath(model.resource || model.name, allModels) : void 0;
|
|
@@ -10319,11 +10372,11 @@ var ReadAndEditReference = ({ value, onChange, field, allModels, model, currentI
|
|
|
10319
10372
|
var NLSentenceBlock = ({ eid, title: titleProp, showLabel }) => {
|
|
10320
10373
|
const { token } = antd.theme.useToken();
|
|
10321
10374
|
const apiUrl = core.useApiUrl();
|
|
10322
|
-
const [html, setHtml] =
|
|
10323
|
-
const [loading, setLoading] =
|
|
10324
|
-
const [error, setError] =
|
|
10325
|
-
const [fetchedTitle, setFetchedTitle] =
|
|
10326
|
-
|
|
10375
|
+
const [html, setHtml] = React6.useState(null);
|
|
10376
|
+
const [loading, setLoading] = React6.useState(true);
|
|
10377
|
+
const [error, setError] = React6.useState(null);
|
|
10378
|
+
const [fetchedTitle, setFetchedTitle] = React6.useState(null);
|
|
10379
|
+
React6.useEffect(() => {
|
|
10327
10380
|
let cancelled = false;
|
|
10328
10381
|
setLoading(true);
|
|
10329
10382
|
setHtml(null);
|
|
@@ -10504,7 +10557,6 @@ var SectionCellContent = ({
|
|
|
10504
10557
|
borderRadius: 6,
|
|
10505
10558
|
overflowWrap: "anywhere",
|
|
10506
10559
|
maxWidth: "100%",
|
|
10507
|
-
border: `1px solid ${token.colorBorder}`,
|
|
10508
10560
|
...parseInlineStyle(item.html_format)
|
|
10509
10561
|
};
|
|
10510
10562
|
const relationLabelStyle = {
|
|
@@ -10539,7 +10591,6 @@ var SectionCellContent = ({
|
|
|
10539
10591
|
lineHeight: 1.15,
|
|
10540
10592
|
background: valueBackground,
|
|
10541
10593
|
borderRadius: 6,
|
|
10542
|
-
border: `1px solid ${token.colorBorder}`,
|
|
10543
10594
|
maxWidth: "100%",
|
|
10544
10595
|
overflowWrap: "anywhere",
|
|
10545
10596
|
textAlign: field.type === "number" && !field.reference ? "right" : "left",
|
|
@@ -10640,10 +10691,10 @@ function buildConfig(configRows, overrides) {
|
|
|
10640
10691
|
function usePageSectionsConfig(configRows, resourceKey, mode) {
|
|
10641
10692
|
const apiUrl = core.useApiUrl();
|
|
10642
10693
|
const preferenceType = mode === "show" ? "ShowLayoutGrid" : "EditLayoutGrid";
|
|
10643
|
-
const [overrides, setOverrides] =
|
|
10644
|
-
const [loading, setLoading] =
|
|
10645
|
-
const loadedKeyRef =
|
|
10646
|
-
|
|
10694
|
+
const [overrides, setOverrides] = React6.useState({});
|
|
10695
|
+
const [loading, setLoading] = React6.useState(true);
|
|
10696
|
+
const loadedKeyRef = React6.useRef(null);
|
|
10697
|
+
React6.useEffect(() => {
|
|
10647
10698
|
if (!resourceKey) {
|
|
10648
10699
|
setLoading(false);
|
|
10649
10700
|
return;
|
|
@@ -10662,17 +10713,17 @@ function usePageSectionsConfig(configRows, resourceKey, mode) {
|
|
|
10662
10713
|
}).catch(() => {
|
|
10663
10714
|
}).finally(() => setLoading(false));
|
|
10664
10715
|
}, [apiUrl, resourceKey, preferenceType]);
|
|
10665
|
-
const savedConfig =
|
|
10716
|
+
const savedConfig = React6.useMemo(
|
|
10666
10717
|
() => buildConfig(configRows, overrides),
|
|
10667
10718
|
[configRows, overrides]
|
|
10668
10719
|
);
|
|
10669
|
-
const [isConfiguring, setIsConfiguring] =
|
|
10670
|
-
const [pendingConfig, setPendingConfig] =
|
|
10671
|
-
const config =
|
|
10720
|
+
const [isConfiguring, setIsConfiguring] = React6.useState(false);
|
|
10721
|
+
const [pendingConfig, setPendingConfig] = React6.useState(null);
|
|
10722
|
+
const config = React6.useMemo(
|
|
10672
10723
|
() => isConfiguring && pendingConfig ? pendingConfig : savedConfig,
|
|
10673
10724
|
[isConfiguring, pendingConfig, savedConfig]
|
|
10674
10725
|
);
|
|
10675
|
-
const save =
|
|
10726
|
+
const save = React6.useCallback((nextConfig) => {
|
|
10676
10727
|
const allCells = nextConfig.tabs.flatMap((t) => t.cells);
|
|
10677
10728
|
const nextOverrides = {};
|
|
10678
10729
|
const cells = allCells.map((c) => {
|
|
@@ -10697,24 +10748,24 @@ function usePageSectionsConfig(configRows, resourceKey, mode) {
|
|
|
10697
10748
|
}).catch(() => {
|
|
10698
10749
|
});
|
|
10699
10750
|
}, [apiUrl, resourceKey, preferenceType]);
|
|
10700
|
-
const getSectionRows =
|
|
10751
|
+
const getSectionRows = React6.useCallback((sectionId) => {
|
|
10701
10752
|
return configRows.filter((r) => (r.section_id || r.section || DETAILS_TAB_NAME) === sectionId);
|
|
10702
10753
|
}, [configRows]);
|
|
10703
|
-
const enterConfigMode =
|
|
10754
|
+
const enterConfigMode = React6.useCallback(() => {
|
|
10704
10755
|
setPendingConfig(savedConfig);
|
|
10705
10756
|
setIsConfiguring(true);
|
|
10706
10757
|
}, [savedConfig]);
|
|
10707
|
-
const cancelLayout =
|
|
10758
|
+
const cancelLayout = React6.useCallback(() => {
|
|
10708
10759
|
setPendingConfig(null);
|
|
10709
10760
|
setIsConfiguring(false);
|
|
10710
10761
|
}, []);
|
|
10711
|
-
const saveLayout =
|
|
10762
|
+
const saveLayout = React6.useCallback(() => {
|
|
10712
10763
|
const toSave = pendingConfig ?? savedConfig;
|
|
10713
10764
|
save(toSave);
|
|
10714
10765
|
setPendingConfig(null);
|
|
10715
10766
|
setIsConfiguring(false);
|
|
10716
10767
|
}, [pendingConfig, savedConfig, save]);
|
|
10717
|
-
const onLayoutChange =
|
|
10768
|
+
const onLayoutChange = React6.useCallback((next) => {
|
|
10718
10769
|
if (isConfiguring) setPendingConfig(next);
|
|
10719
10770
|
}, [isConfiguring]);
|
|
10720
10771
|
return { config, loading, save, getSectionRows, isConfiguring, enterConfigMode, saveLayout, cancelLayout, onLayoutChange };
|
|
@@ -10733,7 +10784,7 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10733
10784
|
const { token } = antd.theme.useToken();
|
|
10734
10785
|
const modelTone = useModelTone(model);
|
|
10735
10786
|
const { settings: viewSettings, loading: viewSettingsLoading } = useViewSettings();
|
|
10736
|
-
const relationViewTypeDefaults =
|
|
10787
|
+
const relationViewTypeDefaults = React6.useMemo(
|
|
10737
10788
|
() => ({
|
|
10738
10789
|
show: normalizeRelationViewType(viewSettings?.showViewType || "") || "totals-details",
|
|
10739
10790
|
edit: normalizeRelationViewType(viewSettings?.editViewType || "") || "editable-table"
|
|
@@ -10741,7 +10792,7 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10741
10792
|
[viewSettings?.showViewType, viewSettings?.editViewType]
|
|
10742
10793
|
);
|
|
10743
10794
|
const apiUrl = core.useApiUrl();
|
|
10744
|
-
const allModelsList =
|
|
10795
|
+
const allModelsList = React6.useMemo(() => allModels || [], [allModels]);
|
|
10745
10796
|
const { rows: editConfigRows, loading: editConfigLoading } = useViewConfigurations(model.name, "AutomaticEntityForm");
|
|
10746
10797
|
const { rows: fallbackConfigRows, loading: fallbackConfigLoading } = useViewConfigurations(model.name, "PrimaryView");
|
|
10747
10798
|
const valueBackground = isDarkColor2(token.colorBgBase || token.colorBgContainer) ? token.colorFillQuaternary : "#F9FFFF";
|
|
@@ -10772,7 +10823,7 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10772
10823
|
})
|
|
10773
10824
|
});
|
|
10774
10825
|
const record = queryResult?.data?.data;
|
|
10775
|
-
const editFormProps =
|
|
10826
|
+
const editFormProps = React6.useMemo(() => {
|
|
10776
10827
|
if (!isFileModel(model)) return formProps;
|
|
10777
10828
|
const originalOnFinish = formProps.onFinish;
|
|
10778
10829
|
return {
|
|
@@ -10783,24 +10834,24 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10783
10834
|
}
|
|
10784
10835
|
};
|
|
10785
10836
|
}, [formProps, model]);
|
|
10786
|
-
useKeyboardShortcuts(
|
|
10837
|
+
useKeyboardShortcuts(React6.useMemo(() => [
|
|
10787
10838
|
{ key: "s", ctrl: true, handler: () => formProps?.form?.submit() },
|
|
10788
10839
|
{ key: "Escape", handler: () => journeyCallbacks?.onCancel ? journeyCallbacks.onCancel() : navigate(-1) }
|
|
10789
10840
|
], [formProps?.form, navigate, journeyCallbacks]));
|
|
10790
10841
|
const pageTitle = record?._label ? asDisplayText(record._label, `${_27("Edit")} ${modelDisplayLabel}`) : `${_27("Edit")} ${modelDisplayLabel}`;
|
|
10791
10842
|
const recordId = getRecordId(record, model.fields);
|
|
10792
|
-
const effectiveFields =
|
|
10843
|
+
const effectiveFields = React6.useMemo(() => applyRelationFieldOverrides(model, allModelsList), [model, allModelsList]);
|
|
10793
10844
|
const { metadataButton: editMetadataButton, metadataModal: editMetadataModal } = useMetadataModal(model, allModels);
|
|
10794
|
-
const [showRelationActions, setShowRelationActions] =
|
|
10795
|
-
const [showRelationCreate, setShowRelationCreate] =
|
|
10796
|
-
const [isSavingActionsPrefs, setIsSavingActionsPrefs] =
|
|
10797
|
-
const actionsPrefsTouchedRef =
|
|
10798
|
-
const actionsPrefsLoadedRef =
|
|
10799
|
-
const actionsPrefsResourceRef =
|
|
10800
|
-
const markActionsPrefsTouched =
|
|
10845
|
+
const [showRelationActions, setShowRelationActions] = React6.useState(DEFAULT_EDIT_RELATION_ROW_ACTIONS);
|
|
10846
|
+
const [showRelationCreate, setShowRelationCreate] = React6.useState(DEFAULT_RELATION_CREATE_ACTIONS);
|
|
10847
|
+
const [isSavingActionsPrefs, setIsSavingActionsPrefs] = React6.useState(false);
|
|
10848
|
+
const actionsPrefsTouchedRef = React6.useRef(false);
|
|
10849
|
+
const actionsPrefsLoadedRef = React6.useRef(false);
|
|
10850
|
+
const actionsPrefsResourceRef = React6.useRef(null);
|
|
10851
|
+
const markActionsPrefsTouched = React6.useCallback(() => {
|
|
10801
10852
|
actionsPrefsTouchedRef.current = true;
|
|
10802
10853
|
}, []);
|
|
10803
|
-
const saveActionsPreferences =
|
|
10854
|
+
const saveActionsPreferences = React6.useCallback(async () => {
|
|
10804
10855
|
const resourceKey2 = resolveResourcePath(model.resource || model.name, allModelsList);
|
|
10805
10856
|
const preferences = {
|
|
10806
10857
|
showActions: showRelationActions,
|
|
@@ -10824,8 +10875,8 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10824
10875
|
setIsSavingActionsPrefs(false);
|
|
10825
10876
|
}
|
|
10826
10877
|
}, [apiUrl, allModelsList, model.name, model.resource, showRelationActions, showRelationCreate]);
|
|
10827
|
-
const [isDuplicating, setIsDuplicating] =
|
|
10828
|
-
const duplicateRecord =
|
|
10878
|
+
const [isDuplicating, setIsDuplicating] = React6.useState(false);
|
|
10879
|
+
const duplicateRecord = React6.useCallback(async (withRelations) => {
|
|
10829
10880
|
if (!record) return;
|
|
10830
10881
|
setIsDuplicating(true);
|
|
10831
10882
|
try {
|
|
@@ -10893,7 +10944,7 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
10893
10944
|
setIsDuplicating(false);
|
|
10894
10945
|
}
|
|
10895
10946
|
}, [record, model, allModelsList, apiUrl, go]);
|
|
10896
|
-
|
|
10947
|
+
React6.useEffect(() => {
|
|
10897
10948
|
const resourceKey2 = resolveResourcePath(model.resource || model.name, allModelsList);
|
|
10898
10949
|
if (actionsPrefsResourceRef.current !== resourceKey2) {
|
|
10899
10950
|
actionsPrefsLoadedRef.current = false;
|
|
@@ -11173,13 +11224,13 @@ var DynamicEdit = ({ model: modelProp, allModels, topContent, extraHeaderButtons
|
|
|
11173
11224
|
});
|
|
11174
11225
|
items.push(...customConfigTabs);
|
|
11175
11226
|
items.push(...relationTabs);
|
|
11176
|
-
const [activeTabKey, setActiveTabKey] =
|
|
11177
|
-
|
|
11227
|
+
const [activeTabKey, setActiveTabKey] = React6.useState("main_data");
|
|
11228
|
+
React6.useEffect(() => {
|
|
11178
11229
|
if (!items.find((item) => item.key === activeTabKey)) {
|
|
11179
11230
|
setActiveTabKey(items[0]?.key || "main_data");
|
|
11180
11231
|
}
|
|
11181
11232
|
}, [activeTabKey, items]);
|
|
11182
|
-
const lazyItems =
|
|
11233
|
+
const lazyItems = React6.useMemo(
|
|
11183
11234
|
() => items.map((item) => ({
|
|
11184
11235
|
...item,
|
|
11185
11236
|
children: item.key === activeTabKey ? item.children : null
|
|
@@ -11276,7 +11327,7 @@ var useStandardShowTabs = (model, record, allModels, actionsState, editForm, ove
|
|
|
11276
11327
|
const { token } = antd.theme.useToken();
|
|
11277
11328
|
const { settings: viewSettings, loading: viewSettingsLoading } = useViewSettings();
|
|
11278
11329
|
const modelTone = useModelTone(model);
|
|
11279
|
-
const relationViewTypeDefaults =
|
|
11330
|
+
const relationViewTypeDefaults = React6.useMemo(
|
|
11280
11331
|
() => ({
|
|
11281
11332
|
show: normalizeRelationViewType(viewSettings?.showViewType || "") || "totals-details",
|
|
11282
11333
|
edit: normalizeRelationViewType(viewSettings?.editViewType || "") || "editable-table"
|
|
@@ -11585,11 +11636,11 @@ var useRelatedInlineItems = ({
|
|
|
11585
11636
|
pageSize = INLINE_DEFAULT_PAGE_SIZE
|
|
11586
11637
|
}) => {
|
|
11587
11638
|
const apiUrl = core.useApiUrl();
|
|
11588
|
-
const [items, setItems] =
|
|
11589
|
-
const [loading, setLoading] =
|
|
11590
|
-
const [error, setError] =
|
|
11591
|
-
const [total, setTotal] =
|
|
11592
|
-
|
|
11639
|
+
const [items, setItems] = React6.useState([]);
|
|
11640
|
+
const [loading, setLoading] = React6.useState(false);
|
|
11641
|
+
const [error, setError] = React6.useState(null);
|
|
11642
|
+
const [total, setTotal] = React6.useState(0);
|
|
11643
|
+
React6.useEffect(() => {
|
|
11593
11644
|
const recordId = record?.eid ?? record?.id;
|
|
11594
11645
|
if (!recordId || !rel.resource || !rel.targetKey) {
|
|
11595
11646
|
setItems([]);
|
|
@@ -11730,10 +11781,10 @@ var useRelatedGalleryRecords = ({
|
|
|
11730
11781
|
allModels
|
|
11731
11782
|
}) => {
|
|
11732
11783
|
const apiUrl = core.useApiUrl();
|
|
11733
|
-
const [records, setRecords] =
|
|
11734
|
-
const [loading, setLoading] =
|
|
11735
|
-
const [error, setError] =
|
|
11736
|
-
|
|
11784
|
+
const [records, setRecords] = React6.useState([]);
|
|
11785
|
+
const [loading, setLoading] = React6.useState(false);
|
|
11786
|
+
const [error, setError] = React6.useState(null);
|
|
11787
|
+
React6.useEffect(() => {
|
|
11737
11788
|
const recordId = record?.eid ?? record?.id;
|
|
11738
11789
|
if (!recordId || !rel.resource || !rel.targetKey) {
|
|
11739
11790
|
setRecords([]);
|
|
@@ -11831,10 +11882,10 @@ var RelatedObjectsInlineValues = ({ rel, record, viewType, allowedRelatedIds, al
|
|
|
11831
11882
|
const go = core.useGo();
|
|
11832
11883
|
const paneNav = usePaneNavigation();
|
|
11833
11884
|
const { token } = antd.theme.useToken();
|
|
11834
|
-
const [page, setPage] =
|
|
11835
|
-
const [pageSize, setPageSize] =
|
|
11885
|
+
const [page, setPage] = React6.useState(1);
|
|
11886
|
+
const [pageSize, setPageSize] = React6.useState(INLINE_DEFAULT_PAGE_SIZE);
|
|
11836
11887
|
const { items, loading, error, total } = useRelatedInlineItems({ rel, record, allowedRelatedIds, allModels, page, pageSize });
|
|
11837
|
-
const handlePageChange =
|
|
11888
|
+
const handlePageChange = React6.useCallback((newPage, newPageSize) => {
|
|
11838
11889
|
if (newPageSize && newPageSize !== pageSize) {
|
|
11839
11890
|
setPageSize(newPageSize);
|
|
11840
11891
|
setPage(1);
|
|
@@ -11896,17 +11947,17 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11896
11947
|
const { token } = antd.theme.useToken();
|
|
11897
11948
|
const { records, loading, error } = useRelatedGalleryRecords({ rel, record, allModels });
|
|
11898
11949
|
const resource = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
11899
|
-
const dateFieldOptions =
|
|
11900
|
-
const [calendarMode, setCalendarMode] =
|
|
11901
|
-
const [calendarDateField, setCalendarDateField] =
|
|
11902
|
-
const [calendarAnchorDate, setCalendarAnchorDate] =
|
|
11903
|
-
const dateFieldKeySet =
|
|
11904
|
-
|
|
11950
|
+
const dateFieldOptions = React6.useMemo(() => getCalendarDateFieldOptions(relatedModel.fields), [relatedModel.fields]);
|
|
11951
|
+
const [calendarMode, setCalendarMode] = React6.useState("month");
|
|
11952
|
+
const [calendarDateField, setCalendarDateField] = React6.useState(() => dateFieldOptions[0]?.key || "");
|
|
11953
|
+
const [calendarAnchorDate, setCalendarAnchorDate] = React6.useState(() => dayjs9__default.default().startOf("month"));
|
|
11954
|
+
const dateFieldKeySet = React6.useMemo(() => new Set(dateFieldOptions.map((field) => field.key)), [dateFieldOptions]);
|
|
11955
|
+
React6.useEffect(() => {
|
|
11905
11956
|
if (calendarDateField && dateFieldKeySet.has(calendarDateField)) return;
|
|
11906
11957
|
const fallback = dateFieldOptions[0]?.key || "";
|
|
11907
11958
|
if (fallback !== calendarDateField) setCalendarDateField(fallback);
|
|
11908
11959
|
}, [calendarDateField, dateFieldKeySet, dateFieldOptions]);
|
|
11909
|
-
const calendarEntries =
|
|
11960
|
+
const calendarEntries = React6.useMemo(() => {
|
|
11910
11961
|
if (!calendarDateField) return [];
|
|
11911
11962
|
const entries = [];
|
|
11912
11963
|
records.forEach((item) => {
|
|
@@ -11922,7 +11973,7 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11922
11973
|
});
|
|
11923
11974
|
return entries;
|
|
11924
11975
|
}, [calendarDateField, records]);
|
|
11925
|
-
const earliestDateTs =
|
|
11976
|
+
const earliestDateTs = React6.useMemo(() => {
|
|
11926
11977
|
if (calendarEntries.length === 0) return null;
|
|
11927
11978
|
let earliest = calendarEntries[0].date.valueOf();
|
|
11928
11979
|
for (let index = 1; index < calendarEntries.length; index += 1) {
|
|
@@ -11931,8 +11982,8 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11931
11982
|
}
|
|
11932
11983
|
return earliest;
|
|
11933
11984
|
}, [calendarEntries]);
|
|
11934
|
-
const initSignatureRef =
|
|
11935
|
-
|
|
11985
|
+
const initSignatureRef = React6.useRef("");
|
|
11986
|
+
React6.useEffect(() => {
|
|
11936
11987
|
const signature = `${calendarDateField}|${calendarMode}|${earliestDateTs ?? "none"}`;
|
|
11937
11988
|
if (initSignatureRef.current === signature) return;
|
|
11938
11989
|
initSignatureRef.current = signature;
|
|
@@ -11942,7 +11993,7 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11942
11993
|
}
|
|
11943
11994
|
setCalendarAnchorDate(dayjs9__default.default(earliestDateTs).startOf(calendarMode));
|
|
11944
11995
|
}, [calendarDateField, calendarMode, earliestDateTs]);
|
|
11945
|
-
const entriesByDate =
|
|
11996
|
+
const entriesByDate = React6.useMemo(() => {
|
|
11946
11997
|
const grouped = /* @__PURE__ */ new Map();
|
|
11947
11998
|
calendarEntries.forEach((entry) => {
|
|
11948
11999
|
const key = entry.date.format("YYYY-MM-DD");
|
|
@@ -11952,7 +12003,7 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11952
12003
|
});
|
|
11953
12004
|
return grouped;
|
|
11954
12005
|
}, [calendarEntries]);
|
|
11955
|
-
const rangeDays =
|
|
12006
|
+
const rangeDays = React6.useMemo(() => {
|
|
11956
12007
|
const current = calendarAnchorDate.startOf(calendarMode);
|
|
11957
12008
|
if (calendarMode === "week") {
|
|
11958
12009
|
const start2 = current.startOf("week");
|
|
@@ -11963,7 +12014,7 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
11963
12014
|
const totalDays = end.diff(start, "day") + 1;
|
|
11964
12015
|
return Array.from({ length: totalDays }, (_unused, offset) => start.add(offset, "day"));
|
|
11965
12016
|
}, [calendarAnchorDate, calendarMode]);
|
|
11966
|
-
const periodLabel =
|
|
12017
|
+
const periodLabel = React6.useMemo(() => {
|
|
11967
12018
|
if (calendarMode === "week") {
|
|
11968
12019
|
const weekStart = calendarAnchorDate.startOf("week");
|
|
11969
12020
|
const weekEnd = weekStart.endOf("week");
|
|
@@ -12123,9 +12174,9 @@ var RelatedObjectsCalendar = ({ rel, record, relatedModel, allModels }) => {
|
|
|
12123
12174
|
] });
|
|
12124
12175
|
};
|
|
12125
12176
|
var RelatedObjectPrimaryCard = ({ record, model, allModels, customPageName }) => {
|
|
12126
|
-
const allModelsList =
|
|
12177
|
+
const allModelsList = React6.useMemo(() => allModels || [], [allModels]);
|
|
12127
12178
|
const tone = useModelTone(model);
|
|
12128
|
-
const PrimaryShowRenderer =
|
|
12179
|
+
const PrimaryShowRenderer = React6.useContext(PrimaryShowContext);
|
|
12129
12180
|
const label = getRecordDisplayLabel(record);
|
|
12130
12181
|
const id = record?.eid ?? record?.id;
|
|
12131
12182
|
const resource = resolveResourcePath(model.resource || model.name, allModelsList);
|
|
@@ -12215,22 +12266,22 @@ var RelatedObjectsEditableList = ({ rel, record, allModels }) => {
|
|
|
12215
12266
|
const location = reactRouterDom.useLocation();
|
|
12216
12267
|
const apiUrl = core.useApiUrl();
|
|
12217
12268
|
const { token } = antd.theme.useToken();
|
|
12218
|
-
const [page, setPage] =
|
|
12219
|
-
const [pageSize, setPageSize] =
|
|
12269
|
+
const [page, setPage] = React6.useState(1);
|
|
12270
|
+
const [pageSize, setPageSize] = React6.useState(INLINE_DEFAULT_PAGE_SIZE);
|
|
12220
12271
|
const { items: fetchedItems, loading, error, total } = useRelatedInlineItems({ rel, record, allModels, page, pageSize });
|
|
12221
|
-
const [localItems, setLocalItems] =
|
|
12222
|
-
|
|
12272
|
+
const [localItems, setLocalItems] = React6.useState(null);
|
|
12273
|
+
React6.useEffect(() => {
|
|
12223
12274
|
setLocalItems(null);
|
|
12224
12275
|
}, [fetchedItems]);
|
|
12225
12276
|
const items = localItems ?? fetchedItems;
|
|
12226
|
-
const [editing, setEditing] =
|
|
12227
|
-
const [saving, setSaving] =
|
|
12228
|
-
const [allOptions, setAllOptions] =
|
|
12229
|
-
const [optionsLoading, setOptionsLoading] =
|
|
12230
|
-
const [selectedIds, setSelectedIds] =
|
|
12231
|
-
const [baselineIds, setBaselineIds] =
|
|
12232
|
-
const [searchText, setSearchText] =
|
|
12233
|
-
|
|
12277
|
+
const [editing, setEditing] = React6.useState(false);
|
|
12278
|
+
const [saving, setSaving] = React6.useState(false);
|
|
12279
|
+
const [allOptions, setAllOptions] = React6.useState([]);
|
|
12280
|
+
const [optionsLoading, setOptionsLoading] = React6.useState(false);
|
|
12281
|
+
const [selectedIds, setSelectedIds] = React6.useState(/* @__PURE__ */ new Set());
|
|
12282
|
+
const [baselineIds, setBaselineIds] = React6.useState(/* @__PURE__ */ new Set());
|
|
12283
|
+
const [searchText, setSearchText] = React6.useState("");
|
|
12284
|
+
React6.useEffect(() => {
|
|
12234
12285
|
if (!editing) return;
|
|
12235
12286
|
const snapshot = new Set(items.map((item) => Number(item.id)));
|
|
12236
12287
|
setBaselineIds(snapshot);
|
|
@@ -12264,7 +12315,7 @@ var RelatedObjectsEditableList = ({ rel, record, allModels }) => {
|
|
|
12264
12315
|
cancelled = true;
|
|
12265
12316
|
};
|
|
12266
12317
|
}, [editing]);
|
|
12267
|
-
const handleSave =
|
|
12318
|
+
const handleSave = React6.useCallback(async () => {
|
|
12268
12319
|
if (!rel.otherKey || !rel.targetKey) return;
|
|
12269
12320
|
const recordId = record?.eid ?? record?.id;
|
|
12270
12321
|
if (recordId === void 0 || recordId === null) return;
|
|
@@ -12340,12 +12391,12 @@ var RelatedObjectsEditableList = ({ rel, record, allModels }) => {
|
|
|
12340
12391
|
setSaving(false);
|
|
12341
12392
|
}
|
|
12342
12393
|
}, [apiUrl, allModels, allOptions, rel, record, selectedIds, baselineIds]);
|
|
12343
|
-
const handleCancel =
|
|
12394
|
+
const handleCancel = React6.useCallback(() => {
|
|
12344
12395
|
setEditing(false);
|
|
12345
12396
|
setSelectedIds(new Set(baselineIds));
|
|
12346
12397
|
setSearchText("");
|
|
12347
12398
|
}, [baselineIds]);
|
|
12348
|
-
const handleCreateNewAndRelate =
|
|
12399
|
+
const handleCreateNewAndRelate = React6.useCallback(() => {
|
|
12349
12400
|
const otherKey = rel.otherKey;
|
|
12350
12401
|
if (!otherKey || !rel.targetKey) return;
|
|
12351
12402
|
const recordId = record?.eid ?? record?.id;
|
|
@@ -12501,17 +12552,17 @@ var _33 = window._ || ((text) => text);
|
|
|
12501
12552
|
var RelatedObjectsEditableCsv = ({ rel, record, allModels }) => {
|
|
12502
12553
|
const apiUrl = core.useApiUrl();
|
|
12503
12554
|
const { items: fetchedItems, loading, error } = useRelatedInlineItems({ rel, record, allModels });
|
|
12504
|
-
const [saving, setSaving] =
|
|
12505
|
-
const [allOptions, setAllOptions] =
|
|
12506
|
-
const [optionsLoading, setOptionsLoading] =
|
|
12507
|
-
const [selectedIds, setSelectedIds] =
|
|
12508
|
-
const [baselineIds, setBaselineIds] =
|
|
12509
|
-
|
|
12555
|
+
const [saving, setSaving] = React6.useState(false);
|
|
12556
|
+
const [allOptions, setAllOptions] = React6.useState([]);
|
|
12557
|
+
const [optionsLoading, setOptionsLoading] = React6.useState(false);
|
|
12558
|
+
const [selectedIds, setSelectedIds] = React6.useState([]);
|
|
12559
|
+
const [baselineIds, setBaselineIds] = React6.useState(/* @__PURE__ */ new Set());
|
|
12560
|
+
React6.useEffect(() => {
|
|
12510
12561
|
const ids = fetchedItems.map((item) => Number(item.id));
|
|
12511
12562
|
setSelectedIds(ids);
|
|
12512
12563
|
setBaselineIds(new Set(ids));
|
|
12513
12564
|
}, [fetchedItems]);
|
|
12514
|
-
|
|
12565
|
+
React6.useEffect(() => {
|
|
12515
12566
|
if (!rel.otherResource) return;
|
|
12516
12567
|
let cancelled = false;
|
|
12517
12568
|
const fetchOptions = async () => {
|
|
@@ -12538,7 +12589,7 @@ var RelatedObjectsEditableCsv = ({ rel, record, allModels }) => {
|
|
|
12538
12589
|
cancelled = true;
|
|
12539
12590
|
};
|
|
12540
12591
|
}, [apiUrl, rel.otherResource]);
|
|
12541
|
-
const handleChange =
|
|
12592
|
+
const handleChange = React6.useCallback(async (newIds) => {
|
|
12542
12593
|
if (!rel.otherKey || !rel.targetKey) return;
|
|
12543
12594
|
const recordId = record?.eid ?? record?.id;
|
|
12544
12595
|
if (recordId === void 0 || recordId === null) return;
|
|
@@ -12600,15 +12651,15 @@ var { Title: Title4 } = antd.Typography;
|
|
|
12600
12651
|
var PolymorphicRelatedObjectsTable = ({ rel, record, relationModel, parentModel, allModels, showActions = false, showCreate = false, allowInlineEdit = false, layoutPreferenceType, viewVariant = "default", viewMode = "table" }) => {
|
|
12601
12652
|
const recordId = record?.[parentModel?.pkField ?? "eid"] ?? record?.eid ?? record?.id;
|
|
12602
12653
|
const apiUrl = core.useApiUrl();
|
|
12603
|
-
const [loading, setLoading] =
|
|
12604
|
-
const [error, setError] =
|
|
12605
|
-
const [groupedIds, setGroupedIds] =
|
|
12606
|
-
const [unresolvedIds, setUnresolvedIds] =
|
|
12607
|
-
const polyInfo =
|
|
12654
|
+
const [loading, setLoading] = React6.useState(false);
|
|
12655
|
+
const [error, setError] = React6.useState(null);
|
|
12656
|
+
const [groupedIds, setGroupedIds] = React6.useState(/* @__PURE__ */ new Map());
|
|
12657
|
+
const [unresolvedIds, setUnresolvedIds] = React6.useState([]);
|
|
12658
|
+
const polyInfo = React6.useMemo(
|
|
12608
12659
|
() => getPolymorphicReferenceInfo(rel, relationModel, allModels),
|
|
12609
12660
|
[rel.otherKey, rel.otherResource, relationModel, allModels]
|
|
12610
12661
|
);
|
|
12611
|
-
|
|
12662
|
+
React6.useEffect(() => {
|
|
12612
12663
|
if (!recordId || !rel.otherKey || !polyInfo) {
|
|
12613
12664
|
setGroupedIds(/* @__PURE__ */ new Map());
|
|
12614
12665
|
setUnresolvedIds([]);
|
|
@@ -12727,96 +12778,96 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12727
12778
|
color: relatedModelTone.solid,
|
|
12728
12779
|
margin: 0
|
|
12729
12780
|
};
|
|
12730
|
-
const chartSvgRef =
|
|
12731
|
-
const skipNextAnimationRef =
|
|
12732
|
-
const [rows, setRows] =
|
|
12733
|
-
const [localSearch, setLocalSearch] =
|
|
12734
|
-
const [filterRules, setFilterRules] =
|
|
12735
|
-
const [filtersCollapsed, setFiltersCollapsed] =
|
|
12736
|
-
const [columnsSelectorOpen, setColumnsSelectorOpen] =
|
|
12737
|
-
const [selectedColumnKeys, setSelectedColumnKeys] =
|
|
12738
|
-
const [columnOrder, setColumnOrder] =
|
|
12739
|
-
const [totalsSummaryFunctions, setTotalsSummaryFunctions] =
|
|
12740
|
-
const [columnFiltersSelected, setColumnFiltersSelected] =
|
|
12741
|
-
const [columnSort, setColumnSort] =
|
|
12742
|
-
const [currentViewName, setCurrentViewName] =
|
|
12743
|
-
const [selectedViewNames, setSelectedViewNames] =
|
|
12744
|
-
const [availableViewNames, setAvailableViewNames] =
|
|
12745
|
-
const [viewNamesLoaded, setViewNamesLoaded] =
|
|
12746
|
-
const [isLoadingViewNames, setIsLoadingViewNames] =
|
|
12747
|
-
const [saveViewModalOpen, setSaveViewModalOpen] =
|
|
12748
|
-
const [saveViewName, setSaveViewName] =
|
|
12749
|
-
const [saveViewAsNew, setSaveViewAsNew] =
|
|
12750
|
-
const [pendingSaveTarget, setPendingSaveTarget] =
|
|
12751
|
-
const [renameViewModalOpen, setRenameViewModalOpen] =
|
|
12752
|
-
const [renameViewName, setRenameViewName] =
|
|
12753
|
-
const [pageSize, setPageSize] =
|
|
12754
|
-
const [currentPage, setCurrentPage] =
|
|
12755
|
-
const [serverTotalRows, setServerTotalRows] =
|
|
12756
|
-
const [fullDataLoaded, setFullDataLoaded] =
|
|
12757
|
-
const [relationRowsCapped, setRelationRowsCapped] =
|
|
12758
|
-
const [loadedRowsCount, setLoadedRowsCount] =
|
|
12759
|
-
const [loadAllRelatedRequested, setLoadAllRelatedRequested] =
|
|
12760
|
-
const [loading, setLoading] =
|
|
12761
|
-
const [error, setError] =
|
|
12762
|
-
const [listVisible, setListVisible] =
|
|
12763
|
-
const [isAnalyzeVertical, setIsAnalyzeVertical] =
|
|
12764
|
-
const [isAnalyzeFirst, setIsAnalyzeFirst] =
|
|
12765
|
-
const [labelCache, setLabelCache] =
|
|
12766
|
-
const [analyzeOpen, setAnalyzeOpen] =
|
|
12767
|
-
const analyzeTouchedRef =
|
|
12768
|
-
const analyzePrefsTouchedRef =
|
|
12769
|
-
const analyzePrefsLoadedRef =
|
|
12770
|
-
const [analyzePrefsReady, setAnalyzePrefsReady] =
|
|
12771
|
-
const analyzePrefsResourceRef =
|
|
12772
|
-
const [categoryField1, setCategoryField1] =
|
|
12773
|
-
const [categoryField2, setCategoryField2] =
|
|
12774
|
-
const [crosstabFilterFields, setCrosstabFilterFields] =
|
|
12775
|
-
const [crosstabStaged, setCrosstabStaged] =
|
|
12776
|
-
const [chartType, setChartType] =
|
|
12777
|
-
const [summaryFn, setSummaryFn] =
|
|
12778
|
-
const [selectedSeriesKeys, setSelectedSeriesKeys] =
|
|
12779
|
-
const [rankingMode, setRankingMode] =
|
|
12780
|
-
const [rankingFieldKey, setRankingFieldKey] =
|
|
12781
|
-
const [rankingN, setRankingN] =
|
|
12782
|
-
const [exportRequested, setExportRequested] =
|
|
12783
|
-
const [isStatsFlipped, setIsStatsFlipped] =
|
|
12784
|
-
const [isSavingAnalyzePrefs, setIsSavingAnalyzePrefs] =
|
|
12785
|
-
const [chartAnimationKey, setChartAnimationKey] =
|
|
12786
|
-
const [chartAnimationStage, setChartAnimationStage] =
|
|
12787
|
-
const [isTotalsDetailsFlipped, setIsTotalsDetailsFlipped] =
|
|
12788
|
-
const defaultDisplayFields =
|
|
12789
|
-
const orderedColumnKeys =
|
|
12781
|
+
const chartSvgRef = React6.useRef(null);
|
|
12782
|
+
const skipNextAnimationRef = React6.useRef(false);
|
|
12783
|
+
const [rows, setRows] = React6.useState([]);
|
|
12784
|
+
const [localSearch, setLocalSearch] = React6.useState("");
|
|
12785
|
+
const [filterRules, setFilterRules] = React6.useState([]);
|
|
12786
|
+
const [filtersCollapsed, setFiltersCollapsed] = React6.useState(true);
|
|
12787
|
+
const [columnsSelectorOpen, setColumnsSelectorOpen] = React6.useState(false);
|
|
12788
|
+
const [selectedColumnKeys, setSelectedColumnKeys] = React6.useState(null);
|
|
12789
|
+
const [columnOrder, setColumnOrder] = React6.useState(null);
|
|
12790
|
+
const [totalsSummaryFunctions, setTotalsSummaryFunctions] = React6.useState({});
|
|
12791
|
+
const [columnFiltersSelected, setColumnFiltersSelected] = React6.useState({});
|
|
12792
|
+
const [columnSort, setColumnSort] = React6.useState([]);
|
|
12793
|
+
const [currentViewName, setCurrentViewName] = React6.useState(getDefaultViewName());
|
|
12794
|
+
const [selectedViewNames, setSelectedViewNames] = React6.useState([]);
|
|
12795
|
+
const [availableViewNames, setAvailableViewNames] = React6.useState([]);
|
|
12796
|
+
const [viewNamesLoaded, setViewNamesLoaded] = React6.useState(false);
|
|
12797
|
+
const [isLoadingViewNames, setIsLoadingViewNames] = React6.useState(false);
|
|
12798
|
+
const [saveViewModalOpen, setSaveViewModalOpen] = React6.useState(false);
|
|
12799
|
+
const [saveViewName, setSaveViewName] = React6.useState(getDefaultViewName());
|
|
12800
|
+
const [saveViewAsNew, setSaveViewAsNew] = React6.useState(false);
|
|
12801
|
+
const [pendingSaveTarget, setPendingSaveTarget] = React6.useState(null);
|
|
12802
|
+
const [renameViewModalOpen, setRenameViewModalOpen] = React6.useState(false);
|
|
12803
|
+
const [renameViewName, setRenameViewName] = React6.useState("");
|
|
12804
|
+
const [pageSize, setPageSize] = React6.useState(10);
|
|
12805
|
+
const [currentPage, setCurrentPage] = React6.useState(1);
|
|
12806
|
+
const [serverTotalRows, setServerTotalRows] = React6.useState(0);
|
|
12807
|
+
const [fullDataLoaded, setFullDataLoaded] = React6.useState(false);
|
|
12808
|
+
const [relationRowsCapped, setRelationRowsCapped] = React6.useState(false);
|
|
12809
|
+
const [loadedRowsCount, setLoadedRowsCount] = React6.useState(0);
|
|
12810
|
+
const [loadAllRelatedRequested, setLoadAllRelatedRequested] = React6.useState(false);
|
|
12811
|
+
const [loading, setLoading] = React6.useState(false);
|
|
12812
|
+
const [error, setError] = React6.useState(null);
|
|
12813
|
+
const [listVisible, setListVisible] = React6.useState(true);
|
|
12814
|
+
const [isAnalyzeVertical, setIsAnalyzeVertical] = React6.useState(false);
|
|
12815
|
+
const [isAnalyzeFirst, setIsAnalyzeFirst] = React6.useState(false);
|
|
12816
|
+
const [labelCache, setLabelCache] = React6.useState({});
|
|
12817
|
+
const [analyzeOpen, setAnalyzeOpen] = React6.useState(false);
|
|
12818
|
+
const analyzeTouchedRef = React6.useRef(false);
|
|
12819
|
+
const analyzePrefsTouchedRef = React6.useRef(false);
|
|
12820
|
+
const analyzePrefsLoadedRef = React6.useRef(false);
|
|
12821
|
+
const [analyzePrefsReady, setAnalyzePrefsReady] = React6.useState(false);
|
|
12822
|
+
const analyzePrefsResourceRef = React6.useRef(null);
|
|
12823
|
+
const [categoryField1, setCategoryField1] = React6.useState(null);
|
|
12824
|
+
const [categoryField2, setCategoryField2] = React6.useState(void 0);
|
|
12825
|
+
const [crosstabFilterFields, setCrosstabFilterFields] = React6.useState([]);
|
|
12826
|
+
const [crosstabStaged, setCrosstabStaged] = React6.useState({});
|
|
12827
|
+
const [chartType, setChartType] = React6.useState("area");
|
|
12828
|
+
const [summaryFn, setSummaryFn] = React6.useState("sum");
|
|
12829
|
+
const [selectedSeriesKeys, setSelectedSeriesKeys] = React6.useState(null);
|
|
12830
|
+
const [rankingMode, setRankingMode] = React6.useState("none");
|
|
12831
|
+
const [rankingFieldKey, setRankingFieldKey] = React6.useState(null);
|
|
12832
|
+
const [rankingN, setRankingN] = React6.useState(10);
|
|
12833
|
+
const [exportRequested, setExportRequested] = React6.useState(false);
|
|
12834
|
+
const [isStatsFlipped, setIsStatsFlipped] = React6.useState(false);
|
|
12835
|
+
const [isSavingAnalyzePrefs, setIsSavingAnalyzePrefs] = React6.useState(false);
|
|
12836
|
+
const [chartAnimationKey, setChartAnimationKey] = React6.useState(0);
|
|
12837
|
+
const [chartAnimationStage, setChartAnimationStage] = React6.useState("enter");
|
|
12838
|
+
const [isTotalsDetailsFlipped, setIsTotalsDetailsFlipped] = React6.useState(false);
|
|
12839
|
+
const defaultDisplayFields = React6.useMemo(() => getListViewFields(relatedModel), [relatedModel]);
|
|
12840
|
+
const orderedColumnKeys = React6.useMemo(() => {
|
|
12790
12841
|
if (!selectedColumnKeys || selectedColumnKeys.length === 0) return null;
|
|
12791
12842
|
const order = columnOrder && columnOrder.length > 0 ? columnOrder : selectedColumnKeys;
|
|
12792
12843
|
const selectedSet = new Set(selectedColumnKeys);
|
|
12793
12844
|
const availableKeys = new Set(relatedModel.fields.map((field) => field.key));
|
|
12794
12845
|
return order.filter((key) => selectedSet.has(key) && availableKeys.has(key));
|
|
12795
12846
|
}, [columnOrder, relatedModel.fields, selectedColumnKeys]);
|
|
12796
|
-
const displayFields =
|
|
12847
|
+
const displayFields = React6.useMemo(() => {
|
|
12797
12848
|
if (!orderedColumnKeys) return defaultDisplayFields;
|
|
12798
12849
|
const fieldMap = new Map(relatedModel.fields.map((field) => [field.key, field]));
|
|
12799
12850
|
return orderedColumnKeys.map((key) => fieldMap.get(key)).filter((field) => Boolean(field));
|
|
12800
12851
|
}, [defaultDisplayFields, orderedColumnKeys, relatedModel.fields]);
|
|
12801
12852
|
const numericBarColor = relatedModelTone.soft || token.colorPrimaryBg || "rgba(22, 119, 255, 0.16)";
|
|
12802
12853
|
const [form] = antd.Form.useForm();
|
|
12803
|
-
const [savingAll, setSavingAll] =
|
|
12804
|
-
const [hasPendingEdits, setHasPendingEdits] =
|
|
12854
|
+
const [savingAll, setSavingAll] = React6.useState(false);
|
|
12855
|
+
const [hasPendingEdits, setHasPendingEdits] = React6.useState(false);
|
|
12805
12856
|
const { setWarnWhen } = core.useWarnAboutChange();
|
|
12806
|
-
const [isSavingLayoutPrefs, setIsSavingLayoutPrefs] =
|
|
12807
|
-
const layoutPrefsTouchedRef =
|
|
12808
|
-
const layoutPrefsLoadedRef =
|
|
12809
|
-
const layoutPrefsResourceRef =
|
|
12810
|
-
const sortIntentRef =
|
|
12857
|
+
const [isSavingLayoutPrefs, setIsSavingLayoutPrefs] = React6.useState(false);
|
|
12858
|
+
const layoutPrefsTouchedRef = React6.useRef(false);
|
|
12859
|
+
const layoutPrefsLoadedRef = React6.useRef(false);
|
|
12860
|
+
const layoutPrefsResourceRef = React6.useRef(null);
|
|
12861
|
+
const sortIntentRef = React6.useRef(null);
|
|
12811
12862
|
const { settings: viewSettings } = useViewSettings();
|
|
12812
12863
|
const relationsMaxRowsToLoad = Math.max(0, Number(viewSettings?.relationsMaxRowsToLoad ?? 1e3));
|
|
12813
|
-
const markAnalyzePrefsTouched =
|
|
12864
|
+
const markAnalyzePrefsTouched = React6.useCallback(() => {
|
|
12814
12865
|
analyzePrefsTouchedRef.current = true;
|
|
12815
12866
|
}, []);
|
|
12816
|
-
const markLayoutPrefsTouched =
|
|
12867
|
+
const markLayoutPrefsTouched = React6.useCallback(() => {
|
|
12817
12868
|
layoutPrefsTouchedRef.current = true;
|
|
12818
12869
|
}, []);
|
|
12819
|
-
const persistLayoutPreferences =
|
|
12870
|
+
const persistLayoutPreferences = React6.useCallback(async (viewName) => {
|
|
12820
12871
|
if (!layoutPreferenceType) return;
|
|
12821
12872
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
12822
12873
|
const resolvedViewName = normalizeViewName(viewName);
|
|
@@ -12860,7 +12911,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12860
12911
|
setIsSavingLayoutPrefs(false);
|
|
12861
12912
|
}
|
|
12862
12913
|
}, [apiUrl, analyzeOpen, columnFiltersSelected, columnOrder, columnSort, filtersCollapsed, filterRules, isAnalyzeFirst, isAnalyzeVertical, layoutPreferenceType, listVisible, pageSize, selectedColumnKeys, relatedModel.name, relatedModel.resource, totalsSummaryFunctions, allModels]);
|
|
12863
|
-
const persistAnalyzePreferences =
|
|
12914
|
+
const persistAnalyzePreferences = React6.useCallback(async (viewName) => {
|
|
12864
12915
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
12865
12916
|
const resolvedViewName = normalizeViewName(viewName);
|
|
12866
12917
|
const preferences = {
|
|
@@ -12892,13 +12943,13 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12892
12943
|
setIsSavingAnalyzePrefs(false);
|
|
12893
12944
|
}
|
|
12894
12945
|
}, [apiUrl, categoryField1, categoryField2, chartType, selectedSeriesKeys, summaryFn, rankingMode, rankingFieldKey, rankingN, crosstabFilterFields, relatedModel.name, relatedModel.resource, allModels]);
|
|
12895
|
-
const categoricalFields =
|
|
12946
|
+
const categoricalFields = React6.useMemo(() => {
|
|
12896
12947
|
return relatedModel.fields.filter((field) => isPkField(field, relatedModel) || (field.type !== "number" || field.reference));
|
|
12897
12948
|
}, [relatedModel]);
|
|
12898
|
-
const numericFields =
|
|
12949
|
+
const numericFields = React6.useMemo(() => {
|
|
12899
12950
|
return relatedModel.fields.filter((field) => !isPkField(field, relatedModel) && field.type === "number" && !field.reference);
|
|
12900
12951
|
}, [relatedModel]);
|
|
12901
|
-
const resetLayoutDefaults =
|
|
12952
|
+
const resetLayoutDefaults = React6.useCallback(() => {
|
|
12902
12953
|
setListVisible(true);
|
|
12903
12954
|
setAnalyzeOpen(false);
|
|
12904
12955
|
setIsAnalyzeVertical(false);
|
|
@@ -12908,7 +12959,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12908
12959
|
setSelectedColumnKeys(null);
|
|
12909
12960
|
setColumnOrder(null);
|
|
12910
12961
|
}, []);
|
|
12911
|
-
const resetAnalyzeDefaults =
|
|
12962
|
+
const resetAnalyzeDefaults = React6.useCallback(() => {
|
|
12912
12963
|
setCategoryField1(categoricalFields[0]?.key ?? null);
|
|
12913
12964
|
setCategoryField2(categoricalFields.length > 1 ? categoricalFields[1].key : null);
|
|
12914
12965
|
setChartType("area");
|
|
@@ -12919,7 +12970,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12919
12970
|
setRankingN(10);
|
|
12920
12971
|
setCrosstabFilterFields([]);
|
|
12921
12972
|
}, [categoricalFields, numericFields]);
|
|
12922
|
-
const persistCurrentViewNames =
|
|
12973
|
+
const persistCurrentViewNames = React6.useCallback(async (nextSelected, nextCurrent) => {
|
|
12923
12974
|
try {
|
|
12924
12975
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
12925
12976
|
await authenticatedFetch(`${apiUrl}/views/preferences/view`, {
|
|
@@ -12935,7 +12986,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12935
12986
|
} catch {
|
|
12936
12987
|
}
|
|
12937
12988
|
}, [apiUrl, relatedModel.name, relatedModel.resource, allModels]);
|
|
12938
|
-
const loadViewNames =
|
|
12989
|
+
const loadViewNames = React6.useCallback(async () => {
|
|
12939
12990
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
12940
12991
|
setIsLoadingViewNames(true);
|
|
12941
12992
|
try {
|
|
@@ -12980,13 +13031,13 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
12980
13031
|
setIsLoadingViewNames(false);
|
|
12981
13032
|
}
|
|
12982
13033
|
}, [apiUrl, relatedModel.name, relatedModel.resource, allModels]);
|
|
12983
|
-
const openSaveViewModalFor =
|
|
13034
|
+
const openSaveViewModalFor = React6.useCallback((target) => {
|
|
12984
13035
|
setSaveViewName(currentViewName || getDefaultViewName());
|
|
12985
13036
|
setSaveViewAsNew(false);
|
|
12986
13037
|
setPendingSaveTarget(target);
|
|
12987
13038
|
setSaveViewModalOpen(true);
|
|
12988
13039
|
}, [currentViewName]);
|
|
12989
|
-
const handleConfirmSaveView =
|
|
13040
|
+
const handleConfirmSaveView = React6.useCallback(async () => {
|
|
12990
13041
|
if (!pendingSaveTarget) return;
|
|
12991
13042
|
const viewName = normalizeViewName(saveViewName || currentViewName);
|
|
12992
13043
|
const viewExists = availableViewNames.includes(viewName);
|
|
@@ -13013,14 +13064,14 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13013
13064
|
await persistCurrentViewNames(nextSelected, viewName);
|
|
13014
13065
|
await loadViewNames();
|
|
13015
13066
|
}, [availableViewNames, currentViewName, loadViewNames, pendingSaveTarget, persistAnalyzePreferences, persistCurrentViewNames, persistLayoutPreferences, saveViewAsNew, saveViewName, selectedViewNames]);
|
|
13016
|
-
const handleChangeViewName =
|
|
13067
|
+
const handleChangeViewName = React6.useCallback(async (nextView) => {
|
|
13017
13068
|
const resolvedName = normalizeViewName(nextView);
|
|
13018
13069
|
setCurrentViewName(resolvedName);
|
|
13019
13070
|
setSaveViewName(resolvedName);
|
|
13020
13071
|
const nextSelected = selectedViewNames.length > 0 ? selectedViewNames : [resolvedName];
|
|
13021
13072
|
await persistCurrentViewNames(nextSelected, resolvedName);
|
|
13022
13073
|
}, [persistCurrentViewNames, selectedViewNames]);
|
|
13023
|
-
const updateSelectedViewNames =
|
|
13074
|
+
const updateSelectedViewNames = React6.useCallback(async (nextSelected) => {
|
|
13024
13075
|
if (nextSelected.length === 0) {
|
|
13025
13076
|
nextSelected = [getDefaultViewName()];
|
|
13026
13077
|
}
|
|
@@ -13032,7 +13083,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13032
13083
|
}
|
|
13033
13084
|
await persistCurrentViewNames(nextSelected, nextCurrent);
|
|
13034
13085
|
}, [currentViewName, persistCurrentViewNames]);
|
|
13035
|
-
const moveSelectedView =
|
|
13086
|
+
const moveSelectedView = React6.useCallback((name, direction) => {
|
|
13036
13087
|
setSelectedViewNames((prev) => {
|
|
13037
13088
|
const idx = prev.indexOf(name);
|
|
13038
13089
|
if (idx < 0) return prev;
|
|
@@ -13044,7 +13095,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13044
13095
|
return next;
|
|
13045
13096
|
});
|
|
13046
13097
|
}, [currentViewName, persistCurrentViewNames]);
|
|
13047
|
-
const handleRenameView =
|
|
13098
|
+
const handleRenameView = React6.useCallback(async () => {
|
|
13048
13099
|
const newName = normalizeViewName(renameViewName);
|
|
13049
13100
|
if (!newName || newName === currentViewName) {
|
|
13050
13101
|
setRenameViewModalOpen(false);
|
|
@@ -13071,7 +13122,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13071
13122
|
antd.message.error(error2 instanceof Error ? error2.message : _34("Failed to rename view."));
|
|
13072
13123
|
}
|
|
13073
13124
|
}, [apiUrl, availableViewNames, currentViewName, relatedModel.name, relatedModel.resource, renameViewName, allModels, loadViewNames]);
|
|
13074
|
-
const confirmDeleteView =
|
|
13125
|
+
const confirmDeleteView = React6.useCallback(() => {
|
|
13075
13126
|
antd.Modal.confirm({
|
|
13076
13127
|
title: _34(_34("Delete view")),
|
|
13077
13128
|
content: `Delete "${currentViewName}" and all its saved preferences?`,
|
|
@@ -13116,10 +13167,10 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13116
13167
|
items: selectedViewNames.map((name) => ({ key: name, label: renderToneTabLabel(name, relatedModelTone) }))
|
|
13117
13168
|
}
|
|
13118
13169
|
) : null;
|
|
13119
|
-
|
|
13170
|
+
React6.useEffect(() => {
|
|
13120
13171
|
loadViewNames();
|
|
13121
13172
|
}, [loadViewNames]);
|
|
13122
|
-
|
|
13173
|
+
React6.useEffect(() => {
|
|
13123
13174
|
if (!viewNamesLoaded) return;
|
|
13124
13175
|
analyzePrefsTouchedRef.current = false;
|
|
13125
13176
|
layoutPrefsTouchedRef.current = false;
|
|
@@ -13131,7 +13182,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13131
13182
|
resetLayoutDefaults();
|
|
13132
13183
|
resetAnalyzeDefaults();
|
|
13133
13184
|
}, [currentViewName, resetAnalyzeDefaults, resetLayoutDefaults, viewNamesLoaded]);
|
|
13134
|
-
|
|
13185
|
+
React6.useEffect(() => {
|
|
13135
13186
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
13136
13187
|
const viewKey = `${resourceKey}::${currentViewName}`;
|
|
13137
13188
|
if (analyzePrefsResourceRef.current !== viewKey) {
|
|
@@ -13184,7 +13235,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13184
13235
|
cancelled = true;
|
|
13185
13236
|
};
|
|
13186
13237
|
}, [apiUrl, currentViewName, relatedModel.name, relatedModel.resource, allModels]);
|
|
13187
|
-
|
|
13238
|
+
React6.useEffect(() => {
|
|
13188
13239
|
if (!layoutPreferenceType) return;
|
|
13189
13240
|
const resourceKey = resolveResourcePath(relatedModel.resource || relatedModel.name, allModels);
|
|
13190
13241
|
const viewKey = `${resourceKey}::${layoutPreferenceType}::${currentViewName}`;
|
|
@@ -13263,17 +13314,17 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13263
13314
|
cancelled = true;
|
|
13264
13315
|
};
|
|
13265
13316
|
}, [apiUrl, currentViewName, layoutPreferenceType, relatedModel.name, relatedModel.resource, allModels, viewNamesLoaded]);
|
|
13266
|
-
const normalizeFieldValue =
|
|
13317
|
+
const normalizeFieldValue = React6.useCallback((field, value) => {
|
|
13267
13318
|
if (field.type === "date" && value) {
|
|
13268
13319
|
if (typeof value?.toISOString === "function") return value.toISOString();
|
|
13269
13320
|
if (typeof value?.format === "function") return value.format("YYYY-MM-DD");
|
|
13270
13321
|
}
|
|
13271
13322
|
return value;
|
|
13272
13323
|
}, []);
|
|
13273
|
-
const hasActiveFilterRules =
|
|
13324
|
+
const hasActiveFilterRules = React6.useMemo(() => {
|
|
13274
13325
|
return filterRules.some((rule) => rule.fieldKey && rule.operator && (rule.value !== void 0 && rule.value !== null && rule.value !== ""));
|
|
13275
13326
|
}, [filterRules]);
|
|
13276
|
-
const resolveRelativeDate =
|
|
13327
|
+
const resolveRelativeDate = React6.useCallback((value, asRange) => {
|
|
13277
13328
|
const count = Number(value?.count ?? 1);
|
|
13278
13329
|
const direction = value?.direction || "next";
|
|
13279
13330
|
const unit = value?.unit || "weeks";
|
|
@@ -13299,7 +13350,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13299
13350
|
}
|
|
13300
13351
|
return { date: target.startOf(unit) };
|
|
13301
13352
|
}, []);
|
|
13302
|
-
const getFieldValueForFilter =
|
|
13353
|
+
const getFieldValueForFilter = React6.useCallback((field, recordRow) => {
|
|
13303
13354
|
const raw = recordRow?.[field.key];
|
|
13304
13355
|
if (raw === void 0 || raw === null) return raw;
|
|
13305
13356
|
if (field.reference) {
|
|
@@ -13311,7 +13362,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13311
13362
|
}
|
|
13312
13363
|
return raw;
|
|
13313
13364
|
}, [labelCache]);
|
|
13314
|
-
const matchesRule =
|
|
13365
|
+
const matchesRule = React6.useCallback((recordRow, rule) => {
|
|
13315
13366
|
const field = relatedModel.fields.find((f) => f.key === rule.fieldKey);
|
|
13316
13367
|
if (!field || !rule.operator) return true;
|
|
13317
13368
|
const rawValue = getFieldValueForFilter(field, recordRow);
|
|
@@ -13391,7 +13442,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13391
13442
|
}
|
|
13392
13443
|
return true;
|
|
13393
13444
|
}, [getFieldValueForFilter, relatedModel.fields, resolveRelativeDate]);
|
|
13394
|
-
const applyGlobalSearch =
|
|
13445
|
+
const applyGlobalSearch = React6.useCallback((data) => {
|
|
13395
13446
|
const query = localSearch.trim().toLowerCase();
|
|
13396
13447
|
if (!query) return data;
|
|
13397
13448
|
return data.filter((recordRow) => {
|
|
@@ -13410,14 +13461,14 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13410
13461
|
return candidates.some((value) => value !== void 0 && value !== null && String(value).toLowerCase().includes(query));
|
|
13411
13462
|
});
|
|
13412
13463
|
}, [labelCache, localSearch, relatedModel.fields]);
|
|
13413
|
-
const applyFilterRules =
|
|
13464
|
+
const applyFilterRules = React6.useCallback((data) => {
|
|
13414
13465
|
if (!hasActiveFilterRules) return data;
|
|
13415
13466
|
return data.filter((recordRow) => filterRules.every((rule) => matchesRule(recordRow, rule)));
|
|
13416
13467
|
}, [filterRules, hasActiveFilterRules, matchesRule]);
|
|
13417
|
-
const filteredRows =
|
|
13468
|
+
const filteredRows = React6.useMemo(() => {
|
|
13418
13469
|
return applyFilterRules(applyGlobalSearch(rows || []));
|
|
13419
13470
|
}, [applyFilterRules, applyGlobalSearch, rows]);
|
|
13420
|
-
const columnFilteredRows =
|
|
13471
|
+
const columnFilteredRows = React6.useMemo(() => {
|
|
13421
13472
|
const activeEntries = Object.entries(columnFiltersSelected).filter(([, values]) => values && values.length > 0);
|
|
13422
13473
|
if (activeEntries.length === 0) return filteredRows;
|
|
13423
13474
|
return filteredRows.filter(
|
|
@@ -13428,10 +13479,10 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13428
13479
|
})
|
|
13429
13480
|
);
|
|
13430
13481
|
}, [filteredRows, columnFiltersSelected, relatedModel.fields]);
|
|
13431
|
-
|
|
13482
|
+
React6.useEffect(() => {
|
|
13432
13483
|
setCurrentPage(1);
|
|
13433
13484
|
}, [localSearch, filterRules]);
|
|
13434
|
-
|
|
13485
|
+
React6.useEffect(() => {
|
|
13435
13486
|
if (!allowInlineEdit) return;
|
|
13436
13487
|
if (form.isFieldsTouched()) return;
|
|
13437
13488
|
const initialValues = {};
|
|
@@ -13445,7 +13496,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13445
13496
|
});
|
|
13446
13497
|
form.setFieldsValue(initialValues);
|
|
13447
13498
|
}, [allowInlineEdit, form, relatedModel.fields, filteredRows]);
|
|
13448
|
-
|
|
13499
|
+
React6.useEffect(() => {
|
|
13449
13500
|
if (!allowInlineEdit) {
|
|
13450
13501
|
setWarnWhen(false);
|
|
13451
13502
|
return;
|
|
@@ -13453,7 +13504,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13453
13504
|
setWarnWhen(hasPendingEdits);
|
|
13454
13505
|
return () => setWarnWhen(false);
|
|
13455
13506
|
}, [allowInlineEdit, hasPendingEdits, setWarnWhen]);
|
|
13456
|
-
const saveAllEdits =
|
|
13507
|
+
const saveAllEdits = React6.useCallback(async () => {
|
|
13457
13508
|
if (!allowInlineEdit) return;
|
|
13458
13509
|
setSavingAll(true);
|
|
13459
13510
|
try {
|
|
@@ -13507,7 +13558,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13507
13558
|
setSavingAll(false);
|
|
13508
13559
|
}
|
|
13509
13560
|
}, [allowInlineEdit, apiUrl, form, normalizeFieldValue, relatedModel.fields, relatedModel.name, relatedModel.resource, allModels, rows]);
|
|
13510
|
-
const handleDeleteRelationRow =
|
|
13561
|
+
const handleDeleteRelationRow = React6.useCallback((row) => {
|
|
13511
13562
|
const relationRow = row?.__relationRow;
|
|
13512
13563
|
const deleteId = relationRow && rel.targetKey && rel.otherKey ? `${relationRow["eid_from"]}:${relationRow["eid_to"]}` : relationRow?.id ?? relationRow?.eid;
|
|
13513
13564
|
if (deleteId === void 0 || deleteId === null) return;
|
|
@@ -13564,7 +13615,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13564
13615
|
overflow: "visible",
|
|
13565
13616
|
order: isAnalyzeFirst ? 1 : 2
|
|
13566
13617
|
};
|
|
13567
|
-
const getSortValue =
|
|
13618
|
+
const getSortValue = React6.useCallback((field, recordRow) => {
|
|
13568
13619
|
const raw = recordRow?.[field.key];
|
|
13569
13620
|
if (raw === void 0 || raw === null) return null;
|
|
13570
13621
|
if (isPkField(field, relatedModel) && recordRow?._label) return recordRow._label;
|
|
@@ -13583,7 +13634,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13583
13634
|
if (field.type === "boolean") return raw ? 1 : 0;
|
|
13584
13635
|
return raw;
|
|
13585
13636
|
}, [labelCache]);
|
|
13586
|
-
const compareSortValues =
|
|
13637
|
+
const compareSortValues = React6.useCallback((field, a, b) => {
|
|
13587
13638
|
const aVal = getSortValue(field, a);
|
|
13588
13639
|
const bVal = getSortValue(field, b);
|
|
13589
13640
|
if (aVal === null && bVal === null) return 0;
|
|
@@ -13592,11 +13643,11 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13592
13643
|
if (typeof aVal === "number" && typeof bVal === "number") return aVal - bVal;
|
|
13593
13644
|
return String(aVal).localeCompare(String(bVal));
|
|
13594
13645
|
}, [getSortValue]);
|
|
13595
|
-
const shouldUseFullDataMode =
|
|
13646
|
+
const shouldUseFullDataMode = React6.useMemo(() => {
|
|
13596
13647
|
if (loadAllRelatedRequested) return true;
|
|
13597
13648
|
return false;
|
|
13598
13649
|
}, [loadAllRelatedRequested]);
|
|
13599
|
-
const fetchRelatedDetailsByIds =
|
|
13650
|
+
const fetchRelatedDetailsByIds = React6.useCallback(async (ids, signal) => {
|
|
13600
13651
|
const uniqueIds = Array.from(new Set(ids.filter((value) => value !== void 0 && value !== null)));
|
|
13601
13652
|
if (!rel.otherResource || uniqueIds.length === 0) return [];
|
|
13602
13653
|
const relatedResource = rel.otherResourcePath || resolveResourcePath(rel.otherResource, allModels);
|
|
@@ -13647,7 +13698,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13647
13698
|
const now = performance.now();
|
|
13648
13699
|
console.log(`[JM_TRACE ${now.toFixed(1)}ms] ${label}${detail ? " | " + detail : ""}`);
|
|
13649
13700
|
};
|
|
13650
|
-
|
|
13701
|
+
React6.useEffect(() => {
|
|
13651
13702
|
if (!recordId || !rel.otherResource || !rel.otherKey) {
|
|
13652
13703
|
setRows([]);
|
|
13653
13704
|
setServerTotalRows(0);
|
|
@@ -13794,26 +13845,26 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13794
13845
|
controller.abort();
|
|
13795
13846
|
};
|
|
13796
13847
|
}, [apiUrl, currentPage, pageSize, recordId, rel.label, rel.otherKey, rel.otherResource, rel.resource, rel.targetKey, allowedRelatedIds, allModels, rel.resourcePath, rel.otherResourcePath, shouldUseFullDataMode, fetchRelatedDetailsByIds, fullDataLoaded, relationsMaxRowsToLoad, rows.length]);
|
|
13797
|
-
|
|
13848
|
+
React6.useEffect(() => {
|
|
13798
13849
|
if (!shouldUseFullDataMode && fullDataLoaded) {
|
|
13799
13850
|
setFullDataLoaded(false);
|
|
13800
13851
|
}
|
|
13801
13852
|
}, [fullDataLoaded, shouldUseFullDataMode]);
|
|
13802
|
-
|
|
13853
|
+
React6.useEffect(() => {
|
|
13803
13854
|
if (loading) return;
|
|
13804
13855
|
if (analyzeTouchedRef.current) return;
|
|
13805
13856
|
if (filteredRows.length <= 1 && analyzeOpen) {
|
|
13806
13857
|
setAnalyzeOpen(false);
|
|
13807
13858
|
}
|
|
13808
13859
|
}, [analyzeOpen, filteredRows.length, loading]);
|
|
13809
|
-
|
|
13860
|
+
React6.useEffect(() => {
|
|
13810
13861
|
if (loading) return;
|
|
13811
13862
|
if (analyzeTouchedRef.current) return;
|
|
13812
13863
|
if (filteredRows.length > 1 && !analyzeOpen) {
|
|
13813
13864
|
setAnalyzeOpen(true);
|
|
13814
13865
|
}
|
|
13815
13866
|
}, [analyzeOpen, filteredRows.length, loading]);
|
|
13816
|
-
|
|
13867
|
+
React6.useEffect(() => {
|
|
13817
13868
|
if (!categoryField1 && categoricalFields.length > 0) {
|
|
13818
13869
|
setCategoryField1(categoricalFields[0].key);
|
|
13819
13870
|
}
|
|
@@ -13821,7 +13872,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13821
13872
|
setCategoryField2(categoricalFields[1].key);
|
|
13822
13873
|
}
|
|
13823
13874
|
}, [categoricalFields, categoryField1, categoryField2]);
|
|
13824
|
-
|
|
13875
|
+
React6.useEffect(() => {
|
|
13825
13876
|
if (selectedSeriesKeys !== null) return;
|
|
13826
13877
|
if (numericFields.length > 0) {
|
|
13827
13878
|
setSelectedSeriesKeys(numericFields.map((field) => field.key));
|
|
@@ -13829,7 +13880,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13829
13880
|
setSelectedSeriesKeys(["__count__"]);
|
|
13830
13881
|
}
|
|
13831
13882
|
}, [numericFields, selectedSeriesKeys]);
|
|
13832
|
-
|
|
13883
|
+
React6.useEffect(() => {
|
|
13833
13884
|
if (numericFields.length === 0) {
|
|
13834
13885
|
if (rankingFieldKey !== null) setRankingFieldKey(null);
|
|
13835
13886
|
if (rankingMode !== "none") setRankingMode("none");
|
|
@@ -13839,7 +13890,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13839
13890
|
setRankingFieldKey(numericFields[0].key);
|
|
13840
13891
|
}
|
|
13841
13892
|
}, [numericFields, rankingFieldKey, rankingMode]);
|
|
13842
|
-
const formatCategoryValue =
|
|
13893
|
+
const formatCategoryValue = React6.useCallback((field, recordRow) => {
|
|
13843
13894
|
if (!field) return _34("All");
|
|
13844
13895
|
const raw = recordRow?.[field.key];
|
|
13845
13896
|
if (raw === void 0 || raw === null) return "-";
|
|
@@ -13855,14 +13906,14 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13855
13906
|
if (field.type === "date") return formatDateValue(raw);
|
|
13856
13907
|
return String(raw);
|
|
13857
13908
|
}, [labelCache]);
|
|
13858
|
-
const chartTitle =
|
|
13909
|
+
const chartTitle = React6.useMemo(() => {
|
|
13859
13910
|
const cat1Label = categoryField1 ? relatedModel.fields.find((field) => field.key === categoryField1)?.label : "All";
|
|
13860
13911
|
const cat2Label = categoryField2 ? relatedModel.fields.find((field) => field.key === categoryField2)?.label : null;
|
|
13861
13912
|
const parts = [relatedModel.label || relatedModel.name, cat1Label];
|
|
13862
13913
|
if (cat2Label) parts.push(cat2Label);
|
|
13863
13914
|
return parts.filter(Boolean).join(" \u2022 ");
|
|
13864
13915
|
}, [categoryField1, categoryField2, relatedModel.fields, relatedModel.label, relatedModel.name]);
|
|
13865
|
-
const chartData =
|
|
13916
|
+
const chartData = React6.useMemo(() => {
|
|
13866
13917
|
const data = Array.isArray(columnFilteredRows) ? columnFilteredRows : [];
|
|
13867
13918
|
const cat1Field = categoryField1 ? relatedModel.fields.find((field) => field.key === categoryField1) : void 0;
|
|
13868
13919
|
const cat2Field = categoryField2 ? relatedModel.fields.find((field) => field.key === categoryField2) : void 0;
|
|
@@ -13970,7 +14021,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13970
14021
|
};
|
|
13971
14022
|
}, [columnFilteredRows, categoryField1, categoryField2, relatedModel.fields, numericFields, formatCategoryValue, summaryFn, selectedSeriesKeys, rankingMode, rankingFieldKey, rankingN]);
|
|
13972
14023
|
const editableCrosstab = isCrosstabView && allowInlineEdit;
|
|
13973
|
-
const stageCrosstabCellEdits =
|
|
14024
|
+
const stageCrosstabCellEdits = React6.useCallback((updates) => {
|
|
13974
14025
|
if (updates.length === 0) return;
|
|
13975
14026
|
setCrosstabStaged((prev) => {
|
|
13976
14027
|
const next = { ...prev };
|
|
@@ -13985,11 +14036,11 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
13985
14036
|
});
|
|
13986
14037
|
setHasPendingEdits(true);
|
|
13987
14038
|
}, [form]);
|
|
13988
|
-
const getCrosstabStagedValue =
|
|
14039
|
+
const getCrosstabStagedValue = React6.useCallback((recordId2, fieldKey) => {
|
|
13989
14040
|
return crosstabStaged[String(recordId2)]?.[fieldKey];
|
|
13990
14041
|
}, [crosstabStaged]);
|
|
13991
|
-
const crosstabResolvedRefIdsRef =
|
|
13992
|
-
|
|
14042
|
+
const crosstabResolvedRefIdsRef = React6.useRef(/* @__PURE__ */ new Set());
|
|
14043
|
+
React6.useEffect(() => {
|
|
13993
14044
|
if (!isCrosstabView) return;
|
|
13994
14045
|
const refFields = [categoryField1, categoryField2, ...crosstabFilterFields].filter((k) => Boolean(k)).map((k) => relatedModel.fields.find((f) => f.key === k)).filter((f) => Boolean(f && f.reference));
|
|
13995
14046
|
if (refFields.length === 0) return;
|
|
@@ -14025,7 +14076,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14025
14076
|
cancelled = true;
|
|
14026
14077
|
};
|
|
14027
14078
|
}, [isCrosstabView, categoryField1, categoryField2, crosstabFilterFields, columnFilteredRows, relatedModel.fields, allModels, apiUrl]);
|
|
14028
|
-
const crosstabFilterOptions =
|
|
14079
|
+
const crosstabFilterOptions = React6.useMemo(() => {
|
|
14029
14080
|
if (crosstabFilterFields.length === 0) return /* @__PURE__ */ new Map();
|
|
14030
14081
|
const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
|
|
14031
14082
|
const fields = crosstabFilterFields.map((k) => relatedModel.fields.find((f) => f.key === k)).filter((f) => Boolean(f));
|
|
@@ -14195,7 +14246,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14195
14246
|
}
|
|
14196
14247
|
)
|
|
14197
14248
|
] });
|
|
14198
|
-
const numericColumnMaxes =
|
|
14249
|
+
const numericColumnMaxes = React6.useMemo(() => {
|
|
14199
14250
|
const maxes = {};
|
|
14200
14251
|
const data = filteredRows || [];
|
|
14201
14252
|
displayFields.forEach((field) => {
|
|
@@ -14209,7 +14260,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14209
14260
|
});
|
|
14210
14261
|
return maxes;
|
|
14211
14262
|
}, [filteredRows, displayFields]);
|
|
14212
|
-
const chartSignature =
|
|
14263
|
+
const chartSignature = React6.useMemo(() => {
|
|
14213
14264
|
return JSON.stringify({
|
|
14214
14265
|
chartType,
|
|
14215
14266
|
summaryFn,
|
|
@@ -14222,13 +14273,13 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14222
14273
|
groups: chartData.groups
|
|
14223
14274
|
});
|
|
14224
14275
|
}, [chartType, summaryFn, categoryField1, categoryField2, rankingMode, rankingFieldKey, rankingN, chartData]);
|
|
14225
|
-
|
|
14276
|
+
React6.useEffect(() => {
|
|
14226
14277
|
if (!analyzeOpen) return;
|
|
14227
14278
|
skipNextAnimationRef.current = true;
|
|
14228
14279
|
setChartAnimationStage("enter");
|
|
14229
14280
|
setChartAnimationKey((key) => key + 1);
|
|
14230
14281
|
}, [analyzeOpen]);
|
|
14231
|
-
|
|
14282
|
+
React6.useEffect(() => {
|
|
14232
14283
|
if (!analyzeOpen) return;
|
|
14233
14284
|
if (skipNextAnimationRef.current) {
|
|
14234
14285
|
skipNextAnimationRef.current = false;
|
|
@@ -14237,7 +14288,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14237
14288
|
setChartAnimationStage("update");
|
|
14238
14289
|
setChartAnimationKey((key) => key + 1);
|
|
14239
14290
|
}, [analyzeOpen, chartSignature]);
|
|
14240
|
-
const formatValueForExport =
|
|
14291
|
+
const formatValueForExport = React6.useCallback((field, recordRow) => {
|
|
14241
14292
|
const raw = recordRow?.[field.key];
|
|
14242
14293
|
if (raw === void 0 || raw === null) return "";
|
|
14243
14294
|
if (field.reference) {
|
|
@@ -14251,7 +14302,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14251
14302
|
if (field.type === "date") return formatDateValue(raw);
|
|
14252
14303
|
return String(raw);
|
|
14253
14304
|
}, [labelCache]);
|
|
14254
|
-
|
|
14305
|
+
React6.useEffect(() => {
|
|
14255
14306
|
if (!exportRequested) return;
|
|
14256
14307
|
const escapeCsv = (value) => {
|
|
14257
14308
|
if (value.includes('"') || value.includes(",") || value.includes("\n")) {
|
|
@@ -14337,31 +14388,31 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14337
14388
|
const exportStatsPdf = () => {
|
|
14338
14389
|
openPdfWindow(`${relatedModel.name}-stats`, buildStatsHtml(statsSummary));
|
|
14339
14390
|
};
|
|
14340
|
-
const columnFilters =
|
|
14391
|
+
const columnFilters = React6.useMemo(() => {
|
|
14341
14392
|
const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
|
|
14342
14393
|
return buildColumnFilterOptions({ fields: displayFields, data: filteredRows || [], rangeCount });
|
|
14343
14394
|
}, [displayFields, filteredRows, viewSettings]);
|
|
14344
|
-
const allFieldOptions =
|
|
14395
|
+
const allFieldOptions = React6.useMemo(() => {
|
|
14345
14396
|
return relatedModel.fields.map((field) => ({ label: field.label, value: field.key }));
|
|
14346
14397
|
}, [relatedModel.fields]);
|
|
14347
|
-
const orderedSelectedColumns =
|
|
14398
|
+
const orderedSelectedColumns = React6.useMemo(() => {
|
|
14348
14399
|
if (!selectedColumnKeys || selectedColumnKeys.length === 0) return [];
|
|
14349
14400
|
return orderedColumnKeys && orderedColumnKeys.length > 0 ? orderedColumnKeys : selectedColumnKeys;
|
|
14350
14401
|
}, [orderedColumnKeys, selectedColumnKeys]);
|
|
14351
|
-
const syncColumnsSelectionToDisplay =
|
|
14402
|
+
const syncColumnsSelectionToDisplay = React6.useCallback(() => {
|
|
14352
14403
|
const keys = displayFields.map((field) => field.key);
|
|
14353
14404
|
if (keys.length === 0) return;
|
|
14354
14405
|
setSelectedColumnKeys(keys);
|
|
14355
14406
|
setColumnOrder(columnOrder && columnOrder.length > 0 ? columnOrder : keys);
|
|
14356
14407
|
}, [columnOrder, displayFields]);
|
|
14357
|
-
|
|
14408
|
+
React6.useEffect(() => {
|
|
14358
14409
|
if (selectedColumnKeys !== null) return;
|
|
14359
14410
|
const defaults = defaultDisplayFields.map((field) => field.key);
|
|
14360
14411
|
if (defaults.length === 0) return;
|
|
14361
14412
|
setSelectedColumnKeys(defaults);
|
|
14362
14413
|
setColumnOrder(defaults);
|
|
14363
14414
|
}, [defaultDisplayFields, selectedColumnKeys]);
|
|
14364
|
-
const handleColumnSelectionChange =
|
|
14415
|
+
const handleColumnSelectionChange = React6.useCallback((values) => {
|
|
14365
14416
|
markLayoutPrefsTouched();
|
|
14366
14417
|
if (!values || values.length === 0) {
|
|
14367
14418
|
setSelectedColumnKeys(null);
|
|
@@ -14375,7 +14426,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14375
14426
|
return [...baseOrder, ...missing];
|
|
14376
14427
|
});
|
|
14377
14428
|
}, [markLayoutPrefsTouched]);
|
|
14378
|
-
const moveColumnOrder =
|
|
14429
|
+
const moveColumnOrder = React6.useCallback((key, direction) => {
|
|
14379
14430
|
setColumnOrder((prev) => {
|
|
14380
14431
|
const base = prev && prev.length > 0 ? [...prev] : selectedColumnKeys ? [...selectedColumnKeys] : [];
|
|
14381
14432
|
const index = base.indexOf(key);
|
|
@@ -14386,18 +14437,18 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14386
14437
|
return base;
|
|
14387
14438
|
});
|
|
14388
14439
|
}, [selectedColumnKeys]);
|
|
14389
|
-
const statsSummary =
|
|
14440
|
+
const statsSummary = React6.useMemo(() => {
|
|
14390
14441
|
return buildStatsSummary(columnFilteredRows, displayFields, labelCache);
|
|
14391
14442
|
}, [columnFilteredRows, displayFields, labelCache]);
|
|
14392
14443
|
const isTotalsDetailsVariant = viewVariant === "totals-details";
|
|
14393
|
-
const getDefaultTotalsSummaryFn =
|
|
14444
|
+
const getDefaultTotalsSummaryFn = React6.useCallback((field) => {
|
|
14394
14445
|
if (isPkField(field, relatedModel)) return "count";
|
|
14395
14446
|
return "sum";
|
|
14396
14447
|
}, [relatedModel]);
|
|
14397
|
-
const resolveTotalsSummaryFn =
|
|
14448
|
+
const resolveTotalsSummaryFn = React6.useCallback((field) => {
|
|
14398
14449
|
return totalsSummaryFunctions[field.key] || getDefaultTotalsSummaryFn(field);
|
|
14399
14450
|
}, [getDefaultTotalsSummaryFn, totalsSummaryFunctions]);
|
|
14400
|
-
const computeTotalsSummaryValue =
|
|
14451
|
+
const computeTotalsSummaryValue = React6.useCallback((field) => {
|
|
14401
14452
|
const fn = resolveTotalsSummaryFn(field);
|
|
14402
14453
|
const rawValues = filteredRows.map((row) => row?.[field.key]);
|
|
14403
14454
|
if (field.type === "number" && !field.reference) {
|
|
@@ -14420,7 +14471,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14420
14471
|
}
|
|
14421
14472
|
return rawValues.length;
|
|
14422
14473
|
}, [filteredRows, resolveTotalsSummaryFn]);
|
|
14423
|
-
const formatCategoricalBoxValue =
|
|
14474
|
+
const formatCategoricalBoxValue = React6.useCallback((field, raw) => {
|
|
14424
14475
|
if (raw === void 0 || raw === null) return "-";
|
|
14425
14476
|
if (field.reference) {
|
|
14426
14477
|
const cacheKey = `${field.reference}:${raw}`;
|
|
@@ -14433,7 +14484,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14433
14484
|
if (field.type === "date") return formatDateValue(raw);
|
|
14434
14485
|
return String(raw);
|
|
14435
14486
|
}, [labelCache]);
|
|
14436
|
-
const totalsDetailsCategoricalBoxes =
|
|
14487
|
+
const totalsDetailsCategoricalBoxes = React6.useMemo(() => {
|
|
14437
14488
|
return displayFields.filter((field) => field.type !== "number" || Boolean(field.reference)).map((field) => {
|
|
14438
14489
|
const counts = /* @__PURE__ */ new Map();
|
|
14439
14490
|
filteredRows.forEach((row) => {
|
|
@@ -14451,7 +14502,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14451
14502
|
};
|
|
14452
14503
|
});
|
|
14453
14504
|
}, [displayFields, filteredRows, formatCategoricalBoxValue]);
|
|
14454
|
-
const totalsDetailsNumericBoxes =
|
|
14505
|
+
const totalsDetailsNumericBoxes = React6.useMemo(() => {
|
|
14455
14506
|
return displayFields.filter((field) => field.type === "number" && !field.reference).map((field) => {
|
|
14456
14507
|
return {
|
|
14457
14508
|
key: field.key,
|
|
@@ -14461,10 +14512,10 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14461
14512
|
};
|
|
14462
14513
|
});
|
|
14463
14514
|
}, [computeTotalsSummaryValue, displayFields, resolveTotalsSummaryFn]);
|
|
14464
|
-
const totalsSummaryConfigFields =
|
|
14515
|
+
const totalsSummaryConfigFields = React6.useMemo(() => {
|
|
14465
14516
|
return displayFields.filter((field) => field.type === "number" && !field.reference);
|
|
14466
14517
|
}, [displayFields]);
|
|
14467
|
-
|
|
14518
|
+
React6.useEffect(() => {
|
|
14468
14519
|
setTotalsSummaryFunctions((prev) => {
|
|
14469
14520
|
const next = { ...prev };
|
|
14470
14521
|
let changed = false;
|
|
@@ -14477,7 +14528,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14477
14528
|
return changed ? next : prev;
|
|
14478
14529
|
});
|
|
14479
14530
|
}, [getDefaultTotalsSummaryFn, totalsSummaryConfigFields]);
|
|
14480
|
-
const statsNumericMaxes =
|
|
14531
|
+
const statsNumericMaxes = React6.useMemo(() => {
|
|
14481
14532
|
const stats = statsSummary.numericStats;
|
|
14482
14533
|
const maxAbs = (values) => {
|
|
14483
14534
|
const absValues = values.filter((val) => typeof val === "number").map((val) => Math.abs(val));
|
|
@@ -14491,7 +14542,7 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
14491
14542
|
stddev: maxAbs(stats.map((row) => row.stddev))
|
|
14492
14543
|
};
|
|
14493
14544
|
}, [statsSummary.numericStats]);
|
|
14494
|
-
|
|
14545
|
+
React6.useEffect(() => {
|
|
14495
14546
|
if (isTotalsDetailsVariant) {
|
|
14496
14547
|
setIsTotalsDetailsFlipped(false);
|
|
14497
14548
|
}
|
|
@@ -15754,15 +15805,15 @@ var RelatedObjectsTable = ({ rel, record, relatedModel, parentModel, showActions
|
|
|
15754
15805
|
};
|
|
15755
15806
|
var RelatedObjectSingleSelect = ({ rel, record, allModels, required }) => {
|
|
15756
15807
|
const apiUrl = core.useApiUrl();
|
|
15757
|
-
const [currentLinkRow, setCurrentLinkRow] =
|
|
15758
|
-
const [currentValue, setCurrentValue] =
|
|
15759
|
-
const [loadingCurrent, setLoadingCurrent] =
|
|
15760
|
-
const [saving, setSaving] =
|
|
15808
|
+
const [currentLinkRow, setCurrentLinkRow] = React6.useState(null);
|
|
15809
|
+
const [currentValue, setCurrentValue] = React6.useState(null);
|
|
15810
|
+
const [loadingCurrent, setLoadingCurrent] = React6.useState(true);
|
|
15811
|
+
const [saving, setSaving] = React6.useState(false);
|
|
15761
15812
|
const relatedResource = rel.otherResourcePath || resolveResourcePath(rel.otherResource || "", allModels);
|
|
15762
15813
|
const linkResource = rel.resourcePath || resolveResourcePath(rel.resource, allModels);
|
|
15763
15814
|
const relatedModel = allModels?.find((m) => m.name === rel.otherResource);
|
|
15764
15815
|
const relatedPkField = relatedModel?.fields.find((f) => f.isPk)?.key ?? "id";
|
|
15765
|
-
|
|
15816
|
+
React6.useEffect(() => {
|
|
15766
15817
|
const recordId = getRecordId(record);
|
|
15767
15818
|
if (!recordId || !rel.targetKey || !rel.otherKey) {
|
|
15768
15819
|
setLoadingCurrent(false);
|
|
@@ -15804,7 +15855,7 @@ var RelatedObjectSingleSelect = ({ rel, record, allModels, required }) => {
|
|
|
15804
15855
|
filters: [],
|
|
15805
15856
|
pagination: { current: 1, pageSize: 2e3, mode: "server" }
|
|
15806
15857
|
});
|
|
15807
|
-
const handleChange =
|
|
15858
|
+
const handleChange = React6.useCallback(async (newValue) => {
|
|
15808
15859
|
const recordId = getRecordId(record);
|
|
15809
15860
|
if (!recordId || !rel.otherKey) return;
|
|
15810
15861
|
setSaving(true);
|
|
@@ -15860,11 +15911,11 @@ function useMillerColumnItems({
|
|
|
15860
15911
|
allModels,
|
|
15861
15912
|
apiUrl
|
|
15862
15913
|
}) {
|
|
15863
|
-
const [branches, setBranches] =
|
|
15864
|
-
const [leaves, setLeaves] =
|
|
15865
|
-
const [loading, setLoading] =
|
|
15866
|
-
const [error, setError] =
|
|
15867
|
-
|
|
15914
|
+
const [branches, setBranches] = React6.useState([]);
|
|
15915
|
+
const [leaves, setLeaves] = React6.useState([]);
|
|
15916
|
+
const [loading, setLoading] = React6.useState(false);
|
|
15917
|
+
const [error, setError] = React6.useState(null);
|
|
15918
|
+
React6.useEffect(() => {
|
|
15868
15919
|
if (!parentId || !rel.resourcePath || !rel.targetKey || !rel.otherKey || !rel.otherResource) {
|
|
15869
15920
|
setBranches([]);
|
|
15870
15921
|
setLeaves([]);
|
|
@@ -16129,16 +16180,16 @@ var MillerBrowserLayout = ({
|
|
|
16129
16180
|
const screens = antd.Grid.useBreakpoint();
|
|
16130
16181
|
const { token } = antd.theme.useToken();
|
|
16131
16182
|
const isDesktop = !!screens.md;
|
|
16132
|
-
const columnsRef =
|
|
16183
|
+
const columnsRef = React6.useRef(null);
|
|
16133
16184
|
const rootId = record?.eid ?? record?.id;
|
|
16134
|
-
const [columns, setColumns] =
|
|
16135
|
-
const [selectedIds, setSelectedIds] =
|
|
16136
|
-
const [detailNode, setDetailNode] =
|
|
16137
|
-
const [drawerOpen, setDrawerOpen] =
|
|
16138
|
-
const [containerHeight, setContainerHeight] =
|
|
16139
|
-
const [columnsWidth, setColumnsWidth] =
|
|
16140
|
-
const [columnWidths, setColumnWidths] =
|
|
16141
|
-
const [draggingDir, setDraggingDir] =
|
|
16185
|
+
const [columns, setColumns] = React6.useState([{ parentId: rootId }]);
|
|
16186
|
+
const [selectedIds, setSelectedIds] = React6.useState([null]);
|
|
16187
|
+
const [detailNode, setDetailNode] = React6.useState(null);
|
|
16188
|
+
const [drawerOpen, setDrawerOpen] = React6.useState(false);
|
|
16189
|
+
const [containerHeight, setContainerHeight] = React6.useState(INITIAL_HEIGHT);
|
|
16190
|
+
const [columnsWidth, setColumnsWidth] = React6.useState(null);
|
|
16191
|
+
const [columnWidths, setColumnWidths] = React6.useState([]);
|
|
16192
|
+
const [draggingDir, setDraggingDir] = React6.useState(null);
|
|
16142
16193
|
const DEFAULT_COL_WIDTH = 240;
|
|
16143
16194
|
const getColWidth = (i) => columnWidths[i] ?? DEFAULT_COL_WIDTH;
|
|
16144
16195
|
const handleResizeV = (e) => {
|
|
@@ -16620,7 +16671,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16620
16671
|
const canBulkEdit = canEditData?.can !== false;
|
|
16621
16672
|
const { settings: viewSettings } = useViewSettings();
|
|
16622
16673
|
viewSettings?.generalActionsButtonPosition || "top-right";
|
|
16623
|
-
const [actionsBarEl, setActionsBarEl] =
|
|
16674
|
+
const [actionsBarEl, setActionsBarEl] = React6.useState(null);
|
|
16624
16675
|
const resolvedLayoutPreferenceType = layoutPreferenceType ?? "ShowLayout";
|
|
16625
16676
|
const [searchParams] = reactRouterDom.useSearchParams();
|
|
16626
16677
|
const selectMode = searchParams.get("select_mode") === "1";
|
|
@@ -16630,7 +16681,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16630
16681
|
const selectModeRelateOtherKey = searchParams.get("relate_other_key");
|
|
16631
16682
|
const selectModeRelateTargetId = searchParams.get("relate_target_id");
|
|
16632
16683
|
const selectModeReturnTo = searchParams.get("returnTo");
|
|
16633
|
-
useKeyboardShortcuts(
|
|
16684
|
+
useKeyboardShortcuts(React6.useMemo(() => isEmbedded ? [] : [
|
|
16634
16685
|
{ key: "n", ctrl: true, handler: () => go({ to: { resource: model.resource || model.name, action: "create" } }) }
|
|
16635
16686
|
], [model.name, model.resource, go, isEmbedded]));
|
|
16636
16687
|
const { token } = antd.theme.useToken();
|
|
@@ -16664,89 +16715,89 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16664
16715
|
const editableCrosstab = resolvedListViewType === "editable-crosstab" || resolvedListViewType === "editablecrosstab";
|
|
16665
16716
|
const galleryImageWidth = viewSettings?.galleryImageWidth ?? 180;
|
|
16666
16717
|
const galleryImageHeight = viewSettings?.galleryImageHeight ?? 140;
|
|
16667
|
-
const calendarDateFieldOptions =
|
|
16668
|
-
const [localSearch, setLocalSearch] =
|
|
16669
|
-
const [listVisible, setListVisible] =
|
|
16670
|
-
const [isTdFlipped, setIsTdFlipped] =
|
|
16671
|
-
const [pageSize, setPageSize] =
|
|
16672
|
-
const [galleryPage, setGalleryPage] =
|
|
16673
|
-
const [calendarMode, setCalendarMode] =
|
|
16674
|
-
const [calendarDateField, setCalendarDateField] =
|
|
16675
|
-
const [calendarAnchorDate, setCalendarAnchorDate] =
|
|
16676
|
-
const [isAnalyzeVertical, setIsAnalyzeVertical] =
|
|
16677
|
-
const [isAnalyzeFirst, setIsAnalyzeFirst] =
|
|
16678
|
-
const [filterRules, setFilterRules] =
|
|
16679
|
-
const [filtersCollapsed, setFiltersCollapsed] =
|
|
16680
|
-
const [layoutPrefsReady, setLayoutPrefsReady] =
|
|
16681
|
-
const [columnsSelectorOpen, setColumnsSelectorOpen] =
|
|
16682
|
-
const [selectedColumnKeys, setSelectedColumnKeys] =
|
|
16683
|
-
const [columnOrder, setColumnOrder] =
|
|
16684
|
-
const [columnFiltersSelected, setColumnFiltersSelected] =
|
|
16685
|
-
const [columnSort, setColumnSort] =
|
|
16718
|
+
const calendarDateFieldOptions = React6.useMemo(() => getCalendarDateFieldOptions(model.fields), [model.fields]);
|
|
16719
|
+
const [localSearch, setLocalSearch] = React6.useState("");
|
|
16720
|
+
const [listVisible, setListVisible] = React6.useState(defaultListVisible ?? true);
|
|
16721
|
+
const [isTdFlipped, setIsTdFlipped] = React6.useState(false);
|
|
16722
|
+
const [pageSize, setPageSize] = React6.useState(10);
|
|
16723
|
+
const [galleryPage, setGalleryPage] = React6.useState(1);
|
|
16724
|
+
const [calendarMode, setCalendarMode] = React6.useState("month");
|
|
16725
|
+
const [calendarDateField, setCalendarDateField] = React6.useState(() => calendarDateFieldOptions[0]?.key || "");
|
|
16726
|
+
const [calendarAnchorDate, setCalendarAnchorDate] = React6.useState(() => dayjs9__default.default().startOf("month"));
|
|
16727
|
+
const [isAnalyzeVertical, setIsAnalyzeVertical] = React6.useState(false);
|
|
16728
|
+
const [isAnalyzeFirst, setIsAnalyzeFirst] = React6.useState(false);
|
|
16729
|
+
const [filterRules, setFilterRules] = React6.useState([]);
|
|
16730
|
+
const [filtersCollapsed, setFiltersCollapsed] = React6.useState(isEmbedded);
|
|
16731
|
+
const [layoutPrefsReady, setLayoutPrefsReady] = React6.useState(false);
|
|
16732
|
+
const [columnsSelectorOpen, setColumnsSelectorOpen] = React6.useState(false);
|
|
16733
|
+
const [selectedColumnKeys, setSelectedColumnKeys] = React6.useState(null);
|
|
16734
|
+
const [columnOrder, setColumnOrder] = React6.useState(null);
|
|
16735
|
+
const [columnFiltersSelected, setColumnFiltersSelected] = React6.useState({});
|
|
16736
|
+
const [columnSort, setColumnSort] = React6.useState(
|
|
16686
16737
|
model.defaultSort ? [{ fieldKey: model.defaultSort.field, order: model.defaultSort.order === "desc" ? "descend" : "ascend" }] : []
|
|
16687
16738
|
);
|
|
16688
|
-
const [totalsSummaryFunctions, setTotalsSummaryFunctions] =
|
|
16689
|
-
const [currentViewName, setCurrentViewName] =
|
|
16690
|
-
const [selectedViewNames, setSelectedViewNames] =
|
|
16691
|
-
const [availableViewNames, setAvailableViewNames] =
|
|
16692
|
-
const [viewNamesLoaded, setViewNamesLoaded] =
|
|
16693
|
-
const [isLoadingViewNames, setIsLoadingViewNames] =
|
|
16694
|
-
const [saveViewModalOpen, setSaveViewModalOpen] =
|
|
16695
|
-
const [saveViewName, setSaveViewName] =
|
|
16696
|
-
const [saveViewAsNew, setSaveViewAsNew] =
|
|
16697
|
-
const [pendingSaveTarget, setPendingSaveTarget] =
|
|
16698
|
-
const [renameViewModalOpen, setRenameViewModalOpen] =
|
|
16699
|
-
const [renameViewName, setRenameViewName] =
|
|
16700
|
-
const [labelCache, setLabelCache] =
|
|
16701
|
-
const [analyzeOpen, setAnalyzeOpen] =
|
|
16702
|
-
const analyzeTouchedRef =
|
|
16703
|
-
const analyzePrefsTouchedRef =
|
|
16704
|
-
const analyzePrefsLoadedRef =
|
|
16705
|
-
const [analyzePrefsReady, setAnalyzePrefsReady] =
|
|
16706
|
-
const analyzePrefsResourceRef =
|
|
16739
|
+
const [totalsSummaryFunctions, setTotalsSummaryFunctions] = React6.useState({});
|
|
16740
|
+
const [currentViewName, setCurrentViewName] = React6.useState(getDefaultViewName());
|
|
16741
|
+
const [selectedViewNames, setSelectedViewNames] = React6.useState([]);
|
|
16742
|
+
const [availableViewNames, setAvailableViewNames] = React6.useState([]);
|
|
16743
|
+
const [viewNamesLoaded, setViewNamesLoaded] = React6.useState(false);
|
|
16744
|
+
const [isLoadingViewNames, setIsLoadingViewNames] = React6.useState(false);
|
|
16745
|
+
const [saveViewModalOpen, setSaveViewModalOpen] = React6.useState(false);
|
|
16746
|
+
const [saveViewName, setSaveViewName] = React6.useState(getDefaultViewName());
|
|
16747
|
+
const [saveViewAsNew, setSaveViewAsNew] = React6.useState(false);
|
|
16748
|
+
const [pendingSaveTarget, setPendingSaveTarget] = React6.useState(null);
|
|
16749
|
+
const [renameViewModalOpen, setRenameViewModalOpen] = React6.useState(false);
|
|
16750
|
+
const [renameViewName, setRenameViewName] = React6.useState("");
|
|
16751
|
+
const [labelCache, setLabelCache] = React6.useState({});
|
|
16752
|
+
const [analyzeOpen, setAnalyzeOpen] = React6.useState(isEmbedded);
|
|
16753
|
+
const analyzeTouchedRef = React6.useRef(false);
|
|
16754
|
+
const analyzePrefsTouchedRef = React6.useRef(false);
|
|
16755
|
+
const analyzePrefsLoadedRef = React6.useRef(false);
|
|
16756
|
+
const [analyzePrefsReady, setAnalyzePrefsReady] = React6.useState(false);
|
|
16757
|
+
const analyzePrefsResourceRef = React6.useRef(null);
|
|
16707
16758
|
const { metadataButton, metadataModal } = useMetadataModal(model, allModels);
|
|
16708
|
-
const defaultDisplayFields =
|
|
16709
|
-
const orderedColumnKeys =
|
|
16759
|
+
const defaultDisplayFields = React6.useMemo(() => getListViewFields(model, filter?.field), [model, filter?.field]);
|
|
16760
|
+
const orderedColumnKeys = React6.useMemo(() => {
|
|
16710
16761
|
if (!selectedColumnKeys || selectedColumnKeys.length === 0) return null;
|
|
16711
16762
|
const order = columnOrder && columnOrder.length > 0 ? columnOrder : selectedColumnKeys;
|
|
16712
16763
|
const selectedSet = new Set(selectedColumnKeys);
|
|
16713
16764
|
const availableKeys = new Set(model.fields.map((field) => field.key));
|
|
16714
16765
|
return order.filter((key) => selectedSet.has(key) && availableKeys.has(key));
|
|
16715
16766
|
}, [columnOrder, model.fields, selectedColumnKeys]);
|
|
16716
|
-
const displayFields =
|
|
16767
|
+
const displayFields = React6.useMemo(() => {
|
|
16717
16768
|
if (!orderedColumnKeys) return defaultDisplayFields;
|
|
16718
16769
|
const fieldMap = new Map(model.fields.map((field) => [field.key, field]));
|
|
16719
16770
|
return orderedColumnKeys.map((key) => fieldMap.get(key)).filter((field) => Boolean(field));
|
|
16720
16771
|
}, [defaultDisplayFields, model.fields, orderedColumnKeys]);
|
|
16721
16772
|
const useLocalSearch = true;
|
|
16722
|
-
const [categoryField1, setCategoryField1] =
|
|
16723
|
-
const [categoryField2, setCategoryField2] =
|
|
16724
|
-
const [crosstabFilterFields, setCrosstabFilterFields] =
|
|
16725
|
-
const [crosstabStaged, setCrosstabStaged] =
|
|
16726
|
-
const [crosstabSaving, setCrosstabSaving] =
|
|
16727
|
-
const [chartType, setChartType] =
|
|
16728
|
-
const [summaryFn, setSummaryFn] =
|
|
16729
|
-
const [selectedSeriesKeys, setSelectedSeriesKeys] =
|
|
16730
|
-
const [rankingMode, setRankingMode] =
|
|
16731
|
-
const [rankingFieldKey, setRankingFieldKey] =
|
|
16732
|
-
const [rankingN, setRankingN] =
|
|
16733
|
-
const [exportRequested, setExportRequested] =
|
|
16734
|
-
const [isStatsFlipped, setIsStatsFlipped] =
|
|
16735
|
-
const [isSavingAnalyzePrefs, setIsSavingAnalyzePrefs] =
|
|
16736
|
-
const chartSvgRef =
|
|
16737
|
-
const [chartAnimationKey, setChartAnimationKey] =
|
|
16738
|
-
const [chartAnimationStage, setChartAnimationStage] =
|
|
16739
|
-
const skipNextAnimationRef =
|
|
16740
|
-
const [isSavingLayoutPrefs, setIsSavingLayoutPrefs] =
|
|
16741
|
-
const layoutPrefsTouchedRef =
|
|
16742
|
-
const layoutPrefsLoadedRef =
|
|
16743
|
-
const layoutPrefsResourceRef =
|
|
16744
|
-
const sortIntentRef =
|
|
16745
|
-
const prevViewNameForResetRef =
|
|
16746
|
-
const [bulkSelectedRowKeys, setBulkSelectedRowKeys] =
|
|
16747
|
-
const bulkSelectedRowsMapRef =
|
|
16748
|
-
const [selectModeAssociating, setSelectModeAssociating] =
|
|
16749
|
-
const handleAssociateSelected =
|
|
16773
|
+
const [categoryField1, setCategoryField1] = React6.useState(null);
|
|
16774
|
+
const [categoryField2, setCategoryField2] = React6.useState(void 0);
|
|
16775
|
+
const [crosstabFilterFields, setCrosstabFilterFields] = React6.useState([]);
|
|
16776
|
+
const [crosstabStaged, setCrosstabStaged] = React6.useState({});
|
|
16777
|
+
const [crosstabSaving, setCrosstabSaving] = React6.useState(false);
|
|
16778
|
+
const [chartType, setChartType] = React6.useState("area");
|
|
16779
|
+
const [summaryFn, setSummaryFn] = React6.useState("sum");
|
|
16780
|
+
const [selectedSeriesKeys, setSelectedSeriesKeys] = React6.useState(null);
|
|
16781
|
+
const [rankingMode, setRankingMode] = React6.useState("none");
|
|
16782
|
+
const [rankingFieldKey, setRankingFieldKey] = React6.useState(null);
|
|
16783
|
+
const [rankingN, setRankingN] = React6.useState(10);
|
|
16784
|
+
const [exportRequested, setExportRequested] = React6.useState(false);
|
|
16785
|
+
const [isStatsFlipped, setIsStatsFlipped] = React6.useState(false);
|
|
16786
|
+
const [isSavingAnalyzePrefs, setIsSavingAnalyzePrefs] = React6.useState(false);
|
|
16787
|
+
const chartSvgRef = React6.useRef(null);
|
|
16788
|
+
const [chartAnimationKey, setChartAnimationKey] = React6.useState(0);
|
|
16789
|
+
const [chartAnimationStage, setChartAnimationStage] = React6.useState("enter");
|
|
16790
|
+
const skipNextAnimationRef = React6.useRef(false);
|
|
16791
|
+
const [isSavingLayoutPrefs, setIsSavingLayoutPrefs] = React6.useState(false);
|
|
16792
|
+
const layoutPrefsTouchedRef = React6.useRef(false);
|
|
16793
|
+
const layoutPrefsLoadedRef = React6.useRef(false);
|
|
16794
|
+
const layoutPrefsResourceRef = React6.useRef(null);
|
|
16795
|
+
const sortIntentRef = React6.useRef(null);
|
|
16796
|
+
const prevViewNameForResetRef = React6.useRef(null);
|
|
16797
|
+
const [bulkSelectedRowKeys, setBulkSelectedRowKeys] = React6.useState([]);
|
|
16798
|
+
const bulkSelectedRowsMapRef = React6.useRef(/* @__PURE__ */ new Map());
|
|
16799
|
+
const [selectModeAssociating, setSelectModeAssociating] = React6.useState(false);
|
|
16800
|
+
const handleAssociateSelected = React6.useCallback(async () => {
|
|
16750
16801
|
if (!selectModeRelateResource || !selectModeRelateTargetKey || !selectModeRelateTargetId) return;
|
|
16751
16802
|
if (!selectModeFk && !selectModeRelateOtherKey) return;
|
|
16752
16803
|
setSelectModeAssociating(true);
|
|
@@ -16781,18 +16832,18 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16781
16832
|
setSelectModeAssociating(false);
|
|
16782
16833
|
}
|
|
16783
16834
|
}, [apiUrl, bulkSelectedRowKeys, selectModeFk, selectModeRelateResource, selectModeRelateTargetKey, selectModeRelateOtherKey, selectModeRelateTargetId, selectModeReturnTo, navigate]);
|
|
16784
|
-
const [bulkActionModalOpen, setBulkActionModalOpen] =
|
|
16785
|
-
const [bulkActionsToApply, setBulkActionsToApply] =
|
|
16786
|
-
const [bulkChangeFieldKey, setBulkChangeFieldKey] =
|
|
16787
|
-
const [bulkChangeFieldValue, setBulkChangeFieldValue] =
|
|
16788
|
-
const [isBulkExecuting, setIsBulkExecuting] =
|
|
16789
|
-
const [selectAllFilteredPending, setSelectAllFilteredPending] =
|
|
16790
|
-
const [columnFilterDropdownEverOpened, setColumnFilterDropdownEverOpened] =
|
|
16791
|
-
const handleReferenceLabel =
|
|
16835
|
+
const [bulkActionModalOpen, setBulkActionModalOpen] = React6.useState(false);
|
|
16836
|
+
const [bulkActionsToApply, setBulkActionsToApply] = React6.useState([]);
|
|
16837
|
+
const [bulkChangeFieldKey, setBulkChangeFieldKey] = React6.useState(null);
|
|
16838
|
+
const [bulkChangeFieldValue, setBulkChangeFieldValue] = React6.useState(null);
|
|
16839
|
+
const [isBulkExecuting, setIsBulkExecuting] = React6.useState(false);
|
|
16840
|
+
const [selectAllFilteredPending, setSelectAllFilteredPending] = React6.useState(false);
|
|
16841
|
+
const [columnFilterDropdownEverOpened, setColumnFilterDropdownEverOpened] = React6.useState(false);
|
|
16842
|
+
const handleReferenceLabel = React6.useCallback((resource, id, label) => {
|
|
16792
16843
|
const key = `${resource}:${id}`;
|
|
16793
16844
|
setLabelCache((prev) => prev[key] === label ? prev : { ...prev, [key]: label });
|
|
16794
16845
|
}, []);
|
|
16795
|
-
const tableFilters =
|
|
16846
|
+
const tableFilters = React6.useMemo(() => {
|
|
16796
16847
|
if (!filter) return [];
|
|
16797
16848
|
if (filter.value === void 0 || filter.value === null) return [];
|
|
16798
16849
|
return [filter];
|
|
@@ -16817,16 +16868,16 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16817
16868
|
return [{ field: searchField.key, operator: "contains", value }];
|
|
16818
16869
|
}
|
|
16819
16870
|
});
|
|
16820
|
-
const [allRowsData, setAllRowsData] =
|
|
16821
|
-
const [isAllRowsLoading, setIsAllRowsLoading] =
|
|
16822
|
-
const [allRowsError, setAllRowsError] =
|
|
16823
|
-
const lastAllRowsSignature =
|
|
16824
|
-
const [allRowsLoaded, setAllRowsLoaded] =
|
|
16871
|
+
const [allRowsData, setAllRowsData] = React6.useState([]);
|
|
16872
|
+
const [isAllRowsLoading, setIsAllRowsLoading] = React6.useState(false);
|
|
16873
|
+
const [allRowsError, setAllRowsError] = React6.useState(null);
|
|
16874
|
+
const lastAllRowsSignature = React6.useRef("");
|
|
16875
|
+
const [allRowsLoaded, setAllRowsLoaded] = React6.useState(false);
|
|
16825
16876
|
const isRelationView = !!filter;
|
|
16826
|
-
const hasActiveFilterRules =
|
|
16877
|
+
const hasActiveFilterRules = React6.useMemo(() => {
|
|
16827
16878
|
return filterRules.some((rule) => rule.fieldKey && rule.operator && (rule.value !== void 0 && rule.value !== null && rule.value !== ""));
|
|
16828
16879
|
}, [filterRules]);
|
|
16829
|
-
const getFieldValueForFilter =
|
|
16880
|
+
const getFieldValueForFilter = React6.useCallback((field, record) => {
|
|
16830
16881
|
const raw = record?.[field.key];
|
|
16831
16882
|
if (raw === void 0 || raw === null) return raw;
|
|
16832
16883
|
if (field.reference) {
|
|
@@ -16838,7 +16889,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16838
16889
|
}
|
|
16839
16890
|
return raw;
|
|
16840
16891
|
}, [labelCache]);
|
|
16841
|
-
const getSortValue =
|
|
16892
|
+
const getSortValue = React6.useCallback((field, record) => {
|
|
16842
16893
|
const raw = record?.[field.key];
|
|
16843
16894
|
if (raw === void 0 || raw === null) return null;
|
|
16844
16895
|
if (isPkField(field, model) && record?._label) return record._label;
|
|
@@ -16860,7 +16911,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16860
16911
|
if (field.type === "boolean") return raw ? 1 : 0;
|
|
16861
16912
|
return raw;
|
|
16862
16913
|
}, [labelCache]);
|
|
16863
|
-
const compareSortValues =
|
|
16914
|
+
const compareSortValues = React6.useCallback((field, a, b) => {
|
|
16864
16915
|
const aVal = getSortValue(field, a);
|
|
16865
16916
|
const bVal = getSortValue(field, b);
|
|
16866
16917
|
if (aVal === null && bVal === null) return 0;
|
|
@@ -16869,7 +16920,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16869
16920
|
if (typeof aVal === "number" && typeof bVal === "number") return aVal - bVal;
|
|
16870
16921
|
return String(aVal).localeCompare(String(bVal));
|
|
16871
16922
|
}, [getSortValue]);
|
|
16872
|
-
const resolveRelativeDate =
|
|
16923
|
+
const resolveRelativeDate = React6.useCallback((value, asRange) => {
|
|
16873
16924
|
const count = Number(value?.count ?? 1);
|
|
16874
16925
|
const direction = value?.direction || "next";
|
|
16875
16926
|
const unit = value?.unit || "weeks";
|
|
@@ -16895,7 +16946,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16895
16946
|
}
|
|
16896
16947
|
return { date: target.startOf(unit) };
|
|
16897
16948
|
}, []);
|
|
16898
|
-
const matchesRule =
|
|
16949
|
+
const matchesRule = React6.useCallback((record, rule) => {
|
|
16899
16950
|
const field = model.fields.find((f) => f.key === rule.fieldKey);
|
|
16900
16951
|
if (!field || !rule.operator) return true;
|
|
16901
16952
|
const rawValue = getFieldValueForFilter(field, record);
|
|
@@ -16975,7 +17026,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16975
17026
|
}
|
|
16976
17027
|
return true;
|
|
16977
17028
|
}, [getFieldValueForFilter, model.fields, resolveRelativeDate]);
|
|
16978
|
-
const applyGlobalSearch =
|
|
17029
|
+
const applyGlobalSearch = React6.useCallback((rows) => {
|
|
16979
17030
|
const query = localSearch.trim().toLowerCase();
|
|
16980
17031
|
if (!query) return rows;
|
|
16981
17032
|
return rows.filter((record) => {
|
|
@@ -16994,11 +17045,11 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
16994
17045
|
return candidates.some((value) => value !== void 0 && value !== null && String(value).toLowerCase().includes(query));
|
|
16995
17046
|
});
|
|
16996
17047
|
}, [labelCache, localSearch, model.fields, useLocalSearch]);
|
|
16997
|
-
const applyFilterRules =
|
|
17048
|
+
const applyFilterRules = React6.useCallback((rows) => {
|
|
16998
17049
|
if (!hasActiveFilterRules) return rows;
|
|
16999
17050
|
return rows.filter((record) => filterRules.every((rule) => matchesRule(record, rule)));
|
|
17000
17051
|
}, [filterRules, hasActiveFilterRules, matchesRule]);
|
|
17001
|
-
const allRows =
|
|
17052
|
+
const allRows = React6.useMemo(() => {
|
|
17002
17053
|
const data = allRowsData || [];
|
|
17003
17054
|
const query = localSearch.trim().toLowerCase();
|
|
17004
17055
|
if (!query) return data;
|
|
@@ -17019,12 +17070,12 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17019
17070
|
});
|
|
17020
17071
|
}, [allRowsData, useLocalSearch, localSearch, model.fields, labelCache]);
|
|
17021
17072
|
const isClientFiltering = allRowsLoaded && !allRowsError;
|
|
17022
|
-
const filteredDataSource =
|
|
17073
|
+
const filteredDataSource = React6.useMemo(() => {
|
|
17023
17074
|
if (!isClientFiltering) return Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
|
|
17024
17075
|
const baseRows = allRows || [];
|
|
17025
17076
|
return applyFilterRules(applyGlobalSearch(baseRows));
|
|
17026
17077
|
}, [allRows, applyFilterRules, applyGlobalSearch, isClientFiltering, tableProps.dataSource]);
|
|
17027
|
-
const columnFilteredDataSource =
|
|
17078
|
+
const columnFilteredDataSource = React6.useMemo(() => {
|
|
17028
17079
|
const activeEntries = Object.entries(columnFiltersSelected).filter(([, values]) => values && values.length > 0);
|
|
17029
17080
|
if (activeEntries.length === 0) return filteredDataSource;
|
|
17030
17081
|
return filteredDataSource.filter(
|
|
@@ -17035,41 +17086,41 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17035
17086
|
})
|
|
17036
17087
|
);
|
|
17037
17088
|
}, [filteredDataSource, columnFiltersSelected, model.fields]);
|
|
17038
|
-
|
|
17089
|
+
React6.useEffect(() => {
|
|
17039
17090
|
setGalleryPage(1);
|
|
17040
17091
|
}, [localSearch, filterRules, resolvedListViewType]);
|
|
17041
|
-
const columnFilters =
|
|
17092
|
+
const columnFilters = React6.useMemo(() => {
|
|
17042
17093
|
const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
|
|
17043
17094
|
const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
|
|
17044
17095
|
return buildColumnFilterOptions({ fields: displayFields, data, rangeCount });
|
|
17045
17096
|
}, [allRowsData, displayFields, tableProps.dataSource, viewSettings]);
|
|
17046
|
-
const allFieldOptions =
|
|
17097
|
+
const allFieldOptions = React6.useMemo(() => {
|
|
17047
17098
|
return model.fields.map((field) => ({ label: field.label, value: field.key }));
|
|
17048
17099
|
}, [model.fields]);
|
|
17049
|
-
const orderedSelectedColumns =
|
|
17100
|
+
const orderedSelectedColumns = React6.useMemo(() => {
|
|
17050
17101
|
if (!selectedColumnKeys || selectedColumnKeys.length === 0) return [];
|
|
17051
17102
|
return orderedColumnKeys && orderedColumnKeys.length > 0 ? orderedColumnKeys : selectedColumnKeys;
|
|
17052
17103
|
}, [orderedColumnKeys, selectedColumnKeys]);
|
|
17053
|
-
const syncColumnsSelectionToDisplay =
|
|
17104
|
+
const syncColumnsSelectionToDisplay = React6.useCallback(() => {
|
|
17054
17105
|
const keys = displayFields.map((field) => field.key);
|
|
17055
17106
|
if (keys.length === 0) return;
|
|
17056
17107
|
setSelectedColumnKeys(keys);
|
|
17057
17108
|
setColumnOrder(orderedColumnKeys && orderedColumnKeys.length > 0 ? orderedColumnKeys : keys);
|
|
17058
17109
|
}, [displayFields, orderedColumnKeys]);
|
|
17059
|
-
|
|
17110
|
+
React6.useEffect(() => {
|
|
17060
17111
|
if (selectedColumnKeys !== null) return;
|
|
17061
17112
|
const defaults = defaultDisplayFields.map((field) => field.key);
|
|
17062
17113
|
if (defaults.length === 0) return;
|
|
17063
17114
|
setSelectedColumnKeys(defaults);
|
|
17064
17115
|
setColumnOrder(defaults);
|
|
17065
17116
|
}, [defaultDisplayFields, selectedColumnKeys]);
|
|
17066
|
-
const markAnalyzePrefsTouched =
|
|
17117
|
+
const markAnalyzePrefsTouched = React6.useCallback(() => {
|
|
17067
17118
|
analyzePrefsTouchedRef.current = true;
|
|
17068
17119
|
}, []);
|
|
17069
|
-
const markLayoutPrefsTouched =
|
|
17120
|
+
const markLayoutPrefsTouched = React6.useCallback(() => {
|
|
17070
17121
|
layoutPrefsTouchedRef.current = true;
|
|
17071
17122
|
}, []);
|
|
17072
|
-
const handleColumnSelectionChange =
|
|
17123
|
+
const handleColumnSelectionChange = React6.useCallback((values) => {
|
|
17073
17124
|
markLayoutPrefsTouched();
|
|
17074
17125
|
if (!values || values.length === 0) {
|
|
17075
17126
|
setSelectedColumnKeys(null);
|
|
@@ -17083,7 +17134,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17083
17134
|
return [...baseOrder, ...missing];
|
|
17084
17135
|
});
|
|
17085
17136
|
}, [markLayoutPrefsTouched]);
|
|
17086
|
-
const moveColumnOrder =
|
|
17137
|
+
const moveColumnOrder = React6.useCallback((key, direction) => {
|
|
17087
17138
|
setColumnOrder((prev) => {
|
|
17088
17139
|
const base = prev && prev.length > 0 ? [...prev] : selectedColumnKeys ? [...selectedColumnKeys] : [];
|
|
17089
17140
|
const index = base.indexOf(key);
|
|
@@ -17094,7 +17145,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17094
17145
|
return base;
|
|
17095
17146
|
});
|
|
17096
17147
|
}, [selectedColumnKeys]);
|
|
17097
|
-
const handleTablePageChange =
|
|
17148
|
+
const handleTablePageChange = React6.useCallback((page, newPageSize) => {
|
|
17098
17149
|
if (newPageSize && newPageSize !== pageSize) {
|
|
17099
17150
|
setPageSize(newPageSize);
|
|
17100
17151
|
setGalleryPage(1);
|
|
@@ -17104,7 +17155,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17104
17155
|
pagination.onChange(page, newPageSize ?? pageSize);
|
|
17105
17156
|
}
|
|
17106
17157
|
}, [pageSize, tableProps.pagination]);
|
|
17107
|
-
const tablePagination =
|
|
17158
|
+
const tablePagination = React6.useMemo(() => {
|
|
17108
17159
|
if (!isClientFiltering) {
|
|
17109
17160
|
if (!tableProps.pagination || typeof tableProps.pagination !== "object") return tableProps.pagination;
|
|
17110
17161
|
return {
|
|
@@ -17125,23 +17176,23 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17125
17176
|
onShowSizeChange: handleTablePageChange
|
|
17126
17177
|
};
|
|
17127
17178
|
}, [handleTablePageChange, isClientFiltering, pageSize, tableProps.pagination]);
|
|
17128
|
-
const categoricalFields =
|
|
17179
|
+
const categoricalFields = React6.useMemo(() => {
|
|
17129
17180
|
return model.fields.filter((field) => isPkField(field, model) || (field.type !== "number" || field.reference));
|
|
17130
17181
|
}, [model.fields]);
|
|
17131
|
-
const numericFields =
|
|
17182
|
+
const numericFields = React6.useMemo(() => {
|
|
17132
17183
|
return model.fields.filter((field) => !isPkField(field, model) && field.type === "number" && !field.reference);
|
|
17133
17184
|
}, [model.fields]);
|
|
17134
|
-
const hasActiveRangeColumnFilter =
|
|
17185
|
+
const hasActiveRangeColumnFilter = React6.useMemo(() => {
|
|
17135
17186
|
return Object.values(columnFiltersSelected).some(
|
|
17136
17187
|
(vals) => vals.some((v) => v.startsWith("__range__:"))
|
|
17137
17188
|
);
|
|
17138
17189
|
}, [columnFiltersSelected]);
|
|
17139
|
-
const shouldLoadAllRows =
|
|
17190
|
+
const shouldLoadAllRows = React6.useMemo(() => {
|
|
17140
17191
|
return Boolean(
|
|
17141
17192
|
localSearch.trim().length > 0 || hasActiveFilterRules || analyzeOpen || exportRequested || isTotalsDetailsView || isCrosstabView || columnFilterDropdownEverOpened || hasActiveRangeColumnFilter
|
|
17142
17193
|
);
|
|
17143
17194
|
}, [analyzeOpen, columnFilterDropdownEverOpened, exportRequested, hasActiveFilterRules, hasActiveRangeColumnFilter, isTotalsDetailsView, isCrosstabView, localSearch]);
|
|
17144
|
-
|
|
17195
|
+
React6.useEffect(() => {
|
|
17145
17196
|
if (!categoryField1 && categoricalFields.length > 0) {
|
|
17146
17197
|
setCategoryField1(categoricalFields[0].key);
|
|
17147
17198
|
}
|
|
@@ -17149,7 +17200,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17149
17200
|
setCategoryField2(categoricalFields[1].key);
|
|
17150
17201
|
}
|
|
17151
17202
|
}, [categoricalFields, categoryField1, categoryField2]);
|
|
17152
|
-
|
|
17203
|
+
React6.useEffect(() => {
|
|
17153
17204
|
if (selectedSeriesKeys !== null) return;
|
|
17154
17205
|
if (numericFields.length > 0) {
|
|
17155
17206
|
setSelectedSeriesKeys(numericFields.map((field) => field.key));
|
|
@@ -17157,7 +17208,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17157
17208
|
setSelectedSeriesKeys(["__count__"]);
|
|
17158
17209
|
}
|
|
17159
17210
|
}, [numericFields, selectedSeriesKeys]);
|
|
17160
|
-
|
|
17211
|
+
React6.useEffect(() => {
|
|
17161
17212
|
if (numericFields.length === 0) {
|
|
17162
17213
|
if (rankingFieldKey !== null) setRankingFieldKey(null);
|
|
17163
17214
|
if (rankingMode !== "none") setRankingMode("none");
|
|
@@ -17167,7 +17218,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17167
17218
|
setRankingFieldKey(numericFields[0].key);
|
|
17168
17219
|
}
|
|
17169
17220
|
}, [numericFields, rankingFieldKey, rankingMode]);
|
|
17170
|
-
const resetLayoutDefaults =
|
|
17221
|
+
const resetLayoutDefaults = React6.useCallback(() => {
|
|
17171
17222
|
setListVisible(defaultListVisible ?? true);
|
|
17172
17223
|
setAnalyzeOpen(isEmbedded);
|
|
17173
17224
|
setIsAnalyzeVertical(false);
|
|
@@ -17178,7 +17229,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17178
17229
|
setColumnOrder(null);
|
|
17179
17230
|
setTotalsSummaryFunctions({});
|
|
17180
17231
|
}, [isEmbedded, defaultListVisible]);
|
|
17181
|
-
const resetAnalyzeDefaults =
|
|
17232
|
+
const resetAnalyzeDefaults = React6.useCallback(() => {
|
|
17182
17233
|
setCategoryField1(categoricalFields[0]?.key ?? null);
|
|
17183
17234
|
setCategoryField2(categoricalFields.length > 1 ? categoricalFields[1].key : null);
|
|
17184
17235
|
setChartType("area");
|
|
@@ -17189,7 +17240,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17189
17240
|
setRankingN(10);
|
|
17190
17241
|
setCrosstabFilterFields([]);
|
|
17191
17242
|
}, [categoricalFields, numericFields]);
|
|
17192
|
-
const persistCurrentViewNames =
|
|
17243
|
+
const persistCurrentViewNames = React6.useCallback(async (nextSelected, nextCurrent) => {
|
|
17193
17244
|
try {
|
|
17194
17245
|
const resourceKey = prefsKey;
|
|
17195
17246
|
await authenticatedFetch(`${apiUrl}/views/preferences/view`, {
|
|
@@ -17205,7 +17256,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17205
17256
|
} catch {
|
|
17206
17257
|
}
|
|
17207
17258
|
}, [apiUrl, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17208
|
-
const loadViewNames =
|
|
17259
|
+
const loadViewNames = React6.useCallback(async () => {
|
|
17209
17260
|
const resourceKey = prefsKey;
|
|
17210
17261
|
setIsLoadingViewNames(true);
|
|
17211
17262
|
try {
|
|
@@ -17250,20 +17301,20 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17250
17301
|
setIsLoadingViewNames(false);
|
|
17251
17302
|
}
|
|
17252
17303
|
}, [apiUrl, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17253
|
-
const openSaveViewModalFor =
|
|
17304
|
+
const openSaveViewModalFor = React6.useCallback((target) => {
|
|
17254
17305
|
setSaveViewName(currentViewName || getDefaultViewName());
|
|
17255
17306
|
setSaveViewAsNew(false);
|
|
17256
17307
|
setPendingSaveTarget(target);
|
|
17257
17308
|
setSaveViewModalOpen(true);
|
|
17258
17309
|
}, [currentViewName]);
|
|
17259
|
-
const handleChangeViewName =
|
|
17310
|
+
const handleChangeViewName = React6.useCallback(async (nextView) => {
|
|
17260
17311
|
const resolvedName = normalizeViewName(nextView);
|
|
17261
17312
|
setCurrentViewName(resolvedName);
|
|
17262
17313
|
setSaveViewName(resolvedName);
|
|
17263
17314
|
const nextSelected = selectedViewNames.length > 0 ? selectedViewNames : [resolvedName];
|
|
17264
17315
|
await persistCurrentViewNames(nextSelected, resolvedName);
|
|
17265
17316
|
}, [persistCurrentViewNames, selectedViewNames]);
|
|
17266
|
-
const updateSelectedViewNames =
|
|
17317
|
+
const updateSelectedViewNames = React6.useCallback(async (nextSelected) => {
|
|
17267
17318
|
if (nextSelected.length === 0) {
|
|
17268
17319
|
nextSelected = [getDefaultViewName()];
|
|
17269
17320
|
}
|
|
@@ -17275,7 +17326,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17275
17326
|
}
|
|
17276
17327
|
await persistCurrentViewNames(nextSelected, nextCurrent);
|
|
17277
17328
|
}, [currentViewName, persistCurrentViewNames]);
|
|
17278
|
-
const moveSelectedView =
|
|
17329
|
+
const moveSelectedView = React6.useCallback((name, direction) => {
|
|
17279
17330
|
setSelectedViewNames((prev) => {
|
|
17280
17331
|
const idx = prev.indexOf(name);
|
|
17281
17332
|
if (idx < 0) return prev;
|
|
@@ -17287,7 +17338,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17287
17338
|
return next;
|
|
17288
17339
|
});
|
|
17289
17340
|
}, [currentViewName, persistCurrentViewNames]);
|
|
17290
|
-
const handleRenameView =
|
|
17341
|
+
const handleRenameView = React6.useCallback(async () => {
|
|
17291
17342
|
const newName = normalizeViewName(renameViewName);
|
|
17292
17343
|
if (!newName || newName === currentViewName) {
|
|
17293
17344
|
setRenameViewModalOpen(false);
|
|
@@ -17314,7 +17365,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17314
17365
|
antd.message.error(error instanceof Error ? error.message : _36("Failed to rename view."));
|
|
17315
17366
|
}
|
|
17316
17367
|
}, [apiUrl, availableViewNames, currentViewName, model.name, model.resource, renameViewName, allModels, loadViewNames]);
|
|
17317
|
-
const confirmDeleteView =
|
|
17368
|
+
const confirmDeleteView = React6.useCallback(() => {
|
|
17318
17369
|
antd.Modal.confirm({
|
|
17319
17370
|
title: _36(_36("Delete view")),
|
|
17320
17371
|
content: `Delete "${currentViewName}" and all its saved preferences?`,
|
|
@@ -17339,7 +17390,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17339
17390
|
}
|
|
17340
17391
|
});
|
|
17341
17392
|
}, [apiUrl, currentViewName, model.name, model.resource, allModels, loadViewNames]);
|
|
17342
|
-
const persistLayoutPreferences =
|
|
17393
|
+
const persistLayoutPreferences = React6.useCallback(async (viewName) => {
|
|
17343
17394
|
if (!resolvedLayoutPreferenceType) return;
|
|
17344
17395
|
const resourceKey = prefsKey;
|
|
17345
17396
|
const resolvedViewName = normalizeViewName(viewName);
|
|
@@ -17383,7 +17434,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17383
17434
|
setIsSavingLayoutPrefs(false);
|
|
17384
17435
|
}
|
|
17385
17436
|
}, [apiUrl, analyzeOpen, columnFiltersSelected, columnOrder, columnSort, filtersCollapsed, filterRules, isAnalyzeFirst, isAnalyzeVertical, resolvedLayoutPreferenceType, listVisible, pageSize, selectedColumnKeys, totalsSummaryFunctions, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17386
|
-
const persistAnalyzePreferences =
|
|
17437
|
+
const persistAnalyzePreferences = React6.useCallback(async (viewName) => {
|
|
17387
17438
|
const resourceKey = prefsKey;
|
|
17388
17439
|
const resolvedViewName = normalizeViewName(viewName);
|
|
17389
17440
|
const preferences = {
|
|
@@ -17415,7 +17466,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17415
17466
|
setIsSavingAnalyzePrefs(false);
|
|
17416
17467
|
}
|
|
17417
17468
|
}, [apiUrl, categoryField1, categoryField2, chartType, selectedSeriesKeys, summaryFn, rankingMode, rankingFieldKey, rankingN, crosstabFilterFields, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17418
|
-
const handleConfirmSaveView =
|
|
17469
|
+
const handleConfirmSaveView = React6.useCallback(async () => {
|
|
17419
17470
|
if (!pendingSaveTarget) return;
|
|
17420
17471
|
const viewName = normalizeViewName(saveViewName || currentViewName);
|
|
17421
17472
|
const viewExists = availableViewNames.includes(viewName);
|
|
@@ -17442,10 +17493,10 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17442
17493
|
await persistCurrentViewNames(nextSelected, viewName);
|
|
17443
17494
|
await loadViewNames();
|
|
17444
17495
|
}, [availableViewNames, currentViewName, loadViewNames, pendingSaveTarget, persistAnalyzePreferences, persistCurrentViewNames, persistLayoutPreferences, saveViewAsNew, saveViewName, selectedViewNames]);
|
|
17445
|
-
|
|
17496
|
+
React6.useEffect(() => {
|
|
17446
17497
|
loadViewNames();
|
|
17447
17498
|
}, [loadViewNames]);
|
|
17448
|
-
|
|
17499
|
+
React6.useEffect(() => {
|
|
17449
17500
|
if (!viewNamesLoaded) return;
|
|
17450
17501
|
const viewChanged = prevViewNameForResetRef.current !== null && prevViewNameForResetRef.current !== currentViewName;
|
|
17451
17502
|
prevViewNameForResetRef.current = currentViewName;
|
|
@@ -17462,7 +17513,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17462
17513
|
resetAnalyzeDefaults();
|
|
17463
17514
|
}
|
|
17464
17515
|
}, [currentViewName, resetAnalyzeDefaults, resetLayoutDefaults, viewNamesLoaded]);
|
|
17465
|
-
|
|
17516
|
+
React6.useEffect(() => {
|
|
17466
17517
|
const resourceKey = prefsKey;
|
|
17467
17518
|
const viewKey = `${resourceKey}::${currentViewName}`;
|
|
17468
17519
|
if (analyzePrefsResourceRef.current !== viewKey) {
|
|
@@ -17515,7 +17566,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17515
17566
|
cancelled = true;
|
|
17516
17567
|
};
|
|
17517
17568
|
}, [apiUrl, currentViewName, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17518
|
-
|
|
17569
|
+
React6.useEffect(() => {
|
|
17519
17570
|
if (!resolvedLayoutPreferenceType) return;
|
|
17520
17571
|
const resourceKey = prefsKey;
|
|
17521
17572
|
const viewKey = `${resourceKey}::${resolvedLayoutPreferenceType}::${currentViewName}`;
|
|
@@ -17600,7 +17651,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17600
17651
|
cancelled = true;
|
|
17601
17652
|
};
|
|
17602
17653
|
}, [apiUrl, currentViewName, resolvedLayoutPreferenceType, model.name, model.resource, allModels, preferencesResourceOverride]);
|
|
17603
|
-
const fetchAllRows =
|
|
17654
|
+
const fetchAllRows = React6.useCallback(async () => {
|
|
17604
17655
|
setIsAllRowsLoading(true);
|
|
17605
17656
|
setAllRowsError(null);
|
|
17606
17657
|
const filtersToApply = activeFilters && activeFilters.length > 0 ? activeFilters : tableFilters;
|
|
@@ -17636,7 +17687,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17636
17687
|
setAllRowsLoaded(true);
|
|
17637
17688
|
}
|
|
17638
17689
|
}, [activeFilters, apiUrl, model.name, model.resource, tableFilters, allModels]);
|
|
17639
|
-
|
|
17690
|
+
React6.useEffect(() => {
|
|
17640
17691
|
if (!shouldLoadAllRows) return;
|
|
17641
17692
|
const filtersToApply = activeFilters && activeFilters.length > 0 ? activeFilters : tableFilters;
|
|
17642
17693
|
const signature = JSON.stringify({
|
|
@@ -17651,7 +17702,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17651
17702
|
lastAllRowsSignature.current = signature;
|
|
17652
17703
|
fetchAllRows();
|
|
17653
17704
|
}, [activeFilters, analyzeOpen, exportRequested, fetchAllRows, model.name, shouldLoadAllRows, tableFilters]);
|
|
17654
|
-
|
|
17705
|
+
React6.useEffect(() => {
|
|
17655
17706
|
if (!allRowsLoaded) return;
|
|
17656
17707
|
if (analyzeTouchedRef.current) return;
|
|
17657
17708
|
if (isTotalsDetailsView) return;
|
|
@@ -17661,7 +17712,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17661
17712
|
setAnalyzeOpen(true);
|
|
17662
17713
|
}
|
|
17663
17714
|
}, [allRows?.length, allRowsLoaded, isTotalsDetailsView]);
|
|
17664
|
-
|
|
17715
|
+
React6.useEffect(() => {
|
|
17665
17716
|
if (!hasActiveFilterRules || isClientFiltering) return;
|
|
17666
17717
|
const resolveServerDate = (val, forRange) => {
|
|
17667
17718
|
if (val?.mode === "relative") {
|
|
@@ -17724,7 +17775,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17724
17775
|
const combined = [...tableFilters, ...serverFilters];
|
|
17725
17776
|
setFilters(combined, "replace");
|
|
17726
17777
|
}, [filterRules, hasActiveFilterRules, isClientFiltering, model.fields, setFilters, tableFilters]);
|
|
17727
|
-
const formatCategoryValue =
|
|
17778
|
+
const formatCategoryValue = React6.useCallback((field, record) => {
|
|
17728
17779
|
if (!field) return _36("All");
|
|
17729
17780
|
const raw = record?.[field.key];
|
|
17730
17781
|
if (raw === void 0 || raw === null) return "-";
|
|
@@ -17742,7 +17793,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17742
17793
|
if (field.type === "time") return formatTimeValue(raw);
|
|
17743
17794
|
return String(raw);
|
|
17744
17795
|
}, [labelCache]);
|
|
17745
|
-
const chartData =
|
|
17796
|
+
const chartData = React6.useMemo(() => {
|
|
17746
17797
|
const data = Array.isArray(columnFilteredDataSource) ? columnFilteredDataSource : [];
|
|
17747
17798
|
const cat1Field = categoryField1 ? model.fields.find((field) => field.key === categoryField1) : void 0;
|
|
17748
17799
|
const cat2Field = categoryField2 ? model.fields.find((field) => field.key === categoryField2) : void 0;
|
|
@@ -17849,7 +17900,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17849
17900
|
};
|
|
17850
17901
|
}, [columnFilteredDataSource, categoryField1, categoryField2, model.fields, numericFields, formatCategoryValue, summaryFn, selectedSeriesKeys, rankingMode, rankingFieldKey, rankingN]);
|
|
17851
17902
|
const crosstabBarColor = modelTone.soft || token.colorPrimaryBg || "rgba(22, 119, 255, 0.16)";
|
|
17852
|
-
const stageCrosstabCellEdits =
|
|
17903
|
+
const stageCrosstabCellEdits = React6.useCallback((updates) => {
|
|
17853
17904
|
if (updates.length === 0) return;
|
|
17854
17905
|
setCrosstabStaged((prev) => {
|
|
17855
17906
|
const next = { ...prev };
|
|
@@ -17860,11 +17911,11 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17860
17911
|
return next;
|
|
17861
17912
|
});
|
|
17862
17913
|
}, []);
|
|
17863
|
-
const getCrosstabStagedValue =
|
|
17914
|
+
const getCrosstabStagedValue = React6.useCallback((recordId, fieldKey) => {
|
|
17864
17915
|
return crosstabStaged[String(recordId)]?.[fieldKey];
|
|
17865
17916
|
}, [crosstabStaged]);
|
|
17866
17917
|
const crosstabHasPendingEdits = Object.keys(crosstabStaged).length > 0;
|
|
17867
|
-
const saveCrosstabEdits =
|
|
17918
|
+
const saveCrosstabEdits = React6.useCallback(async () => {
|
|
17868
17919
|
const entries = Object.entries(crosstabStaged);
|
|
17869
17920
|
if (entries.length === 0) return;
|
|
17870
17921
|
setCrosstabSaving(true);
|
|
@@ -17887,8 +17938,8 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17887
17938
|
setCrosstabSaving(false);
|
|
17888
17939
|
}
|
|
17889
17940
|
}, [crosstabStaged, apiUrl, allModels, model.resource, model.name, invalidate]);
|
|
17890
|
-
const crosstabResolvedRefIdsRef =
|
|
17891
|
-
|
|
17941
|
+
const crosstabResolvedRefIdsRef = React6.useRef(/* @__PURE__ */ new Set());
|
|
17942
|
+
React6.useEffect(() => {
|
|
17892
17943
|
if (!isCrosstabView) return;
|
|
17893
17944
|
const refFields = [categoryField1, categoryField2, ...crosstabFilterFields].filter((k) => Boolean(k)).map((k) => model.fields.find((f) => f.key === k)).filter((f) => Boolean(f && f.reference));
|
|
17894
17945
|
if (refFields.length === 0) return;
|
|
@@ -17923,7 +17974,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
17923
17974
|
cancelled = true;
|
|
17924
17975
|
};
|
|
17925
17976
|
}, [isCrosstabView, categoryField1, categoryField2, crosstabFilterFields, allRowsData, columnFilteredDataSource, model.fields, allModels, apiUrl, handleReferenceLabel]);
|
|
17926
|
-
const crosstabFilterOptions =
|
|
17977
|
+
const crosstabFilterOptions = React6.useMemo(() => {
|
|
17927
17978
|
if (crosstabFilterFields.length === 0) return /* @__PURE__ */ new Map();
|
|
17928
17979
|
const data = allRowsData.length > 0 ? allRowsData : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
|
|
17929
17980
|
const rangeCount = viewSettings?.maxDistinctColumnFilterValuesToRanges ?? 20;
|
|
@@ -18095,7 +18146,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18095
18146
|
}
|
|
18096
18147
|
)
|
|
18097
18148
|
] });
|
|
18098
|
-
const chartSignature =
|
|
18149
|
+
const chartSignature = React6.useMemo(() => {
|
|
18099
18150
|
return JSON.stringify({
|
|
18100
18151
|
chartType,
|
|
18101
18152
|
summaryFn,
|
|
@@ -18108,10 +18159,10 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18108
18159
|
groups: chartData.groups
|
|
18109
18160
|
});
|
|
18110
18161
|
}, [chartType, summaryFn, categoryField1, categoryField2, rankingMode, rankingFieldKey, rankingN, chartData]);
|
|
18111
|
-
const statsSummary =
|
|
18162
|
+
const statsSummary = React6.useMemo(() => {
|
|
18112
18163
|
return buildStatsSummary(columnFilteredDataSource, displayFields, labelCache);
|
|
18113
18164
|
}, [columnFilteredDataSource, displayFields, labelCache]);
|
|
18114
|
-
const tdCategoricalBoxes =
|
|
18165
|
+
const tdCategoricalBoxes = React6.useMemo(() => {
|
|
18115
18166
|
if (!isTotalsDetailsView) return [];
|
|
18116
18167
|
return displayFields.filter((field) => field.type !== "number" || Boolean(field.reference)).map((field) => {
|
|
18117
18168
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -18148,14 +18199,14 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18148
18199
|
};
|
|
18149
18200
|
});
|
|
18150
18201
|
}, [isTotalsDetailsView, allRows, displayFields, labelCache]);
|
|
18151
|
-
const getDefaultTotalsSummaryFn =
|
|
18202
|
+
const getDefaultTotalsSummaryFn = React6.useCallback((field) => {
|
|
18152
18203
|
if (isPkField(field, model) || isReferenceField(field)) return "count";
|
|
18153
18204
|
return "sum";
|
|
18154
18205
|
}, []);
|
|
18155
|
-
const resolveTotalsSummaryFn =
|
|
18206
|
+
const resolveTotalsSummaryFn = React6.useCallback((field) => {
|
|
18156
18207
|
return totalsSummaryFunctions[field.key] || getDefaultTotalsSummaryFn(field);
|
|
18157
18208
|
}, [getDefaultTotalsSummaryFn, totalsSummaryFunctions]);
|
|
18158
|
-
const computeTotalsSummaryValue =
|
|
18209
|
+
const computeTotalsSummaryValue = React6.useCallback((field) => {
|
|
18159
18210
|
const fn = resolveTotalsSummaryFn(field);
|
|
18160
18211
|
if (field.type === "number" && !field.reference) {
|
|
18161
18212
|
const values = (allRows || []).map((row) => Number(row?.[field.key])).filter((v) => !Number.isNaN(v) && Number.isFinite(v));
|
|
@@ -18184,7 +18235,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18184
18235
|
if (fn === "distinct") return new Set(rawValues.map((v) => String(v ?? "-"))).size;
|
|
18185
18236
|
return rawValues.length;
|
|
18186
18237
|
}, [allRows, resolveTotalsSummaryFn]);
|
|
18187
|
-
const getSummaryFunctionDisplayText =
|
|
18238
|
+
const getSummaryFunctionDisplayText = React6.useCallback((fn) => {
|
|
18188
18239
|
if (!fn) return "";
|
|
18189
18240
|
const labels = {
|
|
18190
18241
|
sum: _36("Sum"),
|
|
@@ -18197,7 +18248,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18197
18248
|
};
|
|
18198
18249
|
return labels[fn] || fn;
|
|
18199
18250
|
}, []);
|
|
18200
|
-
const tdNumericBoxes =
|
|
18251
|
+
const tdNumericBoxes = React6.useMemo(() => {
|
|
18201
18252
|
if (!isTotalsDetailsView) return [];
|
|
18202
18253
|
return displayFields.filter((field) => field.type === "number" && !field.reference).map((field) => {
|
|
18203
18254
|
const summaryFnVal = resolveTotalsSummaryFn(field);
|
|
@@ -18206,7 +18257,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18206
18257
|
return { key: field.key, label, value, summaryFn: summaryFnVal };
|
|
18207
18258
|
});
|
|
18208
18259
|
}, [isTotalsDetailsView, displayFields, resolveTotalsSummaryFn, computeTotalsSummaryValue]);
|
|
18209
|
-
const totalsSummaryConfigFields =
|
|
18260
|
+
const totalsSummaryConfigFields = React6.useMemo(() => {
|
|
18210
18261
|
return displayFields.filter((field) => field.type === "number" && !field.reference);
|
|
18211
18262
|
}, [displayFields]);
|
|
18212
18263
|
const renderDynamicListTotalsBoxes = () => {
|
|
@@ -18271,7 +18322,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18271
18322
|
) })
|
|
18272
18323
|
] }) });
|
|
18273
18324
|
};
|
|
18274
|
-
const numericColumnMaxes =
|
|
18325
|
+
const numericColumnMaxes = React6.useMemo(() => {
|
|
18275
18326
|
const maxes = {};
|
|
18276
18327
|
const rows = allRows || [];
|
|
18277
18328
|
displayFields.forEach((field) => {
|
|
@@ -18285,7 +18336,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18285
18336
|
});
|
|
18286
18337
|
return maxes;
|
|
18287
18338
|
}, [allRows, displayFields]);
|
|
18288
|
-
const statsNumericMaxes =
|
|
18339
|
+
const statsNumericMaxes = React6.useMemo(() => {
|
|
18289
18340
|
const stats = statsSummary.numericStats;
|
|
18290
18341
|
const maxAbs = (values) => {
|
|
18291
18342
|
const absValues = values.filter((val) => typeof val === "number").map((val) => Math.abs(val));
|
|
@@ -18299,13 +18350,13 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18299
18350
|
stddev: maxAbs(stats.map((row) => row.stddev))
|
|
18300
18351
|
};
|
|
18301
18352
|
}, [statsSummary.numericStats]);
|
|
18302
|
-
|
|
18353
|
+
React6.useEffect(() => {
|
|
18303
18354
|
if (!analyzeOpen) return;
|
|
18304
18355
|
skipNextAnimationRef.current = true;
|
|
18305
18356
|
setChartAnimationStage("enter");
|
|
18306
18357
|
setChartAnimationKey((key) => key + 1);
|
|
18307
18358
|
}, [analyzeOpen]);
|
|
18308
|
-
|
|
18359
|
+
React6.useEffect(() => {
|
|
18309
18360
|
if (!analyzeOpen) return;
|
|
18310
18361
|
if (skipNextAnimationRef.current) {
|
|
18311
18362
|
skipNextAnimationRef.current = false;
|
|
@@ -18314,17 +18365,17 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18314
18365
|
setChartAnimationStage("update");
|
|
18315
18366
|
setChartAnimationKey((key) => key + 1);
|
|
18316
18367
|
}, [analyzeOpen, chartSignature]);
|
|
18317
|
-
const fieldByKey =
|
|
18368
|
+
const fieldByKey = React6.useMemo(() => {
|
|
18318
18369
|
return new Map(model.fields.map((field) => [field.key, field]));
|
|
18319
18370
|
}, [model.fields]);
|
|
18320
|
-
const chartTitle =
|
|
18371
|
+
const chartTitle = React6.useMemo(() => {
|
|
18321
18372
|
const cat1Label = categoryField1 ? fieldByKey.get(categoryField1)?.label : "All";
|
|
18322
18373
|
const cat2Label = categoryField2 ? fieldByKey.get(categoryField2)?.label : null;
|
|
18323
18374
|
const parts = [model.label || model.name, cat1Label];
|
|
18324
18375
|
if (cat2Label) parts.push(cat2Label);
|
|
18325
18376
|
return parts.filter(Boolean).join(" \u2022 ");
|
|
18326
18377
|
}, [categoryField1, categoryField2, fieldByKey, model.label, model.name]);
|
|
18327
|
-
const formatValueForExport =
|
|
18378
|
+
const formatValueForExport = React6.useCallback((field, record) => {
|
|
18328
18379
|
const raw = record?.[field.key];
|
|
18329
18380
|
if (raw === void 0 || raw === null) return "";
|
|
18330
18381
|
if (field.reference) {
|
|
@@ -18340,7 +18391,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18340
18391
|
if (field.type === "time") return formatTimeValue(raw);
|
|
18341
18392
|
return String(raw);
|
|
18342
18393
|
}, [labelCache]);
|
|
18343
|
-
|
|
18394
|
+
React6.useEffect(() => {
|
|
18344
18395
|
if (!exportRequested || isAllRowsLoading) return;
|
|
18345
18396
|
const escapeCsv = (value) => {
|
|
18346
18397
|
if (value.includes('"') || value.includes(",") || value.includes("\n")) {
|
|
@@ -18453,11 +18504,11 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18453
18504
|
}
|
|
18454
18505
|
return { resource: null, id: null, isLinkRow: false };
|
|
18455
18506
|
};
|
|
18456
|
-
const clearBulkSelection =
|
|
18507
|
+
const clearBulkSelection = React6.useCallback(() => {
|
|
18457
18508
|
setBulkSelectedRowKeys([]);
|
|
18458
18509
|
bulkSelectedRowsMapRef.current.clear();
|
|
18459
18510
|
}, []);
|
|
18460
|
-
|
|
18511
|
+
React6.useEffect(() => {
|
|
18461
18512
|
if (!selectAllFilteredPending || !allRowsLoaded) return;
|
|
18462
18513
|
setSelectAllFilteredPending(false);
|
|
18463
18514
|
const keys = filteredDataSource.map((r) => getRowKey(r));
|
|
@@ -18465,7 +18516,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18465
18516
|
filteredDataSource.forEach((r) => bulkSelectedRowsMapRef.current.set(getRowKey(r), r));
|
|
18466
18517
|
setBulkSelectedRowKeys(keys);
|
|
18467
18518
|
}, [selectAllFilteredPending, allRowsLoaded, filteredDataSource]);
|
|
18468
|
-
const handleSelectAllFiltered =
|
|
18519
|
+
const handleSelectAllFiltered = React6.useCallback(() => {
|
|
18469
18520
|
if (!allRowsLoaded) {
|
|
18470
18521
|
setSelectAllFilteredPending(true);
|
|
18471
18522
|
fetchAllRows();
|
|
@@ -18476,7 +18527,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18476
18527
|
setBulkSelectedRowKeys(keys);
|
|
18477
18528
|
}
|
|
18478
18529
|
}, [allRowsLoaded, fetchAllRows, filteredDataSource]);
|
|
18479
|
-
const executeBulkActions =
|
|
18530
|
+
const executeBulkActions = React6.useCallback(async () => {
|
|
18480
18531
|
const records = bulkSelectedRowKeys.map((k) => bulkSelectedRowsMapRef.current.get(k)).filter(Boolean);
|
|
18481
18532
|
if (records.length === 0) return;
|
|
18482
18533
|
const resource = resolveResourcePath(model.resource || model.name, allModels);
|
|
@@ -18588,9 +18639,9 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18588
18639
|
}
|
|
18589
18640
|
};
|
|
18590
18641
|
const isEmptyTable = (filteredDataSource?.length ?? 0) === 0;
|
|
18591
|
-
const getRowKeyRef =
|
|
18642
|
+
const getRowKeyRef = React6.useRef(getRowKey);
|
|
18592
18643
|
getRowKeyRef.current = getRowKey;
|
|
18593
|
-
const handleBulkRowSelectionChange =
|
|
18644
|
+
const handleBulkRowSelectionChange = React6.useCallback(
|
|
18594
18645
|
(newKeys, newRowsOnPage) => {
|
|
18595
18646
|
const currentPageData = isClientFiltering ? filteredDataSource : Array.isArray(tableProps.dataSource) ? tableProps.dataSource : [];
|
|
18596
18647
|
const currentPageKeys = new Set(currentPageData.map((r) => String(getRowKeyRef.current(r))));
|
|
@@ -18619,7 +18670,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
18619
18670
|
]
|
|
18620
18671
|
};
|
|
18621
18672
|
const filteredTotalCount = isClientFiltering ? filteredDataSource.length : typeof tableProps.pagination === "object" ? tableProps.pagination?.total ?? filteredDataSource.length : filteredDataSource.length;
|
|
18622
|
-
const bulkActionsAvailable =
|
|
18673
|
+
const bulkActionsAvailable = React6.useMemo(() => {
|
|
18623
18674
|
const opts = [];
|
|
18624
18675
|
if (canBulkEdit) {
|
|
18625
18676
|
opts.push({ label: _36("Change field value"), value: "__change_field__" });
|
|
@@ -19049,7 +19100,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19049
19100
|
});
|
|
19050
19101
|
};
|
|
19051
19102
|
const galleryPageSize = typeof tablePagination === "object" && tablePagination?.pageSize ? tablePagination.pageSize : 10;
|
|
19052
|
-
const handleGalleryPageChange =
|
|
19103
|
+
const handleGalleryPageChange = React6.useCallback((page, nextPageSize) => {
|
|
19053
19104
|
setGalleryPage(page);
|
|
19054
19105
|
if (nextPageSize && nextPageSize !== pageSize) {
|
|
19055
19106
|
setPageSize(nextPageSize);
|
|
@@ -19067,19 +19118,19 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19067
19118
|
}, [isClientFiltering, pageSize, tableProps]);
|
|
19068
19119
|
const serverCurrentPage = !isClientFiltering && typeof tableProps.pagination === "object" ? Number(tableProps.pagination.current || 1) : 1;
|
|
19069
19120
|
const serverTotal = !isClientFiltering && typeof tableProps.pagination === "object" ? Number(tableProps.pagination.total || 0) : 0;
|
|
19070
|
-
|
|
19121
|
+
React6.useEffect(() => {
|
|
19071
19122
|
if (isClientFiltering) return;
|
|
19072
19123
|
if (Number.isFinite(serverCurrentPage) && serverCurrentPage > 0 && serverCurrentPage !== galleryPage) {
|
|
19073
19124
|
setGalleryPage(serverCurrentPage);
|
|
19074
19125
|
}
|
|
19075
19126
|
}, [galleryPage, isClientFiltering, serverCurrentPage]);
|
|
19076
|
-
const galleryRows =
|
|
19127
|
+
const galleryRows = React6.useMemo(() => {
|
|
19077
19128
|
if (!isGalleryView) return [];
|
|
19078
19129
|
if (!isClientFiltering) return filteredDataSource;
|
|
19079
19130
|
const start = (galleryPage - 1) * galleryPageSize;
|
|
19080
19131
|
return filteredDataSource.slice(start, start + galleryPageSize);
|
|
19081
19132
|
}, [filteredDataSource, galleryPage, galleryPageSize, isClientFiltering, isGalleryView]);
|
|
19082
|
-
const galleryPaginationProps =
|
|
19133
|
+
const galleryPaginationProps = React6.useMemo(() => {
|
|
19083
19134
|
if (!isGalleryView) return void 0;
|
|
19084
19135
|
if (!isClientFiltering) {
|
|
19085
19136
|
return {
|
|
@@ -19104,17 +19155,17 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19104
19155
|
onShowSizeChange: handleGalleryPageChange
|
|
19105
19156
|
};
|
|
19106
19157
|
}, [filteredDataSource.length, galleryPage, galleryPageSize, handleGalleryPageChange, isClientFiltering, isGalleryView, serverTotal, tablePagination]);
|
|
19107
|
-
const calendarDateFieldKeySet =
|
|
19158
|
+
const calendarDateFieldKeySet = React6.useMemo(
|
|
19108
19159
|
() => new Set(calendarDateFieldOptions.map((field) => field.key)),
|
|
19109
19160
|
[calendarDateFieldOptions]
|
|
19110
19161
|
);
|
|
19111
|
-
|
|
19162
|
+
React6.useEffect(() => {
|
|
19112
19163
|
if (!isCalendarView) return;
|
|
19113
19164
|
if (calendarDateField && calendarDateFieldKeySet.has(calendarDateField)) return;
|
|
19114
19165
|
const fallback = calendarDateFieldOptions[0]?.key || "";
|
|
19115
19166
|
if (fallback !== calendarDateField) setCalendarDateField(fallback);
|
|
19116
19167
|
}, [calendarDateField, calendarDateFieldKeySet, calendarDateFieldOptions, isCalendarView]);
|
|
19117
|
-
const calendarEntries =
|
|
19168
|
+
const calendarEntries = React6.useMemo(() => {
|
|
19118
19169
|
if (!isCalendarView || !calendarDateField) return [];
|
|
19119
19170
|
const entries = [];
|
|
19120
19171
|
filteredDataSource.forEach((record) => {
|
|
@@ -19132,7 +19183,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19132
19183
|
});
|
|
19133
19184
|
return entries;
|
|
19134
19185
|
}, [calendarDateField, filteredDataSource, isCalendarView]);
|
|
19135
|
-
const calendarEarliestDateTs =
|
|
19186
|
+
const calendarEarliestDateTs = React6.useMemo(() => {
|
|
19136
19187
|
if (calendarEntries.length === 0) return null;
|
|
19137
19188
|
let earliest = calendarEntries[0].date.valueOf();
|
|
19138
19189
|
for (let index = 1; index < calendarEntries.length; index += 1) {
|
|
@@ -19141,8 +19192,8 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19141
19192
|
}
|
|
19142
19193
|
return earliest;
|
|
19143
19194
|
}, [calendarEntries]);
|
|
19144
|
-
const calendarInitSignatureRef =
|
|
19145
|
-
|
|
19195
|
+
const calendarInitSignatureRef = React6.useRef("");
|
|
19196
|
+
React6.useEffect(() => {
|
|
19146
19197
|
if (!isCalendarView) return;
|
|
19147
19198
|
const signature = `${calendarDateField}|${calendarMode}|${calendarEarliestDateTs ?? "none"}`;
|
|
19148
19199
|
if (calendarInitSignatureRef.current === signature) return;
|
|
@@ -19153,7 +19204,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19153
19204
|
}
|
|
19154
19205
|
setCalendarAnchorDate(dayjs9__default.default(calendarEarliestDateTs).startOf(calendarMode));
|
|
19155
19206
|
}, [calendarDateField, calendarEarliestDateTs, calendarMode, isCalendarView]);
|
|
19156
|
-
const calendarEntriesByDate =
|
|
19207
|
+
const calendarEntriesByDate = React6.useMemo(() => {
|
|
19157
19208
|
const grouped = /* @__PURE__ */ new Map();
|
|
19158
19209
|
calendarEntries.forEach((entry) => {
|
|
19159
19210
|
const key = entry.date.format("YYYY-MM-DD");
|
|
@@ -19163,7 +19214,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19163
19214
|
});
|
|
19164
19215
|
return grouped;
|
|
19165
19216
|
}, [calendarEntries]);
|
|
19166
|
-
const calendarRangeDays =
|
|
19217
|
+
const calendarRangeDays = React6.useMemo(() => {
|
|
19167
19218
|
const current = calendarAnchorDate.startOf(calendarMode);
|
|
19168
19219
|
if (calendarMode === "week") {
|
|
19169
19220
|
const start2 = current.startOf("week");
|
|
@@ -19174,7 +19225,7 @@ var DynamicList = ({ model: modelProp, allModels, filter, relationConfig, isEmbe
|
|
|
19174
19225
|
const totalDays = end.diff(start, "day") + 1;
|
|
19175
19226
|
return Array.from({ length: totalDays }, (_unused, offset) => start.add(offset, "day"));
|
|
19176
19227
|
}, [calendarAnchorDate, calendarMode]);
|
|
19177
|
-
const calendarPeriodLabel =
|
|
19228
|
+
const calendarPeriodLabel = React6.useMemo(() => {
|
|
19178
19229
|
if (calendarMode === "week") {
|
|
19179
19230
|
const weekStart = calendarAnchorDate.startOf("week");
|
|
19180
19231
|
const weekEnd = weekStart.endOf("week");
|
|
@@ -20363,8 +20414,8 @@ var LIST_PANEL_ID = "list-panel";
|
|
|
20363
20414
|
var detailPanelId = (idx) => `detail-panel-${idx}`;
|
|
20364
20415
|
var COLLAPSED_SIZE = 10;
|
|
20365
20416
|
var FakeRouteProvider = ({ model, id, children }) => {
|
|
20366
|
-
const existingRouteContext =
|
|
20367
|
-
const fakeRouteContext =
|
|
20417
|
+
const existingRouteContext = React6.useContext(reactRouterDom.UNSAFE_RouteContext);
|
|
20418
|
+
const fakeRouteContext = React6.useMemo(() => ({
|
|
20368
20419
|
...existingRouteContext,
|
|
20369
20420
|
matches: [
|
|
20370
20421
|
...existingRouteContext.matches,
|
|
@@ -20484,9 +20535,9 @@ var ResizeHandle = () => {
|
|
|
20484
20535
|
);
|
|
20485
20536
|
};
|
|
20486
20537
|
var MultiPaneLayout = ({ children }) => {
|
|
20487
|
-
const containerRef =
|
|
20488
|
-
const [panelHeight, setPanelHeight] =
|
|
20489
|
-
|
|
20538
|
+
const containerRef = React6.useRef(null);
|
|
20539
|
+
const [panelHeight, setPanelHeight] = React6.useState("100vh");
|
|
20540
|
+
React6.useLayoutEffect(() => {
|
|
20490
20541
|
const measure = () => {
|
|
20491
20542
|
if (!containerRef.current) return;
|
|
20492
20543
|
const top = containerRef.current.getBoundingClientRect().top;
|
|
@@ -20498,13 +20549,13 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20498
20549
|
}, []);
|
|
20499
20550
|
const [searchParams, setSearchParams] = reactRouterDom.useSearchParams();
|
|
20500
20551
|
const allModels = useAllModels();
|
|
20501
|
-
const PrimaryShowRenderer =
|
|
20552
|
+
const PrimaryShowRenderer = React6.useContext(PrimaryShowContext);
|
|
20502
20553
|
const { token } = antd.theme.useToken();
|
|
20503
|
-
const panes =
|
|
20504
|
-
const groupRef =
|
|
20505
|
-
const pendingLayoutRef =
|
|
20506
|
-
const prevPaneCountRef =
|
|
20507
|
-
|
|
20554
|
+
const panes = React6.useMemo(() => parsePanes(searchParams), [searchParams]);
|
|
20555
|
+
const groupRef = React6.useRef(null);
|
|
20556
|
+
const pendingLayoutRef = React6.useRef(null);
|
|
20557
|
+
const prevPaneCountRef = React6.useRef(0);
|
|
20558
|
+
React6.useEffect(() => {
|
|
20508
20559
|
const newCount = panes.length;
|
|
20509
20560
|
const prevCount = prevPaneCountRef.current;
|
|
20510
20561
|
if (!pendingLayoutRef.current || !groupRef.current) {
|
|
@@ -20531,7 +20582,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20531
20582
|
});
|
|
20532
20583
|
return () => cancelAnimationFrame(frameId);
|
|
20533
20584
|
}, [panes.length]);
|
|
20534
|
-
const openDetail =
|
|
20585
|
+
const openDetail = React6.useCallback(
|
|
20535
20586
|
(fromPaneIndex, resource, id) => {
|
|
20536
20587
|
if (groupRef.current) {
|
|
20537
20588
|
pendingLayoutRef.current = { ...groupRef.current.getLayout() };
|
|
@@ -20551,7 +20602,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20551
20602
|
},
|
|
20552
20603
|
[allModels, setSearchParams]
|
|
20553
20604
|
);
|
|
20554
|
-
const closePane =
|
|
20605
|
+
const closePane = React6.useCallback(
|
|
20555
20606
|
(fromArrayIndex) => {
|
|
20556
20607
|
setSearchParams(
|
|
20557
20608
|
(prev) => {
|
|
@@ -20563,7 +20614,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20563
20614
|
},
|
|
20564
20615
|
[setSearchParams]
|
|
20565
20616
|
);
|
|
20566
|
-
const minimizePane =
|
|
20617
|
+
const minimizePane = React6.useCallback((panelId) => {
|
|
20567
20618
|
if (!groupRef.current) return;
|
|
20568
20619
|
const layout = groupRef.current.getLayout();
|
|
20569
20620
|
const currentSize = layout[panelId] ?? COLLAPSED_SIZE;
|
|
@@ -20578,7 +20629,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20578
20629
|
});
|
|
20579
20630
|
groupRef.current.setLayout(newLayout);
|
|
20580
20631
|
}, []);
|
|
20581
|
-
const maximizePane =
|
|
20632
|
+
const maximizePane = React6.useCallback((panelId) => {
|
|
20582
20633
|
if (!groupRef.current) return;
|
|
20583
20634
|
const layout = groupRef.current.getLayout();
|
|
20584
20635
|
const panelIds = Object.keys(layout);
|
|
@@ -20590,7 +20641,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20590
20641
|
});
|
|
20591
20642
|
groupRef.current.setLayout(newLayout);
|
|
20592
20643
|
}, []);
|
|
20593
|
-
const listPaneContext =
|
|
20644
|
+
const listPaneContext = React6.useMemo(
|
|
20594
20645
|
() => ({
|
|
20595
20646
|
isInMultiPane: true,
|
|
20596
20647
|
paneIndex: 0,
|
|
@@ -20598,7 +20649,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20598
20649
|
}),
|
|
20599
20650
|
[openDetail]
|
|
20600
20651
|
);
|
|
20601
|
-
const detailPaneContexts =
|
|
20652
|
+
const detailPaneContexts = React6.useMemo(
|
|
20602
20653
|
() => panes.map((_43, idx) => ({
|
|
20603
20654
|
isInMultiPane: true,
|
|
20604
20655
|
paneIndex: idx + 1,
|
|
@@ -20606,7 +20657,7 @@ var MultiPaneLayout = ({ children }) => {
|
|
|
20606
20657
|
})),
|
|
20607
20658
|
[panes, openDetail]
|
|
20608
20659
|
);
|
|
20609
|
-
const panelChildren =
|
|
20660
|
+
const panelChildren = React6.useMemo(() => {
|
|
20610
20661
|
const result = [
|
|
20611
20662
|
/* @__PURE__ */ jsxRuntime.jsx(Yt, { id: LIST_PANEL_ID, minSize: 10, style: { overflow: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(PaneNavigationContext.Provider, { value: listPaneContext, children }) }, "master-list")
|
|
20612
20663
|
];
|
|
@@ -20737,8 +20788,8 @@ var HierarchyView = ({ resource, recordId, fallback }) => {
|
|
|
20737
20788
|
};
|
|
20738
20789
|
var instanceCounter = 0;
|
|
20739
20790
|
var InlinePlotlyHtml = ({ html, style }) => {
|
|
20740
|
-
const containerRef =
|
|
20741
|
-
const instanceIdRef =
|
|
20791
|
+
const containerRef = React6.useRef(null);
|
|
20792
|
+
const instanceIdRef = React6.useRef("");
|
|
20742
20793
|
if (!instanceIdRef.current) {
|
|
20743
20794
|
instanceCounter += 1;
|
|
20744
20795
|
instanceIdRef.current = `iph-${instanceCounter}-${Date.now()}`;
|
|
@@ -20764,7 +20815,7 @@ var InlinePlotlyHtml = ({ html, style }) => {
|
|
|
20764
20815
|
/((?:reduceCardWidth|increaseCardWidth|optimizeCardSizeInViewPort|maximizeCardSize|minimizeCardSize|flipCard)\()(\d+)\)/g,
|
|
20765
20816
|
(match, func, suffix) => `${func}'${suffix}-${instanceId}')`
|
|
20766
20817
|
);
|
|
20767
|
-
|
|
20818
|
+
React6.useEffect(() => {
|
|
20768
20819
|
const container = containerRef.current;
|
|
20769
20820
|
if (!container) return;
|
|
20770
20821
|
const scripts = Array.from(container.querySelectorAll("script"));
|
|
@@ -21028,15 +21079,15 @@ var ColorModeContextProvider = ({
|
|
|
21028
21079
|
"(prefers-color-scheme: dark)"
|
|
21029
21080
|
).matches;
|
|
21030
21081
|
const systemPreference = isSystemPreferenceDark ? "dark" : "light";
|
|
21031
|
-
const [mode, setMode] =
|
|
21082
|
+
const [mode, setMode] = React6.useState(
|
|
21032
21083
|
colorModeFromLocalStorage === "dark" || colorModeFromLocalStorage === "light" ? colorModeFromLocalStorage : systemPreference
|
|
21033
21084
|
);
|
|
21034
|
-
const initializedFromServer =
|
|
21035
|
-
const [schemaVersion, setSchemaVersion] =
|
|
21036
|
-
|
|
21085
|
+
const initializedFromServer = React6.useRef(false);
|
|
21086
|
+
const [schemaVersion, setSchemaVersion] = React6.useState(0);
|
|
21087
|
+
React6.useEffect(() => {
|
|
21037
21088
|
return onColorSchemaChange(() => setSchemaVersion((v) => v + 1));
|
|
21038
21089
|
}, []);
|
|
21039
|
-
|
|
21090
|
+
React6.useEffect(() => {
|
|
21040
21091
|
let cancelled = false;
|
|
21041
21092
|
const load = async () => {
|
|
21042
21093
|
try {
|
|
@@ -21057,12 +21108,12 @@ var ColorModeContextProvider = ({
|
|
|
21057
21108
|
cancelled = true;
|
|
21058
21109
|
};
|
|
21059
21110
|
}, []);
|
|
21060
|
-
|
|
21111
|
+
React6.useEffect(() => {
|
|
21061
21112
|
window.localStorage.setItem("colorMode", mode);
|
|
21062
21113
|
document.body.classList.toggle("jm-dark", mode === "dark");
|
|
21063
21114
|
document.body.classList.toggle("jm-light", mode === "light");
|
|
21064
21115
|
}, [mode]);
|
|
21065
|
-
const saveToServer =
|
|
21116
|
+
const saveToServer = React6.useCallback(async (newMode) => {
|
|
21066
21117
|
try {
|
|
21067
21118
|
await authenticatedFetch(`${API_BASE_URL}/views/preferences/color-mode`, {
|
|
21068
21119
|
method: "POST",
|
|
@@ -21072,7 +21123,7 @@ var ColorModeContextProvider = ({
|
|
|
21072
21123
|
} catch (_e3) {
|
|
21073
21124
|
}
|
|
21074
21125
|
}, []);
|
|
21075
|
-
const setColorMode =
|
|
21126
|
+
const setColorMode = React6.useCallback((newMode) => {
|
|
21076
21127
|
setMode(newMode);
|
|
21077
21128
|
void saveToServer(newMode);
|
|
21078
21129
|
}, [saveToServer]);
|
|
@@ -21088,7 +21139,7 @@ var ColorModeContextProvider = ({
|
|
|
21088
21139
|
}
|
|
21089
21140
|
) });
|
|
21090
21141
|
};
|
|
21091
|
-
var ResourceContext =
|
|
21142
|
+
var ResourceContext = React6.createContext({
|
|
21092
21143
|
allResources: [],
|
|
21093
21144
|
allSystemModels: []
|
|
21094
21145
|
});
|
|
@@ -21194,10 +21245,10 @@ var LoginPage = ({ appTitle = "VeloIQ", logo }) => {
|
|
|
21194
21245
|
};
|
|
21195
21246
|
function useDashboardConfig() {
|
|
21196
21247
|
const apiUrl = core.useApiUrl();
|
|
21197
|
-
const [config, setConfig] =
|
|
21198
|
-
const [enabled, setEnabled] =
|
|
21199
|
-
const [loading, setLoading] =
|
|
21200
|
-
const load =
|
|
21248
|
+
const [config, setConfig] = React6.useState(null);
|
|
21249
|
+
const [enabled, setEnabled] = React6.useState(false);
|
|
21250
|
+
const [loading, setLoading] = React6.useState(true);
|
|
21251
|
+
const load = React6.useCallback(async () => {
|
|
21201
21252
|
setLoading(true);
|
|
21202
21253
|
try {
|
|
21203
21254
|
const res = await authenticatedFetch(`${apiUrl}/dashboard/config`);
|
|
@@ -21215,10 +21266,10 @@ function useDashboardConfig() {
|
|
|
21215
21266
|
setLoading(false);
|
|
21216
21267
|
}
|
|
21217
21268
|
}, [apiUrl]);
|
|
21218
|
-
|
|
21269
|
+
React6.useEffect(() => {
|
|
21219
21270
|
load();
|
|
21220
21271
|
}, [load]);
|
|
21221
|
-
const save =
|
|
21272
|
+
const save = React6.useCallback(async (next) => {
|
|
21222
21273
|
setConfig(next);
|
|
21223
21274
|
try {
|
|
21224
21275
|
await authenticatedFetch(`${apiUrl}/dashboard/config`, {
|
|
@@ -21232,10 +21283,10 @@ function useDashboardConfig() {
|
|
|
21232
21283
|
return { config, enabled, loading, save, reload: load };
|
|
21233
21284
|
}
|
|
21234
21285
|
var PlotlyChartContent = ({ chartUrl, refreshNonce }) => {
|
|
21235
|
-
const [chartHtml, setChartHtml] =
|
|
21236
|
-
const [loading, setLoading] =
|
|
21237
|
-
const [error, setError] =
|
|
21238
|
-
const fetchChart =
|
|
21286
|
+
const [chartHtml, setChartHtml] = React6.useState("");
|
|
21287
|
+
const [loading, setLoading] = React6.useState(true);
|
|
21288
|
+
const [error, setError] = React6.useState("");
|
|
21289
|
+
const fetchChart = React6.useCallback(async () => {
|
|
21239
21290
|
setLoading(true);
|
|
21240
21291
|
setError("");
|
|
21241
21292
|
try {
|
|
@@ -21259,7 +21310,7 @@ var PlotlyChartContent = ({ chartUrl, refreshNonce }) => {
|
|
|
21259
21310
|
setLoading(false);
|
|
21260
21311
|
}
|
|
21261
21312
|
}, [chartUrl]);
|
|
21262
|
-
|
|
21313
|
+
React6.useEffect(() => {
|
|
21263
21314
|
fetchChart();
|
|
21264
21315
|
}, [fetchChart, refreshNonce]);
|
|
21265
21316
|
if (loading) {
|
|
@@ -21276,7 +21327,7 @@ var PlotlyChartContent = ({ chartUrl, refreshNonce }) => {
|
|
|
21276
21327
|
var DashboardGridCell = ({ cell, allModels, isMaximized, isMinimized, canConfigureLayout, onConfigure, onMaximize, onMinimize, onResize, onMove }) => {
|
|
21277
21328
|
const { token } = antd.theme.useToken();
|
|
21278
21329
|
const model = findModelByName(allModels, cell.model);
|
|
21279
|
-
const cellRef =
|
|
21330
|
+
const cellRef = React6.useRef(null);
|
|
21280
21331
|
const cellStyle = {
|
|
21281
21332
|
position: "relative",
|
|
21282
21333
|
border: `1px solid ${token.colorBorderSecondary}`,
|
|
@@ -21310,8 +21361,8 @@ var DashboardGridCell = ({ cell, allModels, isMaximized, isMinimized, canConfigu
|
|
|
21310
21361
|
const isModelLike = cell.source_type === "model" || cell.source_type === "named_query";
|
|
21311
21362
|
const cellTitle = isPlotlyChart ? cell.chart_title || cell.model : isModelLike ? model?.label || cell.model : cell.section_name || cell.model;
|
|
21312
21363
|
const tone = isModelLike && model ? getModelTone(model) : null;
|
|
21313
|
-
const [chartRefreshNonce, setChartRefreshNonce] =
|
|
21314
|
-
const startResize =
|
|
21364
|
+
const [chartRefreshNonce, setChartRefreshNonce] = React6.useState(0);
|
|
21365
|
+
const startResize = React6.useCallback((e, dir) => {
|
|
21315
21366
|
e.preventDefault();
|
|
21316
21367
|
e.stopPropagation();
|
|
21317
21368
|
const el = cellRef.current;
|
|
@@ -21487,11 +21538,11 @@ var DashboardGridCell = ({ cell, allModels, isMaximized, isMinimized, canConfigu
|
|
|
21487
21538
|
};
|
|
21488
21539
|
var DashboardTabContent = ({ tab, allModels, maximizedCellId, minimizedCellIds, canConfigureLayout, onMaximize, onMinimize, onConfigure, onResize, onMove }) => {
|
|
21489
21540
|
const cells = tab.cells;
|
|
21490
|
-
const numCols =
|
|
21541
|
+
const numCols = React6.useMemo(() => {
|
|
21491
21542
|
if (!cells.length) return 2;
|
|
21492
21543
|
return Math.max(...cells.map((c) => c.col)) + 1;
|
|
21493
21544
|
}, [cells]);
|
|
21494
|
-
const numRows =
|
|
21545
|
+
const numRows = React6.useMemo(() => {
|
|
21495
21546
|
if (!cells.length) return 1;
|
|
21496
21547
|
return Math.max(...cells.map((c) => c.row)) + 1;
|
|
21497
21548
|
}, [cells]);
|
|
@@ -21537,13 +21588,13 @@ var DashboardTabContent = ({ tab, allModels, maximizedCellId, minimizedCellIds,
|
|
|
21537
21588
|
var ViewsGrid = ({ config, allModels, onConfigChange }) => {
|
|
21538
21589
|
const { data: canLayoutData } = core.useCan({ resource: "veloiq_layout", action: "configure_layout" });
|
|
21539
21590
|
const canConfigureLayout = canLayoutData?.can !== false;
|
|
21540
|
-
const [maximizedCellId, setMaximizedCellId] =
|
|
21541
|
-
const [minimizedCellIds, setMinimizedCellIds] =
|
|
21542
|
-
const [drawerSelection, setDrawerSelection] =
|
|
21543
|
-
const handleMaximize =
|
|
21591
|
+
const [maximizedCellId, setMaximizedCellId] = React6.useState(null);
|
|
21592
|
+
const [minimizedCellIds, setMinimizedCellIds] = React6.useState(/* @__PURE__ */ new Set());
|
|
21593
|
+
const [drawerSelection, setDrawerSelection] = React6.useState(null);
|
|
21594
|
+
const handleMaximize = React6.useCallback((cellId) => {
|
|
21544
21595
|
setMaximizedCellId((prev) => prev === cellId ? null : cellId);
|
|
21545
21596
|
}, []);
|
|
21546
|
-
const handleMinimize =
|
|
21597
|
+
const handleMinimize = React6.useCallback((cellId) => {
|
|
21547
21598
|
setMinimizedCellIds((prev) => {
|
|
21548
21599
|
const next = new Set(prev);
|
|
21549
21600
|
if (next.has(cellId)) {
|
|
@@ -21554,14 +21605,14 @@ var ViewsGrid = ({ config, allModels, onConfigChange }) => {
|
|
|
21554
21605
|
return next;
|
|
21555
21606
|
});
|
|
21556
21607
|
}, []);
|
|
21557
|
-
const handleOpenDrawer =
|
|
21608
|
+
const handleOpenDrawer = React6.useCallback((tabId, cell) => {
|
|
21558
21609
|
setDrawerSelection({ tabId, cell });
|
|
21559
21610
|
}, []);
|
|
21560
|
-
const handleSaveConfig =
|
|
21611
|
+
const handleSaveConfig = React6.useCallback((nextConfig) => {
|
|
21561
21612
|
onConfigChange(nextConfig);
|
|
21562
21613
|
setDrawerSelection(null);
|
|
21563
21614
|
}, [onConfigChange]);
|
|
21564
|
-
const handleMoveCell =
|
|
21615
|
+
const handleMoveCell = React6.useCallback((tabId, cellId, direction) => {
|
|
21565
21616
|
const nextTabs = config.tabs.map((tab) => {
|
|
21566
21617
|
if (tab.id !== tabId) return tab;
|
|
21567
21618
|
const cell = tab.cells.find((c) => c.id === cellId);
|
|
@@ -21582,7 +21633,7 @@ var ViewsGrid = ({ config, allModels, onConfigChange }) => {
|
|
|
21582
21633
|
});
|
|
21583
21634
|
onConfigChange({ ...config, tabs: nextTabs });
|
|
21584
21635
|
}, [config, onConfigChange]);
|
|
21585
|
-
const handleResizeCell =
|
|
21636
|
+
const handleResizeCell = React6.useCallback((tabId, cellId, minWidth, minHeight) => {
|
|
21586
21637
|
const nextTabs = config.tabs.map((tab) => {
|
|
21587
21638
|
if (tab.id !== tabId) return tab;
|
|
21588
21639
|
return {
|
|
@@ -21599,7 +21650,7 @@ var ViewsGrid = ({ config, allModels, onConfigChange }) => {
|
|
|
21599
21650
|
});
|
|
21600
21651
|
onConfigChange({ ...config, tabs: nextTabs });
|
|
21601
21652
|
}, [config, onConfigChange]);
|
|
21602
|
-
const tabItems =
|
|
21653
|
+
const tabItems = React6.useMemo(
|
|
21603
21654
|
() => config.tabs.map((tab) => ({
|
|
21604
21655
|
key: tab.id,
|
|
21605
21656
|
label: tab.name,
|
|
@@ -21679,7 +21730,7 @@ function relativeTime3(iso) {
|
|
|
21679
21730
|
var RecentActivityPanel = () => {
|
|
21680
21731
|
const { token } = antd.theme.useToken();
|
|
21681
21732
|
const allModels = useAllModels();
|
|
21682
|
-
const [days, setDays] =
|
|
21733
|
+
const [days, setDays] = React6.useState(30);
|
|
21683
21734
|
const { data, loading, reload } = useRecentActivity(days);
|
|
21684
21735
|
const groups = data?.groups ?? [];
|
|
21685
21736
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "16px 0" }, children: [
|
|
@@ -21787,9 +21838,9 @@ var RecentActivityPanel = () => {
|
|
|
21787
21838
|
};
|
|
21788
21839
|
var { Text: AntText, Title: AntTitle } = antd.Typography;
|
|
21789
21840
|
function usePinnedRecords() {
|
|
21790
|
-
const [groups, setGroups] =
|
|
21791
|
-
const [loading, setLoading] =
|
|
21792
|
-
const load =
|
|
21841
|
+
const [groups, setGroups] = React6.useState([]);
|
|
21842
|
+
const [loading, setLoading] = React6.useState(true);
|
|
21843
|
+
const load = React6.useCallback(async () => {
|
|
21793
21844
|
setLoading(true);
|
|
21794
21845
|
try {
|
|
21795
21846
|
const res = await authenticatedFetch(`${API_URL3}/dashboard/pinned-records`);
|
|
@@ -21802,7 +21853,7 @@ function usePinnedRecords() {
|
|
|
21802
21853
|
setLoading(false);
|
|
21803
21854
|
}
|
|
21804
21855
|
}, []);
|
|
21805
|
-
|
|
21856
|
+
React6__default.default.useEffect(() => {
|
|
21806
21857
|
load();
|
|
21807
21858
|
}, [load]);
|
|
21808
21859
|
return { groups, loading, reload: load };
|
|
@@ -21811,9 +21862,9 @@ var PinnedRecordsPanel = () => {
|
|
|
21811
21862
|
const { token } = antd.theme.useToken();
|
|
21812
21863
|
const allModels = useAllModels();
|
|
21813
21864
|
const { groups, loading, reload } = usePinnedRecords();
|
|
21814
|
-
const [unpinning, setUnpinning] =
|
|
21865
|
+
const [unpinning, setUnpinning] = React6.useState(/* @__PURE__ */ new Set());
|
|
21815
21866
|
const visibleGroups = groups.filter((g) => findModelByName(allModels, g.resource));
|
|
21816
|
-
const handleUnpin =
|
|
21867
|
+
const handleUnpin = React6.useCallback(async (resource, recordId) => {
|
|
21817
21868
|
const key = `${resource}:${recordId}`;
|
|
21818
21869
|
setUnpinning((prev) => new Set(prev).add(key));
|
|
21819
21870
|
try {
|