@capillarytech/blaze-ui 1.0.3-alpha.13 → 1.0.3-alpha.15
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/CapUnifiedSelect/CapUnifiedSelect.d.ts +1 -21
- package/CapUnifiedSelect/CapUnifiedSelect.d.ts.map +1 -1
- package/CapUnifiedSelect/components.d.ts +9 -0
- package/CapUnifiedSelect/components.d.ts.map +1 -0
- package/CapUnifiedSelect/constants.d.ts +0 -28
- package/CapUnifiedSelect/constants.d.ts.map +1 -1
- package/CapUnifiedSelect/index.js +440 -704
- package/CapUnifiedSelect/index.js.map +1 -1
- package/CapUnifiedSelect/testData.d.ts +0 -50
- package/CapUnifiedSelect/testData.d.ts.map +1 -1
- package/CapUnifiedSelect/types.d.ts +45 -0
- package/CapUnifiedSelect/types.d.ts.map +1 -0
- package/CapUnifiedSelect/utils.d.ts +34 -0
- package/CapUnifiedSelect/utils.d.ts.map +1 -0
- package/index.js +440 -704
- package/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,102 @@
|
|
|
1
1
|
/******/ (() => { // webpackBootstrap
|
|
2
2
|
/******/ var __webpack_modules__ = ({
|
|
3
3
|
|
|
4
|
+
/***/ 455:
|
|
5
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.__esModule = true;
|
|
11
|
+
exports.SelectAllCheckbox = exports.NoResult = void 0;
|
|
12
|
+
var _antdV = __webpack_require__(4273);
|
|
13
|
+
var _classnames = _interopRequireDefault(__webpack_require__(6942));
|
|
14
|
+
var _react = _interopRequireDefault(__webpack_require__(9206));
|
|
15
|
+
var _CapIcon = _interopRequireDefault(__webpack_require__(8244));
|
|
16
|
+
var _CapLabel = _interopRequireDefault(__webpack_require__(3737));
|
|
17
|
+
var _CapRow = _interopRequireDefault(__webpack_require__(7375));
|
|
18
|
+
var _constants = __webpack_require__(9788);
|
|
19
|
+
var _styles = _interopRequireDefault(__webpack_require__(8263));
|
|
20
|
+
var _jsxRuntime = __webpack_require__(4848);
|
|
21
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
|
+
const NoResult = _ref => {
|
|
23
|
+
let {
|
|
24
|
+
noResultCustomText,
|
|
25
|
+
className,
|
|
26
|
+
showUpload,
|
|
27
|
+
options,
|
|
28
|
+
noResultCustomIcon
|
|
29
|
+
} = _ref;
|
|
30
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
31
|
+
className: (0, _classnames.default)(className, _styles.default['cap-unified-select-no-result']),
|
|
32
|
+
align: "middle",
|
|
33
|
+
gap: 8,
|
|
34
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CapIcon.default, {
|
|
35
|
+
type: noResultCustomIcon,
|
|
36
|
+
size: "m"
|
|
37
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapLabel.default, {
|
|
38
|
+
className: _styles.default['cap-unified-select-no-result-text'],
|
|
39
|
+
children: showUpload && (options == null ? void 0 : options.length) === 0 ? noResultCustomText : _constants.DEFAULTS.NO_RESULT_TEXT
|
|
40
|
+
})]
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* SelectAllCheckbox component for selecting/deselecting all available options
|
|
46
|
+
* Only shown for multi-select with static data
|
|
47
|
+
*/
|
|
48
|
+
exports.NoResult = NoResult;
|
|
49
|
+
const SelectAllCheckbox = _ref2 => {
|
|
50
|
+
let {
|
|
51
|
+
currentItems,
|
|
52
|
+
tempValue,
|
|
53
|
+
setTempValue,
|
|
54
|
+
processTreeData,
|
|
55
|
+
disabled = false
|
|
56
|
+
} = _ref2;
|
|
57
|
+
const {
|
|
58
|
+
leafValues = []
|
|
59
|
+
} = processTreeData ? processTreeData(currentItems) : {};
|
|
60
|
+
const totalAvailable = leafValues.length;
|
|
61
|
+
const leafSet = new Set(leafValues);
|
|
62
|
+
const selectedInScope = Array.isArray(tempValue) ? tempValue.filter(v => leafSet.has(v)).length : 0;
|
|
63
|
+
const allChecked = totalAvailable > 0 && selectedInScope === totalAvailable;
|
|
64
|
+
const indeterminate = selectedInScope > 0 && selectedInScope < totalAvailable;
|
|
65
|
+
const handleChange = e => {
|
|
66
|
+
if (disabled) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (e.target.checked) {
|
|
70
|
+
const merged = new Set(Array.isArray(tempValue) ? tempValue : []);
|
|
71
|
+
leafValues.forEach(v => merged.add(v));
|
|
72
|
+
setTempValue(Array.from(merged));
|
|
73
|
+
} else {
|
|
74
|
+
const toRemove = new Set(leafValues);
|
|
75
|
+
const next = (Array.isArray(tempValue) ? tempValue : []).filter(v => !toRemove.has(v));
|
|
76
|
+
setTempValue(next);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapRow.default, {
|
|
80
|
+
className: _styles.default['cap-unified-select-select-all-container'],
|
|
81
|
+
align: "middle",
|
|
82
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_antdV.Checkbox, {
|
|
83
|
+
className: _styles.default['cap-unified-select-select-all-checkbox'],
|
|
84
|
+
checked: allChecked,
|
|
85
|
+
indeterminate: indeterminate,
|
|
86
|
+
onChange: handleChange,
|
|
87
|
+
disabled: disabled,
|
|
88
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapLabel.default, {
|
|
89
|
+
type: "label14",
|
|
90
|
+
className: _styles.default['cap-unified-select-select-all-label'],
|
|
91
|
+
children: "Select all"
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
exports.SelectAllCheckbox = SelectAllCheckbox;
|
|
97
|
+
|
|
98
|
+
/***/ }),
|
|
99
|
+
|
|
4
100
|
/***/ 540:
|
|
5
101
|
/***/ ((module) => {
|
|
6
102
|
|
|
@@ -773,146 +869,17 @@ var _CapRow = _interopRequireDefault(__webpack_require__(7375));
|
|
|
773
869
|
var _CapSpin = _interopRequireDefault(__webpack_require__(1549));
|
|
774
870
|
var _CapTooltip = _interopRequireDefault(__webpack_require__(5636));
|
|
775
871
|
var _CapTooltipWithInfo = _interopRequireDefault(__webpack_require__(2608));
|
|
872
|
+
var _components = __webpack_require__(455);
|
|
776
873
|
var _constants = __webpack_require__(9788);
|
|
777
874
|
var _styles = _interopRequireDefault(__webpack_require__(8263));
|
|
875
|
+
var _utils = __webpack_require__(8052);
|
|
778
876
|
var _jsxRuntime = __webpack_require__(4848);
|
|
779
877
|
const _excluded = ["type", "options", "value", "onChange", "placeholder", "className", "style", "isError", "errorMessage", "containerClassName", "popoverClassName", "allowClear", "headerLabel", "onUpload", "uploadLabel", "tooltip", "bylineText", "disabled", "showUpload", "customPopupRender", "showSearch", "searchBasedOn", "onSearch", "searchDebounce", "onConfirm", "clearText", "noResultCustomText", "noResultCustomIcon", "readOnly", "staticValue", "onFooterDownloadChange", "onPopupScroll", "hasMore", "enableVirtualization", "virtualRowHeight", "resetSearch", "resetData", "fetchMissingOptions"];
|
|
780
878
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
781
879
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
880
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
782
881
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
783
|
-
|
|
784
|
-
const NoResult = _ref => {
|
|
785
|
-
let {
|
|
786
|
-
noResultCustomText,
|
|
787
|
-
className,
|
|
788
|
-
showUpload,
|
|
789
|
-
options,
|
|
790
|
-
noResultCustomIcon
|
|
791
|
-
} = _ref;
|
|
792
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
793
|
-
className: (0, _classnames.default)(className, _styles.default['cap-unified-select-no-result']),
|
|
794
|
-
align: "middle",
|
|
795
|
-
gap: 8,
|
|
796
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CapIcon.default, {
|
|
797
|
-
type: noResultCustomIcon,
|
|
798
|
-
size: "m"
|
|
799
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapLabel.default, {
|
|
800
|
-
className: _styles.default['cap-unified-select-no-result-text'],
|
|
801
|
-
children: showUpload && (options == null ? void 0 : options.length) === 0 ? noResultCustomText : _constants.DEFAULTS.NO_RESULT_TEXT
|
|
802
|
-
})]
|
|
803
|
-
});
|
|
804
|
-
};
|
|
805
|
-
const SelectAllCheckbox = _ref2 => {
|
|
806
|
-
let {
|
|
807
|
-
currentItems,
|
|
808
|
-
tempValue,
|
|
809
|
-
setTempValue,
|
|
810
|
-
processTreeData
|
|
811
|
-
} = _ref2;
|
|
812
|
-
const {
|
|
813
|
-
leafValues = []
|
|
814
|
-
} = processTreeData ? processTreeData(currentItems) : {};
|
|
815
|
-
const totalAvailable = leafValues.length;
|
|
816
|
-
const leafSet = new Set(leafValues);
|
|
817
|
-
const selectedInScope = Array.isArray(tempValue) ? tempValue.filter(v => leafSet.has(v)).length : 0;
|
|
818
|
-
const allChecked = totalAvailable > 0 && selectedInScope === totalAvailable;
|
|
819
|
-
const indeterminate = selectedInScope > 0 && selectedInScope < totalAvailable;
|
|
820
|
-
const handleChange = e => {
|
|
821
|
-
if (e.target.checked) {
|
|
822
|
-
const merged = new Set(Array.isArray(tempValue) ? tempValue : []);
|
|
823
|
-
leafValues.forEach(v => merged.add(v));
|
|
824
|
-
setTempValue(Array.from(merged));
|
|
825
|
-
} else {
|
|
826
|
-
const toRemove = new Set(leafValues);
|
|
827
|
-
const next = (Array.isArray(tempValue) ? tempValue : []).filter(v => !toRemove.has(v));
|
|
828
|
-
setTempValue(next);
|
|
829
|
-
}
|
|
830
|
-
};
|
|
831
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapRow.default, {
|
|
832
|
-
className: _styles.default['cap-unified-select-select-all-container'],
|
|
833
|
-
align: "middle",
|
|
834
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_antdV.Checkbox, {
|
|
835
|
-
className: _styles.default['cap-unified-select-select-all-checkbox'],
|
|
836
|
-
checked: allChecked,
|
|
837
|
-
indeterminate: indeterminate,
|
|
838
|
-
onChange: handleChange,
|
|
839
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapLabel.default, {
|
|
840
|
-
type: "label14",
|
|
841
|
-
className: _styles.default['cap-unified-select-select-all-label'],
|
|
842
|
-
children: "Select all"
|
|
843
|
-
})
|
|
844
|
-
})
|
|
845
|
-
});
|
|
846
|
-
};
|
|
847
|
-
const buildTreeMaps = nodes => {
|
|
848
|
-
const result = {
|
|
849
|
-
leafValues: [],
|
|
850
|
-
parentChildMap: {},
|
|
851
|
-
nodeMap: {}
|
|
852
|
-
};
|
|
853
|
-
if (!nodes) return result;
|
|
854
|
-
const traverse = items => {
|
|
855
|
-
items == null || items.forEach(item => {
|
|
856
|
-
if (item.value !== undefined) {
|
|
857
|
-
result.nodeMap[item.value] = item;
|
|
858
|
-
if (item != null && item.children && item.children.length > 0) {
|
|
859
|
-
result.parentChildMap[item.value] = item.children.map(child => child == null ? void 0 : child.value).filter(v => v !== undefined);
|
|
860
|
-
traverse(item.children);
|
|
861
|
-
} else {
|
|
862
|
-
result.leafValues.push(item.value);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
});
|
|
866
|
-
};
|
|
867
|
-
traverse(nodes);
|
|
868
|
-
return result;
|
|
869
|
-
};
|
|
870
|
-
const countSelectedLeaves = (treeMaps, selectedValues) => {
|
|
871
|
-
var _treeMaps$leafValues;
|
|
872
|
-
if (!Array.isArray(selectedValues) || !(selectedValues != null && selectedValues.length)) return 0;
|
|
873
|
-
const expandedSet = new Set(selectedValues);
|
|
874
|
-
const processNode = value => {
|
|
875
|
-
var _treeMaps$parentChild;
|
|
876
|
-
const children = treeMaps == null || (_treeMaps$parentChild = treeMaps.parentChildMap) == null ? void 0 : _treeMaps$parentChild[value];
|
|
877
|
-
if (!children) return;
|
|
878
|
-
children == null || children.forEach(childValue => {
|
|
879
|
-
expandedSet.add(childValue);
|
|
880
|
-
processNode(childValue);
|
|
881
|
-
});
|
|
882
|
-
};
|
|
883
|
-
selectedValues == null || selectedValues.forEach(processNode);
|
|
884
|
-
return (treeMaps == null || (_treeMaps$leafValues = treeMaps.leafValues) == null ? void 0 : _treeMaps$leafValues.reduce((count, leaf) => expandedSet.has(leaf) ? count + 1 : count, 0)) || 0;
|
|
885
|
-
};
|
|
886
|
-
const filterTreeData = function (data, search, searchBasedOn, selectedValues) {
|
|
887
|
-
if (searchBasedOn === void 0) {
|
|
888
|
-
searchBasedOn = 'label';
|
|
889
|
-
}
|
|
890
|
-
if (!(data != null && data.length) || !search) return data;
|
|
891
|
-
const searchLower = search.toLowerCase();
|
|
892
|
-
const selectedSet = new Set(selectedValues || []);
|
|
893
|
-
const nodeMatchesSearch = node => {
|
|
894
|
-
var _node$value, _node$key, _ref3, _node$label;
|
|
895
|
-
const target = searchBasedOn === 'value' ? String((_node$value = node == null ? void 0 : node.value) != null ? _node$value : '') : searchBasedOn === 'key' ? String((_node$key = node == null ? void 0 : node.key) != null ? _node$key : '') : String((_ref3 = (_node$label = node == null ? void 0 : node.label) != null ? _node$label : node == null ? void 0 : node.title) != null ? _ref3 : '');
|
|
896
|
-
return target.toLowerCase().includes(searchLower);
|
|
897
|
-
};
|
|
898
|
-
const isNodeSelected = node => {
|
|
899
|
-
return node.value !== undefined && selectedSet.has(node.value);
|
|
900
|
-
};
|
|
901
|
-
const loop = items => items.reduce((acc, item) => {
|
|
902
|
-
var _item$children;
|
|
903
|
-
if (!item) return acc;
|
|
904
|
-
const children = item != null && (_item$children = item.children) != null && _item$children.length ? loop(item.children) : [];
|
|
905
|
-
// Include node if: matches search OR is selected OR has matching children
|
|
906
|
-
if (nodeMatchesSearch(item) || isNodeSelected(item) || children.length) {
|
|
907
|
-
acc.push(_extends({}, item, {
|
|
908
|
-
children
|
|
909
|
-
}));
|
|
910
|
-
}
|
|
911
|
-
return acc;
|
|
912
|
-
}, []);
|
|
913
|
-
return loop(data);
|
|
914
|
-
};
|
|
915
|
-
const CapUnifiedSelect = _ref4 => {
|
|
882
|
+
const CapUnifiedSelect = _ref => {
|
|
916
883
|
let {
|
|
917
884
|
type = _constants.SELECT_TYPES.SELECT,
|
|
918
885
|
options = [],
|
|
@@ -952,141 +919,79 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
952
919
|
resetSearch = true,
|
|
953
920
|
resetData,
|
|
954
921
|
fetchMissingOptions
|
|
955
|
-
} =
|
|
956
|
-
rest = _objectWithoutPropertiesLoose(
|
|
922
|
+
} = _ref,
|
|
923
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
957
924
|
const [searchText, setSearchText] = (0, _react.useState)('');
|
|
958
925
|
const [tempValue, setTempValue] = (0, _react.useState)(value);
|
|
959
926
|
const [dropdownOpen, setDropdownOpen] = (0, _react.useState)(false);
|
|
960
927
|
const [isSearching, setIsSearching] = (0, _react.useState)(false);
|
|
961
928
|
const [isLoadingOnScroll, setIsLoadingOnScroll] = (0, _react.useState)(false);
|
|
962
929
|
const [isResettingData, setIsResettingData] = (0, _react.useState)(false);
|
|
963
|
-
// Store ordered options after confirm (selected items moved to top based on selection order)
|
|
964
930
|
const [orderedOptions, setOrderedOptions] = (0, _react.useState)(null);
|
|
965
931
|
const searchTimeoutRef = (0, _react.useRef)(null);
|
|
966
932
|
const scrollContainerRef = (0, _react.useRef)(null);
|
|
967
933
|
const scrollLoadingTimeoutRef = (0, _react.useRef)(null);
|
|
968
|
-
// Track if scroll handler is currently processing to prevent duplicate calls
|
|
969
934
|
const isScrollProcessingRef = (0, _react.useRef)(false);
|
|
970
|
-
// Throttle ref for scroll events
|
|
971
935
|
const scrollThrottleTimeoutRef = (0, _react.useRef)(null);
|
|
972
|
-
// Ref to track options for scroll handler (avoids recreating handleScroll)
|
|
973
936
|
const optionsRef = (0, _react.useRef)(options);
|
|
974
|
-
// Cache of selected items from async results to preserve them during search
|
|
975
937
|
const selectedItemsCacheRef = (0, _react.useRef)(new Map());
|
|
976
|
-
// Track the last search query to detect when options update after search
|
|
977
938
|
const lastSearchQueryRef = (0, _react.useRef)('');
|
|
978
|
-
// Track when search was cleared to help clear loading state
|
|
979
939
|
const searchClearedTimeRef = (0, _react.useRef)(null);
|
|
980
|
-
// Track previous options to detect when they change after a search
|
|
981
940
|
const prevOptionsRef = (0, _react.useRef)(options);
|
|
982
|
-
// Track previous options before resetData is called to detect when options update
|
|
983
941
|
const prevOptionsBeforeResetRef = (0, _react.useRef)(options);
|
|
984
|
-
// Track previous options count to detect when options change after scroll
|
|
985
942
|
const prevOptionsCountRef = (0, _react.useRef)(options.length);
|
|
986
|
-
// Track previous options to detect when options change (even if count stays same)
|
|
987
943
|
const prevOptionsRefForScroll = (0, _react.useRef)(options);
|
|
988
|
-
// Track options count when scroll was triggered (for orderedOptions update)
|
|
989
944
|
const scrollTriggerOptionsCountRef = (0, _react.useRef)(options.length);
|
|
990
|
-
// Track if initial sort has been done (only sort once on initial load with selected values)
|
|
991
945
|
const initialSortDoneRef = (0, _react.useRef)(false);
|
|
992
|
-
// Track if user has interacted with the dropdown during current session (selected, searched, etc.)
|
|
993
946
|
const hasInteractedRef = (0, _react.useRef)(false);
|
|
994
|
-
// Track the initial tempValue when dropdown opens to detect if user made changes
|
|
995
947
|
const initialTempValueRef = (0, _react.useRef)(value);
|
|
996
|
-
// Track if resetData was already called in the current session to prevent duplicate calls
|
|
997
948
|
const resetDataCalledRef = (0, _react.useRef)(false);
|
|
998
|
-
// Track when resetData was called to help clear loading state
|
|
999
949
|
const resetDataCalledTimeRef = (0, _react.useRef)(null);
|
|
1000
|
-
// Track if fetchMissingOptions was already called to prevent duplicate calls
|
|
1001
950
|
const fetchMissingOptionsCalledRef = (0, _react.useRef)(false);
|
|
1002
|
-
// Track the last missing values that were sent to prevent duplicate calls with same values
|
|
1003
951
|
const lastMissingValuesRef = (0, _react.useRef)('');
|
|
1004
|
-
|
|
1005
|
-
// Helper function to check if a value exists in options (recursive for tree structures)
|
|
1006
|
-
const findValueInOptions = (0, _react.useCallback)((opts, targetValue) => {
|
|
1007
|
-
for (const opt of opts) {
|
|
1008
|
-
if (opt.value === targetValue) {
|
|
1009
|
-
return true;
|
|
1010
|
-
}
|
|
1011
|
-
if (opt.children && opt.children.length > 0) {
|
|
1012
|
-
if (findValueInOptions(opt.children, targetValue)) {
|
|
1013
|
-
return true;
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
return false;
|
|
1018
|
-
}, []);
|
|
1019
|
-
|
|
1020
|
-
// Helper function to find missing selected values
|
|
1021
|
-
const findMissingValues = (0, _react.useCallback)((selectedValues, currentOptions) => {
|
|
1022
|
-
if (!selectedValues.length || !currentOptions.length) {
|
|
1023
|
-
return selectedValues;
|
|
1024
|
-
}
|
|
1025
|
-
return selectedValues.filter(val => !findValueInOptions(currentOptions, val));
|
|
1026
|
-
}, [findValueInOptions]);
|
|
1027
|
-
|
|
1028
|
-
// Check for missing options and call fetchMissingOptions if needed
|
|
1029
952
|
(0, _react.useEffect)(() => {
|
|
1030
|
-
// Only check if fetchMissingOptions is provided
|
|
1031
953
|
if (!fetchMissingOptions) {
|
|
1032
954
|
return;
|
|
1033
955
|
}
|
|
1034
|
-
|
|
1035
|
-
// Don't check for missing values if options array is empty
|
|
1036
|
-
// This prevents false positives during initial render before data is fetched
|
|
1037
|
-
// Only check once options have been loaded (options.length > 0)
|
|
1038
956
|
if (options.length === 0) {
|
|
1039
957
|
return;
|
|
1040
958
|
}
|
|
1041
959
|
|
|
1042
|
-
//
|
|
960
|
+
// For API-driven data, don't fetch missing options during active search
|
|
961
|
+
// Only fetch when there's no search query or search is cleared
|
|
962
|
+
const hasActiveSearch = !staticValue && lastSearchQueryRef.current.trim().length > 0;
|
|
963
|
+
if (hasActiveSearch) {
|
|
964
|
+
return;
|
|
965
|
+
}
|
|
1043
966
|
const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
1044
967
|
if (selectedValues.length === 0) {
|
|
1045
|
-
// No selected values, reset the tracking
|
|
1046
968
|
fetchMissingOptionsCalledRef.current = false;
|
|
1047
969
|
lastMissingValuesRef.current = '';
|
|
1048
970
|
return;
|
|
1049
971
|
}
|
|
1050
|
-
|
|
1051
|
-
// Find missing values
|
|
1052
|
-
const missingValues = findMissingValues(selectedValues, options);
|
|
1053
|
-
|
|
1054
|
-
// If no missing values, reset tracking and return
|
|
972
|
+
const missingValues = (0, _utils.findMissingValues)(selectedValues, options);
|
|
1055
973
|
if (missingValues.length === 0) {
|
|
1056
974
|
fetchMissingOptionsCalledRef.current = false;
|
|
1057
975
|
lastMissingValuesRef.current = '';
|
|
1058
976
|
return;
|
|
1059
977
|
}
|
|
1060
|
-
|
|
1061
|
-
// Create a sorted string representation of missing values for comparison
|
|
1062
|
-
// Use slice() to avoid mutating the original array
|
|
1063
978
|
const missingValuesKey = [...missingValues].sort().join(',');
|
|
1064
|
-
|
|
1065
|
-
// Only call if:
|
|
1066
|
-
// 1. We haven't called it before, OR
|
|
1067
|
-
// 2. The missing values have changed (different values are missing now)
|
|
1068
979
|
if (!fetchMissingOptionsCalledRef.current || lastMissingValuesRef.current !== missingValuesKey) {
|
|
1069
980
|
fetchMissingOptionsCalledRef.current = true;
|
|
1070
981
|
lastMissingValuesRef.current = missingValuesKey;
|
|
1071
|
-
// Call the developer's function with missing values (pass a copy to avoid mutation)
|
|
1072
982
|
fetchMissingOptions([...missingValues]);
|
|
1073
983
|
}
|
|
1074
|
-
}, [value, options, fetchMissingOptions,
|
|
984
|
+
}, [value, options, fetchMissingOptions, staticValue]);
|
|
1075
985
|
(0, _react.useEffect)(() => {
|
|
1076
986
|
const isEqual = Array.isArray(value) && Array.isArray(tempValue) ? (value == null ? void 0 : value.length) === (tempValue == null ? void 0 : tempValue.length) && value.every(v => Array.isArray(tempValue) && tempValue.includes(v)) : value === tempValue;
|
|
1077
987
|
if (!isEqual) {
|
|
1078
988
|
setTempValue(value);
|
|
1079
|
-
// Reset ordered options when value changes from outside
|
|
1080
989
|
setOrderedOptions(null);
|
|
1081
990
|
}
|
|
1082
991
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1083
992
|
}, [value]);
|
|
1084
|
-
|
|
1085
|
-
// Cache selected items when tempValue changes
|
|
1086
993
|
(0, _react.useEffect)(() => {
|
|
1087
994
|
const currentSelected = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1088
|
-
|
|
1089
|
-
// Store selected items in cache for persistence
|
|
1090
995
|
const findAndCacheOption = (opts, val) => {
|
|
1091
996
|
for (const opt of opts) {
|
|
1092
997
|
if (opt.value === val) {
|
|
@@ -1106,8 +1011,6 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1106
1011
|
findAndCacheOption(options, val);
|
|
1107
1012
|
}
|
|
1108
1013
|
});
|
|
1109
|
-
|
|
1110
|
-
// Clean up cache for unselected items
|
|
1111
1014
|
const selectedSet = new Set(currentSelected);
|
|
1112
1015
|
selectedItemsCacheRef.current.forEach((_, value) => {
|
|
1113
1016
|
if (!selectedSet.has(value)) {
|
|
@@ -1115,15 +1018,9 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1115
1018
|
}
|
|
1116
1019
|
});
|
|
1117
1020
|
}, [tempValue, options]);
|
|
1118
|
-
|
|
1119
|
-
// Reset ordered options when options change, but only if it would invalidate the current ordering
|
|
1120
|
-
// This prevents resetting when options are updated via onSearch/onScroll but selected items still exist
|
|
1121
1021
|
(0, _react.useEffect)(() => {
|
|
1122
|
-
// Only reset if we have orderedOptions and the current value's items are no longer in options
|
|
1123
1022
|
if (orderedOptions) {
|
|
1124
1023
|
const currentSelected = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1125
|
-
|
|
1126
|
-
// Check if all selected values still exist in the new options
|
|
1127
1024
|
const checkValueExists = (opts, val) => {
|
|
1128
1025
|
for (const opt of opts) {
|
|
1129
1026
|
if (opt.value === val) return true;
|
|
@@ -1133,27 +1030,16 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1133
1030
|
}
|
|
1134
1031
|
return false;
|
|
1135
1032
|
};
|
|
1136
|
-
|
|
1137
|
-
// If any selected value is missing from new options, reset ordering
|
|
1138
1033
|
const allSelectedStillExist = currentSelected.every(val => checkValueExists(options, val));
|
|
1139
1034
|
if (!allSelectedStillExist) {
|
|
1140
1035
|
setOrderedOptions(null);
|
|
1141
1036
|
}
|
|
1142
|
-
// Otherwise, keep the ordering even if options changed (e.g., via onSearch adding more items)
|
|
1143
|
-
} else {
|
|
1144
|
-
// No ordering set, nothing to reset
|
|
1145
1037
|
}
|
|
1146
1038
|
}, [options, orderedOptions, tempValue]);
|
|
1147
|
-
|
|
1148
|
-
// Extract debounce timeout (extracted early for use in useEffects)
|
|
1149
1039
|
const debounceTimeout = searchDebounce != null ? searchDebounce : _constants.TIMEOUTS.DEFAULT_SEARCH_DEBOUNCE;
|
|
1150
|
-
|
|
1151
|
-
// Keep optionsRef in sync with options
|
|
1152
1040
|
(0, _react.useEffect)(() => {
|
|
1153
1041
|
optionsRef.current = options;
|
|
1154
1042
|
}, [options]);
|
|
1155
|
-
|
|
1156
|
-
// Cleanup timeouts on unmount
|
|
1157
1043
|
(0, _react.useEffect)(() => {
|
|
1158
1044
|
return () => {
|
|
1159
1045
|
if (searchTimeoutRef.current) {
|
|
@@ -1167,35 +1053,21 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1167
1053
|
}
|
|
1168
1054
|
};
|
|
1169
1055
|
}, []);
|
|
1170
|
-
|
|
1171
|
-
// Detect when options update after a search to clear loading state
|
|
1172
|
-
// This prevents showing "No results found" before data arrives
|
|
1173
1056
|
(0, _react.useEffect)(() => {
|
|
1174
|
-
// Only handle this for API-based searches (staticValue = false)
|
|
1175
|
-
// Check if lastSearchQueryRef has been set (including empty string for cleared search)
|
|
1176
1057
|
const hasSearchQuery = lastSearchQueryRef.current !== null && lastSearchQueryRef.current !== undefined;
|
|
1177
1058
|
if (staticValue || !isSearching || !hasSearchQuery) {
|
|
1178
1059
|
prevOptionsRef.current = options;
|
|
1179
1060
|
return;
|
|
1180
1061
|
}
|
|
1181
|
-
|
|
1182
|
-
// Check if options actually changed (reference or content)
|
|
1183
1062
|
const optionsChanged = prevOptionsRef.current !== options || prevOptionsRef.current.length !== options.length;
|
|
1184
|
-
|
|
1185
|
-
// Also check if search was cleared (empty string) and enough time has passed
|
|
1186
|
-
// This handles the case where clearing search reloads initial data that might be the same reference
|
|
1187
1063
|
const searchCleared = lastSearchQueryRef.current === '';
|
|
1188
1064
|
const timeSinceCleared = searchClearedTimeRef.current ? Date.now() - searchClearedTimeRef.current : Infinity;
|
|
1189
1065
|
const hasOptionsData = options.length > 0;
|
|
1190
|
-
// Wait at least SEARCH_CLEARED_TIMEOUT after search is cleared to allow API call to complete
|
|
1191
1066
|
const clearedSearchReady = searchCleared && hasOptionsData && timeSinceCleared > _constants.TIMEOUTS.SEARCH_CLEARED_TIMEOUT;
|
|
1192
1067
|
if (optionsChanged || clearedSearchReady) {
|
|
1193
|
-
// Options updated after search - data has arrived
|
|
1194
|
-
// Use a small delay to ensure state updates are processed
|
|
1195
1068
|
const timeoutId = setTimeout(() => {
|
|
1196
1069
|
setIsSearching(false);
|
|
1197
1070
|
prevOptionsRef.current = options;
|
|
1198
|
-
// Clear timestamp when search loading is cleared
|
|
1199
1071
|
if (searchCleared) {
|
|
1200
1072
|
searchClearedTimeRef.current = null;
|
|
1201
1073
|
}
|
|
@@ -1204,91 +1076,50 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1204
1076
|
}
|
|
1205
1077
|
prevOptionsRef.current = options;
|
|
1206
1078
|
}, [options, staticValue, isSearching]);
|
|
1207
|
-
|
|
1208
|
-
// Fallback: Clear searching state after a reasonable timeout to prevent infinite loading
|
|
1209
|
-
// This handles edge cases where options might not change reference but data has arrived
|
|
1210
|
-
// Also handles error cases where options don't update after search
|
|
1211
1079
|
(0, _react.useEffect)(() => {
|
|
1212
|
-
// Check if lastSearchQueryRef has been set (including empty string for cleared search)
|
|
1213
1080
|
const hasSearchQuery = lastSearchQueryRef.current !== null && lastSearchQueryRef.current !== undefined;
|
|
1214
1081
|
if (!isSearching || staticValue || !hasSearchQuery) {
|
|
1215
1082
|
return;
|
|
1216
1083
|
}
|
|
1217
|
-
|
|
1218
|
-
// For cleared search (empty string), use a shorter timeout since it should reload initial data quickly
|
|
1219
|
-
// For regular search, use debounce timeout + buffer
|
|
1220
1084
|
const searchCleared = lastSearchQueryRef.current === '';
|
|
1221
|
-
const timeoutDuration = searchCleared ? debounceTimeout + _constants.TIMEOUTS.SEARCH_CLEARED_BUFFER
|
|
1222
|
-
: debounceTimeout + _constants.TIMEOUTS.SEARCH_REGULAR_BUFFER; // Longer timeout for regular search
|
|
1223
|
-
|
|
1224
|
-
// Calculate timeout: debounce timeout + a small buffer for API response
|
|
1225
|
-
// This ensures we wait for the API call to complete before showing "No results"
|
|
1226
|
-
// For error cases where options don't update, this will clear loading state
|
|
1085
|
+
const timeoutDuration = searchCleared ? debounceTimeout + _constants.TIMEOUTS.SEARCH_CLEARED_BUFFER : debounceTimeout + _constants.TIMEOUTS.SEARCH_REGULAR_BUFFER;
|
|
1227
1086
|
const fallbackTimeout = setTimeout(() => {
|
|
1228
1087
|
setIsSearching(false);
|
|
1229
|
-
searchClearedTimeRef.current = null;
|
|
1088
|
+
searchClearedTimeRef.current = null;
|
|
1230
1089
|
}, timeoutDuration);
|
|
1231
1090
|
return () => clearTimeout(fallbackTimeout);
|
|
1232
1091
|
}, [isSearching, staticValue, debounceTimeout, options.length]);
|
|
1233
|
-
|
|
1234
|
-
// Detect when options update after resetData is called to clear loading state
|
|
1235
1092
|
(0, _react.useEffect)(() => {
|
|
1236
1093
|
if (!isResettingData) {
|
|
1237
|
-
// Update ref even when not resetting to keep it in sync
|
|
1238
1094
|
prevOptionsBeforeResetRef.current = options;
|
|
1239
|
-
// Clear timestamp when not resetting
|
|
1240
1095
|
resetDataCalledTimeRef.current = null;
|
|
1241
1096
|
return;
|
|
1242
1097
|
}
|
|
1243
|
-
|
|
1244
|
-
// Check if options actually changed (reference, length, or content)
|
|
1245
|
-
// Compare against the options that existed before resetData was called
|
|
1246
1098
|
const prevOptions = prevOptionsBeforeResetRef.current;
|
|
1247
1099
|
const currentOptions = options;
|
|
1248
|
-
|
|
1249
|
-
// More robust comparison: check reference, length, or any content differences
|
|
1250
|
-
const optionsChanged = prevOptions !== currentOptions || prevOptions.length !== currentOptions.length ||
|
|
1251
|
-
// Deep comparison: check if any option values or labels changed
|
|
1252
|
-
prevOptions.length === currentOptions.length && prevOptions.length > 0 && prevOptions.some((prevOpt, idx) => {
|
|
1100
|
+
const optionsChanged = prevOptions !== currentOptions || prevOptions.length !== currentOptions.length || prevOptions.length === currentOptions.length && prevOptions.length > 0 && prevOptions.some((prevOpt, idx) => {
|
|
1253
1101
|
const currentOpt = currentOptions[idx];
|
|
1254
1102
|
return !currentOpt || prevOpt.value !== currentOpt.value || prevOpt.label !== currentOpt.label;
|
|
1255
1103
|
});
|
|
1256
|
-
|
|
1257
|
-
// Additional check: if enough time has passed since resetData was called
|
|
1258
|
-
// and we have options data, assume data has loaded even if comparison didn't detect change
|
|
1259
1104
|
const timeSinceReset = resetDataCalledTimeRef.current ? Date.now() - resetDataCalledTimeRef.current : Infinity;
|
|
1260
1105
|
const hasDataAfterTimeout = currentOptions.length > 0 && timeSinceReset > _constants.TIMEOUTS.RESET_DATA_MIN_TIME && timeSinceReset < _constants.TIMEOUTS.RESET_DATA_MAX_TIME;
|
|
1261
|
-
|
|
1262
|
-
// If options changed or enough time has passed with data, clear the loading state
|
|
1263
1106
|
if (optionsChanged || hasDataAfterTimeout) {
|
|
1264
|
-
// Options updated after resetData - data has arrived
|
|
1265
|
-
// Clear immediately without delay for faster response
|
|
1266
1107
|
setIsResettingData(false);
|
|
1267
1108
|
prevOptionsBeforeResetRef.current = currentOptions;
|
|
1268
1109
|
resetDataCalledTimeRef.current = null;
|
|
1269
1110
|
}
|
|
1270
1111
|
}, [options, isResettingData]);
|
|
1271
|
-
|
|
1272
|
-
// Fallback: Clear resetData loading state after a reasonable timeout
|
|
1273
|
-
// This handles edge cases where options might not change reference but data has arrived
|
|
1274
1112
|
(0, _react.useEffect)(() => {
|
|
1275
1113
|
if (!isResettingData) {
|
|
1276
1114
|
return;
|
|
1277
1115
|
}
|
|
1278
|
-
|
|
1279
|
-
// Set a timeout to clear loading state if options don't update
|
|
1280
|
-
// Reduced timeout to 1 second for faster recovery
|
|
1281
1116
|
const fallbackTimeout = setTimeout(() => {
|
|
1282
1117
|
setIsResettingData(false);
|
|
1283
|
-
// Update ref to current options to prevent false positives in future comparisons
|
|
1284
1118
|
prevOptionsBeforeResetRef.current = options;
|
|
1285
|
-
// Clear timestamp
|
|
1286
1119
|
resetDataCalledTimeRef.current = null;
|
|
1287
1120
|
}, _constants.TIMEOUTS.RESET_DATA_TIMEOUT);
|
|
1288
1121
|
return () => clearTimeout(fallbackTimeout);
|
|
1289
1122
|
}, [isResettingData, options]);
|
|
1290
|
-
|
|
1291
|
-
// Clear loading state when hasMore becomes false (all items exhausted)
|
|
1292
1123
|
(0, _react.useEffect)(() => {
|
|
1293
1124
|
if (!hasMore && isLoadingOnScroll) {
|
|
1294
1125
|
setIsLoadingOnScroll(false);
|
|
@@ -1299,79 +1130,47 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1299
1130
|
}
|
|
1300
1131
|
}
|
|
1301
1132
|
}, [hasMore, isLoadingOnScroll]);
|
|
1302
|
-
|
|
1303
|
-
// Detect when options change after scroll to clear loading overlay
|
|
1304
1133
|
(0, _react.useEffect)(() => {
|
|
1305
|
-
// Always update refs when options change (when not loading)
|
|
1306
|
-
// This ensures we track the current state for next scroll detection
|
|
1307
1134
|
if (!isLoadingOnScroll) {
|
|
1308
1135
|
prevOptionsCountRef.current = options.length;
|
|
1309
|
-
// Store a reference to the options array for comparison
|
|
1310
|
-
// We'll compare by length and last item to detect changes
|
|
1311
1136
|
prevOptionsRefForScroll.current = options;
|
|
1312
1137
|
}
|
|
1313
|
-
|
|
1314
|
-
// Only check for changes if we're currently loading from scroll
|
|
1315
1138
|
if (!isLoadingOnScroll || !onPopupScroll) {
|
|
1316
1139
|
return;
|
|
1317
1140
|
}
|
|
1318
|
-
|
|
1319
|
-
// Check if options count increased (new data loaded via append)
|
|
1320
1141
|
const optionsCountIncreased = options.length > prevOptionsCountRef.current;
|
|
1321
|
-
|
|
1322
|
-
// Check if options content changed (even if count is same - replacement scenario)
|
|
1323
|
-
// Compare the last option to detect if new data was appended
|
|
1324
1142
|
const optionsContentChanged = (() => {
|
|
1325
1143
|
const prevCount = prevOptionsCountRef.current;
|
|
1326
1144
|
const currentCount = options.length;
|
|
1327
|
-
|
|
1328
|
-
// If count changed, definitely content changed
|
|
1329
1145
|
if (prevCount !== currentCount) {
|
|
1330
1146
|
return true;
|
|
1331
1147
|
}
|
|
1332
|
-
|
|
1333
|
-
// If count is same, check if last option changed (indicates new data appended/replaced)
|
|
1334
1148
|
if (currentCount > 0 && prevCount > 0 && prevOptionsRefForScroll.current.length > 0) {
|
|
1335
1149
|
const prevOptions = prevOptionsRefForScroll.current;
|
|
1336
1150
|
const lastPrevOption = prevOptions[prevOptions.length - 1];
|
|
1337
1151
|
const lastCurrentOption = options[options.length - 1];
|
|
1338
|
-
|
|
1339
|
-
// If last option is different, content changed
|
|
1340
1152
|
if ((lastPrevOption == null ? void 0 : lastPrevOption.value) !== (lastCurrentOption == null ? void 0 : lastCurrentOption.value) || (lastPrevOption == null ? void 0 : lastPrevOption.label) !== (lastCurrentOption == null ? void 0 : lastCurrentOption.label)) {
|
|
1341
1153
|
return true;
|
|
1342
1154
|
}
|
|
1343
1155
|
}
|
|
1344
1156
|
return false;
|
|
1345
1157
|
})();
|
|
1346
|
-
|
|
1347
|
-
// Clear loading if options changed (either count increased or content changed)
|
|
1348
|
-
// This handles both append (count increase) and replace (content change) scenarios
|
|
1349
1158
|
if (optionsCountIncreased || optionsContentChanged) {
|
|
1350
|
-
// Options updated after scroll - data has arrived, clear loading overlay
|
|
1351
1159
|
setIsLoadingOnScroll(false);
|
|
1352
|
-
// Reset processing flag to allow next scroll event
|
|
1353
1160
|
isScrollProcessingRef.current = false;
|
|
1354
1161
|
if (scrollLoadingTimeoutRef.current) {
|
|
1355
1162
|
clearTimeout(scrollLoadingTimeoutRef.current);
|
|
1356
1163
|
scrollLoadingTimeoutRef.current = null;
|
|
1357
1164
|
}
|
|
1358
|
-
|
|
1359
|
-
// Update refs to track the new state after options change
|
|
1360
|
-
// This is critical for detecting subsequent scroll loads
|
|
1361
1165
|
prevOptionsCountRef.current = options.length;
|
|
1362
1166
|
prevOptionsRefForScroll.current = options;
|
|
1363
1167
|
}
|
|
1364
1168
|
}, [options, isLoadingOnScroll, onPopupScroll]);
|
|
1365
|
-
|
|
1366
|
-
// Handle search with debouncing
|
|
1367
1169
|
const handleSearch = (0, _react.useCallback)(query => {
|
|
1368
|
-
// Clear existing timeout
|
|
1369
1170
|
if (searchTimeoutRef.current) {
|
|
1370
1171
|
clearTimeout(searchTimeoutRef.current);
|
|
1371
1172
|
}
|
|
1372
1173
|
const trimmedQuery = query.trim();
|
|
1373
|
-
|
|
1374
|
-
// Track when search is cleared (empty string after having a query)
|
|
1375
1174
|
const wasSearching = lastSearchQueryRef.current !== '';
|
|
1376
1175
|
const isNowCleared = trimmedQuery === '';
|
|
1377
1176
|
if (wasSearching && isNowCleared) {
|
|
@@ -1379,36 +1178,19 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1379
1178
|
} else if (!isNowCleared) {
|
|
1380
1179
|
searchClearedTimeRef.current = null;
|
|
1381
1180
|
}
|
|
1382
|
-
|
|
1383
|
-
// Track the search query to detect when options update
|
|
1384
1181
|
lastSearchQueryRef.current = trimmedQuery;
|
|
1385
|
-
|
|
1386
|
-
// Mark as interacted if user typed something (even if they clear it later)
|
|
1387
1182
|
if (trimmedQuery.length > 0 || lastSearchQueryRef.current.length > 0) {
|
|
1388
1183
|
hasInteractedRef.current = true;
|
|
1389
1184
|
}
|
|
1390
|
-
|
|
1391
|
-
// For API-based searches (staticValue = false), always call onSearch
|
|
1392
|
-
// This allows the developer to reload all initial data when search is cleared
|
|
1393
1185
|
if (!staticValue && onSearch) {
|
|
1394
|
-
// Set loading state for both empty and non-empty queries
|
|
1395
1186
|
setIsSearching(true);
|
|
1396
|
-
|
|
1397
|
-
// Debounce the search callback
|
|
1398
1187
|
searchTimeoutRef.current = setTimeout(() => {
|
|
1399
|
-
// Send the search input (empty string when cleared, or the actual query)
|
|
1400
1188
|
onSearch(trimmedQuery);
|
|
1401
|
-
// For API-based searches, keep isSearching true until options update
|
|
1402
|
-
// This prevents showing "No results found" before data arrives
|
|
1403
1189
|
}, debounceTimeout);
|
|
1404
1190
|
} else if (!trimmedQuery) {
|
|
1405
|
-
// For static searches, if query is empty, just reset the state
|
|
1406
1191
|
setIsSearching(false);
|
|
1407
1192
|
} else {
|
|
1408
|
-
// For static searches with content, show brief loading indicator
|
|
1409
|
-
// Set loading state briefly to show user feedback
|
|
1410
1193
|
setIsSearching(true);
|
|
1411
|
-
// Clear loading state after a short delay (filtering is instant but we show feedback)
|
|
1412
1194
|
searchTimeoutRef.current = setTimeout(() => {
|
|
1413
1195
|
setIsSearching(false);
|
|
1414
1196
|
}, _constants.TIMEOUTS.STATIC_SEARCH_DELAY);
|
|
@@ -1416,222 +1198,78 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1416
1198
|
}, [onSearch, staticValue, debounceTimeout]);
|
|
1417
1199
|
const isMulti = (0, _react.useMemo)(() => type === _constants.SELECT_TYPES.MULTI_SELECT || type === _constants.SELECT_TYPES.MULTI_TREE_SELECT, [type]);
|
|
1418
1200
|
const isTree = (0, _react.useMemo)(() => type === _constants.SELECT_TYPES.TREE_SELECT || type === _constants.SELECT_TYPES.MULTI_TREE_SELECT, [type]);
|
|
1419
|
-
|
|
1420
|
-
// Use options directly since pagination is handled by the developer
|
|
1421
1201
|
const mergedOptions = (0, _react.useMemo)(() => {
|
|
1422
1202
|
return options;
|
|
1423
1203
|
}, [options]);
|
|
1424
|
-
|
|
1425
|
-
// Helper function to reorder options based on selection order
|
|
1426
|
-
// Selected items are moved to top in the order they were selected
|
|
1427
|
-
// For tree structures, maintains parent-child relationships
|
|
1428
|
-
// For flat lists, directly reorders items
|
|
1429
|
-
// Works for all data types: flat lists, tree structures, nested trees
|
|
1430
|
-
const reorderOptionsBySelection = (0, _react.useCallback)((opts, selectedOrder) => {
|
|
1431
|
-
if (!Array.isArray(selectedOrder) || selectedOrder.length === 0 || !(opts != null && opts.length)) {
|
|
1432
|
-
return opts;
|
|
1433
|
-
}
|
|
1434
|
-
const selectedSet = new Set(selectedOrder);
|
|
1435
|
-
const selectedItems = [];
|
|
1436
|
-
const unselectedItems = [];
|
|
1437
|
-
const processedTopLevelValues = new Set();
|
|
1438
|
-
|
|
1439
|
-
// Deep clone helper to avoid mutating original items
|
|
1440
|
-
const deepCloneItem = item => {
|
|
1441
|
-
return _extends({}, item, {
|
|
1442
|
-
children: item.children ? item.children.map(deepCloneItem) : undefined
|
|
1443
|
-
});
|
|
1444
|
-
};
|
|
1445
|
-
|
|
1446
|
-
// Find the top-level item that contains the selected value
|
|
1447
|
-
// For flat lists, returns the item itself
|
|
1448
|
-
// For tree structures, returns the top-level parent from opts
|
|
1449
|
-
const findTopLevelItem = targetValue => {
|
|
1450
|
-
// First, find which top-level item in opts contains this value
|
|
1451
|
-
for (const topLevelItem of opts) {
|
|
1452
|
-
// Check if this top-level item itself matches
|
|
1453
|
-
if (topLevelItem.value === targetValue) {
|
|
1454
|
-
return topLevelItem;
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
// Recursively search in children
|
|
1458
|
-
const searchInChildren = items => {
|
|
1459
|
-
for (const item of items) {
|
|
1460
|
-
if (item.value === targetValue) {
|
|
1461
|
-
return true; // Found it
|
|
1462
|
-
}
|
|
1463
|
-
if (item.children && item.children.length > 0) {
|
|
1464
|
-
if (searchInChildren(item.children)) {
|
|
1465
|
-
return true;
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
return false;
|
|
1470
|
-
};
|
|
1471
|
-
|
|
1472
|
-
// If found in this top-level item's children, return the top-level item
|
|
1473
|
-
if (topLevelItem.children && topLevelItem.children.length > 0) {
|
|
1474
|
-
if (searchInChildren(topLevelItem.children)) {
|
|
1475
|
-
return topLevelItem;
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
return null;
|
|
1480
|
-
};
|
|
1481
|
-
|
|
1482
|
-
// Check if an item or any of its descendants is selected
|
|
1483
|
-
const hasSelectedDescendant = item => {
|
|
1484
|
-
if (item.value !== undefined && selectedSet.has(item.value)) {
|
|
1485
|
-
return true;
|
|
1486
|
-
}
|
|
1487
|
-
if (item.children && item.children.length > 0) {
|
|
1488
|
-
return item.children.some(child => hasSelectedDescendant(child));
|
|
1489
|
-
}
|
|
1490
|
-
return false;
|
|
1491
|
-
};
|
|
1492
|
-
|
|
1493
|
-
// Collect selected items in selection order
|
|
1494
|
-
selectedOrder.forEach(selectedVal => {
|
|
1495
|
-
const topLevelItem = findTopLevelItem(selectedVal);
|
|
1496
|
-
if (topLevelItem && topLevelItem.value !== undefined && !processedTopLevelValues.has(topLevelItem.value)) {
|
|
1497
|
-
// Clone the item to avoid mutating the original
|
|
1498
|
-
const clonedItem = deepCloneItem(topLevelItem);
|
|
1499
|
-
selectedItems.push(clonedItem);
|
|
1500
|
-
processedTopLevelValues.add(topLevelItem.value);
|
|
1501
|
-
}
|
|
1502
|
-
});
|
|
1503
|
-
|
|
1504
|
-
// Collect unselected items maintaining original order
|
|
1505
|
-
// For tree structures, only include top-level items that don't have any selected descendants
|
|
1506
|
-
opts.forEach(item => {
|
|
1507
|
-
if (item.value === undefined) {
|
|
1508
|
-
// Item without value, include as-is
|
|
1509
|
-
unselectedItems.push(deepCloneItem(item));
|
|
1510
|
-
} else if (!processedTopLevelValues.has(item.value)) {
|
|
1511
|
-
// Check if this item or any of its descendants is selected
|
|
1512
|
-
if (!hasSelectedDescendant(item)) {
|
|
1513
|
-
unselectedItems.push(deepCloneItem(item));
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
});
|
|
1517
|
-
|
|
1518
|
-
// Return selected items first (in selection order), then unselected items
|
|
1519
|
-
return [...selectedItems, ...unselectedItems];
|
|
1520
|
-
}, []);
|
|
1521
|
-
|
|
1522
|
-
// Track previous options count before fetchMissingOptions to detect when missing options are added
|
|
1523
1204
|
const prevOptionsCountBeforeFetchMissingRef = (0, _react.useRef)(options.length);
|
|
1524
|
-
// Track previous options before fetchMissingOptions to detect when missing options are added
|
|
1525
1205
|
const prevOptionsBeforeFetchMissingRef = (0, _react.useRef)(options);
|
|
1526
|
-
|
|
1527
|
-
// Update orderedOptions when new options are appended via scroll (when items are selected)
|
|
1528
|
-
// This ensures new data appears even when items are selected
|
|
1529
1206
|
(0, _react.useEffect)(() => {
|
|
1530
|
-
// Only update if we have orderedOptions (items are selected), onPopupScroll is provided,
|
|
1531
|
-
// and options increased from when scroll was triggered
|
|
1532
1207
|
if (!orderedOptions || !onPopupScroll) {
|
|
1533
1208
|
return;
|
|
1534
1209
|
}
|
|
1535
1210
|
const currentOptions = options;
|
|
1536
|
-
// Compare against the count when scroll was triggered, not the current ref value
|
|
1537
|
-
// This ensures we detect increases even if refs were updated in other useEffects
|
|
1538
1211
|
const optionsCountIncreased = currentOptions.length > scrollTriggerOptionsCountRef.current;
|
|
1539
|
-
|
|
1540
|
-
// Only update if options increased from scroll trigger time
|
|
1541
|
-
// This prevents updating on other option changes (like search)
|
|
1542
1212
|
if (optionsCountIncreased && scrollTriggerOptionsCountRef.current > 0) {
|
|
1543
1213
|
const selectedValues = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1544
1214
|
if (selectedValues.length > 0) {
|
|
1545
|
-
|
|
1546
|
-
// This will put selected items at top and append new unselected items at bottom
|
|
1547
|
-
const reordered = reorderOptionsBySelection(currentOptions, selectedValues);
|
|
1215
|
+
const reordered = (0, _utils.reorderOptionsBySelection)(currentOptions, selectedValues);
|
|
1548
1216
|
setOrderedOptions(reordered);
|
|
1549
|
-
// Update the scroll trigger count for next scroll detection
|
|
1550
1217
|
scrollTriggerOptionsCountRef.current = currentOptions.length;
|
|
1551
1218
|
}
|
|
1552
1219
|
}
|
|
1553
|
-
}, [options, orderedOptions, onPopupScroll, tempValue
|
|
1554
|
-
|
|
1555
|
-
// Update orderedOptions when new options are added via fetchMissingOptions (for paginated API-driven data)
|
|
1556
|
-
// This handles the case when user selects items from paginated pages and confirms
|
|
1557
|
-
// The fetchMissingOptions callback fetches the missing selected items, and we need to reorder them to top
|
|
1558
|
-
// Also handles search cases and upload cases where selected items might not be in current options
|
|
1220
|
+
}, [options, orderedOptions, onPopupScroll, tempValue]);
|
|
1559
1221
|
(0, _react.useEffect)(() => {
|
|
1560
|
-
// Only handle if fetchMissingOptions is provided (indicates API-driven pagination)
|
|
1561
1222
|
if (!fetchMissingOptions) {
|
|
1562
|
-
// Update refs even when fetchMissingOptions is not provided
|
|
1563
1223
|
prevOptionsCountBeforeFetchMissingRef.current = options.length;
|
|
1564
1224
|
prevOptionsBeforeFetchMissingRef.current = options;
|
|
1565
1225
|
return;
|
|
1566
1226
|
}
|
|
1227
|
+
|
|
1228
|
+
// For API-driven data, don't reorder options during active search
|
|
1229
|
+
// Only reorder when there's no search query or search is cleared
|
|
1230
|
+
const hasActiveSearch = !staticValue && lastSearchQueryRef.current.trim().length > 0;
|
|
1231
|
+
if (hasActiveSearch) {
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1567
1234
|
const currentOptions = options;
|
|
1568
1235
|
const currentSelectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
1569
1236
|
const tempSelectedValues = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1570
|
-
// Use tempValue if available (during selection), otherwise use value (after confirm)
|
|
1571
1237
|
const selectedValues = tempSelectedValues.length > 0 ? tempSelectedValues : currentSelectedValues;
|
|
1572
1238
|
if (selectedValues.length === 0) {
|
|
1573
|
-
// No selected values, update refs and return
|
|
1574
1239
|
prevOptionsCountBeforeFetchMissingRef.current = currentOptions.length;
|
|
1575
1240
|
prevOptionsBeforeFetchMissingRef.current = currentOptions;
|
|
1576
1241
|
return;
|
|
1577
1242
|
}
|
|
1578
|
-
|
|
1579
|
-
// Check if options changed (count or content) after fetchMissingOptions was called
|
|
1580
1243
|
const prevOptions = prevOptionsBeforeFetchMissingRef.current;
|
|
1581
1244
|
const optionsCountIncreased = currentOptions.length > prevOptionsCountBeforeFetchMissingRef.current;
|
|
1582
1245
|
const optionsChanged = prevOptions !== currentOptions || optionsCountIncreased;
|
|
1583
|
-
|
|
1584
|
-
// Check if any previously missing selected values now exist in options
|
|
1585
|
-
// This handles both cases: when fetchMissingOptions was called, and when options update for any reason
|
|
1586
1246
|
const hasNewlyFetchedSelectedItems = (() => {
|
|
1587
1247
|
if (selectedValues.length === 0 || !optionsChanged) {
|
|
1588
1248
|
return false;
|
|
1589
1249
|
}
|
|
1590
|
-
|
|
1591
|
-
// Find which selected values were missing in previous options
|
|
1592
|
-
const previouslyMissingValues = selectedValues.filter(val => !findValueInOptions(prevOptions, val));
|
|
1250
|
+
const previouslyMissingValues = selectedValues.filter(val => !(0, _utils.findValueInOptions)(prevOptions, val));
|
|
1593
1251
|
if (previouslyMissingValues.length === 0) {
|
|
1594
1252
|
return false;
|
|
1595
1253
|
}
|
|
1596
|
-
|
|
1597
|
-
// Check if any of those previously missing values now exist in current options
|
|
1598
|
-
const nowPresentValues = previouslyMissingValues.filter(val => findValueInOptions(currentOptions, val));
|
|
1254
|
+
const nowPresentValues = previouslyMissingValues.filter(val => (0, _utils.findValueInOptions)(currentOptions, val));
|
|
1599
1255
|
return nowPresentValues.length > 0;
|
|
1600
1256
|
})();
|
|
1601
|
-
|
|
1602
|
-
// Update orderedOptions if:
|
|
1603
|
-
// 1. Options changed (increased or content changed) AND
|
|
1604
|
-
// 2. Previously missing selected items are now present in options
|
|
1605
|
-
// This works for both cases: when fetchMissingOptions was explicitly called, and when options update for other reasons
|
|
1606
1257
|
if (optionsChanged && hasNewlyFetchedSelectedItems) {
|
|
1607
|
-
|
|
1608
|
-
const reordered = reorderOptionsBySelection(currentOptions, selectedValues);
|
|
1258
|
+
const reordered = (0, _utils.reorderOptionsBySelection)(currentOptions, selectedValues);
|
|
1609
1259
|
setOrderedOptions(reordered);
|
|
1610
1260
|
}
|
|
1611
|
-
|
|
1612
|
-
// Always update the previous options and count for next comparison
|
|
1613
|
-
// This ensures we can detect when missing options are added in the future
|
|
1614
1261
|
prevOptionsCountBeforeFetchMissingRef.current = currentOptions.length;
|
|
1615
1262
|
prevOptionsBeforeFetchMissingRef.current = currentOptions;
|
|
1616
|
-
}, [options, value, tempValue, fetchMissingOptions,
|
|
1617
|
-
|
|
1618
|
-
// Sort selected items to top on initial load (only once)
|
|
1619
|
-
// This handles the case when user comes from another flow with pre-selected values
|
|
1263
|
+
}, [options, value, tempValue, fetchMissingOptions, staticValue]);
|
|
1620
1264
|
(0, _react.useEffect)(() => {
|
|
1621
|
-
// Only do this once, and only if we have options and selected values
|
|
1622
1265
|
if (initialSortDoneRef.current || !(options != null && options.length)) {
|
|
1623
1266
|
return;
|
|
1624
1267
|
}
|
|
1625
|
-
|
|
1626
|
-
// Check if there are selected values
|
|
1627
1268
|
const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
1628
1269
|
if (selectedValues.length === 0) {
|
|
1629
|
-
// No selected values, mark as done
|
|
1630
1270
|
initialSortDoneRef.current = true;
|
|
1631
1271
|
return;
|
|
1632
1272
|
}
|
|
1633
|
-
|
|
1634
|
-
// Check if any selected values exist in options
|
|
1635
1273
|
const checkValueExists = (opts, val) => {
|
|
1636
1274
|
for (const opt of opts) {
|
|
1637
1275
|
if (opt.value === val) return true;
|
|
@@ -1643,40 +1281,27 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1643
1281
|
};
|
|
1644
1282
|
const hasSelectedInOptions = selectedValues.some(val => checkValueExists(options, val));
|
|
1645
1283
|
if (hasSelectedInOptions) {
|
|
1646
|
-
|
|
1647
|
-
const reordered = reorderOptionsBySelection(options, selectedValues);
|
|
1284
|
+
const reordered = (0, _utils.reorderOptionsBySelection)(options, selectedValues);
|
|
1648
1285
|
setOrderedOptions(reordered);
|
|
1649
1286
|
}
|
|
1650
|
-
|
|
1651
|
-
// Mark as done - only sort once on initial load
|
|
1652
1287
|
initialSortDoneRef.current = true;
|
|
1653
|
-
}, [options, value
|
|
1288
|
+
}, [options, value]);
|
|
1654
1289
|
const dataSource = (0, _react.useMemo)(() => {
|
|
1655
|
-
// During search, use normal options (mergedOptions) to show filtered results without selected items at top
|
|
1656
|
-
// When not searching, use ordered options if available (selected items at top), otherwise use merged options
|
|
1657
1290
|
const sourceOptions = searchText.trim() ? mergedOptions : orderedOptions || mergedOptions;
|
|
1658
|
-
|
|
1659
|
-
// Get current selected values to check for missing ones
|
|
1660
|
-
// Use value prop (external state) instead of tempValue (internal state)
|
|
1661
|
-
// This ensures we only create virtual options for values that are actually selected
|
|
1662
|
-
// and not just temporarily selected during dropdown interaction
|
|
1663
1291
|
const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
1664
1292
|
const hasSearchQuery = searchText.trim().length > 0;
|
|
1665
1293
|
|
|
1666
|
-
//
|
|
1667
|
-
// Only
|
|
1668
|
-
|
|
1294
|
+
// For API-driven data, don't append virtual options during search
|
|
1295
|
+
// Only show search results when searching
|
|
1296
|
+
const shouldAppendVirtualOptions = staticValue || !hasSearchQuery;
|
|
1669
1297
|
const missingSelectedValues = [];
|
|
1670
|
-
if (selectedValues.length > 0) {
|
|
1298
|
+
if (shouldAppendVirtualOptions && selectedValues.length > 0) {
|
|
1671
1299
|
selectedValues.forEach(val => {
|
|
1672
|
-
if (!findValueInOptions(sourceOptions, val)) {
|
|
1300
|
+
if (!(0, _utils.findValueInOptions)(sourceOptions, val)) {
|
|
1673
1301
|
missingSelectedValues.push(val);
|
|
1674
1302
|
}
|
|
1675
1303
|
});
|
|
1676
1304
|
}
|
|
1677
|
-
|
|
1678
|
-
// Create virtual option nodes for missing selected values
|
|
1679
|
-
// Use cached option data if available, otherwise create a simple node with value as label
|
|
1680
1305
|
const virtualOptions = missingSelectedValues.map(val => {
|
|
1681
1306
|
const cachedOption = selectedItemsCacheRef.current.get(val);
|
|
1682
1307
|
return _extends({
|
|
@@ -1692,10 +1317,6 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1692
1317
|
children: cachedOption.children
|
|
1693
1318
|
});
|
|
1694
1319
|
});
|
|
1695
|
-
|
|
1696
|
-
// Combine source options with virtual options for missing selected values
|
|
1697
|
-
// When not searching, add virtual options at the beginning so selected items appear first
|
|
1698
|
-
// When searching, still include them if they match the search (handled by filterTreeData)
|
|
1699
1320
|
const allOptions = hasSearchQuery ? [...sourceOptions, ...virtualOptions] : [...virtualOptions, ...sourceOptions];
|
|
1700
1321
|
if (!(allOptions != null && allOptions.length)) return [];
|
|
1701
1322
|
const enhanceOptions = opts => opts.map(opt => {
|
|
@@ -1752,20 +1373,13 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1752
1373
|
}),
|
|
1753
1374
|
label: opt == null ? void 0 : opt.label
|
|
1754
1375
|
}));
|
|
1755
|
-
}, [isTree, mergedOptions, orderedOptions, searchText, value,
|
|
1376
|
+
}, [isTree, mergedOptions, orderedOptions, searchText, value, staticValue]);
|
|
1756
1377
|
const filteredTree = (0, _react.useMemo)(() => {
|
|
1757
1378
|
const selectedValues = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1758
|
-
|
|
1759
|
-
// If staticValue is true, use local filtering on existing options
|
|
1760
|
-
// If staticValue is false, still use local filtering for immediate feedback,
|
|
1761
|
-
// but onSearch callback will be triggered for parent to update options
|
|
1762
|
-
// Always include selectedValues to ensure uploaded/selected items are visible
|
|
1763
|
-
// This ensures that when dev uploads values, they remain visible in the dropdown
|
|
1764
|
-
// even if they're not in the options array yet
|
|
1765
|
-
return filterTreeData(dataSource, searchText.trim(), searchBasedOn, selectedValues.length > 0 ? selectedValues : undefined);
|
|
1379
|
+
return (0, _utils.filterTreeData)(dataSource, searchText.trim(), searchBasedOn, selectedValues.length > 0 ? selectedValues : undefined);
|
|
1766
1380
|
}, [dataSource, searchText, searchBasedOn, tempValue]);
|
|
1767
|
-
const treeMaps = (0, _react.useMemo)(() => buildTreeMaps(options), [options]);
|
|
1768
|
-
const selectedLeafCount = (0, _react.useMemo)(() => countSelectedLeaves(treeMaps, Array.isArray(tempValue) ? tempValue : undefined), [treeMaps, tempValue]);
|
|
1381
|
+
const treeMaps = (0, _react.useMemo)(() => (0, _utils.buildTreeMaps)(options), [options]);
|
|
1382
|
+
const selectedLeafCount = (0, _react.useMemo)(() => (0, _utils.countSelectedLeaves)(treeMaps, Array.isArray(tempValue) ? tempValue : undefined), [treeMaps, tempValue]);
|
|
1769
1383
|
const displayValue = dropdownOpen ? tempValue : value;
|
|
1770
1384
|
const suffix = (0, _react.useMemo)(() => {
|
|
1771
1385
|
const count = Array.isArray(displayValue) ? displayValue == null ? void 0 : displayValue.length : displayValue ? 1 : 0;
|
|
@@ -1800,27 +1414,22 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1800
1414
|
if (isMulti && Array.isArray(displayValue) && (displayValue == null ? void 0 : displayValue.length) > 0) {
|
|
1801
1415
|
var _treeMaps$nodeMap;
|
|
1802
1416
|
const firstLeafValue = displayValue.find(val => {
|
|
1803
|
-
var _treeMaps$
|
|
1804
|
-
return treeMaps == null || (_treeMaps$
|
|
1417
|
+
var _treeMaps$leafValues;
|
|
1418
|
+
return treeMaps == null || (_treeMaps$leafValues = treeMaps.leafValues) == null ? void 0 : _treeMaps$leafValues.includes(val);
|
|
1805
1419
|
});
|
|
1806
1420
|
return firstLeafValue ? (treeMaps == null || (_treeMaps$nodeMap = treeMaps.nodeMap) == null || (_treeMaps$nodeMap = _treeMaps$nodeMap[firstLeafValue]) == null ? void 0 : _treeMaps$nodeMap.label) || null : null;
|
|
1807
1421
|
}
|
|
1808
1422
|
return null;
|
|
1809
1423
|
}, [isMulti, displayValue, treeMaps]);
|
|
1810
1424
|
const handleConfirm = (0, _react.useCallback)(() => {
|
|
1811
|
-
// Mark as interacted since user clicked confirm (explicit action)
|
|
1812
1425
|
hasInteractedRef.current = true;
|
|
1813
|
-
|
|
1814
|
-
// Reorder options based on selection order when confirm is clicked
|
|
1815
|
-
// Use mergedOptions to include paginated options if they exist
|
|
1816
1426
|
const optionsToReorder = mergedOptions;
|
|
1817
1427
|
if (isMulti && Array.isArray(tempValue) && tempValue.length > 0) {
|
|
1818
|
-
|
|
1819
|
-
const reordered = reorderOptionsBySelection(optionsToReorder, tempValue);
|
|
1428
|
+
const reordered = (0, _utils.reorderOptionsBySelection)(optionsToReorder, tempValue);
|
|
1820
1429
|
setOrderedOptions(reordered);
|
|
1821
1430
|
} else if (!isMulti && tempValue && !Array.isArray(tempValue)) {
|
|
1822
1431
|
// For single select, move selected item to top
|
|
1823
|
-
const reordered = reorderOptionsBySelection(optionsToReorder, [tempValue]);
|
|
1432
|
+
const reordered = (0, _utils.reorderOptionsBySelection)(optionsToReorder, [tempValue]);
|
|
1824
1433
|
setOrderedOptions(reordered);
|
|
1825
1434
|
} else {
|
|
1826
1435
|
// No selection, reset to original order
|
|
@@ -1828,19 +1437,13 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1828
1437
|
}
|
|
1829
1438
|
onChange == null || onChange(tempValue);
|
|
1830
1439
|
setDropdownOpen(false);
|
|
1831
|
-
// Always clear searching state since search operation is complete
|
|
1832
1440
|
setIsSearching(false);
|
|
1833
|
-
searchClearedTimeRef.current = null;
|
|
1834
|
-
// Clear search text on confirm only if resetSearch is true
|
|
1835
|
-
// This allows users to keep their search when reopening the dropdown if desired
|
|
1441
|
+
searchClearedTimeRef.current = null;
|
|
1836
1442
|
if (resetSearch) {
|
|
1837
1443
|
setSearchText('');
|
|
1838
|
-
lastSearchQueryRef.current = '';
|
|
1444
|
+
lastSearchQueryRef.current = '';
|
|
1839
1445
|
}
|
|
1840
|
-
// Call resetData to allow developer to reload initial data
|
|
1841
|
-
// Only call if options array is not empty
|
|
1842
1446
|
if (resetData && mergedOptions.length > 0) {
|
|
1843
|
-
// Store current options before calling resetData to detect when they update
|
|
1844
1447
|
prevOptionsBeforeResetRef.current = mergedOptions;
|
|
1845
1448
|
setIsResettingData(true);
|
|
1846
1449
|
resetDataCalledRef.current = true;
|
|
@@ -1848,18 +1451,55 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1848
1451
|
resetData();
|
|
1849
1452
|
}
|
|
1850
1453
|
onConfirm == null || onConfirm(tempValue);
|
|
1851
|
-
}, [onChange, onConfirm, tempValue, resetSearch, isMulti, mergedOptions,
|
|
1454
|
+
}, [onChange, onConfirm, tempValue, resetSearch, isMulti, mergedOptions, resetData]);
|
|
1852
1455
|
const handleClearAll = (0, _react.useCallback)(() => {
|
|
1853
|
-
//
|
|
1854
|
-
hasInteractedRef.current = true;
|
|
1456
|
+
// Reset all state as if it's a fresh dropdown
|
|
1855
1457
|
const cleared = isMulti ? [] : undefined;
|
|
1458
|
+
|
|
1459
|
+
// Clear search state
|
|
1460
|
+
setSearchText('');
|
|
1461
|
+
setIsSearching(false);
|
|
1462
|
+
lastSearchQueryRef.current = '';
|
|
1463
|
+
searchClearedTimeRef.current = null;
|
|
1464
|
+
|
|
1465
|
+
// Clear timeouts
|
|
1466
|
+
if (searchTimeoutRef.current) {
|
|
1467
|
+
clearTimeout(searchTimeoutRef.current);
|
|
1468
|
+
searchTimeoutRef.current = null;
|
|
1469
|
+
}
|
|
1470
|
+
if (scrollLoadingTimeoutRef.current) {
|
|
1471
|
+
clearTimeout(scrollLoadingTimeoutRef.current);
|
|
1472
|
+
scrollLoadingTimeoutRef.current = null;
|
|
1473
|
+
}
|
|
1474
|
+
if (scrollThrottleTimeoutRef.current) {
|
|
1475
|
+
clearTimeout(scrollThrottleTimeoutRef.current);
|
|
1476
|
+
scrollThrottleTimeoutRef.current = null;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
// Reset scroll state
|
|
1480
|
+
setIsLoadingOnScroll(false);
|
|
1481
|
+
isScrollProcessingRef.current = false;
|
|
1482
|
+
scrollContainerRef.current = null;
|
|
1483
|
+
|
|
1484
|
+
// Reset ordered options
|
|
1485
|
+
setOrderedOptions(null);
|
|
1486
|
+
initialSortDoneRef.current = false;
|
|
1487
|
+
|
|
1488
|
+
// Reset interaction flags
|
|
1489
|
+
hasInteractedRef.current = false;
|
|
1490
|
+
resetDataCalledRef.current = false;
|
|
1491
|
+
fetchMissingOptionsCalledRef.current = false;
|
|
1492
|
+
lastMissingValuesRef.current = '';
|
|
1493
|
+
|
|
1494
|
+
// Reset temp value and call onChange (same as allowClear X button)
|
|
1856
1495
|
setTempValue(cleared);
|
|
1857
1496
|
onChange == null || onChange(cleared);
|
|
1497
|
+
|
|
1498
|
+
// Close dropdown
|
|
1858
1499
|
setDropdownOpen(false);
|
|
1859
|
-
|
|
1860
|
-
//
|
|
1500
|
+
|
|
1501
|
+
// Reset data if needed (same as allowClear X button behavior)
|
|
1861
1502
|
if (resetData && options.length > 0) {
|
|
1862
|
-
// Store current options before calling resetData to detect when they update
|
|
1863
1503
|
prevOptionsBeforeResetRef.current = options;
|
|
1864
1504
|
setIsResettingData(true);
|
|
1865
1505
|
resetDataCalledRef.current = true;
|
|
@@ -1868,25 +1508,19 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1868
1508
|
}
|
|
1869
1509
|
}, [isMulti, onChange, resetData, options]);
|
|
1870
1510
|
const handleDropdownVisibilityChange = (0, _react.useCallback)(open => {
|
|
1871
|
-
if (readOnly) {
|
|
1511
|
+
if (readOnly || disabled) {
|
|
1872
1512
|
return;
|
|
1873
1513
|
}
|
|
1874
1514
|
if (open) {
|
|
1875
|
-
// Reset interaction tracking when dropdown opens
|
|
1876
|
-
// Store initial value (not tempValue) to detect if user makes changes
|
|
1877
|
-
// This ensures we track changes from the actual selected value, not temporary state
|
|
1878
1515
|
initialTempValueRef.current = value;
|
|
1879
1516
|
hasInteractedRef.current = false;
|
|
1880
1517
|
resetDataCalledRef.current = false;
|
|
1881
|
-
// Reset fetchMissingOptions tracking to allow re-checking when dropdown opens
|
|
1882
1518
|
fetchMissingOptionsCalledRef.current = false;
|
|
1883
1519
|
lastMissingValuesRef.current = '';
|
|
1884
|
-
// Clear any pending search timeouts
|
|
1885
1520
|
if (searchTimeoutRef.current) {
|
|
1886
1521
|
clearTimeout(searchTimeoutRef.current);
|
|
1887
1522
|
searchTimeoutRef.current = null;
|
|
1888
1523
|
}
|
|
1889
|
-
// Clear any pending scroll loading timeouts
|
|
1890
1524
|
if (scrollLoadingTimeoutRef.current) {
|
|
1891
1525
|
clearTimeout(scrollLoadingTimeoutRef.current);
|
|
1892
1526
|
scrollLoadingTimeoutRef.current = null;
|
|
@@ -1895,35 +1529,27 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1895
1529
|
clearTimeout(scrollThrottleTimeoutRef.current);
|
|
1896
1530
|
scrollThrottleTimeoutRef.current = null;
|
|
1897
1531
|
}
|
|
1898
|
-
// Reset loading states
|
|
1899
1532
|
setIsSearching(false);
|
|
1900
|
-
searchClearedTimeRef.current = null;
|
|
1533
|
+
searchClearedTimeRef.current = null;
|
|
1901
1534
|
setIsLoadingOnScroll(false);
|
|
1902
1535
|
isScrollProcessingRef.current = false;
|
|
1903
|
-
// Safety check: Clear isResettingData if it's still true when opening
|
|
1904
|
-
// This handles cases where options updated while dropdown was closed
|
|
1905
1536
|
if (isResettingData) {
|
|
1906
1537
|
setIsResettingData(false);
|
|
1907
|
-
// Update ref to current options to prevent false positives
|
|
1908
1538
|
prevOptionsBeforeResetRef.current = options;
|
|
1909
|
-
// Clear timestamp
|
|
1910
1539
|
resetDataCalledTimeRef.current = null;
|
|
1911
1540
|
}
|
|
1912
1541
|
} else {
|
|
1913
|
-
// Dropdown is closing
|
|
1914
1542
|
if (!customPopupRender) {
|
|
1915
1543
|
onChange == null || onChange(tempValue);
|
|
1916
1544
|
} else {
|
|
1917
1545
|
setTempValue(value);
|
|
1918
1546
|
}
|
|
1919
|
-
// Clear search when closing (if enabled)
|
|
1920
1547
|
if (resetSearch) {
|
|
1921
1548
|
setSearchText('');
|
|
1922
1549
|
setIsSearching(false);
|
|
1923
|
-
lastSearchQueryRef.current = '';
|
|
1924
|
-
searchClearedTimeRef.current = null;
|
|
1550
|
+
lastSearchQueryRef.current = '';
|
|
1551
|
+
searchClearedTimeRef.current = null;
|
|
1925
1552
|
}
|
|
1926
|
-
// Reset scroll loading state
|
|
1927
1553
|
setIsLoadingOnScroll(false);
|
|
1928
1554
|
isScrollProcessingRef.current = false;
|
|
1929
1555
|
if (scrollLoadingTimeoutRef.current) {
|
|
@@ -1935,36 +1561,25 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1935
1561
|
scrollThrottleTimeoutRef.current = null;
|
|
1936
1562
|
}
|
|
1937
1563
|
scrollContainerRef.current = null;
|
|
1938
|
-
|
|
1939
|
-
// Only call resetData if user actually interacted (selected, searched, etc.)
|
|
1940
|
-
// and resetData hasn't been called already in this session
|
|
1941
|
-
// This prevents multiple API calls when user just opens/closes without interaction
|
|
1942
|
-
// Only call if options array is not empty
|
|
1943
1564
|
if (resetData && hasInteractedRef.current && !resetDataCalledRef.current && options.length > 0) {
|
|
1944
|
-
// Store current options before calling resetData to detect when they update
|
|
1945
1565
|
prevOptionsBeforeResetRef.current = options;
|
|
1946
1566
|
setIsResettingData(true);
|
|
1947
1567
|
resetDataCalledRef.current = true;
|
|
1948
1568
|
resetDataCalledTimeRef.current = Date.now();
|
|
1949
1569
|
resetData();
|
|
1950
1570
|
} else if (!hasInteractedRef.current) {
|
|
1951
|
-
// User did nothing - reset everything as if it's a fresh load
|
|
1952
|
-
// Clear any pending operations
|
|
1953
1571
|
if (searchTimeoutRef.current) {
|
|
1954
1572
|
clearTimeout(searchTimeoutRef.current);
|
|
1955
1573
|
searchTimeoutRef.current = null;
|
|
1956
1574
|
}
|
|
1957
1575
|
setIsSearching(false);
|
|
1958
1576
|
setIsResettingData(false);
|
|
1959
|
-
// Reset search query ref
|
|
1960
1577
|
lastSearchQueryRef.current = '';
|
|
1961
1578
|
}
|
|
1962
|
-
|
|
1963
|
-
// Reset interaction flag for next session
|
|
1964
1579
|
hasInteractedRef.current = false;
|
|
1965
1580
|
}
|
|
1966
1581
|
setDropdownOpen(open);
|
|
1967
|
-
}, [customPopupRender, value, onChange, tempValue, readOnly, resetSearch, resetData, options, isResettingData]);
|
|
1582
|
+
}, [customPopupRender, value, onChange, tempValue, readOnly, disabled, resetSearch, resetData, options, isResettingData]);
|
|
1968
1583
|
const handleFooterDownload = (0, _react.useCallback)(() => {
|
|
1969
1584
|
const currentValues = Array.isArray(tempValue) ? tempValue : tempValue ? [tempValue] : [];
|
|
1970
1585
|
onFooterDownloadChange == null || onFooterDownloadChange(currentValues);
|
|
@@ -1976,151 +1591,80 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
1976
1591
|
const handleSearchChange = (0, _react.useCallback)(e => {
|
|
1977
1592
|
const query = e.target.value;
|
|
1978
1593
|
setSearchText(query);
|
|
1979
|
-
|
|
1980
|
-
// Trigger search handler (handles debouncing and minLength check)
|
|
1981
1594
|
handleSearch(query);
|
|
1982
1595
|
}, [handleSearch]);
|
|
1983
1596
|
const handleSearchKeyDown = (0, _react.useCallback)(e => {
|
|
1984
|
-
// Stop propagation of backspace and delete keys to prevent TreeSelect from deselecting items
|
|
1985
|
-
// The input itself will handle the deletion, we just need to prevent TreeSelect from handling it
|
|
1986
1597
|
if (e.key === 'Backspace' || e.key === 'Delete') {
|
|
1987
1598
|
e.stopPropagation();
|
|
1988
1599
|
}
|
|
1989
|
-
// Also stop Escape key to prevent dropdown from closing when clearing search
|
|
1990
1600
|
if (e.key === 'Escape' && searchText.length > 0) {
|
|
1991
1601
|
e.stopPropagation();
|
|
1992
1602
|
}
|
|
1993
1603
|
}, [searchText]);
|
|
1994
|
-
|
|
1995
|
-
// Handle scroll event - automatically checks if scroll is near bottom
|
|
1996
|
-
// Developer handles hasMore and isLoading conditions in onPopupScroll callback
|
|
1997
|
-
// Using refs to avoid recreating the callback when options change
|
|
1998
1604
|
const handleScroll = (0, _react.useCallback)(event => {
|
|
1999
1605
|
if (!onPopupScroll) return;
|
|
2000
1606
|
const target = event.target;
|
|
2001
1607
|
if (!target) return;
|
|
2002
|
-
|
|
2003
|
-
// Check if scroll is near bottom
|
|
2004
1608
|
const isNearBottom = Math.floor(target.scrollHeight - target.scrollTop) <= target.clientHeight;
|
|
2005
|
-
|
|
2006
|
-
// Only call onPopupScroll if scroll is near bottom
|
|
2007
|
-
// Developer will handle hasMore and isLoading checks inside the callback
|
|
2008
1609
|
if (!isNearBottom) {
|
|
2009
|
-
// Reset processing flag when not near bottom
|
|
2010
1610
|
isScrollProcessingRef.current = false;
|
|
2011
1611
|
return;
|
|
2012
1612
|
}
|
|
2013
|
-
|
|
2014
|
-
// Prevent multiple scroll triggers while already processing
|
|
2015
|
-
// This ensures we don't trigger multiple API calls simultaneously
|
|
2016
1613
|
if (isScrollProcessingRef.current) return;
|
|
2017
|
-
|
|
2018
|
-
// Prevent multiple scroll triggers while already loading
|
|
2019
|
-
// This ensures loading state is managed properly and data loading completes
|
|
2020
1614
|
if (isLoadingOnScroll) return;
|
|
2021
|
-
|
|
2022
|
-
// Don't trigger if there are no more items to load
|
|
2023
|
-
// This prevents showing loading state when all items are exhausted
|
|
2024
1615
|
if (!hasMore) {
|
|
2025
1616
|
isScrollProcessingRef.current = false;
|
|
2026
1617
|
return;
|
|
2027
1618
|
}
|
|
2028
|
-
|
|
2029
|
-
// Throttle scroll events to prevent rapid-fire API calls
|
|
2030
|
-
// Clear any existing throttle timeout
|
|
2031
1619
|
if (scrollThrottleTimeoutRef.current) {
|
|
2032
1620
|
clearTimeout(scrollThrottleTimeoutRef.current);
|
|
2033
1621
|
}
|
|
2034
|
-
|
|
2035
|
-
// Set processing flag immediately to prevent duplicate calls
|
|
2036
1622
|
isScrollProcessingRef.current = true;
|
|
2037
|
-
|
|
2038
|
-
// Throttle the actual API call to prevent multiple rapid triggers
|
|
2039
1623
|
scrollThrottleTimeoutRef.current = setTimeout(() => {
|
|
2040
|
-
// Double-check we're still near bottom and not loading
|
|
2041
1624
|
const stillNearBottom = Math.floor(target.scrollHeight - target.scrollTop) <= target.clientHeight;
|
|
2042
|
-
// Also check if hasMore is still true (might have changed during throttle delay)
|
|
2043
1625
|
if (!stillNearBottom || isLoadingOnScroll || !hasMore) {
|
|
2044
1626
|
isScrollProcessingRef.current = false;
|
|
2045
1627
|
return;
|
|
2046
1628
|
}
|
|
2047
|
-
|
|
2048
|
-
// Store current options count and options reference before triggering load
|
|
2049
|
-
// This helps detect when new data arrives
|
|
2050
|
-
// Use ref to get current options without depending on options.length
|
|
2051
1629
|
const currentOptions = optionsRef.current;
|
|
2052
1630
|
prevOptionsCountRef.current = currentOptions.length;
|
|
2053
1631
|
prevOptionsRefForScroll.current = currentOptions;
|
|
2054
|
-
// Also store the count at scroll trigger time for orderedOptions update
|
|
2055
1632
|
scrollTriggerOptionsCountRef.current = currentOptions.length;
|
|
2056
|
-
|
|
2057
|
-
// Show loading indicator when scrolling near bottom
|
|
2058
|
-
// This happens before calling onPopupScroll to provide immediate feedback
|
|
2059
1633
|
setIsLoadingOnScroll(true);
|
|
2060
|
-
|
|
2061
|
-
// Clear any existing timeout
|
|
2062
1634
|
if (scrollLoadingTimeoutRef.current) {
|
|
2063
1635
|
clearTimeout(scrollLoadingTimeoutRef.current);
|
|
2064
1636
|
scrollLoadingTimeoutRef.current = null;
|
|
2065
1637
|
}
|
|
2066
|
-
|
|
2067
|
-
// Mark as interacted when user scrolls (triggers data loading)
|
|
2068
1638
|
hasInteractedRef.current = true;
|
|
2069
|
-
|
|
2070
|
-
// Call the developer's scroll handler - component already checked scroll position
|
|
2071
|
-
// Developer should check hasMore and isLoading inside the callback
|
|
2072
|
-
// This triggers the async data loading
|
|
2073
1639
|
onPopupScroll();
|
|
2074
|
-
|
|
2075
|
-
// Set a fallback timeout to clear loading if options don't change
|
|
2076
|
-
// This prevents loading from staying forever if data never arrives
|
|
2077
|
-
// Using a longer timeout (10 seconds) to give enough time for slow API calls
|
|
2078
1640
|
scrollLoadingTimeoutRef.current = setTimeout(() => {
|
|
2079
|
-
// Only clear if still loading (options change detection might have cleared it already)
|
|
2080
1641
|
setIsLoadingOnScroll(prev => {
|
|
2081
1642
|
if (prev) {
|
|
2082
|
-
// Clear the timeout reference when clearing loading state
|
|
2083
1643
|
scrollLoadingTimeoutRef.current = null;
|
|
2084
|
-
// Reset processing flag when loading times out
|
|
2085
1644
|
isScrollProcessingRef.current = false;
|
|
2086
1645
|
return false;
|
|
2087
1646
|
}
|
|
2088
1647
|
return prev;
|
|
2089
1648
|
});
|
|
2090
1649
|
}, _constants.TIMEOUTS.SCROLL_LOADING_TIMEOUT);
|
|
2091
|
-
}, 150);
|
|
1650
|
+
}, 150);
|
|
2092
1651
|
}, [onPopupScroll, isLoadingOnScroll, hasMore]);
|
|
2093
|
-
|
|
2094
|
-
// Setup scroll listener for onPopupScroll
|
|
2095
1652
|
(0, _react.useEffect)(() => {
|
|
2096
1653
|
if (!onPopupScroll || !dropdownOpen) return;
|
|
2097
|
-
|
|
2098
|
-
// Use a small delay to ensure DOM is ready
|
|
2099
1654
|
const timeoutId = setTimeout(() => {
|
|
2100
|
-
// Find the scrollable container in the dropdown
|
|
2101
1655
|
const findScrollContainer = () => {
|
|
2102
|
-
// Try to find the Ant Design dropdown scroll container
|
|
2103
|
-
// Look for dropdowns that are currently visible (not hidden)
|
|
2104
1656
|
const dropdowns = document.querySelectorAll('.ant-select-dropdown:not(.ant-select-dropdown-hidden)');
|
|
2105
1657
|
if (dropdowns.length === 0) return null;
|
|
2106
|
-
|
|
2107
|
-
// Get the last opened dropdown (most recent)
|
|
2108
1658
|
const dropdown = Array.from(dropdowns).pop();
|
|
2109
1659
|
if (!dropdown) return null;
|
|
2110
|
-
|
|
2111
|
-
// Look for the scrollable list container
|
|
2112
1660
|
const treeList = dropdown.querySelector('.ant-select-tree-list-holder');
|
|
2113
1661
|
if (treeList && treeList.scrollHeight > treeList.clientHeight) {
|
|
2114
1662
|
return treeList;
|
|
2115
1663
|
}
|
|
2116
|
-
|
|
2117
|
-
// Try alternative selectors
|
|
2118
1664
|
const virtualList = dropdown.querySelector('.rc-virtual-list-holder');
|
|
2119
1665
|
if (virtualList && virtualList.scrollHeight > virtualList.clientHeight) {
|
|
2120
1666
|
return virtualList;
|
|
2121
1667
|
}
|
|
2122
|
-
|
|
2123
|
-
// Fallback to dropdown itself if it's scrollable
|
|
2124
1668
|
if (dropdown.scrollHeight > dropdown.clientHeight) {
|
|
2125
1669
|
return dropdown;
|
|
2126
1670
|
}
|
|
@@ -2136,7 +1680,6 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2136
1680
|
}, _constants.TIMEOUTS.SCROLL_CONTAINER_DELAY);
|
|
2137
1681
|
return () => {
|
|
2138
1682
|
clearTimeout(timeoutId);
|
|
2139
|
-
// Clear throttle timeout when cleaning up
|
|
2140
1683
|
if (scrollThrottleTimeoutRef.current) {
|
|
2141
1684
|
clearTimeout(scrollThrottleTimeoutRef.current);
|
|
2142
1685
|
scrollThrottleTimeoutRef.current = null;
|
|
@@ -2145,7 +1688,6 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2145
1688
|
scrollContainerRef.current.removeEventListener('scroll', handleScroll);
|
|
2146
1689
|
scrollContainerRef.current = null;
|
|
2147
1690
|
}
|
|
2148
|
-
// Reset processing flag when listener is removed
|
|
2149
1691
|
isScrollProcessingRef.current = false;
|
|
2150
1692
|
};
|
|
2151
1693
|
}, [onPopupScroll, dropdownOpen, handleScroll]);
|
|
@@ -2193,9 +1735,10 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2193
1735
|
value: searchText,
|
|
2194
1736
|
onChange: handleSearchChange,
|
|
2195
1737
|
onKeyDown: handleSearchKeyDown,
|
|
2196
|
-
allowClear: true
|
|
1738
|
+
allowClear: true,
|
|
1739
|
+
disabled: disabled
|
|
2197
1740
|
})
|
|
2198
|
-
}), isMulti && showUpload && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
1741
|
+
}), isMulti && showUpload && !disabled && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
2199
1742
|
className: _styles.default['cap-unified-select-upload-container'],
|
|
2200
1743
|
align: "middle",
|
|
2201
1744
|
onClick: handleUpload,
|
|
@@ -2208,11 +1751,12 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2208
1751
|
className: _styles.default['cap-unified-select-upload-label'],
|
|
2209
1752
|
children: uploadLabel
|
|
2210
1753
|
})]
|
|
2211
|
-
}), isMulti && staticValue && currentItems.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(SelectAllCheckbox, {
|
|
1754
|
+
}), isMulti && staticValue && currentItems.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.SelectAllCheckbox, {
|
|
2212
1755
|
currentItems: currentItems,
|
|
2213
1756
|
tempValue: Array.isArray(tempValue) ? tempValue : undefined,
|
|
2214
1757
|
setTempValue: val => setTempValue(val),
|
|
2215
|
-
processTreeData: buildTreeMaps
|
|
1758
|
+
processTreeData: _utils.buildTreeMaps,
|
|
1759
|
+
disabled: disabled
|
|
2216
1760
|
}), currentItems.length === 0 ? isSearching || isResettingData ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
2217
1761
|
className: _styles.default['cap-unified-select-loading-container'],
|
|
2218
1762
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_CapRow.default, {
|
|
@@ -2229,7 +1773,7 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2229
1773
|
children: "Loading..."
|
|
2230
1774
|
})
|
|
2231
1775
|
})]
|
|
2232
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(NoResult, {
|
|
1776
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.NoResult, {
|
|
2233
1777
|
noResultCustomText: noResultCustomText,
|
|
2234
1778
|
className: className,
|
|
2235
1779
|
showUpload: showUpload,
|
|
@@ -2279,15 +1823,16 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2279
1823
|
size: "small",
|
|
2280
1824
|
className: _styles.default['cap-unified-select-confirm-button'],
|
|
2281
1825
|
onClick: handleConfirm,
|
|
2282
|
-
disabled: selectedLeafCount === 0,
|
|
1826
|
+
disabled: disabled || selectedLeafCount === 0,
|
|
2283
1827
|
children: "Confirm"
|
|
2284
1828
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_antdV.Button, {
|
|
2285
1829
|
type: "text",
|
|
2286
1830
|
className: _styles.default['cap-unified-select-cancel-button'],
|
|
2287
1831
|
size: "small",
|
|
2288
1832
|
onClick: handleClearAll,
|
|
1833
|
+
disabled: disabled,
|
|
2289
1834
|
children: clearText
|
|
2290
|
-
}), onFooterDownloadChange && selectedLeafCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
1835
|
+
}), onFooterDownloadChange && selectedLeafCount > 0 && !disabled && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
2291
1836
|
className: _styles.default['cap-unified-select-footer-download-container'],
|
|
2292
1837
|
align: "middle",
|
|
2293
1838
|
onClick: handleFooterDownload,
|
|
@@ -2301,7 +1846,7 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2301
1846
|
})]
|
|
2302
1847
|
})]
|
|
2303
1848
|
})
|
|
2304
|
-
}), (type === _constants.SELECT_TYPES.SELECT || type === _constants.SELECT_TYPES.TREE_SELECT) && allowClear && /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapRow.default, {
|
|
1849
|
+
}), (type === _constants.SELECT_TYPES.SELECT || type === _constants.SELECT_TYPES.TREE_SELECT) && allowClear && !disabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapRow.default, {
|
|
2305
1850
|
className: _styles.default['cap-unified-select-tree-clear-container'],
|
|
2306
1851
|
onClick: handleClearAll,
|
|
2307
1852
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CapLabel.default, {
|
|
@@ -2310,23 +1855,19 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2310
1855
|
})
|
|
2311
1856
|
})]
|
|
2312
1857
|
});
|
|
2313
|
-
}, [customPopupRender, filteredTree, searchText, isMulti, showUpload, uploadLabel, handleUpload, noResultCustomText, noResultCustomIcon, options, type, tempValue, handleConfirm, handleClearAll, popoverClassName, className, selectedLeafCount, clearText, allowClear, staticValue, showSearch, onFooterDownloadChange, handleFooterDownload, isSearching, handleSearchChange, handleSearchKeyDown, isLoadingOnScroll, onPopupScroll, hasMore, isResettingData]);
|
|
1858
|
+
}, [customPopupRender, filteredTree, searchText, isMulti, showUpload, uploadLabel, handleUpload, noResultCustomText, noResultCustomIcon, options, type, tempValue, handleConfirm, handleClearAll, popoverClassName, className, selectedLeafCount, clearText, allowClear, staticValue, showSearch, onFooterDownloadChange, handleFooterDownload, isSearching, handleSearchChange, handleSearchKeyDown, isLoadingOnScroll, onPopupScroll, hasMore, isResettingData, disabled]);
|
|
2314
1859
|
const combinedClassName = (0, _react.useMemo)(() => (0, _classnames.default)(containerClassName, _styles.default['cap-unified-tree-select'], {
|
|
2315
1860
|
[_styles.default['cap-unified-tree-select-readonly']]: readOnly
|
|
2316
1861
|
}, className), [containerClassName, className, readOnly]);
|
|
2317
|
-
|
|
2318
|
-
// Handle onChange for single select - detect clear button click and call resetData
|
|
2319
1862
|
const handleSingleSelectChange = (0, _react.useCallback)(newValue => {
|
|
2320
|
-
|
|
1863
|
+
if (disabled) {
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
2321
1866
|
if (newValue !== initialTempValueRef.current) {
|
|
2322
1867
|
hasInteractedRef.current = true;
|
|
2323
1868
|
}
|
|
2324
|
-
|
|
2325
|
-
// If value is cleared (becomes undefined), call resetData
|
|
2326
|
-
// Only call if options array is not empty
|
|
2327
1869
|
if (newValue === undefined || newValue === null) {
|
|
2328
1870
|
if (resetData && options.length > 0) {
|
|
2329
|
-
// Store current options before calling resetData to detect when they update
|
|
2330
1871
|
prevOptionsBeforeResetRef.current = options;
|
|
2331
1872
|
setIsResettingData(true);
|
|
2332
1873
|
resetDataCalledRef.current = true;
|
|
@@ -2335,21 +1876,18 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2335
1876
|
}
|
|
2336
1877
|
}
|
|
2337
1878
|
onChange == null || onChange(newValue);
|
|
2338
|
-
}, [onChange, resetData, options]);
|
|
2339
|
-
|
|
2340
|
-
// Handle onChange for multi select - detect clear and call resetData
|
|
1879
|
+
}, [onChange, resetData, options, disabled]);
|
|
2341
1880
|
const handleMultiSelectChange = (0, _react.useCallback)(newValue => {
|
|
2342
|
-
|
|
1881
|
+
if (disabled) {
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
2343
1884
|
const initialValue = initialTempValueRef.current;
|
|
2344
1885
|
const hasChanged = Array.isArray(newValue) && Array.isArray(initialValue) ? newValue.length !== initialValue.length || !newValue.every(v => initialValue.includes(v)) || !initialValue.every(v => newValue.includes(v)) : newValue !== initialValue;
|
|
2345
1886
|
if (hasChanged) {
|
|
2346
1887
|
hasInteractedRef.current = true;
|
|
2347
1888
|
}
|
|
2348
|
-
// If value is cleared (becomes empty array or undefined), call resetData
|
|
2349
|
-
// Only call if options array is not empty
|
|
2350
1889
|
if (newValue === undefined || newValue === null || Array.isArray(newValue) && newValue.length === 0) {
|
|
2351
1890
|
if (resetData && options.length > 0) {
|
|
2352
|
-
// Store current options before calling resetData to detect when they update
|
|
2353
1891
|
prevOptionsBeforeResetRef.current = options;
|
|
2354
1892
|
setIsResettingData(true);
|
|
2355
1893
|
resetDataCalledRef.current = true;
|
|
@@ -2358,7 +1896,7 @@ const CapUnifiedSelect = _ref4 => {
|
|
|
2358
1896
|
}
|
|
2359
1897
|
}
|
|
2360
1898
|
setTempValue(newValue);
|
|
2361
|
-
}, [resetData, options]);
|
|
1899
|
+
}, [resetData, options, disabled]);
|
|
2362
1900
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CapRow.default, {
|
|
2363
1901
|
className: className,
|
|
2364
1902
|
children: [renderHeader, /*#__PURE__*/(0, _jsxRuntime.jsx)(_antdV.TreeSelect, _extends({
|
|
@@ -3115,6 +2653,233 @@ module.exports = insertBySelector;
|
|
|
3115
2653
|
|
|
3116
2654
|
/***/ }),
|
|
3117
2655
|
|
|
2656
|
+
/***/ 8052:
|
|
2657
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
2658
|
+
|
|
2659
|
+
"use strict";
|
|
2660
|
+
|
|
2661
|
+
|
|
2662
|
+
exports.__esModule = true;
|
|
2663
|
+
exports.reorderOptionsBySelection = exports.findValueInOptions = exports.findMissingValues = exports.filterTreeData = exports.countSelectedLeaves = exports.buildTreeMaps = void 0;
|
|
2664
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
2665
|
+
/**
|
|
2666
|
+
* Builds tree maps for efficient tree operations
|
|
2667
|
+
* Creates maps for leaf values, parent-child relationships, and node lookups
|
|
2668
|
+
*/
|
|
2669
|
+
const buildTreeMaps = nodes => {
|
|
2670
|
+
const result = {
|
|
2671
|
+
leafValues: [],
|
|
2672
|
+
parentChildMap: {},
|
|
2673
|
+
nodeMap: {}
|
|
2674
|
+
};
|
|
2675
|
+
if (!nodes) return result;
|
|
2676
|
+
const traverse = items => {
|
|
2677
|
+
items == null || items.forEach(item => {
|
|
2678
|
+
if (item.value !== undefined) {
|
|
2679
|
+
result.nodeMap[item.value] = item;
|
|
2680
|
+
if (item != null && item.children && item.children.length > 0) {
|
|
2681
|
+
result.parentChildMap[item.value] = item.children.map(child => child == null ? void 0 : child.value).filter(v => v !== undefined);
|
|
2682
|
+
traverse(item.children);
|
|
2683
|
+
} else {
|
|
2684
|
+
result.leafValues.push(item.value);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
});
|
|
2688
|
+
};
|
|
2689
|
+
traverse(nodes);
|
|
2690
|
+
return result;
|
|
2691
|
+
};
|
|
2692
|
+
|
|
2693
|
+
/**
|
|
2694
|
+
* Counts the number of selected leaf nodes in a tree structure
|
|
2695
|
+
* Handles parent-child relationships by expanding selected parent nodes
|
|
2696
|
+
*/
|
|
2697
|
+
exports.buildTreeMaps = buildTreeMaps;
|
|
2698
|
+
const countSelectedLeaves = (treeMaps, selectedValues) => {
|
|
2699
|
+
var _treeMaps$leafValues;
|
|
2700
|
+
if (!Array.isArray(selectedValues) || !(selectedValues != null && selectedValues.length)) return 0;
|
|
2701
|
+
const expandedSet = new Set(selectedValues);
|
|
2702
|
+
const processNode = value => {
|
|
2703
|
+
var _treeMaps$parentChild;
|
|
2704
|
+
const children = treeMaps == null || (_treeMaps$parentChild = treeMaps.parentChildMap) == null ? void 0 : _treeMaps$parentChild[value];
|
|
2705
|
+
if (!children) return;
|
|
2706
|
+
children == null || children.forEach(childValue => {
|
|
2707
|
+
expandedSet.add(childValue);
|
|
2708
|
+
processNode(childValue);
|
|
2709
|
+
});
|
|
2710
|
+
};
|
|
2711
|
+
selectedValues == null || selectedValues.forEach(processNode);
|
|
2712
|
+
return (treeMaps == null || (_treeMaps$leafValues = treeMaps.leafValues) == null ? void 0 : _treeMaps$leafValues.reduce((count, leaf) => expandedSet.has(leaf) ? count + 1 : count, 0)) || 0;
|
|
2713
|
+
};
|
|
2714
|
+
|
|
2715
|
+
/**
|
|
2716
|
+
* Filters tree data based on search query
|
|
2717
|
+
* Includes nodes that match search OR are selected OR have matching children
|
|
2718
|
+
* Supports searching by label, value, or key
|
|
2719
|
+
*/
|
|
2720
|
+
exports.countSelectedLeaves = countSelectedLeaves;
|
|
2721
|
+
const filterTreeData = function (data, search, searchBasedOn, selectedValues) {
|
|
2722
|
+
if (searchBasedOn === void 0) {
|
|
2723
|
+
searchBasedOn = 'label';
|
|
2724
|
+
}
|
|
2725
|
+
if (!(data != null && data.length) || !search) return data;
|
|
2726
|
+
const searchLower = search.toLowerCase();
|
|
2727
|
+
const selectedSet = new Set(selectedValues || []);
|
|
2728
|
+
const nodeMatchesSearch = node => {
|
|
2729
|
+
var _node$value, _node$key, _ref, _node$label;
|
|
2730
|
+
const target = searchBasedOn === 'value' ? String((_node$value = node == null ? void 0 : node.value) != null ? _node$value : '') : searchBasedOn === 'key' ? String((_node$key = node == null ? void 0 : node.key) != null ? _node$key : '') : String((_ref = (_node$label = node == null ? void 0 : node.label) != null ? _node$label : node == null ? void 0 : node.title) != null ? _ref : '');
|
|
2731
|
+
return target.toLowerCase().includes(searchLower);
|
|
2732
|
+
};
|
|
2733
|
+
const isNodeSelected = node => {
|
|
2734
|
+
return node.value !== undefined && selectedSet.has(node.value);
|
|
2735
|
+
};
|
|
2736
|
+
const loop = items => items.reduce((acc, item) => {
|
|
2737
|
+
var _item$children;
|
|
2738
|
+
if (!item) return acc;
|
|
2739
|
+
const children = item != null && (_item$children = item.children) != null && _item$children.length ? loop(item.children) : [];
|
|
2740
|
+
// Include node if: matches search OR is selected OR has matching children
|
|
2741
|
+
if (nodeMatchesSearch(item) || isNodeSelected(item) || children.length) {
|
|
2742
|
+
acc.push(_extends({}, item, {
|
|
2743
|
+
children
|
|
2744
|
+
}));
|
|
2745
|
+
}
|
|
2746
|
+
return acc;
|
|
2747
|
+
}, []);
|
|
2748
|
+
return loop(data);
|
|
2749
|
+
};
|
|
2750
|
+
|
|
2751
|
+
/**
|
|
2752
|
+
* Checks if a value exists in options (recursive for tree structures)
|
|
2753
|
+
*/
|
|
2754
|
+
exports.filterTreeData = filterTreeData;
|
|
2755
|
+
const findValueInOptions = (opts, targetValue) => {
|
|
2756
|
+
for (const opt of opts) {
|
|
2757
|
+
if (opt.value === targetValue) {
|
|
2758
|
+
return true;
|
|
2759
|
+
}
|
|
2760
|
+
if (opt.children && opt.children.length > 0) {
|
|
2761
|
+
if (findValueInOptions(opt.children, targetValue)) {
|
|
2762
|
+
return true;
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
return false;
|
|
2767
|
+
};
|
|
2768
|
+
|
|
2769
|
+
/**
|
|
2770
|
+
* Finds selected values that don't exist in the current options
|
|
2771
|
+
*/
|
|
2772
|
+
exports.findValueInOptions = findValueInOptions;
|
|
2773
|
+
const findMissingValues = (selectedValues, currentOptions) => {
|
|
2774
|
+
if (!selectedValues.length || !currentOptions.length) {
|
|
2775
|
+
return selectedValues;
|
|
2776
|
+
}
|
|
2777
|
+
return selectedValues.filter(val => !findValueInOptions(currentOptions, val));
|
|
2778
|
+
};
|
|
2779
|
+
|
|
2780
|
+
/**
|
|
2781
|
+
* Reorders options based on selection order
|
|
2782
|
+
* Selected items are moved to top in the order they were selected
|
|
2783
|
+
* For tree structures, maintains parent-child relationships
|
|
2784
|
+
* For flat lists, directly reorders items
|
|
2785
|
+
* Works for all data types: flat lists, tree structures, nested trees
|
|
2786
|
+
*/
|
|
2787
|
+
exports.findMissingValues = findMissingValues;
|
|
2788
|
+
const reorderOptionsBySelection = (opts, selectedOrder) => {
|
|
2789
|
+
if (!Array.isArray(selectedOrder) || selectedOrder.length === 0 || !(opts != null && opts.length)) {
|
|
2790
|
+
return opts;
|
|
2791
|
+
}
|
|
2792
|
+
const selectedSet = new Set(selectedOrder);
|
|
2793
|
+
const selectedItems = [];
|
|
2794
|
+
const unselectedItems = [];
|
|
2795
|
+
const processedTopLevelValues = new Set();
|
|
2796
|
+
|
|
2797
|
+
// Deep clone helper to avoid mutating original items
|
|
2798
|
+
const deepCloneItem = item => {
|
|
2799
|
+
return _extends({}, item, {
|
|
2800
|
+
children: item.children ? item.children.map(deepCloneItem) : undefined
|
|
2801
|
+
});
|
|
2802
|
+
};
|
|
2803
|
+
|
|
2804
|
+
// Find the top-level item that contains the selected value
|
|
2805
|
+
// For flat lists, returns the item itself
|
|
2806
|
+
// For tree structures, returns the top-level parent from opts
|
|
2807
|
+
const findTopLevelItem = targetValue => {
|
|
2808
|
+
// First, find which top-level item in opts contains this value
|
|
2809
|
+
for (const topLevelItem of opts) {
|
|
2810
|
+
// Check if this top-level item itself matches
|
|
2811
|
+
if (topLevelItem.value === targetValue) {
|
|
2812
|
+
return topLevelItem;
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// Recursively search in children
|
|
2816
|
+
const searchInChildren = items => {
|
|
2817
|
+
for (const item of items) {
|
|
2818
|
+
if (item.value === targetValue) {
|
|
2819
|
+
return true; // Found it
|
|
2820
|
+
}
|
|
2821
|
+
if (item.children && item.children.length > 0) {
|
|
2822
|
+
if (searchInChildren(item.children)) {
|
|
2823
|
+
return true;
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
}
|
|
2827
|
+
return false;
|
|
2828
|
+
};
|
|
2829
|
+
|
|
2830
|
+
// If found in this top-level item's children, return the top-level item
|
|
2831
|
+
if (topLevelItem.children && topLevelItem.children.length > 0) {
|
|
2832
|
+
if (searchInChildren(topLevelItem.children)) {
|
|
2833
|
+
return topLevelItem;
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
}
|
|
2837
|
+
return null;
|
|
2838
|
+
};
|
|
2839
|
+
|
|
2840
|
+
// Check if an item or any of its descendants is selected
|
|
2841
|
+
const hasSelectedDescendant = item => {
|
|
2842
|
+
if (item.value !== undefined && selectedSet.has(item.value)) {
|
|
2843
|
+
return true;
|
|
2844
|
+
}
|
|
2845
|
+
if (item.children && item.children.length > 0) {
|
|
2846
|
+
return item.children.some(child => hasSelectedDescendant(child));
|
|
2847
|
+
}
|
|
2848
|
+
return false;
|
|
2849
|
+
};
|
|
2850
|
+
|
|
2851
|
+
// Collect selected items in selection order
|
|
2852
|
+
selectedOrder.forEach(selectedVal => {
|
|
2853
|
+
const topLevelItem = findTopLevelItem(selectedVal);
|
|
2854
|
+
if (topLevelItem && topLevelItem.value !== undefined && !processedTopLevelValues.has(topLevelItem.value)) {
|
|
2855
|
+
// Clone the item to avoid mutating the original
|
|
2856
|
+
const clonedItem = deepCloneItem(topLevelItem);
|
|
2857
|
+
selectedItems.push(clonedItem);
|
|
2858
|
+
processedTopLevelValues.add(topLevelItem.value);
|
|
2859
|
+
}
|
|
2860
|
+
});
|
|
2861
|
+
|
|
2862
|
+
// Collect unselected items maintaining original order
|
|
2863
|
+
// For tree structures, only include top-level items that don't have any selected descendants
|
|
2864
|
+
opts.forEach(item => {
|
|
2865
|
+
if (item.value === undefined) {
|
|
2866
|
+
// Item without value, include as-is
|
|
2867
|
+
unselectedItems.push(deepCloneItem(item));
|
|
2868
|
+
} else if (!processedTopLevelValues.has(item.value)) {
|
|
2869
|
+
// Check if this item or any of its descendants is selected
|
|
2870
|
+
if (!hasSelectedDescendant(item)) {
|
|
2871
|
+
unselectedItems.push(deepCloneItem(item));
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
});
|
|
2875
|
+
|
|
2876
|
+
// Return selected items first (in selection order), then unselected items
|
|
2877
|
+
return [...selectedItems, ...unselectedItems];
|
|
2878
|
+
};
|
|
2879
|
+
exports.reorderOptionsBySelection = reorderOptionsBySelection;
|
|
2880
|
+
|
|
2881
|
+
/***/ }),
|
|
2882
|
+
|
|
3118
2883
|
/***/ 8244:
|
|
3119
2884
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3120
2885
|
|
|
@@ -3197,7 +2962,7 @@ var ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ = __webpack_require__(1601);
|
|
|
3197
2962
|
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(6314);
|
|
3198
2963
|
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___);
|
|
3199
2964
|
// Module
|
|
3200
|
-
___CSS_LOADER_EXPORT___.push([module.id, `.blaze-ui-cap-unified-select-header-wrapper{display:flex;align-items:center}.blaze-ui-cap-unified-select-header-wrapper.blaze-ui-disabled{opacity:.5;cursor:not-allowed}.blaze-ui-cap-unified-select-header-wrapper .blaze-ui-cap-unified-select-header-label{font-family:"Roboto",sans-serif;font-weight:500;font-size:1rem;line-height:1.429rem;letter-spacing:0}.blaze-ui-cap-unified-select-header-byline-text{font-family:"Roboto",sans-serif;font-weight:400;font-size:.857rem;letter-spacing:0;color:#97a0af}.blaze-ui-cap-unified-select-container{text-align:justify;min-width:13.786rem}.blaze-ui-cap-unified-select-container.blaze-ui-disabled{cursor:not-allowed}.blaze-ui-cap-unified-select-container.ant-select-focused .ant-select-selector{border:.071rem solid #091e42 !important}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-more-text{cursor:pointer;color:#091e42;margin-right:.286rem;position:relative}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-suffix-icon{color:#7a869a}.blaze-ui-cap-unified-select-container .blaze-ui-cap-tooltip-with-info-icon{margin-top:.143rem}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select.blaze-ui-cap-unified-tree-select-readonly{pointer-events:none}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select.blaze-ui-cap-unified-tree-select-readonly .blaze-ui-cap-unified-select-more-text{pointer-events:auto}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select .ant-select-tree-treenode{padding-left:.286rem}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly .ant-select-selector{background-color:#fff;border-color:#ebecf0 !important;cursor:default}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly .ant-select-arrow{pointer-events:auto;color:#b3bac5}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:hover .ant-select-selector,.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:active .ant-select-selector,.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:focus .ant-select-selector{border-color:#ebecf0 !important}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-status{color:#ea213a}.blaze-ui-cap-unified-select-container .ant-select-outlined:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer):hover .ant-select-selector{border-color:#7a869a}.blaze-ui-cap-unified-select-container .ant-select-selector{background-color:#fff !important;border:.071rem solid #7a869a !important;border-radius:.286rem !important}.blaze-ui-cap-unified-select-container .ant-select-selector .ant-select-selection-placeholder{pointer-events:unset;color:#97a0af;display:flex;align-items:center}.blaze-ui-cap-unified-select-container .ant-select-prefix{font-size:1rem;font-weight:400;color:#091e42;line-height:1.429rem}.blaze-ui-cap-unified-select-container .ant-input-affix-wrapper .ant-input-prefix{left:.857rem}.blaze-ui-cap-unified-select-container .ant-select-selector{border-color:#7a869a !important;box-shadow:none !important;outline:0}.blaze-ui-cap-unified-select-container .ant-btn-variant-solid:not(:disabled):not(.ant-btn-disabled):hover{background-color:#47af46}.blaze-ui-cap-unified-select-container .ant-select-dropdown{margin-top:-0.571rem !important;border-radius:.286rem;background-color:#fff;box-shadow:0 .286rem .571rem -0.143rem rgba(9,30,66,.15),0 0 .071rem 0 rgba(9,30,66,.1);max-height:25.714rem;overflow:visible}.blaze-ui-cap-unified-select-container .ant-select-outlined.ant-select-multiple .ant-select-selection-wrap .ant-select-selection-item{background:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-container .ant-select-multiple .ant-select-selection-wrap .ant-select-selection-item,.blaze-ui-cap-unified-select-container .ant-select-selection-wrap .ant-select-selection-item{background:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-container .ant-select-multiple .ant-select-selection-wrap{align-self:center}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-search-container{border-bottom:.071rem solid #ebecf0 !important;line-height:2.857rem !important}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-search-container .blaze-ui-cap-unified-select-search-icon{color:#b3bac5}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-select-all-container{padding:.643rem 1.071rem;display:flex;align-items:center;border-bottom:.071rem solid #ebecf0;height:2.857rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-select-all-container .blaze-ui-cap-unified-select-select-all-checkbox{display:contents !important}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container{cursor:pointer;display:flex;align-items:center;border-bottom:.071rem solid #ebecf0;height:2.857rem;padding-left:1.143rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container .blaze-ui-cap-unified-select-upload-icon{color:#2466ea}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container .blaze-ui-cap-unified-select-upload-label{margin-left:.857rem;color:#2466ea}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container{display:flex;align-items:center;height:3.429rem;padding:.5rem;border-top:.071rem solid #ebecf0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group{display:flex;padding-left:.571rem;align-items:center;width:100%}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button{background-color:#47af46;height:2.286rem;width:6.714rem;color:#fff}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button:hover{background-color:#1f9a1d}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button:disabled{background-color:#a1d8a0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-cancel-button{border:rgba(0,0,0,0);box-shadow:none;width:5.714rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-selected-count{display:flex;margin-left:auto;font-size:.857rem;font-weight:400;line-height:1.143rem;color:#5e6c84}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container{display:flex;justify-content:center;align-items:center;height:2.857rem;border-top:.071rem solid #ebecf0;cursor:pointer;color:#091e42}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container:hover{background-color:#ebecf0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container .blaze-ui-cap-unified-select-tree-clear-label{font-size:1rem;font-weight:400}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container{cursor:pointer;display:flex;align-items:center;margin-left:auto;padding-right:1.143rem;gap:.857rem;flex-wrap:nowrap}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container:hover{opacity:.8}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container .blaze-ui-cap-unified-select-footer-download-icon{color:#2466ea;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;line-height:1}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container .blaze-ui-cap-unified-select-footer-download-label{color:#2466ea;font-family:Roboto,sans-serif;font-weight:400;font-style:normal;font-size:.857rem;line-height:1.143rem;letter-spacing:0;white-space:nowrap;display:inline-flex;align-items:center}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-no-result{display:flex;flex-direction:column;align-items:center;justify-content:center;height:14.286rem;color:#97a0af;font-size:1rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-no-result .blaze-ui-cap-unified-select-no-result-text{font-weight:500}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:14.286rem;width:100%;gap:.571rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-more{display:flex;align-items:center;justify-content:center;padding:.857rem;border-top:.071rem solid #ebecf0;color:#97a0af}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-menu-wrapper{position:relative;width:100%}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background-color:rgba(255,255,255,.8);z-index:10;gap:.571rem;color:#97a0af}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix{display:flex;justify-content:start;align-items:center;width:100%;height:100%;line-height:1.5;vertical-align:middle;flex:1}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-label{display:flex;align-items:center;flex-shrink:1;min-width:0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-end{display:flex;align-items:center;gap:.571rem;flex-shrink:0;margin-left:auto}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-suffix{display:flex;align-items:center;padding:0 .571rem;max-height:1.429rem;white-space:nowrap}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-tooltip-with-info .blaze-ui-cap-tooltip-with-info-icon{margin-top:.357rem;color:#42526e}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-tooltip-with-info .blaze-ui-cap-tooltip-with-info-icon .blaze-ui-cap-icon{color:#42526e}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu{margin-top:0 !important}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu .ant-select-dropdown-menu-item{padding:.571rem 1.714rem !important;height:unset !important;font-size:1rem !important}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu-item-disabled{color:rgba(0,0,0,.25) !important;cursor:not-allowed !important;line-height:1.428rem !important;font-size:1rem !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper{background-color:rgba(0,0,0,0);height:100%;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode{height:2.857rem;margin-bottom:0;display:flex;align-items:center;width:100%}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode:hover{background-color:#fffbe6}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-selected{background-color:#f4f5f7 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled{cursor:not-allowed !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled .blaze-ui-cap-unified-select-option-label{color:#b3bac5}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled .blaze-ui-cap-icon{color:#b3bac5 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode.ant-select-tree-treenode-selected{background-color:#f4f5f7}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-leaf .ant-select-tree-switcher-noop{display:none}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox{display:flex;align-items:center;justify-content:center;line-height:1;vertical-align:middle}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox .ant-select-tree-checkbox-inner{height:1.286rem;width:1.286rem;border:.143rem solid #b3bac5;border-radius:.286rem;display:flex;align-items:center;justify-content:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox-checked .ant-select-tree-checkbox-inner{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox-checked .ant-select-tree-checkbox-inner:hover{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox.ant-select-tree-checkbox-indeterminate .ant-select-tree-checkbox-inner{background-color:#47af46 !important;border-color:#47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox.ant-select-tree-checkbox-indeterminate .ant-select-tree-checkbox-inner::after{content:"";position:absolute;top:50%;left:50%;width:.714rem;height:.143rem;background-color:#fff;transform:translate(-50%, -50%);border-radius:.071rem}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper{border-radius:0;padding-left:.214rem;width:100%;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper .ant-select-tree-title{width:100%;display:flex}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-indent{margin-left:.857rem;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher{display:flex;align-items:center;justify-content:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher:not(.ant-select-tree-switcher-noop):hover:before{background-color:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher .ant-select-tree-switcher-icon{font-size:.857rem;margin-top:1.286rem}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-list-holder-inner{width:fit-content !important;min-width:100%}.blaze-ui-cap-unified-select-popup .ant-tree-select:hover .ant-select-selector{border-color:#7a869a}.blaze-ui-cap-unified-select-popup .ant-tree-select-focused .ant-select-selector,.blaze-ui-cap-unified-select-popup .ant-tree-select-open .ant-select-selector{border-color:#7a869a;box-shadow:none;outline:none}.blaze-ui-cap-unified-select-popup .ant-checkbox-inner{height:1.286rem;width:1.286rem;border:.143rem solid #b3bac5;border-radius:.286rem}.blaze-ui-cap-unified-select-popup .ant-checkbox-wrapper:not(.ant-checkbox-wrapper-disabled):hover .ant-checkbox-checked:not(.ant-checkbox-disabled) .ant-checkbox-inner{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-checkbox-indeterminate .ant-checkbox-inner{background-color:#47af46 !important;border-color:#47af46 !important}.blaze-ui-cap-unified-select-popup .ant-checkbox-indeterminate .ant-checkbox-inner::after{content:"";position:absolute;top:50%;left:50%;width:.714rem;height:.143rem;background-color:#fff;transform:translate(-50%, -50%);border-radius:.071rem}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper{padding-left:.571rem;border:none;box-shadow:none;border-radius:0;border-bottom:.071rem solid rgba(0,0,0,0);transition:border-color .2s ease}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper:hover{border-bottom:.071rem solid #7a869a !important;box-shadow:none}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper:focus-within{border-bottom:.071rem solid #091e42 !important;box-shadow:none;outline:none}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper .ant-input{border:none !important;box-shadow:none !important}`, ""]);
|
|
2965
|
+
___CSS_LOADER_EXPORT___.push([module.id, `.blaze-ui-cap-unified-select-header-wrapper{display:flex;align-items:center}.blaze-ui-cap-unified-select-header-wrapper.blaze-ui-disabled{opacity:.5;cursor:not-allowed}.blaze-ui-cap-unified-select-header-wrapper .blaze-ui-cap-unified-select-header-label{font-family:"Roboto",sans-serif;font-weight:500;font-size:1rem;line-height:1.429rem;letter-spacing:0}.blaze-ui-cap-unified-select-header-byline-text{font-family:"Roboto",sans-serif;font-weight:400;font-size:.857rem;letter-spacing:0;color:#97a0af}.blaze-ui-cap-unified-select-container{text-align:justify;min-width:13.786rem}.blaze-ui-cap-unified-select-container.blaze-ui-disabled{cursor:not-allowed}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-more-text{cursor:pointer;color:#091e42;margin-right:.286rem;position:relative}.blaze-ui-cap-unified-select-container.ant-select-disabled .blaze-ui-cap-unified-select-more-text{color:unset !important;cursor:not-allowed}.blaze-ui-cap-unified-select-container.ant-select-focused .ant-select-selector{border:.071rem solid #091e42 !important}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-suffix-icon{color:#7a869a}.blaze-ui-cap-unified-select-container .blaze-ui-cap-tooltip-with-info-icon{margin-top:.143rem}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select.blaze-ui-cap-unified-tree-select-readonly{pointer-events:none}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select.blaze-ui-cap-unified-tree-select-readonly .blaze-ui-cap-unified-select-more-text{pointer-events:auto;color:unset !important}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select .ant-select-tree-treenode{padding-left:.286rem}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly .ant-select-selector{background-color:#fff;border-color:#ebecf0 !important;cursor:default}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly .ant-select-arrow{pointer-events:auto;color:#b3bac5}.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:hover .ant-select-selector,.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:active .ant-select-selector,.blaze-ui-cap-unified-select-container.blaze-ui-cap-unified-tree-select-readonly.ant-select-outlined:focus .ant-select-selector{border-color:#ebecf0 !important}.blaze-ui-cap-unified-select-container .blaze-ui-cap-unified-select-status{color:#ea213a}.blaze-ui-cap-unified-select-container .ant-select-outlined:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer):hover .ant-select-selector{border-color:#7a869a}.blaze-ui-cap-unified-select-container .ant-select-selector{background-color:#fff !important;border:.071rem solid #7a869a !important;border-radius:.286rem !important}.blaze-ui-cap-unified-select-container .ant-select-selector .ant-select-selection-placeholder{pointer-events:unset;color:#97a0af;display:flex;align-items:center}.blaze-ui-cap-unified-select-container .ant-select-prefix{font-size:1rem;font-weight:400;color:unset !important;line-height:1.429rem}.blaze-ui-cap-unified-select-container .ant-select-disabled .ant-select-prefix{color:unset !important}.blaze-ui-cap-unified-select-container .ant-input-affix-wrapper .ant-input-prefix{left:.857rem}.blaze-ui-cap-unified-select-container .ant-select-selector{border-color:#7a869a !important;box-shadow:none !important;outline:0}.blaze-ui-cap-unified-select-container .ant-btn-variant-solid:not(:disabled):not(.ant-btn-disabled):hover{background-color:#47af46}.blaze-ui-cap-unified-select-container .ant-select-dropdown{margin-top:-0.571rem !important;border-radius:.286rem;background-color:#fff;box-shadow:0 .286rem .571rem -0.143rem rgba(9,30,66,.15),0 0 .071rem 0 rgba(9,30,66,.1);max-height:25.714rem;overflow:visible}.blaze-ui-cap-unified-select-container .ant-select-outlined.ant-select-multiple .ant-select-selection-wrap .ant-select-selection-item{background:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-container .ant-select-multiple .ant-select-selection-wrap .ant-select-selection-item,.blaze-ui-cap-unified-select-container .ant-select-selection-wrap .ant-select-selection-item{background:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-container .ant-select-multiple .ant-select-selection-wrap{align-self:center}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-search-container{border-bottom:.071rem solid #ebecf0 !important;line-height:2.857rem !important}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-search-container .blaze-ui-cap-unified-select-search-icon{color:#b3bac5}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-select-all-container{padding:.643rem 1.071rem;display:flex;align-items:center;border-bottom:.071rem solid #ebecf0;height:2.857rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-select-all-container .blaze-ui-cap-unified-select-select-all-checkbox{display:contents !important}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container{cursor:pointer;display:flex;align-items:center;border-bottom:.071rem solid #ebecf0;height:2.857rem;padding-left:1.143rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container .blaze-ui-cap-unified-select-upload-icon{color:#2466ea}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-upload-container .blaze-ui-cap-unified-select-upload-label{margin-left:.857rem;color:#2466ea}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container{display:flex;align-items:center;height:3.429rem;padding:.5rem;border-top:.071rem solid #ebecf0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group{display:flex;padding-left:.571rem;align-items:center;width:100%}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button{background-color:#47af46;height:2.286rem;width:6.714rem;color:#fff}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button:hover{background-color:#1f9a1d}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-confirm-button:disabled{background-color:#a1d8a0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-cancel-button{border:rgba(0,0,0,0);box-shadow:none;width:5.714rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-confirm-container .blaze-ui-cap-unified-select-confirm-button-group .blaze-ui-cap-unified-select-selected-count{display:flex;margin-left:auto;font-size:.857rem;font-weight:400;line-height:1.143rem;color:#5e6c84}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container{display:flex;justify-content:center;align-items:center;height:2.857rem;border-top:.071rem solid #ebecf0;cursor:pointer;color:#091e42}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container:hover{background-color:#ebecf0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-tree-clear-container .blaze-ui-cap-unified-select-tree-clear-label{font-size:1rem;font-weight:400}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container{cursor:pointer;display:flex;align-items:center;margin-left:auto;padding-right:1.143rem;gap:.857rem;flex-wrap:nowrap}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container:hover{opacity:.8}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container .blaze-ui-cap-unified-select-footer-download-icon{color:#2466ea;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;line-height:1}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-footer-download-container .blaze-ui-cap-unified-select-footer-download-label{color:#2466ea;font-family:Roboto,sans-serif;font-weight:400;font-style:normal;font-size:.857rem;line-height:1.143rem;letter-spacing:0;white-space:nowrap;display:inline-flex;align-items:center}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-no-result{display:flex;flex-direction:column;align-items:center;justify-content:center;height:14.286rem;color:#97a0af;font-size:1rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-no-result .blaze-ui-cap-unified-select-no-result-text{font-weight:500}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;height:14.286rem;width:100%;gap:.571rem}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-more{display:flex;align-items:center;justify-content:center;padding:.857rem;border-top:.071rem solid #ebecf0;color:#97a0af}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-menu-wrapper{position:relative;width:100%}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background-color:rgba(255,255,255,.8);z-index:10;gap:.571rem;color:#97a0af}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix{display:flex;justify-content:start;align-items:center;width:100%;height:100%;line-height:1.5;vertical-align:middle;flex:1}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-label{display:flex;align-items:center;flex-shrink:1;min-width:0}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-end{display:flex;align-items:center;gap:.571rem;flex-shrink:0;margin-left:auto}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-unified-select-option-suffix{display:flex;align-items:center;padding:0 .571rem;max-height:1.429rem;white-space:nowrap}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-tooltip-with-info .blaze-ui-cap-tooltip-with-info-icon{margin-top:.357rem;color:#42526e}.blaze-ui-cap-unified-select-popup .blaze-ui-cap-unified-select-option-with-suffix .blaze-ui-cap-tooltip-with-info .blaze-ui-cap-tooltip-with-info-icon .blaze-ui-cap-icon{color:#42526e}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu{margin-top:0 !important}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu .ant-select-dropdown-menu-item{padding:.571rem 1.714rem !important;height:unset !important;font-size:1rem !important}.blaze-ui-cap-unified-select-popup .ant-select-dropdown .ant-select-dropdown-menu-item-disabled{color:rgba(0,0,0,.25) !important;cursor:not-allowed !important;line-height:1.428rem !important;font-size:1rem !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper{background-color:rgba(0,0,0,0);height:100%;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper:hover{background-color:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-active .ant-select-tree-node-content-wrapper{background-color:rgba(0,0,0,0) !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode{height:2.857rem;margin-bottom:0;display:flex;align-items:center;width:100%}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode:hover{background-color:#fffbe6}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-selected{background-color:#f4f5f7 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled{cursor:not-allowed !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled .blaze-ui-cap-unified-select-option-label{color:#b3bac5}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-disabled .blaze-ui-cap-icon{color:#b3bac5 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode.ant-select-tree-treenode-selected{background-color:#f4f5f7}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-treenode-leaf .ant-select-tree-switcher-noop{display:none}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox{display:flex;align-items:center;justify-content:center;line-height:1;vertical-align:middle}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox .ant-select-tree-checkbox-inner{height:1.286rem;width:1.286rem;border:.143rem solid #b3bac5;border-radius:.286rem;display:flex;align-items:center;justify-content:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox-checked .ant-select-tree-checkbox-inner{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox-checked .ant-select-tree-checkbox-inner:hover{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox.ant-select-tree-checkbox-indeterminate .ant-select-tree-checkbox-inner{background-color:#47af46 !important;border-color:#47af46 !important}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-checkbox.ant-select-tree-checkbox-indeterminate .ant-select-tree-checkbox-inner::after{content:"";position:absolute;top:50%;left:50%;width:.714rem;height:.143rem;background-color:#fff;transform:translate(-50%, -50%);border-radius:.071rem}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper{border-radius:0;padding-left:.214rem;width:100%;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-node-content-wrapper .ant-select-tree-title{width:100%;display:flex}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-indent{margin-left:.857rem;display:flex;align-items:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher{display:flex;align-items:center;justify-content:center}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher:not(.ant-select-tree-switcher-noop):hover:before{background-color:rgba(0,0,0,0)}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-switcher .ant-select-tree-switcher-icon{font-size:.857rem;margin-top:1.286rem}.blaze-ui-cap-unified-select-popup .ant-select-tree .ant-select-tree-list-holder-inner{width:fit-content !important;min-width:100%}.blaze-ui-cap-unified-select-popup .ant-tree-select:hover .ant-select-selector{border-color:#7a869a}.blaze-ui-cap-unified-select-popup .ant-tree-select-focused .ant-select-selector,.blaze-ui-cap-unified-select-popup .ant-tree-select-open .ant-select-selector{border-color:#7a869a;box-shadow:none;outline:none}.blaze-ui-cap-unified-select-popup .ant-checkbox-inner{height:1.286rem;width:1.286rem;border:.143rem solid #b3bac5;border-radius:.286rem}.blaze-ui-cap-unified-select-popup .ant-checkbox-wrapper:not(.ant-checkbox-wrapper-disabled):hover .ant-checkbox-checked:not(.ant-checkbox-disabled) .ant-checkbox-inner{background-color:#47af46;border:.143rem solid #47af46 !important}.blaze-ui-cap-unified-select-popup .ant-checkbox-indeterminate .ant-checkbox-inner{background-color:#47af46 !important;border-color:#47af46 !important}.blaze-ui-cap-unified-select-popup .ant-checkbox-indeterminate .ant-checkbox-inner::after{content:"";position:absolute;top:50%;left:50%;width:.714rem;height:.143rem;background-color:#fff;transform:translate(-50%, -50%);border-radius:.071rem}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper{padding-left:.571rem;border:none;box-shadow:none;border-radius:0;border-bottom:.071rem solid rgba(0,0,0,0);transition:border-color .2s ease}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper:hover{border-bottom:.071rem solid #7a869a !important;box-shadow:none}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper:focus-within{border-bottom:.071rem solid #091e42 !important;box-shadow:none;outline:none}.blaze-ui-cap-unified-select-popup .ant-input-affix-wrapper .ant-input{border:none !important;box-shadow:none !important}`, ""]);
|
|
3201
2966
|
// Exports
|
|
3202
2967
|
___CSS_LOADER_EXPORT___.locals = {
|
|
3203
2968
|
"cap-unified-select-header-wrapper": `blaze-ui-cap-unified-select-header-wrapper`,
|
|
@@ -3255,62 +3020,33 @@ module.exports = ___CSS_LOADER_EXPORT___;
|
|
|
3255
3020
|
|
|
3256
3021
|
exports.__esModule = true;
|
|
3257
3022
|
exports.TIMEOUTS = exports.SELECT_TYPES = exports.DEFAULTS = void 0;
|
|
3258
|
-
/**
|
|
3259
|
-
* Select type constants for CapUnifiedSelect component
|
|
3260
|
-
*/
|
|
3261
3023
|
const SELECT_TYPES = exports.SELECT_TYPES = {
|
|
3262
3024
|
SELECT: 'select',
|
|
3263
3025
|
MULTI_SELECT: 'multiSelect',
|
|
3264
3026
|
TREE_SELECT: 'treeSelect',
|
|
3265
3027
|
MULTI_TREE_SELECT: 'multiTreeSelect'
|
|
3266
3028
|
};
|
|
3267
|
-
/**
|
|
3268
|
-
* Timeout constants (in milliseconds)
|
|
3269
|
-
*/
|
|
3270
3029
|
const TIMEOUTS = exports.TIMEOUTS = {
|
|
3271
|
-
/** Default search debounce timeout */
|
|
3272
3030
|
DEFAULT_SEARCH_DEBOUNCE: 300,
|
|
3273
|
-
/** Delay for state updates after search */
|
|
3274
3031
|
SEARCH_STATE_UPDATE_DELAY: 100,
|
|
3275
|
-
/** Minimum time since search was cleared to consider data ready */
|
|
3276
3032
|
SEARCH_CLEARED_TIMEOUT: 200,
|
|
3277
|
-
/** Buffer time added to debounce for cleared search */
|
|
3278
3033
|
SEARCH_CLEARED_BUFFER: 300,
|
|
3279
|
-
/** Buffer time added to debounce for regular search */
|
|
3280
3034
|
SEARCH_REGULAR_BUFFER: 500,
|
|
3281
|
-
/** Brief delay to show loading indicator for static search */
|
|
3282
3035
|
STATIC_SEARCH_DELAY: 150,
|
|
3283
|
-
/** Timeout for resetData fallback (1 second) */
|
|
3284
3036
|
RESET_DATA_TIMEOUT: 1000,
|
|
3285
|
-
/** Minimum time since resetData was called to consider data ready */
|
|
3286
3037
|
RESET_DATA_MIN_TIME: 300,
|
|
3287
|
-
/** Maximum time since resetData was called to consider data ready */
|
|
3288
3038
|
RESET_DATA_MAX_TIME: 2000,
|
|
3289
|
-
/** Fallback timeout for scroll loading (10 seconds) */
|
|
3290
3039
|
SCROLL_LOADING_TIMEOUT: 10000,
|
|
3291
|
-
/** Delay before setting up scroll container listener */
|
|
3292
3040
|
SCROLL_CONTAINER_DELAY: 100
|
|
3293
3041
|
};
|
|
3294
|
-
|
|
3295
|
-
/**
|
|
3296
|
-
* Default values for component props
|
|
3297
|
-
*/
|
|
3298
3042
|
const DEFAULTS = exports.DEFAULTS = {
|
|
3299
|
-
/** Default placeholder text */
|
|
3300
3043
|
PLACEHOLDER: 'Select an option',
|
|
3301
|
-
/** Default upload button label */
|
|
3302
3044
|
UPLOAD_LABEL: 'Upload',
|
|
3303
|
-
/** Default clear button text */
|
|
3304
3045
|
CLEAR_TEXT: 'Clear',
|
|
3305
|
-
/** Default no results message */
|
|
3306
3046
|
NO_RESULT_TEXT: 'No results found',
|
|
3307
|
-
/** Default no results icon */
|
|
3308
3047
|
NO_RESULT_ICON: 'warning',
|
|
3309
|
-
/** Default virtual row height in pixels */
|
|
3310
3048
|
VIRTUAL_ROW_HEIGHT: 32,
|
|
3311
|
-
/** Default list height in pixels */
|
|
3312
3049
|
LIST_HEIGHT: 256,
|
|
3313
|
-
/** Default search input placeholder */
|
|
3314
3050
|
SEARCH_PLACEHOLDER: 'Search'
|
|
3315
3051
|
};
|
|
3316
3052
|
|