@ryuzaki13/react-foundation-ui 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced-search/index.js +90 -89
- package/dist/advanced-search/index.js.map +1 -1
- package/dist/chunks/Select-BJ5OqTe7.js +182 -0
- package/dist/chunks/Select-BJ5OqTe7.js.map +1 -0
- package/dist/chunks/{SerializableSelect-DkYeJtAO.js → SerializableSelect-CNe728Qa.js} +2 -2
- package/dist/chunks/{SerializableSelect-DkYeJtAO.js.map → SerializableSelect-CNe728Qa.js.map} +1 -1
- package/dist/chunks/{StateSelect-1jH3uLz9.js → StateSelect-ujAre258.js} +2 -2
- package/dist/chunks/{StateSelect-1jH3uLz9.js.map → StateSelect-ujAre258.js.map} +1 -1
- package/dist/chunks/multi-select-BYsbh2ca.js +126 -0
- package/dist/chunks/multi-select-BYsbh2ca.js.map +1 -0
- package/dist/chunks/{multi-select-BzYIviCU.js → odata-DSW7z3nh.js} +373 -569
- package/dist/chunks/odata-DSW7z3nh.js.map +1 -0
- package/dist/chunks/select-BkLc6dyx.js +81 -0
- package/dist/chunks/select-BkLc6dyx.js.map +1 -0
- package/dist/chunks/useODataSelectBase-BbeKdq6x.js +125 -0
- package/dist/chunks/useODataSelectBase-BbeKdq6x.js.map +1 -0
- package/dist/expandable-action-panel/stories/ExpandableActionPanel.stories.js +1 -1
- package/dist/multi-select/index.js +3 -3
- package/dist/preset-select/index.js +1 -1
- package/dist/preset-select/index.js.map +1 -1
- package/dist/select/Select.d.ts +10 -5
- package/dist/select/Select.d.ts.map +1 -1
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.d.ts.map +1 -1
- package/dist/select/index.js +4 -3
- package/dist/select/stories/Select.stories.d.ts +1 -1
- package/dist/select/stories/Select.stories.js +1 -1
- package/dist/select/stories/SerializableSelect.stories.js +1 -1
- package/dist/state-select/index.js +1 -1
- package/dist/state-select/stories/StateSelect.stories.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tree-select/index.d.ts +2 -0
- package/dist/tree-select/index.d.ts.map +1 -1
- package/dist/tree-select/index.js +173 -4
- package/dist/tree-select/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/Select-CXeVjVKA.js +0 -182
- package/dist/chunks/Select-CXeVjVKA.js.map +0 -1
- package/dist/chunks/multi-select-BzYIviCU.js.map +0 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { n as
|
|
4
|
-
import { i as
|
|
5
|
-
import { t as
|
|
6
|
-
import { r as
|
|
7
|
-
import { c
|
|
8
|
-
import { t as
|
|
9
|
-
import { c as
|
|
10
|
-
import { a as
|
|
1
|
+
import { s as e, t } from "../chunks/odata-DSW7z3nh.js";
|
|
2
|
+
import { t as n } from "../chunks/ui.module-BisoTevy.js";
|
|
3
|
+
import { n as r, t as i } from "../chunks/BadgeList-DYgun2rf.js";
|
|
4
|
+
import { i as a } from "../chunks/Flex-DUYSL5TE.js";
|
|
5
|
+
import { t as o } from "../chunks/Button-CCWuggdA.js";
|
|
6
|
+
import { r as s } from "../chunks/Grid-ByIIytjh.js";
|
|
7
|
+
import { c, l } from "../chunks/Input-BmjlpA09.js";
|
|
8
|
+
import { t as u } from "../chunks/input-search-Dw4rnJBq.js";
|
|
9
|
+
import { c as d } from "../chunks/misc-DoqZBMof.js";
|
|
10
|
+
import { a as f, i as p, n as m, r as h } from "../chunks/modal-ByNRME3b.js";
|
|
11
|
+
import { n as g } from "../chunks/multi-select-BYsbh2ca.js";
|
|
11
12
|
import { t as _ } from "../chunks/table-Dc3AqMzP.js";
|
|
12
13
|
import { useCallback as v, useEffect as y, useMemo as b, useState as x } from "react";
|
|
13
14
|
import { cn as S } from "@ryuzaki13/react-foundation-lib/utils";
|
|
@@ -41,39 +42,39 @@ function P(e, t, n) {
|
|
|
41
42
|
//#endregion
|
|
42
43
|
//#region src/advanced-search/model/useAdvancedSearch.ts
|
|
43
44
|
var F = 50;
|
|
44
|
-
function I(
|
|
45
|
-
let [
|
|
45
|
+
function I(t) {
|
|
46
|
+
let [n, r] = x(""), [i, a] = x(() => Object.keys(t.segments ?? {}).reduce((e, t) => (e[t] = [], e), {})), o = N(n), s = o.length > 1, c = s ? 5e3 : F, l = C({
|
|
46
47
|
queryKey: [
|
|
47
48
|
"search",
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
t.odata.service,
|
|
50
|
+
t.odata.target,
|
|
50
51
|
i,
|
|
51
|
-
|
|
52
|
+
n
|
|
52
53
|
],
|
|
53
|
-
queryFn: async ({ pageParam:
|
|
54
|
-
let l =
|
|
54
|
+
queryFn: async ({ pageParam: n = 0, signal: r, client: a }) => {
|
|
55
|
+
let l = t.columns.map((e) => e.key), u = await e({
|
|
55
56
|
odata: {
|
|
56
|
-
service:
|
|
57
|
-
target:
|
|
57
|
+
service: t.odata.service,
|
|
58
|
+
target: t.odata.target
|
|
58
59
|
},
|
|
59
60
|
options: {
|
|
60
61
|
top: c,
|
|
61
|
-
skip:
|
|
62
|
+
skip: n,
|
|
62
63
|
select: l,
|
|
63
64
|
expression: {
|
|
64
65
|
and: !0,
|
|
65
|
-
filters: [{ filters: o ?
|
|
66
|
+
filters: [{ filters: o ? t.searchKeys.map((e) => ({ filters: o.map((t) => T(e, t)) })) : [] }, {
|
|
66
67
|
and: !0,
|
|
67
68
|
filters: Object.keys(i).map((e) => E(e, i[e]))
|
|
68
69
|
}]
|
|
69
70
|
},
|
|
70
|
-
sorts: [{ key:
|
|
71
|
+
sorts: [{ key: t.leadingKey }]
|
|
71
72
|
}
|
|
72
73
|
})({
|
|
73
74
|
signal: r,
|
|
74
75
|
client: a
|
|
75
76
|
});
|
|
76
|
-
return s ? P(u.data, o,
|
|
77
|
+
return s ? P(u.data, o, t.searchKeys) : u.data;
|
|
77
78
|
},
|
|
78
79
|
getNextPageParam: (e, t) => {
|
|
79
80
|
if (!(e.length < c)) return t.length * c;
|
|
@@ -87,7 +88,7 @@ function I(e) {
|
|
|
87
88
|
return {
|
|
88
89
|
query: l,
|
|
89
90
|
items: b(() => l.data?.pages.flatMap((e) => e) ?? [], [l.data?.pages]),
|
|
90
|
-
searchTerm:
|
|
91
|
+
searchTerm: n,
|
|
91
92
|
setSearch: u,
|
|
92
93
|
clearSearch: d,
|
|
93
94
|
filters: i,
|
|
@@ -96,35 +97,35 @@ function I(e) {
|
|
|
96
97
|
}
|
|
97
98
|
//#endregion
|
|
98
99
|
//#region src/advanced-search/model/useAdvancedSearchInitialSelected.ts
|
|
99
|
-
function L(
|
|
100
|
+
function L(t, n = []) {
|
|
100
101
|
return D(w({
|
|
101
102
|
queryKey: [
|
|
102
103
|
"searchSelected",
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
t.odata.service,
|
|
105
|
+
t.odata.target,
|
|
106
|
+
n
|
|
106
107
|
],
|
|
107
108
|
queryFn: async ({ client: r, signal: i }) => {
|
|
108
|
-
if (
|
|
109
|
+
if (n.length === 0) return {
|
|
109
110
|
data: [],
|
|
110
111
|
totalCount: void 0
|
|
111
112
|
};
|
|
112
|
-
let a =
|
|
113
|
-
return await
|
|
113
|
+
let a = t.columns.map((e) => e.key);
|
|
114
|
+
return await e({
|
|
114
115
|
odata: {
|
|
115
|
-
service:
|
|
116
|
-
target:
|
|
116
|
+
service: t.odata.service,
|
|
117
|
+
target: t.odata.target
|
|
117
118
|
},
|
|
118
119
|
options: {
|
|
119
120
|
select: a,
|
|
120
|
-
expression: { filters:
|
|
121
|
+
expression: { filters: n.map((e) => E(t.leadingKey, e)) }
|
|
121
122
|
}
|
|
122
123
|
})({
|
|
123
124
|
client: r,
|
|
124
125
|
signal: i
|
|
125
126
|
});
|
|
126
127
|
},
|
|
127
|
-
enabled:
|
|
128
|
+
enabled: n.length > 0
|
|
128
129
|
}));
|
|
129
130
|
}
|
|
130
131
|
//#endregion
|
|
@@ -159,78 +160,78 @@ function R(e) {
|
|
|
159
160
|
}
|
|
160
161
|
//#endregion
|
|
161
162
|
//#region src/advanced-search/ui/AdvancedSearchModal.tsx
|
|
162
|
-
function z({ onClose:
|
|
163
|
-
let x = b(() =>
|
|
163
|
+
function z({ onClose: e, onItemsSelect: n, config: c, initialSelectedItems: l = [] }) {
|
|
164
|
+
let x = b(() => c.columns.map((e) => ({
|
|
164
165
|
id: e.key,
|
|
165
166
|
accessorKey: e.key,
|
|
166
167
|
header: e.label,
|
|
167
168
|
meta: { width: e.width || "auto" }
|
|
168
|
-
})), [
|
|
169
|
-
service:
|
|
170
|
-
target:
|
|
169
|
+
})), [c.columns]), { columns: S, isLoading: C } = t({
|
|
170
|
+
service: c.odata.service,
|
|
171
|
+
target: c.odata.target,
|
|
171
172
|
mode: "enrich",
|
|
172
173
|
columns: x
|
|
173
|
-
}), { query: w, items: T, searchTerm: E, setSearch: D, clearSearch: O, filters: k, setFilters: A } = I(
|
|
174
|
+
}), { query: w, items: T, searchTerm: E, setSearch: D, clearSearch: O, filters: k, setFilters: A } = I(c), { selectedItems: N, deselect: P, replaceSelection: F } = R(c), L = v((e) => String(e[c.leadingKey]), [c.leadingKey]), z = b(() => N.map((e) => String(e[c.leadingKey])), [N, c.leadingKey]), B = b(() => new Set(T.map((e) => String(e[c.leadingKey]))), [T, c.leadingKey]);
|
|
174
175
|
y(() => {
|
|
175
|
-
F(
|
|
176
|
-
}, [
|
|
176
|
+
F(l);
|
|
177
|
+
}, [l, F]);
|
|
177
178
|
let V = v(() => {
|
|
178
179
|
w.hasNextPage && !w.isFetchingNextPage && w.fetchNextPage();
|
|
179
180
|
}, [w]), H = v((e) => {
|
|
180
|
-
let t = new Set(e.map((e) => String(e[
|
|
181
|
+
let t = new Set(e.map((e) => String(e[c.leadingKey]))), n = N.filter((e) => !B.has(String(e[c.leadingKey]))), r = T.filter((e) => t.has(String(e[c.leadingKey])));
|
|
181
182
|
F([...n, ...r]);
|
|
182
183
|
}, [
|
|
183
|
-
|
|
184
|
+
c.leadingKey,
|
|
184
185
|
T,
|
|
185
186
|
F,
|
|
186
187
|
N,
|
|
187
188
|
B
|
|
188
189
|
]), U = v((e) => {
|
|
189
|
-
P(String(e[
|
|
190
|
-
}, [
|
|
191
|
-
|
|
190
|
+
P(String(e[c.leadingKey]));
|
|
191
|
+
}, [c.leadingKey, P]), W = v(() => {
|
|
192
|
+
n(N), e();
|
|
192
193
|
}, [
|
|
193
194
|
N,
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
n,
|
|
196
|
+
e
|
|
196
197
|
]), G = b(() => {
|
|
197
|
-
if ("segments" in
|
|
198
|
-
let e = Object.keys(
|
|
198
|
+
if ("segments" in c && c.segments) {
|
|
199
|
+
let e = Object.keys(c.segments);
|
|
199
200
|
if (e.length) return {
|
|
200
201
|
odata: {
|
|
201
|
-
...
|
|
202
|
+
...c.odata,
|
|
202
203
|
limitedKeys: e
|
|
203
204
|
},
|
|
204
|
-
segments:
|
|
205
|
-
model:
|
|
205
|
+
segments: c.segments,
|
|
206
|
+
model: c.model
|
|
206
207
|
};
|
|
207
208
|
}
|
|
208
|
-
}, [
|
|
209
|
-
return /* @__PURE__ */ M(
|
|
209
|
+
}, [c]);
|
|
210
|
+
return /* @__PURE__ */ M(m, {
|
|
210
211
|
isOpen: !0,
|
|
211
|
-
onClose:
|
|
212
|
-
title:
|
|
212
|
+
onClose: e,
|
|
213
|
+
title: c.title,
|
|
213
214
|
size: "lg",
|
|
214
215
|
height: "min(50em, 80dvh)",
|
|
215
216
|
children: [
|
|
216
|
-
/* @__PURE__ */ j(
|
|
217
|
+
/* @__PURE__ */ j(f, { children: /* @__PURE__ */ M(a, {
|
|
217
218
|
gap: "sm",
|
|
218
|
-
children: [G && /* @__PURE__ */ j(
|
|
219
|
+
children: [G && /* @__PURE__ */ j(g, {
|
|
219
220
|
odata: G.odata,
|
|
220
221
|
segments: G.segments,
|
|
221
222
|
model: G.model,
|
|
222
223
|
values: k,
|
|
223
224
|
onChange: A
|
|
224
|
-
}), /* @__PURE__ */ j(
|
|
225
|
+
}), /* @__PURE__ */ j(u, {
|
|
225
226
|
size: "md",
|
|
226
|
-
placeholder:
|
|
227
|
+
placeholder: c.searchLabel ?? "Введите поисковый запрос",
|
|
227
228
|
value: E,
|
|
228
229
|
onChange: D,
|
|
229
230
|
onClear: O,
|
|
230
231
|
className: "flexGrow"
|
|
231
232
|
})]
|
|
232
233
|
}) }),
|
|
233
|
-
/* @__PURE__ */ j(
|
|
234
|
+
/* @__PURE__ */ j(h, { children: /* @__PURE__ */ M(s, {
|
|
234
235
|
gap: "md",
|
|
235
236
|
templateRows: "1fr auto",
|
|
236
237
|
className: "h100",
|
|
@@ -247,23 +248,23 @@ function z({ onClose: n, onItemsSelect: r, config: l, initialSelectedItems: u =
|
|
|
247
248
|
className: "w100"
|
|
248
249
|
}), /* @__PURE__ */ j("div", {
|
|
249
250
|
className: "marginBlockMd border",
|
|
250
|
-
children: /* @__PURE__ */ j(
|
|
251
|
+
children: /* @__PURE__ */ j(d, {
|
|
251
252
|
className: "paddingSm",
|
|
252
253
|
height: "6em",
|
|
253
|
-
children: /* @__PURE__ */ j(
|
|
254
|
+
children: /* @__PURE__ */ j(i, { children: N.map((e) => /* @__PURE__ */ j(r, {
|
|
254
255
|
size: "md",
|
|
255
256
|
tone: "info",
|
|
256
257
|
appearance: "outline",
|
|
257
258
|
onRemove: () => U(e),
|
|
258
|
-
children:
|
|
259
|
-
}, e[
|
|
259
|
+
children: c.leadingText && e[c.leadingText] || e[c.leadingKey]
|
|
260
|
+
}, e[c.leadingKey])) })
|
|
260
261
|
})
|
|
261
262
|
})]
|
|
262
263
|
}) }),
|
|
263
|
-
/* @__PURE__ */ M(
|
|
264
|
-
onClick:
|
|
264
|
+
/* @__PURE__ */ M(p, { children: [/* @__PURE__ */ j(o, {
|
|
265
|
+
onClick: e,
|
|
265
266
|
children: "Отмена"
|
|
266
|
-
}), /* @__PURE__ */ j(
|
|
267
|
+
}), /* @__PURE__ */ j(o, {
|
|
267
268
|
variant: "successOutline",
|
|
268
269
|
onClick: W,
|
|
269
270
|
children: "Выбрать"
|
|
@@ -273,42 +274,42 @@ function z({ onClose: n, onItemsSelect: r, config: l, initialSelectedItems: u =
|
|
|
273
274
|
}
|
|
274
275
|
//#endregion
|
|
275
276
|
//#region src/advanced-search/ui/AdvancedSearchSelectUI.tsx
|
|
276
|
-
var B = ({ label: e, description: t, disabled:
|
|
277
|
-
let { controlId: f, labelId: p, descriptionId: m } =
|
|
277
|
+
var B = ({ label: e, description: t, disabled: r, size: i, placeholder: o = "Выбрать", token: s, onOpen: u, onClear: d }) => {
|
|
278
|
+
let { controlId: f, labelId: p, descriptionId: m } = c({
|
|
278
279
|
hasLabel: e != null,
|
|
279
280
|
hasDescription: !!t
|
|
280
281
|
}), h = !!s;
|
|
281
282
|
return /* @__PURE__ */ M("div", {
|
|
282
|
-
"aria-disabled":
|
|
283
|
-
className: S(
|
|
283
|
+
"aria-disabled": r || void 0,
|
|
284
|
+
className: S(n.uiElement, n.uiSizable, i && n[i]),
|
|
284
285
|
children: [
|
|
285
286
|
e && /* @__PURE__ */ j("label", {
|
|
286
287
|
id: p,
|
|
287
288
|
htmlFor: f,
|
|
288
|
-
className:
|
|
289
|
+
className: n.uiLabel,
|
|
289
290
|
children: e
|
|
290
291
|
}),
|
|
291
292
|
t && /* @__PURE__ */ j("p", {
|
|
292
293
|
id: m,
|
|
293
|
-
className:
|
|
294
|
+
className: n.uiDescription,
|
|
294
295
|
children: t
|
|
295
296
|
}),
|
|
296
297
|
/* @__PURE__ */ M("div", {
|
|
297
|
-
className:
|
|
298
|
+
className: n.uiInputContainer,
|
|
298
299
|
children: [/* @__PURE__ */ j("div", {
|
|
299
|
-
className:
|
|
300
|
-
children: !h && /* @__PURE__ */ j(
|
|
300
|
+
className: n.uiInputWithToggle,
|
|
301
|
+
children: !h && /* @__PURE__ */ j(a, {
|
|
301
302
|
align: "center",
|
|
302
303
|
className: "h100",
|
|
303
304
|
children: /* @__PURE__ */ j("div", {
|
|
304
|
-
className:
|
|
305
|
-
children:
|
|
305
|
+
className: n.uiPlaceholder,
|
|
306
|
+
children: o
|
|
306
307
|
})
|
|
307
308
|
})
|
|
308
309
|
}), /* @__PURE__ */ j("div", {
|
|
309
|
-
className:
|
|
310
|
+
className: l.controlEndAdornment,
|
|
310
311
|
children: /* @__PURE__ */ M("div", {
|
|
311
|
-
className:
|
|
312
|
+
className: n.uiToggleButtonContainer,
|
|
312
313
|
children: [
|
|
313
314
|
/* @__PURE__ */ j("div", {
|
|
314
315
|
className: "flexEllipsis",
|
|
@@ -318,17 +319,17 @@ var B = ({ label: e, description: t, disabled: n, size: i, placeholder: a = "В
|
|
|
318
319
|
/* @__PURE__ */ j("button", {
|
|
319
320
|
type: "button",
|
|
320
321
|
disabled: !s,
|
|
321
|
-
className:
|
|
322
|
+
className: n.uiClearButton,
|
|
322
323
|
onClick: d,
|
|
323
324
|
"aria-label": "Очистить все",
|
|
324
325
|
children: /* @__PURE__ */ j(k, {})
|
|
325
326
|
}),
|
|
326
|
-
/* @__PURE__ */ j("div", { className:
|
|
327
|
+
/* @__PURE__ */ j("div", { className: n.uiButtonSeparator }),
|
|
327
328
|
/* @__PURE__ */ j("button", {
|
|
328
329
|
type: "button",
|
|
329
|
-
onClick:
|
|
330
|
-
className:
|
|
331
|
-
children: /* @__PURE__ */ j(O, { className:
|
|
330
|
+
onClick: u,
|
|
331
|
+
className: n.uiToggleButton,
|
|
332
|
+
children: /* @__PURE__ */ j(O, { className: n.uiToggleIcon })
|
|
332
333
|
})
|
|
333
334
|
]
|
|
334
335
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>([]);\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst nextSelectionMap = new Map<string, T>();\n\n\t\t\t\tfor (const item of nextItems) {\n\t\t\t\t\tnextSelectionMap.set(String(item[config.leadingKey]), item);\n\t\t\t\t}\n\n\t\t\t\tconst normalizedItems = Array.from(nextSelectionMap.values());\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelectedItems?: T[];\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Модальное окно поиска клиентов\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tconfig,\n\tinitialSelectedItems = []\n}: SearchModalProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\t// До изменения: пустой внешний набор не очищал внутренний выбор.\n\t// После изменения: модальное окно синхронизирует выбор с внешним набором полностью.\n\tuseEffect(() => {\n\t\treplaceSelection(initialSelectedItems);\n\t}, [initialSelectedItems, replaceSelection]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t// До изменения: выбор собирался чекбоксами по строкам.\n\t// После изменения: таблица управляет multi-selection, а модалка сохраняет скрытые фильтрами элементы.\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/**\n\t * Удаляет отдельный элемент из общего выбора.\n\t */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t// Обработчик подтверждения выбора\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching} // или query.isFetchingNextPage\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\tconfig: SearchConfig<T>;\n};\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst { data: selectedItems } = useAdvancedSearchInitialSelected(config, value);\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelectedItems={selectedItems}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>([]);\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst nextSelectionMap = new Map<string, T>();\n\n\t\t\t\tfor (const item of nextItems) {\n\t\t\t\t\tnextSelectionMap.set(String(item[config.leadingKey]), item);\n\t\t\t\t}\n\n\t\t\t\tconst normalizedItems = Array.from(nextSelectionMap.values());\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelectedItems?: T[];\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Модальное окно поиска клиентов\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tconfig,\n\tinitialSelectedItems = []\n}: SearchModalProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\t// До изменения: пустой внешний набор не очищал внутренний выбор.\n\t// После изменения: модальное окно синхронизирует выбор с внешним набором полностью.\n\tuseEffect(() => {\n\t\treplaceSelection(initialSelectedItems);\n\t}, [initialSelectedItems, replaceSelection]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t// До изменения: выбор собирался чекбоксами по строкам.\n\t// После изменения: таблица управляет multi-selection, а модалка сохраняет скрытые фильтрами элементы.\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/**\n\t * Удаляет отдельный элемент из общего выбора.\n\t */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t// Обработчик подтверждения выбора\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching} // или query.isFetchingNextPage\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\tconfig: SearchConfig<T>;\n};\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst { data: selectedItems } = useAdvancedSearchInitialSelected(config, value);\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelectedItems={selectedItems}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
|