ui-soxo-bootstrap-core 2.6.24 → 2.6.25
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.
|
@@ -600,7 +600,7 @@ function UserInput({ field, onUpload, selectedInformation, onChange, onFieldUpda
|
|
|
600
600
|
|
|
601
601
|
> */}
|
|
602
602
|
{isVisible === true ? (
|
|
603
|
-
<div className=
|
|
603
|
+
<div className={`form-item-element ${field.type === 'search' ? 'form-item-element-search' : ''}`}>
|
|
604
604
|
|
|
605
605
|
{/* <Button
|
|
606
606
|
size="small"
|
package/core/modules/reporting/components/reporting-dashboard/adavance-search/advance-search.js
CHANGED
|
@@ -5,6 +5,7 @@ import { CoreScripts } from "../../../../../models";
|
|
|
5
5
|
import "./advance-search.scss";
|
|
6
6
|
|
|
7
7
|
const { Search } = Input;
|
|
8
|
+
const advancedSearchCache = {};
|
|
8
9
|
|
|
9
10
|
export default function AdvancedSearchSelect({ reportId, onReset, field, value, onChange, style, ...rest }) {
|
|
10
11
|
// Normalize the configuration.
|
|
@@ -17,14 +18,31 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
17
18
|
const isSearchQuery = !!config.search_query;
|
|
18
19
|
const fieldName = isObjectMode ? field.field : field;
|
|
19
20
|
const caption = config.caption;
|
|
21
|
+
const cacheKey = `${finalReportId || "no-report"}::${fieldName || "no-field"}`;
|
|
20
22
|
|
|
21
23
|
const safeValue = Array.isArray(value) ? value : [];
|
|
24
|
+
const cachedState = advancedSearchCache[cacheKey] || { optionLabels: {}, displayOptions: [] };
|
|
22
25
|
|
|
23
26
|
const [searchResults, setSearchResults] = useState([]);
|
|
24
|
-
const [displayOptions, setDisplayOptions] = useState(
|
|
25
|
-
const [optionLabels, setOptionLabels] = useState(
|
|
27
|
+
const [displayOptions, setDisplayOptions] = useState(cachedState.displayOptions);
|
|
28
|
+
const [optionLabels, setOptionLabels] = useState(cachedState.optionLabels);
|
|
26
29
|
const [loading, setLoading] = useState(false);
|
|
27
30
|
const debounceRef = useRef(null);
|
|
31
|
+
const missingLabelsFetchRef = useRef("");
|
|
32
|
+
|
|
33
|
+
const mergeDisplayOptions = (apiOptions = [], selectedValues = safeValue, labels = optionLabels) => {
|
|
34
|
+
const selectedOptions = selectedValues
|
|
35
|
+
.filter((item) => labels[item])
|
|
36
|
+
.map((item) => ({
|
|
37
|
+
search_value: item,
|
|
38
|
+
display_value: labels[item],
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
return [...selectedOptions, ...apiOptions].filter(
|
|
42
|
+
(item, index, array) =>
|
|
43
|
+
array.findIndex((entry) => entry.search_value === item.search_value) === index
|
|
44
|
+
);
|
|
45
|
+
};
|
|
28
46
|
|
|
29
47
|
const loadOptions = async (searchText = "") => {
|
|
30
48
|
try {
|
|
@@ -38,24 +56,21 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
38
56
|
|
|
39
57
|
const res = await CoreScripts.getQuerySeacch(formBody);
|
|
40
58
|
const data = Array.isArray(res.data) ? res.data : [];
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
setSearchResults(apiValues);
|
|
44
|
-
setDisplayOptions(data);
|
|
45
|
-
setOptionLabels((prev) => ({
|
|
46
|
-
...prev,
|
|
59
|
+
const nextLabels = {
|
|
60
|
+
...optionLabels,
|
|
47
61
|
...data.reduce((acc, item) => {
|
|
48
62
|
acc[item.search_value] = item.display_value;
|
|
49
63
|
return acc;
|
|
50
64
|
}, {}),
|
|
51
|
-
}
|
|
65
|
+
};
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
setSearchResults(data.map((item) => item.search_value));
|
|
68
|
+
setOptionLabels(nextLabels);
|
|
69
|
+
setDisplayOptions(mergeDisplayOptions(data, safeValue, nextLabels));
|
|
70
|
+
advancedSearchCache[cacheKey] = {
|
|
71
|
+
optionLabels: nextLabels,
|
|
72
|
+
displayOptions: mergeDisplayOptions(data, safeValue, nextLabels),
|
|
73
|
+
};
|
|
59
74
|
} catch (error) {
|
|
60
75
|
console.error("Search API error", error);
|
|
61
76
|
} finally {
|
|
@@ -64,26 +79,58 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
64
79
|
};
|
|
65
80
|
|
|
66
81
|
useEffect(() => {
|
|
67
|
-
//
|
|
68
|
-
// but do not load automatically on mount.
|
|
82
|
+
// Restore cached labels/options for the current field after remounts like submit refreshes.
|
|
69
83
|
setSearchResults([]);
|
|
70
|
-
|
|
84
|
+
setOptionLabels(cachedState.optionLabels || {});
|
|
85
|
+
setDisplayOptions(cachedState.displayOptions || []);
|
|
86
|
+
missingLabelsFetchRef.current = "";
|
|
87
|
+
}, [cacheKey]);
|
|
71
88
|
|
|
72
89
|
useEffect(() => {
|
|
73
90
|
// FormCreator can remount this field after submit with only search_value(s).
|
|
74
91
|
// If any selected value is missing a label, fetch the option list once to recover display_value.
|
|
75
|
-
const
|
|
92
|
+
const missingValues = safeValue.filter((item) => !optionLabels[item]);
|
|
93
|
+
const missingKey = missingValues.join("||");
|
|
76
94
|
|
|
77
|
-
if (isSearchQuery
|
|
95
|
+
if (!isSearchQuery || safeValue.length === 0 || missingValues.length === 0) {
|
|
96
|
+
missingLabelsFetchRef.current = "";
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (missingLabelsFetchRef.current === missingKey) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
missingLabelsFetchRef.current = missingKey;
|
|
105
|
+
if (isSearchQuery && safeValue.length > 0) {
|
|
78
106
|
loadOptions("");
|
|
79
107
|
}
|
|
80
108
|
}, [isSearchQuery, safeValue, optionLabels]);
|
|
81
109
|
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (!isSearchQuery || safeValue.length === 0) return;
|
|
112
|
+
|
|
113
|
+
setDisplayOptions((prev) => {
|
|
114
|
+
const nextDisplayOptions = mergeDisplayOptions(prev, safeValue, optionLabels);
|
|
115
|
+
advancedSearchCache[cacheKey] = {
|
|
116
|
+
optionLabels,
|
|
117
|
+
displayOptions: nextDisplayOptions,
|
|
118
|
+
};
|
|
119
|
+
return nextDisplayOptions;
|
|
120
|
+
});
|
|
121
|
+
}, [cacheKey, isSearchQuery, safeValue, optionLabels]);
|
|
122
|
+
|
|
82
123
|
const handleSearch = (text) => {
|
|
83
124
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
84
125
|
debounceRef.current = setTimeout(() => loadOptions(text), 400);
|
|
85
126
|
};
|
|
86
127
|
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
return () => {
|
|
130
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
131
|
+
};
|
|
132
|
+
}, []);
|
|
133
|
+
|
|
87
134
|
const toggleValue = (checked, item) => {
|
|
88
135
|
let newValues;
|
|
89
136
|
|
|
@@ -143,6 +190,7 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
143
190
|
className={`advanced-search-select ${isActive ? "advanced-search-active" : ""}`}
|
|
144
191
|
style={style}
|
|
145
192
|
mode="multiple"
|
|
193
|
+
showSearch={false}
|
|
146
194
|
value={safeValue}
|
|
147
195
|
options={selectOptions}
|
|
148
196
|
placeholder={caption}
|
|
@@ -152,10 +200,7 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
152
200
|
} else {
|
|
153
201
|
// When closing, re-sort selected items to the top so they are visible next time it opens
|
|
154
202
|
const currentResults = displayOptions.length > 0 ? displayOptions : [];
|
|
155
|
-
setDisplayOptions(
|
|
156
|
-
...currentResults.filter((item) => safeValue.includes(item.search_value)),
|
|
157
|
-
...currentResults.filter((item) => !safeValue.includes(item.search_value)),
|
|
158
|
-
]);
|
|
203
|
+
setDisplayOptions(mergeDisplayOptions(currentResults, safeValue, optionLabels));
|
|
159
204
|
}
|
|
160
205
|
}}
|
|
161
206
|
allowClear
|
|
@@ -171,6 +216,10 @@ export default function AdvancedSearchSelect({ reportId, onReset, field, value,
|
|
|
171
216
|
<Search
|
|
172
217
|
placeholder={`Search ${caption}`}
|
|
173
218
|
onChange={(e) => handleSearch(e.target.value)}
|
|
219
|
+
onKeyDown={(e) => {
|
|
220
|
+
// Prevent the parent Select from treating backspace as "remove last selected tag".
|
|
221
|
+
e.stopPropagation();
|
|
222
|
+
}}
|
|
174
223
|
/>
|
|
175
224
|
|
|
176
225
|
<div className="dropdown-options-list">
|