@topvisor/ui 1.4.0 → 1.4.1-projectSelector.0
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/.chunks/core-BgoBbm_5.es.js +242 -0
- package/.chunks/core-BgoBbm_5.es.js.map +1 -0
- package/.chunks/core-D1KnwO7l.amd.js +2 -0
- package/.chunks/core-D1KnwO7l.amd.js.map +1 -0
- package/.chunks/{datepicker-D1Hw3a3o.es.js → datepicker-BPTUHd97.es.js} +2 -2
- package/.chunks/datepicker-BPTUHd97.es.js.map +1 -0
- package/.chunks/{datepicker-3coUsFW2.amd.js → datepicker-O_SK-Dz4.amd.js} +2 -2
- package/.chunks/datepicker-O_SK-Dz4.amd.js.map +1 -0
- package/.chunks/{dialog_regionSelectorRegions-CZ8IX7la.amd.js → dialog_regionSelectorRegions-Ba-Eypgv.amd.js} +2 -2
- package/.chunks/dialog_regionSelectorRegions-Ba-Eypgv.amd.js.map +1 -0
- package/.chunks/{dialog_regionSelectorRegions-1UVhgK2f.es.js → dialog_regionSelectorRegions-DA38RsiW.es.js} +4 -4
- package/.chunks/dialog_regionSelectorRegions-DA38RsiW.es.js.map +1 -0
- package/.chunks/{dialogs.vue_vue_type_script_setup_true_lang-Dq9kWWMg.amd.js → dialogs.vue_vue_type_script_setup_true_lang-CWprVs8d.amd.js} +2 -2
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CWprVs8d.amd.js.map +1 -0
- package/.chunks/{dialogs.vue_vue_type_script_setup_true_lang-DRbTG0vh.es.js → dialogs.vue_vue_type_script_setup_true_lang-CzFMOjlE.es.js} +2 -2
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CzFMOjlE.es.js.map +1 -0
- package/.chunks/field-Cvv0SRcJ.amd.js.map +1 -1
- package/.chunks/field-CyyFzM-Y.es.js.map +1 -1
- package/.chunks/{forms-CUSCBQu3.amd.js → forms-4D_EVI46.amd.js} +3 -3
- package/.chunks/forms-4D_EVI46.amd.js.map +1 -0
- package/.chunks/{forms-BseC3Ftz.es.js → forms-xkXHvvah.es.js} +565 -551
- package/.chunks/forms-xkXHvvah.es.js.map +1 -0
- package/.chunks/index-DLUtoTUg.amd.js.map +1 -1
- package/.chunks/index-DkQWJkMc.es.js.map +1 -1
- package/.chunks/lazy-40pjr8cZ.es.js.map +1 -1
- package/.chunks/lazy-DSFLxvj4.amd.js.map +1 -1
- package/.chunks/{notice-DwjipV21.amd.js → notice-hF3z8ewG.amd.js} +2 -2
- package/.chunks/notice-hF3z8ewG.amd.js.map +1 -0
- package/.chunks/{notice-Cl3ZgiHm.es.js → notice-wqZxmsUH.es.js} +2 -2
- package/.chunks/notice-wqZxmsUH.es.js.map +1 -0
- package/.chunks/{page.vue_vue_type_script_setup_true_lang-CpRJQFD1.es.js → page.vue_vue_type_script_setup_true_lang-rW3w9LMh.es.js} +4 -4
- package/.chunks/page.vue_vue_type_script_setup_true_lang-rW3w9LMh.es.js.map +1 -0
- package/.chunks/{page.vue_vue_type_script_setup_true_lang-CjIiZU-D.amd.js → page.vue_vue_type_script_setup_true_lang-tiWuQ_ZK.amd.js} +2 -2
- package/.chunks/page.vue_vue_type_script_setup_true_lang-tiWuQ_ZK.amd.js.map +1 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js +503 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js.map +1 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DABqSSXw.amd.js +2 -0
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DABqSSXw.amd.js.map +1 -0
- package/.chunks/{popup-Jw_Yyg3U.es.js → popup-BeLPdHWv.es.js} +2 -2
- package/.chunks/popup-BeLPdHWv.es.js.map +1 -0
- package/.chunks/{popup-DRuyYFGB.amd.js → popup-Bwmu8rOb.amd.js} +2 -2
- package/.chunks/popup-Bwmu8rOb.amd.js.map +1 -0
- package/.chunks/{popupHint.vue_vue_type_style_index_0_lang-DtiT6NE4.amd.js → popupHint.vue_vue_type_style_index_0_lang-B0BWXhHK.amd.js} +2 -2
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-B0BWXhHK.amd.js.map +1 -0
- package/.chunks/{popupHint.vue_vue_type_style_index_0_lang-DD59yF6H.es.js → popupHint.vue_vue_type_style_index_0_lang-fnjq0yg1.es.js} +2 -2
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-fnjq0yg1.es.js.map +1 -0
- package/.chunks/store-CX_6ZXhO.es.js.map +1 -1
- package/.chunks/store-YRW59xEF.amd.js.map +1 -1
- package/.chunks/{utils-D9nYQabE.amd.js → utils-BRJvuqe_.amd.js} +2 -2
- package/.chunks/utils-BRJvuqe_.amd.js.map +1 -0
- package/.chunks/{utils-YrUExsH7.es.js → utils-ByqQkftW.es.js} +2 -2
- package/.chunks/utils-ByqQkftW.es.js.map +1 -0
- package/.chunks/{utils-Q69SXlnV.es.js → utils-YVlPlqDK.es.js} +3 -3
- package/.chunks/utils-YVlPlqDK.es.js.map +1 -0
- package/.chunks/{utils-CzHUG_xz.amd.js → utils-cAJahDml.amd.js} +2 -2
- package/.chunks/utils-cAJahDml.amd.js.map +1 -0
- package/.chunks/{widgetInput.vue_vue_type_script_setup_true_lang-CkE912ll.amd.js → widgetInput.vue_vue_type_script_setup_true_lang-D7lVLE3D.amd.js} +2 -2
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-D7lVLE3D.amd.js.map +1 -0
- package/.chunks/{widgetInput.vue_vue_type_script_setup_true_lang-CDkeKVqY.es.js → widgetInput.vue_vue_type_script_setup_true_lang-UUovJzhL.es.js} +2 -2
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-UUovJzhL.es.js.map +1 -0
- package/README.md +82 -82
- package/api/additional.amd.js.map +1 -1
- package/api/additional.js.map +1 -1
- package/api/index.amd.js +1 -1
- package/api/index.amd.js.map +1 -1
- package/api/index.js +1 -1
- package/api/index.js.map +1 -1
- package/assets/core.css +1 -1
- package/assets/forms.css +1 -1
- package/assets/policy.css +1 -1
- package/assets/project.css +1 -1
- package/charts/charts.amd.js +1 -1
- package/charts/charts.amd.js.map +1 -1
- package/charts/charts.js +1 -1
- package/charts/charts.js.map +1 -1
- package/core/app.amd.js +1 -1
- package/core/app.amd.js.map +1 -1
- package/core/app.js +5 -5
- package/core/app.js.map +1 -1
- package/dialog/dialog.amd.js +1 -1
- package/dialog/dialog.amd.js.map +1 -1
- package/dialog/dialog.js +2 -2
- package/dialog/dialog.js.map +1 -1
- package/extra/extra.amd.js.map +1 -1
- package/extra/extra.js.map +1 -1
- package/forms/forms.amd.js +1 -1
- package/forms/forms.js +3 -3
- package/formsExt/formsExt.amd.js +1 -1
- package/formsExt/formsExt.amd.js.map +1 -1
- package/formsExt/formsExt.js +123 -111
- package/formsExt/formsExt.js.map +1 -1
- package/icomoon/Read Me.txt +7 -7
- package/icomoon/Topvisor icons.json +6658 -0
- package/icomoon/demo-files/demo.css +158 -158
- package/icomoon/demo-files/demo.js +30 -30
- package/icomoon/demo.css +158 -158
- package/icomoon/demo.html +15 -1
- package/icomoon/demo.js +30 -30
- package/icomoon/fonts/Topvisor-2.eot +0 -0
- package/icomoon/fonts/Topvisor-2.svg +1 -0
- package/icomoon/fonts/Topvisor-2.ttf +0 -0
- package/icomoon/fonts/Topvisor-2.woff +0 -0
- package/icomoon/selection.json +1 -1
- package/icomoon/style.css +8 -5
- package/jquery-ui.min.css +5 -5
- package/layout/layout.amd.js +1 -1
- package/layout/layout.amd.js.map +1 -1
- package/layout/layout.js +1 -1
- package/layout/layout.js.map +1 -1
- package/package.json +1 -1
- package/popup/popup.amd.js +1 -1
- package/popup/popup.amd.js.map +1 -1
- package/popup/popup.js +6 -6
- package/popup/popup.js.map +1 -1
- package/popup/worker.amd.js +1 -1
- package/popup/worker.amd.js.map +1 -1
- package/popup/worker.js +2 -2
- package/popup/worker.js.map +1 -1
- package/project/project.amd.js +1 -1
- package/project/project.amd.js.map +1 -1
- package/project/project.js +896 -614
- package/project/project.js.map +1 -1
- package/require/css.amd.js +12 -12
- package/src/api/api/types/client/request-options.d.ts +8 -3
- package/src/components/forms/caption/types.d.ts +5 -1
- package/src/components/forms/input/input.vue.d.ts +2 -4
- package/src/components/forms/input/types.d.ts +15 -0
- package/src/components/forms/select/select.vue.d.ts +15 -2
- package/src/components/forms/select/types.d.ts +6 -0
- package/src/components/formsExt/editArea/editArea.vue.d.ts +15 -2
- package/src/components/formsExt/editArea/types.d.ts +6 -0
- package/src/components/formsExt/editInput/editInput.vue.d.ts +16 -1
- package/src/components/formsExt/selector2/composables/useAPI.d.ts +2 -0
- package/src/components/formsExt/selector2/composables/useMenu.d.ts +3 -1
- package/src/components/formsExt/selector2/types.d.ts +14 -0
- package/src/components/popup/popup/listItem.vue.d.ts +24 -4
- package/src/components/popup/popup/types.d.ts +1 -0
- package/src/components/project/groupSelector/groups/groups.vue.d.ts +2 -0
- package/src/components/project/groupSelector/groups/utils.d.ts +1 -1
- package/src/components/project/project.d.ts +1 -0
- package/src/components/project/projectSelector/projectSelector.vue.d.ts +121 -0
- package/src/components/project/projectSelector/stories/mocks/projects.d.ts +10 -0
- package/src/components/project/projectSelector/submenu/submenu.vue.d.ts +4 -0
- package/src/components/project/projectSelector/submenu/types.d.ts +17 -0
- package/src/components/project/projectSelector/types.d.ts +57 -0
- package/src/components/project/projectSelector/utils.d.ts +206 -0
- package/src/core/directives/shortcut.d.ts +12 -0
- package/src/core/utils/string.d.ts +1 -1
- package/tabs/tabs.amd.js.map +1 -1
- package/tabs/tabs.js.map +1 -1
- package/tabsView/tabsView.amd.js +1 -1
- package/tabsView/tabsView.amd.js.map +1 -1
- package/tabsView/tabsView.js +2 -2
- package/tabsView/tabsView.js.map +1 -1
- package/utils/check.amd.js.map +1 -1
- package/utils/check.js.map +1 -1
- package/utils/clipboard.amd.js +1 -1
- package/utils/clipboard.amd.js.map +1 -1
- package/utils/clipboard.js +1 -1
- package/utils/clipboard.js.map +1 -1
- package/utils/date.amd.js +1 -1
- package/utils/date.js +1 -1
- package/utils/device.amd.js +1 -1
- package/utils/device.js +1 -1
- package/utils/dom.amd.js.map +1 -1
- package/utils/dom.js.map +1 -1
- package/utils/image.amd.js.map +1 -1
- package/utils/image.js.map +1 -1
- package/utils/keyboard.amd.js.map +1 -1
- package/utils/keyboard.js.map +1 -1
- package/utils/lodash.amd.js +1 -1
- package/utils/lodash.js +1 -1
- package/utils/number.amd.js.map +1 -1
- package/utils/number.js.map +1 -1
- package/utils/price.amd.js +1 -1
- package/utils/price.amd.js.map +1 -1
- package/utils/price.js +1 -1
- package/utils/price.js.map +1 -1
- package/utils/route.amd.js.map +1 -1
- package/utils/route.js.map +1 -1
- package/utils/scroll.amd.js.map +1 -1
- package/utils/scroll.js.map +1 -1
- package/utils/searchers.amd.js +1 -1
- package/utils/searchers.amd.js.map +1 -1
- package/utils/searchers.js +3 -3
- package/utils/searchers.js.map +1 -1
- package/utils/string.amd.js +1 -1
- package/utils/string.amd.js.map +1 -1
- package/utils/string.js +1 -1
- package/utils/string.js.map +1 -1
- package/utils/system.amd.js.map +1 -1
- package/utils/system.js.map +1 -1
- package/utils/url.amd.js.map +1 -1
- package/utils/url.js.map +1 -1
- package/web-types.json +31 -0
- package/.chunks/core-BL-38XF7.es.js +0 -196
- package/.chunks/core-BL-38XF7.es.js.map +0 -1
- package/.chunks/core-BsPx05H9.amd.js +0 -2
- package/.chunks/core-BsPx05H9.amd.js.map +0 -1
- package/.chunks/datepicker-3coUsFW2.amd.js.map +0 -1
- package/.chunks/datepicker-D1Hw3a3o.es.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-1UVhgK2f.es.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-CZ8IX7la.amd.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-DRbTG0vh.es.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-Dq9kWWMg.amd.js.map +0 -1
- package/.chunks/forms-BseC3Ftz.es.js.map +0 -1
- package/.chunks/forms-CUSCBQu3.amd.js.map +0 -1
- package/.chunks/notice-Cl3ZgiHm.es.js.map +0 -1
- package/.chunks/notice-DwjipV21.amd.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-CjIiZU-D.amd.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-CpRJQFD1.es.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-BBDJEs5Q.es.js +0 -496
- package/.chunks/policy.vue_vue_type_style_index_0_lang-BBDJEs5Q.es.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js +0 -2
- package/.chunks/policy.vue_vue_type_style_index_0_lang-DJOaMdBm.amd.js.map +0 -1
- package/.chunks/popup-DRuyYFGB.amd.js.map +0 -1
- package/.chunks/popup-Jw_Yyg3U.es.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DD59yF6H.es.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DtiT6NE4.amd.js.map +0 -1
- package/.chunks/utils-CzHUG_xz.amd.js.map +0 -1
- package/.chunks/utils-D9nYQabE.amd.js.map +0 -1
- package/.chunks/utils-Q69SXlnV.es.js.map +0 -1
- package/.chunks/utils-YrUExsH7.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CDkeKVqY.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CkE912ll.amd.js.map +0 -1
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
|
|
2
|
+
import { Core as _autoloadCSSCore } from '../core/app.js';
|
|
3
|
+
const fileNames = ['../assets/policy.css'].map(fileName => import.meta.resolve(fileName));
|
|
4
|
+
_autoloadCSSCore.insertCSSLinkToPage(fileNames, true);
|
|
5
|
+
|
|
6
|
+
import { defineComponent as G, mergeModels as U, useModel as se, ref as $, onMounted as ie, onUpdated as ue, createElementBlock as L, openBlock as y, normalizeClass as ce, createCommentVNode as M, Fragment as E, renderList as H, createBlock as x, mergeProps as q, createSlots as Y, withCtx as B, createTextVNode as N, toDisplayString as P, createVNode as ne, createElementVNode as re, withModifiers as de, computed as K, watch as J, toRef as R, resolveComponent as fe, resolveDirective as Z, unref as c, renderSlot as _, withDirectives as ee, resolveDynamicComponent as pe } from "vue";
|
|
7
|
+
import { e as te, b as ve, C as j, d as me, u as he, s as ye } from "./forms-xkXHvvah.es.js";
|
|
8
|
+
import { _ as ge, b as le } from "./popupHint.vue_vue_type_style_index_0_lang-fnjq0yg1.es.js";
|
|
9
|
+
import { _ as Ae } from "./widgetInput.vue_vue_type_script_setup_true_lang-UUovJzhL.es.js";
|
|
10
|
+
import { invertKeyboardLayout as Ie } from "../utils/keyboard.js";
|
|
11
|
+
import { g as ke } from "./field-CyyFzM-Y.es.js";
|
|
12
|
+
const Ce = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "top-menu_selectAll"
|
|
15
|
+
}, We = /* @__PURE__ */ G({
|
|
16
|
+
__name: "menu",
|
|
17
|
+
props: /* @__PURE__ */ U({
|
|
18
|
+
modelValue: {},
|
|
19
|
+
items: {},
|
|
20
|
+
isMultiple: { type: Boolean },
|
|
21
|
+
canBeEmptyMultiple: { type: Boolean },
|
|
22
|
+
styling: { default: "default" },
|
|
23
|
+
selectAllItem: {}
|
|
24
|
+
}, {
|
|
25
|
+
modelValue: {
|
|
26
|
+
required: !0
|
|
27
|
+
},
|
|
28
|
+
modelModifiers: {}
|
|
29
|
+
}),
|
|
30
|
+
emits: ["update:modelValue"],
|
|
31
|
+
setup(e) {
|
|
32
|
+
const a = e, l = se(e, "modelValue"), t = $();
|
|
33
|
+
!a.isMultiple && typeof l.value != "string" && typeof l.value != "number" && console.warn('Type check failed for prop "modelValue". Expected String: ' + typeof l.value), a.isMultiple && !Array.isArray(l.value) && console.warn('Type check failed for prop "modelValue". Expected Array: ' + typeof l.value), a.isMultiple && !a.canBeEmptyMultiple && Array.isArray(l.value) && !l.value.length && a.items[0] && (l.value = [a.items[0]?.href ?? a.items[0]?.value]);
|
|
34
|
+
const i = (r) => Array.isArray(l.value) ? l.value.includes(r.value) : r.value === l.value, T = (r, d = !1) => {
|
|
35
|
+
if (Array.isArray(l.value)) {
|
|
36
|
+
let o = l.value.slice();
|
|
37
|
+
if (d) {
|
|
38
|
+
o.length || (o = a.items.map((h) => h.value));
|
|
39
|
+
const A = o.indexOf(r.value);
|
|
40
|
+
A === -1 ? o.push(r.value) : o.splice(A, 1);
|
|
41
|
+
} else
|
|
42
|
+
o.length === 1 && o[0] === r.value ? o = [] : o = [r.value];
|
|
43
|
+
!a.canBeEmptyMultiple && !o.length && (o = [r.value]), l.value = o;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
l.value = r.value;
|
|
47
|
+
}, p = (r) => {
|
|
48
|
+
if (t.value.scrollWidth <= t.value.offsetWidth || r.shiftKey || Math.abs(r.deltaY) < 50) return;
|
|
49
|
+
r.preventDefault();
|
|
50
|
+
const d = r.deltaY > 0 ? 30 : -30;
|
|
51
|
+
t.value.scrollLeft = t.value.scrollLeft + d;
|
|
52
|
+
}, u = (r = !0) => {
|
|
53
|
+
const d = t.value.querySelector(".top-active");
|
|
54
|
+
if (!d) return;
|
|
55
|
+
const o = 24, A = d.offsetLeft - t.value.offsetLeft - o, h = d.offsetLeft - t.value.offsetLeft + d.clientWidth + o, g = t.value.scrollLeft, w = t.value.clientWidth + t.value.scrollLeft;
|
|
56
|
+
let I;
|
|
57
|
+
A < g && (I = A), h > w && (I = h - t.value.clientWidth), I !== void 0 && (ve() ? j.$?.(t.value).animate({ scrollLeft: I }, r ? 200 : 0) : t.value.scrollTo({ left: I, behavior: r ? "smooth" : "auto" }));
|
|
58
|
+
}, n = () => {
|
|
59
|
+
if (Array.isArray(l.value)) {
|
|
60
|
+
if (l.value.length === a.items.length) {
|
|
61
|
+
l.value = [a.items[0].href ?? a.items[0].value];
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
l.value = a.items.map((r) => r.href ?? r.value);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
return ie(() => u(!1)), ue(() => u(!0)), (r, d) => (y(), L("div", {
|
|
68
|
+
ref_key: "el",
|
|
69
|
+
ref: t,
|
|
70
|
+
class: ce({
|
|
71
|
+
"top-menu": !0,
|
|
72
|
+
["top-style_" + e.styling]: !0
|
|
73
|
+
// ['top-unwrap-x']: styling === 'default',
|
|
74
|
+
}),
|
|
75
|
+
onWheel: p
|
|
76
|
+
}, [
|
|
77
|
+
(y(!0), L(E, null, H(e.items, (o) => (y(), x(te, q({ ref_for: !0 }, o, {
|
|
78
|
+
class: "top-menu_item",
|
|
79
|
+
color: "theme",
|
|
80
|
+
onClick: (A) => T(o, A.ctrlKey || A.metaKey),
|
|
81
|
+
isActive: i(o)
|
|
82
|
+
}), Y({ _: 2 }, [
|
|
83
|
+
o.content ? {
|
|
84
|
+
name: "default",
|
|
85
|
+
fn: B(() => [
|
|
86
|
+
N(P(o.content), 1)
|
|
87
|
+
]),
|
|
88
|
+
key: "0"
|
|
89
|
+
} : void 0
|
|
90
|
+
]), 1040, ["onClick", "isActive"]))), 256)),
|
|
91
|
+
Array.isArray(l.value) && e.selectAllItem ? (y(), L("div", Ce, [
|
|
92
|
+
ne(te, q(e.selectAllItem, {
|
|
93
|
+
class: "top-menu_item",
|
|
94
|
+
color: "theme",
|
|
95
|
+
styling: "",
|
|
96
|
+
onClick: d[0] || (d[0] = (o) => n()),
|
|
97
|
+
isActive: l.value.length === e.items.length
|
|
98
|
+
}), Y({ _: 2 }, [
|
|
99
|
+
e.selectAllItem.content ? {
|
|
100
|
+
name: "default",
|
|
101
|
+
fn: B(() => [
|
|
102
|
+
N(P(e.selectAllItem.content), 1)
|
|
103
|
+
]),
|
|
104
|
+
key: "0"
|
|
105
|
+
} : void 0
|
|
106
|
+
]), 1040, ["isActive"])
|
|
107
|
+
])) : M("", !0)
|
|
108
|
+
], 34));
|
|
109
|
+
}
|
|
110
|
+
}), Le = { class: "top-selector2_itemMulti top-ellipsis" }, Se = /* @__PURE__ */ G({
|
|
111
|
+
__name: "itemMulti",
|
|
112
|
+
props: {
|
|
113
|
+
id: {},
|
|
114
|
+
name: {}
|
|
115
|
+
},
|
|
116
|
+
emits: ["delete"],
|
|
117
|
+
setup(e) {
|
|
118
|
+
return (a, l) => (y(), L("div", Le, [
|
|
119
|
+
N(P(e.name) + " ", 1),
|
|
120
|
+
re("span", {
|
|
121
|
+
class: "top-selector2_itemMultiDelete",
|
|
122
|
+
"data-top-icon": "",
|
|
123
|
+
onClick: l[0] || (l[0] = (t) => a.$emit("delete", { id: e.id, name: e.name })),
|
|
124
|
+
onMousedown: l[1] || (l[1] = de(() => {
|
|
125
|
+
}, ["stop"]))
|
|
126
|
+
}, null, 32)
|
|
127
|
+
]));
|
|
128
|
+
}
|
|
129
|
+
}), V = /* @__PURE__ */ new Map(), Te = (e) => {
|
|
130
|
+
V.get(e)?.clear();
|
|
131
|
+
}, we = (e) => {
|
|
132
|
+
const a = window.mo?.user?.id;
|
|
133
|
+
return JSON.stringify(e.params) + ":" + e.url + ":" + a;
|
|
134
|
+
}, be = (e, a) => V.get(a)?.get(e), xe = (e, a, l) => {
|
|
135
|
+
V.has(a) || V.set(a, /* @__PURE__ */ new Map()), V.get(a)?.set(e, l);
|
|
136
|
+
}, Be = (e, a, l, t) => {
|
|
137
|
+
const i = $([]), T = $(!1), p = $(0);
|
|
138
|
+
let u = "", n;
|
|
139
|
+
e && !e.params.limit && (e.params.limit = 100);
|
|
140
|
+
const r = async () => {
|
|
141
|
+
if (!e) return;
|
|
142
|
+
const h = t ? we(e) : void 0;
|
|
143
|
+
if (h) {
|
|
144
|
+
const I = be(h, e.path);
|
|
145
|
+
if (I)
|
|
146
|
+
return e.abortByFingerprint(), I;
|
|
147
|
+
}
|
|
148
|
+
const g = await e.call();
|
|
149
|
+
if (g.errors) return;
|
|
150
|
+
if (!Array.isArray(g.result)) {
|
|
151
|
+
console.warn("Array expected in `res.result`");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const w = g.result.findIndex((I) => I.id === void 0 || I.name === void 0);
|
|
155
|
+
if (w !== -1) {
|
|
156
|
+
console.warn(`В result[${w}] нет id или name`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
return h && xe(h, e.path, g), g;
|
|
160
|
+
}, d = async (h) => {
|
|
161
|
+
if (!e) return;
|
|
162
|
+
if (h) {
|
|
163
|
+
if (!n || T.value) return;
|
|
164
|
+
e.params.offset = n;
|
|
165
|
+
} else
|
|
166
|
+
e.params.offset = 0;
|
|
167
|
+
a?.(e, u), T.value = !0;
|
|
168
|
+
const g = await r();
|
|
169
|
+
T.value = !1, p.value++, g && (n = g.nextOffset, h ? i.value = i.value.concat(g.result) : i.value = g.result);
|
|
170
|
+
}, o = me(() => d(!1), 200);
|
|
171
|
+
return {
|
|
172
|
+
apiRequest: e,
|
|
173
|
+
items: i,
|
|
174
|
+
isLoading: T,
|
|
175
|
+
countLoading: p,
|
|
176
|
+
load: d,
|
|
177
|
+
setSearchTextAndLoad: (h, g = !0) => {
|
|
178
|
+
if (e) {
|
|
179
|
+
if (h.length < l) {
|
|
180
|
+
e.abortByFingerprint(), i.value = [];
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
h === u && i.value.length || (u = h, g ? o() : d(!1));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}, oe = 0, W = null, ae = (e, a, l = !0) => l && a.id === W ? Array.isArray(e) ? e.some((t) => t.id === a.id && t.name === a.name) : a.name === e.name : Array.isArray(e) ? e.some((t) => t.id === a.id) : a.id === e.id, Oe = (e, a, l) => {
|
|
188
|
+
let t = e.params.filters ?? [];
|
|
189
|
+
t = t.filter((i) => i.name !== l), a && t.push(ke(l, "CONTAINS", [a])), e.changeParams({ filters: t });
|
|
190
|
+
}, Me = (e, a, l, t, i, T, p, u, n, r) => {
|
|
191
|
+
const d = $(""), o = {
|
|
192
|
+
id: oe,
|
|
193
|
+
name: he().Common.All
|
|
194
|
+
}, A = () => {
|
|
195
|
+
d.value = "";
|
|
196
|
+
}, h = () => !(!r.apiRequest || d.value.length >= n), g = K(() => {
|
|
197
|
+
const s = [];
|
|
198
|
+
return !t && i.value && (typeof i.value == "string" && (o.name = i.value), s.push(o)), l.value?.forEach((b) => s.push({ ...b })), s;
|
|
199
|
+
}), w = $([]), I = () => {
|
|
200
|
+
w.value = O();
|
|
201
|
+
}, O = () => {
|
|
202
|
+
const s = d.value.toLowerCase(), b = Ie(s), f = s.replace(/^https?:\/\/(www\.)?|\/$/g, "");
|
|
203
|
+
let k = [], z;
|
|
204
|
+
const S = [], Q = () => {
|
|
205
|
+
S.at(-1)?.listItemProps?.type === "delimiter" && S.pop(), S.length && (z && k.push(z), k.push(...S), S.length = 0);
|
|
206
|
+
};
|
|
207
|
+
for (const C of g.value)
|
|
208
|
+
switch (C.listItemProps?.type) {
|
|
209
|
+
case "title":
|
|
210
|
+
Q(), z = C;
|
|
211
|
+
break;
|
|
212
|
+
case "delimiter":
|
|
213
|
+
if (S.length) {
|
|
214
|
+
let X = S.length;
|
|
215
|
+
S.at(-1)?.listItemProps?.type === "delimiter" && X--, S[X] = C;
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
const D = C.name.toLowerCase();
|
|
220
|
+
(String(C.id).includes(s) || D.includes(s) || D.includes(b) || D.includes(f)) && (D === s || D === b ? S.unshift(C) : S.push(C));
|
|
221
|
+
}
|
|
222
|
+
if (Q(), k.push(...r.items.value), T.value && d.value && (!p.value || p.value(s)) && // результаты могут быть найдены, но не точные, тогда предложить добавить элемент
|
|
223
|
+
!k.find((C) => C.name.toLowerCase() === s)) {
|
|
224
|
+
const C = {
|
|
225
|
+
id: W,
|
|
226
|
+
name: d.value
|
|
227
|
+
};
|
|
228
|
+
k.push(C);
|
|
229
|
+
}
|
|
230
|
+
return t && (k = k.filter((C) => !ae(e.value, C))), k;
|
|
231
|
+
}, v = (s) => {
|
|
232
|
+
s.listItemProps?.type === "title" || s.listItemProps?.type === "delimiter" || (t && Array.isArray(e.value) ? ae(e.value, s) || (e.value = [...e.value, s]) : e.value = s, s.id === W && a("appendItem", s), setTimeout(() => {
|
|
233
|
+
A();
|
|
234
|
+
}));
|
|
235
|
+
};
|
|
236
|
+
if (r.apiRequest) {
|
|
237
|
+
const s = [l, r.items];
|
|
238
|
+
t && s.push(e), J(s, () => {
|
|
239
|
+
I();
|
|
240
|
+
});
|
|
241
|
+
} else
|
|
242
|
+
J([e, l, d], () => {
|
|
243
|
+
I();
|
|
244
|
+
}, {
|
|
245
|
+
immediate: !0,
|
|
246
|
+
// слежение за изменениями `items`
|
|
247
|
+
deep: 2
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
searchText: d,
|
|
251
|
+
resetSearch: A,
|
|
252
|
+
genIsShort: h,
|
|
253
|
+
itemsForShow: w,
|
|
254
|
+
selectItem: v,
|
|
255
|
+
selectNextItem: () => {
|
|
256
|
+
if (Array.isArray(e.value)) return;
|
|
257
|
+
const s = w.value.filter((k) => !["title", "delimiter"].includes(k.listItemProps?.type ?? "")), f = (s.findIndex((k) => k.id === e.value.id) + 1) % s.length;
|
|
258
|
+
e.value = { ...s[f] };
|
|
259
|
+
},
|
|
260
|
+
deleteItemByItem: async (s) => {
|
|
261
|
+
Array.isArray(e.value) && (e.value = e.value.filter((b) => b.id !== s.id || b.name !== s.name));
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}, Pe = {
|
|
265
|
+
key: 0,
|
|
266
|
+
class: "top-selector2_activeItems"
|
|
267
|
+
}, $e = {
|
|
268
|
+
key: 1,
|
|
269
|
+
class: "top-selector2_activeName top-ellipsis"
|
|
270
|
+
}, Fe = {
|
|
271
|
+
key: 2,
|
|
272
|
+
class: "top-selector2_placeholder top-ellipsis"
|
|
273
|
+
}, De = { class: "top-selector2_searchWidget" }, ze = /* @__PURE__ */ G({
|
|
274
|
+
__name: "selector2",
|
|
275
|
+
props: /* @__PURE__ */ U({
|
|
276
|
+
modelValue: {},
|
|
277
|
+
items: { default: () => [] },
|
|
278
|
+
title: {},
|
|
279
|
+
disabled: { type: Boolean },
|
|
280
|
+
icon: {},
|
|
281
|
+
modificator: {},
|
|
282
|
+
size: { default: "s" },
|
|
283
|
+
isError: { type: Boolean },
|
|
284
|
+
openByFocusInput: { type: Boolean, default: void 0 },
|
|
285
|
+
searchType: { default: "popup" },
|
|
286
|
+
placeholder: {},
|
|
287
|
+
api: {},
|
|
288
|
+
apiSetSearchParams: {},
|
|
289
|
+
minLength: { default: 0 },
|
|
290
|
+
useCache: { type: Boolean },
|
|
291
|
+
appendSearchToResult: { type: Boolean },
|
|
292
|
+
appendSearchToResultCond: {},
|
|
293
|
+
multiselect: { type: Boolean },
|
|
294
|
+
useAllItem: { type: [Boolean, String] },
|
|
295
|
+
addChanger: { type: Boolean },
|
|
296
|
+
buttonProps: {},
|
|
297
|
+
selectedAsPlaceholder: { type: Boolean },
|
|
298
|
+
openerShortcut: {}
|
|
299
|
+
}, {
|
|
300
|
+
modelValue: { required: !0 },
|
|
301
|
+
modelModifiers: {}
|
|
302
|
+
}),
|
|
303
|
+
emits: /* @__PURE__ */ U(["appendItem"], ["update:modelValue"]),
|
|
304
|
+
setup(e, { expose: a, emit: l }) {
|
|
305
|
+
const t = e, i = se(e, "modelValue"), T = l;
|
|
306
|
+
a({
|
|
307
|
+
/**
|
|
308
|
+
* Сброс локального кеша и кеша api
|
|
309
|
+
*
|
|
310
|
+
* @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными
|
|
311
|
+
*/
|
|
312
|
+
resetCache: (v = !1) => {
|
|
313
|
+
u.apiRequest && (v && Te(u.apiRequest.path), u.items.value = [], u.countLoading.value = 0, u.apiRequest.params.offset = 0, requestAnimationFrame(() => {
|
|
314
|
+
n.itemsForShow.value = [];
|
|
315
|
+
}), o()?.elPopup && u.setSearchTextAndLoad(n.searchText.value));
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
const p = K(() => t.searchType === "inline" && t.multiselect || t.searchType === "inline" && j.state.isMobile ? "popup" : t.searchType), u = Be(t.api, t.apiSetSearchParams, t.minLength, t.useCache), n = Me(
|
|
319
|
+
i,
|
|
320
|
+
T,
|
|
321
|
+
R(t, "items"),
|
|
322
|
+
t.multiselect,
|
|
323
|
+
R(t, "useAllItem"),
|
|
324
|
+
R(t, "appendSearchToResult"),
|
|
325
|
+
R(t, "appendSearchToResultCond"),
|
|
326
|
+
p,
|
|
327
|
+
t.minLength,
|
|
328
|
+
u
|
|
329
|
+
), r = K(() => t.buttonProps ? "TopButton" : p.value === "inline" ? "TopInput" : "div"), d = $(null), o = () => d.value?.popup;
|
|
330
|
+
u.apiRequest && J(n.searchText, () => {
|
|
331
|
+
u.setSearchTextAndLoad(n.searchText.value);
|
|
332
|
+
});
|
|
333
|
+
const A = K(() => Array.isArray(i.value) || t.multiselect || !t.selectedAsPlaceholder && p.value !== "inline" ? t.placeholder : i.value?.name || t.placeholder), h = (v) => {
|
|
334
|
+
let m = !1;
|
|
335
|
+
switch (v.key) {
|
|
336
|
+
case "Delete":
|
|
337
|
+
case "Backspace":
|
|
338
|
+
Array.isArray(i.value) && (v.preventDefault(), v.stopPropagation(), i.value.pop());
|
|
339
|
+
break;
|
|
340
|
+
case "ArrowUp":
|
|
341
|
+
case "ArrowRight":
|
|
342
|
+
case "ArrowDown":
|
|
343
|
+
case "ArrowLeft":
|
|
344
|
+
case "Enter":
|
|
345
|
+
case " ":
|
|
346
|
+
m = !0;
|
|
347
|
+
break;
|
|
348
|
+
case "Escape":
|
|
349
|
+
p.value === "inline" && n.resetSearch();
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
const F = v.key.length === 1 && !v.ctrlKey && !v.metaKey;
|
|
353
|
+
(p.value === "popup" || p.value === "inline") && F && (m = !0), o()?.elPopup && (m = !1), m && (p.value === "popup" && (v.preventDefault(), v.stopPropagation(), F && (n.searchText.value || (n.searchText.value = v.key))), v.currentTarget?.click());
|
|
354
|
+
}, g = (v) => {
|
|
355
|
+
v.preventDefault(), n.selectNextItem();
|
|
356
|
+
}, w = () => {
|
|
357
|
+
u.apiRequest && u.setSearchTextAndLoad(n.searchText.value, !1);
|
|
358
|
+
}, I = () => {
|
|
359
|
+
p.value === "popup" && n.searchText.value && n.resetSearch();
|
|
360
|
+
}, O = (v) => {
|
|
361
|
+
const m = v.target;
|
|
362
|
+
m.scrollTop / (m.scrollHeight - m.offsetHeight) > 0.8 && u.load(!0);
|
|
363
|
+
};
|
|
364
|
+
return (v, m) => {
|
|
365
|
+
const F = fe("TopLoadbar"), s = Z("top-focus"), b = Z("top-shortcut");
|
|
366
|
+
return y(), x(c(ge), {
|
|
367
|
+
ref_key: "popupRef",
|
|
368
|
+
ref: d,
|
|
369
|
+
onOpen: m[3] || (m[3] = (f) => w()),
|
|
370
|
+
onClose: m[4] || (m[4] = (f) => I()),
|
|
371
|
+
onScrollContentList: m[5] || (m[5] = (f) => c(u) ? O(f) : void 0),
|
|
372
|
+
notch: !1,
|
|
373
|
+
transitionDuration: 0,
|
|
374
|
+
openByFocusInput: p.value === "inline" && (e.openByFocusInput ?? !0),
|
|
375
|
+
disabled: p.value === "inline" && c(n).genIsShort()
|
|
376
|
+
}, Y({
|
|
377
|
+
opener: B(() => [
|
|
378
|
+
ee((y(), x(pe(r.value), q(e.buttonProps, {
|
|
379
|
+
class: {
|
|
380
|
+
"top-selector2": !0,
|
|
381
|
+
"top-selector2-multiselect": e.multiselect,
|
|
382
|
+
["top-selector2-" + e.modificator]: !!e.modificator,
|
|
383
|
+
"top-as-input": !e.buttonProps && p.value !== "inline",
|
|
384
|
+
"top-as-selector": !0,
|
|
385
|
+
["top-size_" + e.size]: !0,
|
|
386
|
+
"top-disabled": e.disabled,
|
|
387
|
+
"top-forms-focusable": !e.disabled,
|
|
388
|
+
"top-error": e.isError
|
|
389
|
+
},
|
|
390
|
+
icon: e.icon,
|
|
391
|
+
tabindex: "0",
|
|
392
|
+
onKeydown: h,
|
|
393
|
+
onBlur: m[0] || (m[0] = (f) => p.value === "inline" && c(n).resetSearch()),
|
|
394
|
+
placeholder: A.value,
|
|
395
|
+
title: e.title,
|
|
396
|
+
captionType: p.value === "inline" && e.title !== void 0 ? "top" : void 0,
|
|
397
|
+
modelValue: c(n).searchText.value,
|
|
398
|
+
"onUpdate:modelValue": m[1] || (m[1] = (f) => c(n).searchText.value = f)
|
|
399
|
+
}), {
|
|
400
|
+
default: B(() => [
|
|
401
|
+
e.multiselect ? (y(), L("div", Pe, [
|
|
402
|
+
(y(!0), L(E, null, H(i.value, (f) => (y(), x(Se, {
|
|
403
|
+
id: f.id,
|
|
404
|
+
name: f.name,
|
|
405
|
+
onDelete: c(n).deleteItemByItem
|
|
406
|
+
}, null, 8, ["id", "name", "onDelete"]))), 256))
|
|
407
|
+
])) : M("", !0),
|
|
408
|
+
p.value !== "inline" && !e.multiselect ? (y(), L("span", $e, P(Array.isArray(i.value) ? "" : i.value.name), 1)) : M("", !0),
|
|
409
|
+
e.multiselect && !i.value.length ? (y(), L("span", Fe, P(A.value), 1)) : M("", !0),
|
|
410
|
+
e.addChanger && !e.buttonProps && !e.multiselect && c(n).itemsForShow.value.length > 1 && !e.disabled ? (y(), L("span", {
|
|
411
|
+
key: 3,
|
|
412
|
+
class: "top-changer top-changer-selector",
|
|
413
|
+
"data-top-popup-disabled": "true",
|
|
414
|
+
onClick: g
|
|
415
|
+
})) : M("", !0)
|
|
416
|
+
]),
|
|
417
|
+
_: 1
|
|
418
|
+
}, 16, ["class", "icon", "placeholder", "title", "captionType", "modelValue"])), [
|
|
419
|
+
[
|
|
420
|
+
s,
|
|
421
|
+
e.isError,
|
|
422
|
+
void 0,
|
|
423
|
+
{ onupdate: !0 }
|
|
424
|
+
],
|
|
425
|
+
[b, e.openerShortcut]
|
|
426
|
+
])
|
|
427
|
+
]),
|
|
428
|
+
contentList: B(() => [
|
|
429
|
+
(y(!0), L(E, null, H(c(n).itemsForShow.value, (f) => (y(), x(c(le), q({
|
|
430
|
+
key: f.id ?? void 0,
|
|
431
|
+
class: {
|
|
432
|
+
"top-active": !Array.isArray(i.value) && !e.multiselect && i.value.id === f.id && i.value.name === f.name,
|
|
433
|
+
"top-selector2_item-all": f.id === c(oe),
|
|
434
|
+
"top-selector2_item-new": f.id === c(W)
|
|
435
|
+
}
|
|
436
|
+
}, { ref_for: !0 }, f.listItemProps, {
|
|
437
|
+
closeByClick: !e.multiselect || c(j).state.isMobile,
|
|
438
|
+
onClick: (k) => c(n).selectItem(f)
|
|
439
|
+
}), {
|
|
440
|
+
default: B(() => [
|
|
441
|
+
v.$slots.item ? _(v.$slots, "item", {
|
|
442
|
+
key: 0,
|
|
443
|
+
item: f
|
|
444
|
+
}) : (y(), L(E, { key: 1 }, [
|
|
445
|
+
N(P(f.name), 1)
|
|
446
|
+
], 64))
|
|
447
|
+
]),
|
|
448
|
+
_: 2
|
|
449
|
+
}, 1040, ["class", "closeByClick", "onClick"]))), 128)),
|
|
450
|
+
!c(n).itemsForShow.value.length && !c(n).genIsShort() ? (y(), x(c(le), {
|
|
451
|
+
key: 0,
|
|
452
|
+
type: "regular"
|
|
453
|
+
}, {
|
|
454
|
+
default: B(() => [
|
|
455
|
+
!c(u).isLoading.value || c(u).countLoading.value ? (y(), L(E, { key: 0 }, [
|
|
456
|
+
N(P(v.$i18n.Common.No_results), 1)
|
|
457
|
+
], 64)) : (y(), x(c(ye), {
|
|
458
|
+
key: 1,
|
|
459
|
+
type: "circles"
|
|
460
|
+
}))
|
|
461
|
+
]),
|
|
462
|
+
_: 1
|
|
463
|
+
})) : M("", !0),
|
|
464
|
+
c(u).countLoading.value && c(u).isLoading.value && p.value === "inline" ? (y(), x(F, { key: 1 })) : M("", !0)
|
|
465
|
+
]),
|
|
466
|
+
_: 2
|
|
467
|
+
}, [
|
|
468
|
+
p.value === "popup" ? {
|
|
469
|
+
name: "widget",
|
|
470
|
+
fn: B(() => [
|
|
471
|
+
re("div", De, [
|
|
472
|
+
ee(ne(c(Ae), {
|
|
473
|
+
title: "Поиск",
|
|
474
|
+
icon: "",
|
|
475
|
+
modelValue: c(n).searchText.value,
|
|
476
|
+
"onUpdate:modelValue": m[2] || (m[2] = (f) => c(n).searchText.value = f),
|
|
477
|
+
isLoading: !!c(u).countLoading.value && c(u).isLoading.value,
|
|
478
|
+
placeholder: A.value
|
|
479
|
+
}, null, 8, ["modelValue", "isLoading", "placeholder"]), [
|
|
480
|
+
[
|
|
481
|
+
s,
|
|
482
|
+
i.value,
|
|
483
|
+
void 0,
|
|
484
|
+
{ onupdate: !0 }
|
|
485
|
+
]
|
|
486
|
+
]),
|
|
487
|
+
_(v.$slots, "widgetAction")
|
|
488
|
+
])
|
|
489
|
+
]),
|
|
490
|
+
key: "0"
|
|
491
|
+
} : void 0
|
|
492
|
+
]), 1032, ["openByFocusInput", "disabled"]);
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
export {
|
|
497
|
+
W as I,
|
|
498
|
+
ze as _,
|
|
499
|
+
We as a,
|
|
500
|
+
Oe as b,
|
|
501
|
+
oe as c
|
|
502
|
+
};
|
|
503
|
+
//# sourceMappingURL=policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.vue_vue_type_style_index_0_lang-C9A--uWd.es.js","sources":["../../src/components/formsExt/menu/menu.vue","../../src/components/formsExt/selector2/itemMulti.vue","../../src/components/formsExt/selector2/cache.ts","../../src/components/formsExt/selector2/composables/useAPI.ts","../../src/components/formsExt/selector2/utils.ts","../../src/components/formsExt/selector2/composables/useMenu.ts","../../src/components/formsExt/selector2/selector2.vue"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { onMounted, onUpdated, ref } from 'vue';\r\nimport type { Item, Props } from './types';\r\nimport Core from '@/core/core/core';\r\nimport { isSafari } from '@/core/utils/device';\r\nimport TopButton from '@/components/forms/button/button.vue';\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tstyling: 'default',\r\n});\r\n\r\nconst model = defineModel({\r\n\trequired: true,\r\n});\r\n\r\nconst el = ref();\r\n\r\n// валидация типа modelValue без возможности выбора нескольких значений (ожидается строка или число)\r\nif (!props.isMultiple && typeof (model.value) !== 'string' && typeof (model.value) !== 'number') {\r\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected String: ' + typeof (model.value));\r\n}\r\n\r\n// валидация типа modelValue с возможностью выбора нескольких значений (ожидается массив)\r\nif (props.isMultiple && !Array.isArray(model.value)) {\r\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected Array: ' + typeof (model.value));\r\n}\r\n\r\n/**\r\n * Для множественного выбора без пустого множества\r\n *\r\n * Если ничего не выбрано, присваиваем 1-ое значение\r\n */\r\nif (props.isMultiple && !props.canBeEmptyMultiple && Array.isArray(model.value) && !model.value.length && props.items[0]) {\r\n\tmodel.value = [props.items[0]?.href ?? props.items[0]?.value];\r\n}\r\n\r\nconst itemIsActive = (item: Item) => {\r\n\tif (!Array.isArray(model.value)) {\r\n\t\treturn item.value === model.value;\r\n\t}\r\n\r\n\treturn model.value.includes(item.value);\r\n};\r\n\r\n/**\r\n * Выбрать элемент\r\n * @param item\r\n * @param toggle - добавить или исключить элемент, для isMultiple\r\n */\r\nconst select = (item: Item, toggle = false) => {\r\n\tif (Array.isArray(model.value)) {\r\n\t\tlet modelNew = model.value.slice();\r\n\r\n\t\tif (toggle) {\r\n\t\t\tif (!modelNew.length) modelNew = props.items.map(item => item.value);\r\n\r\n\t\t\tconst index = modelNew.indexOf(item.value);\r\n\t\t\tif (index === -1) {\r\n\t\t\t\tmodelNew.push(item.value);\r\n\t\t\t} else {\r\n\t\t\t\tmodelNew.splice(index, 1);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (modelNew.length === 1 && modelNew[0] === item.value) {\r\n\t\t\t\tmodelNew = [];\r\n\t\t\t} else {\r\n\t\t\t\tmodelNew = [item.value];\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!props.canBeEmptyMultiple && !modelNew.length) modelNew = [item.value];\r\n\r\n\t\tmodel.value = modelNew;\r\n\r\n\t\treturn;\r\n\t}\r\n\r\n\tmodel.value = item.value;\r\n};\r\n\r\n// вертикальный скролл в горизонтальный скролл\r\nconst onWheel = (event: WheelEvent) => {\r\n\tif (el.value.scrollWidth <= el.value.offsetWidth) return;\r\n\tif (event.shiftKey) return;\r\n\tif (Math.abs(event.deltaY) < 50) return; // устройство с высокой точностью, например тачпад\r\n\r\n\tevent.preventDefault();\r\n\r\n\tconst delta = event.deltaY > 0 ? 30 : -30;\r\n\tel.value.scrollLeft = el.value.scrollLeft + delta;\r\n};\r\n\r\n/**\r\n * Замена стандартному scrollIntoView, который меняет скролл документа\r\n *\r\n * Выравнивание по ближнему краю элемента\r\n *\r\n * Выравнивается таким образом, чтобы был виден соседний элемент\r\n */\r\nconst scrollIntoView = (isSmooth = true) => {\r\n\tconst elBtn = el.value.querySelector('.top-active');\r\n\tif (!elBtn) return;\r\n\r\n\tconst gap = 24;\r\n\r\n\t// левая и правая координаты элемента\r\n\tconst leftMargin = elBtn.offsetLeft - el.value.offsetLeft - gap;\r\n\tconst rightMargin = elBtn.offsetLeft - el.value.offsetLeft + elBtn.clientWidth + gap;\r\n\r\n\t// левая и правая границы видимой части меню\r\n\tconst leftMarginParent = el.value.scrollLeft;\r\n\tconst rightMarginParent = el.value.clientWidth + el.value.scrollLeft;\r\n\r\n\tlet scrollLeft: number | undefined = undefined;\r\n\r\n\t// левую границу элемента к левой границе меню\r\n\tif (leftMargin < leftMarginParent) scrollLeft = leftMargin;\r\n\r\n\t// правую границу элемента к правой границе меню\r\n\tif (rightMargin > rightMarginParent) scrollLeft = rightMargin - el.value.clientWidth;\r\n\r\n\tif (scrollLeft !== undefined) {\r\n\t\tif (isSafari()) {\r\n\t\t\tCore.$?.(el.value).animate({ scrollLeft: scrollLeft }, isSmooth ? 200 : 0);\r\n\t\t} else {\r\n\t\t\tel.value.scrollTo({ left: scrollLeft, behavior: isSmooth ? 'smooth' : 'auto' });\r\n\t\t}\r\n\t}\r\n};\r\n\r\n/**\r\n * Выбрать все элементы в меню\r\n */\r\nconst selectAll = () => {\r\n\tif (!Array.isArray(model.value)) return;\r\n\r\n\tif (model.value.length === props.items.length) {\r\n\t\tmodel.value = [props.items[0].href ?? props.items[0].value];\r\n\t\treturn;\r\n\t}\r\n\r\n\tmodel.value = props.items.map(item => item.href ?? item.value);\r\n};\r\n\r\nonMounted(() => scrollIntoView(false));\r\nonUpdated(() => scrollIntoView(true));\r\n\r\n</script>\r\n\r\n<template>\r\n\t<div\r\n\t\tref=\"el\"\r\n\t\t:class=\"{\r\n\t\t\t'top-menu': true,\r\n\t\t\t['top-style_' + styling]: true,\r\n\t\t\t// ['top-unwrap-x']: styling === 'default',\r\n\t\t}\"\r\n\t\t@wheel=\"onWheel\"\r\n\t>\r\n\t\t<TopButton\r\n\t\t\tv-for=\"item in items\"\r\n\t\t\t:=\"item\"\r\n\t\t\tclass=\"top-menu_item\"\r\n\t\t\tcolor=\"theme\"\r\n\t\t\t@click=\"select(item, $event.ctrlKey || $event.metaKey)\"\r\n\t\t\t:isActive=\"itemIsActive(item)\"\r\n\t\t>\r\n\t\t\t<template #default v-if=\"item.content\">\r\n\t\t\t\t{{ item.content }}\r\n\t\t\t</template>\r\n\t\t</TopButton>\r\n\r\n\t\t<div\r\n\t\t\tv-if=\"Array.isArray(model) && selectAllItem\"\r\n\t\t\tclass=\"top-menu_selectAll\"\r\n\t\t>\r\n\t\t\t<TopButton\r\n\t\t\t\t:=\"selectAllItem\"\r\n\t\t\t\tclass=\"top-menu_item\"\r\n\t\t\t\tcolor=\"theme\"\r\n\t\t\t\tstyling=\"\"\r\n\t\t\t\t@click=\"selectAll()\"\r\n\t\t\t\t:isActive=\"model.length === items.length\"\r\n\t\t\t>\r\n\t\t\t\t<template #default v-if=\"selectAllItem.content\">\r\n\t\t\t\t\t{{ selectAllItem.content }}\r\n\t\t\t\t</template>\r\n\t\t\t</TopButton>\r\n\t\t</div>\r\n\t</div>\r\n</template>\r\n\r\n<style>\r\n.top-menu {\r\n\t--scroll-thumb-color: var(--color-line-1);\r\n\t--scroll-thumb-color-hover: var(--color-line-2);\r\n\t--scroll-thumb-color-active: var(--color-line-3);\r\n\r\n\tmax-width: 100%;\r\n\tdisplay: flex;\r\n\talign-items: flex-start;\r\n\tgap: var(--top-gap-2);\r\n\toverflow-x: auto;\r\n\tscrollbar-width: none; /* firefox */\r\n\r\n\t/* предотвратить натинвые события браузера (назад / вперед) */\r\n\toverscroll-behavior-x: contain;\r\n}\r\n\r\n.top-menu::-webkit-scrollbar { display: none; }\r\n\r\n.top-menu .top-menu_item {\r\n\t--top-button-color: var(--color-text-2);\r\n\r\n\toutline-offset: -2px !important;\r\n\tmin-width: 0;\r\n\tmax-width: 200px;\r\n\tmargin: 0;\r\n\tflex-shrink: 0;\r\n}\r\n\r\n.top-menu .top-menu_item[data-top-icon] {\r\n\t--top-icon-color: var(--color-text-2);\r\n}\r\n\r\n.top-menu_selectAll {\r\n\tposition: sticky;\r\n\tright: 0;\r\n\tbackground: var(--color-layout-front-1);\r\n\tborder-left: 1px solid var(--color-line-1);\r\n\tpadding-left: var(--top-padding-1);\r\n\tbox-shadow: var(--color-layout-front-1) var(--top-padding-2) 0px;\r\n}\r\n\r\n/* style default */\r\n.top-menu.top-style_default .top-menu_item {\r\n\t--top-forms-radius: 0;\r\n\t--top-forms-border-color: transparent;\r\n\t--top-forms-border-width: 2px;\r\n\r\n\tfilter: none;\r\n\tbox-shadow: none;\r\n\tborder: none;\r\n\tborder-bottom: var(--top-forms-border-width) solid var(--top-forms-border-color);\r\n\tbackground: none;\r\n}\r\n\r\n.top-style_default > .top-menu_item > [data-top-badge] {\r\n\tmargin-top: 0;\r\n}\r\n\r\n.top-menu.top-style_default .top-menu_item:hover {\r\n\t--top-icon-color: var(--color-text-1);\r\n\t--top-button-color: var(--color-text-1);\r\n\t--top-forms-border-color: var(--color-line-2);\r\n}\r\n\r\n.top-menu.top-style_default .top-menu_item:active,\r\n.top-menu.top-style_default .top-menu_item.top-active {\r\n\t--top-icon-color: var(--color-text-primary);\r\n\t--top-button-color: var(--color-text-1);\r\n\t--top-forms-border-color: var(--color-line-primary-1);\r\n}\r\n\r\n.top-menu.top-style_default .top-menu_selectAll {\r\n\tpadding-left: var(--top-padding-2);\r\n}\r\n\r\n/* style bar */\r\n.top-menu.top-style_bar {\r\n\tborder-radius: var(--top-radius-3);\r\n\tborder: 1px solid var(--color-line-2);\r\n\tpadding: var(--top-padding-1);\r\n\tgap: 3px;\r\n}\r\n.top-menu.top-style_bar .top-menu_item {\r\n\t--top-button-background-color-hover: var(--color-layer-1);\r\n\t--top-button-background-color-active: var(--color-layer-2);\r\n\t--top-button-background-color-selected: var(--color-layer-primary-1);\r\n\r\n\tposition: relative;\r\n}\r\n\r\n.top-menu.top-style_bar .top-menu_item:hover {\r\n\t--top-icon-color: var(--color-text-1);\r\n\t--top-button-color: var(--color-text-1);\r\n}\r\n\r\n.top-menu.top-style_bar .top-menu_item.top-active {\r\n\t--top-icon-color: var(--color-text-primary);\r\n\t--top-button-color: var(--color-text-primary);\r\n}\r\n\r\n/* разделители кнопок в баре */\r\n.top-menu.top-style_bar .top-menu_item:not(:first-child):not(.top-active):not(:hover):after {\r\n\tcontent: \"\";\r\n\tbackground: var(--color-line-1-opacity);\r\n\twidth: 1px;\r\n\theight: 60%;\r\n\tdisplay: block;\r\n\tposition: absolute;\r\n\tleft: -2px;\r\n}\r\n.top-menu.top-style_bar .top-menu_item.top-active + .top-menu_item:after,\r\n.top-menu.top-style_bar .top-menu_item:hover + .top-menu_item:after {\r\n\tcontent: none !important;\r\n}\r\n\r\n/*\r\n.top-style_bar > .top-menu_item > [data-top-badge] {\r\n\tmargin-top: -3px;\r\n}\r\n*/\r\n\r\n/** TODO: .top-unwrap-x надо вынести глобально в UI или добавить в стили для storybook */\r\n/*\r\n.top-menu.top-unwrap-x {\r\n\tpadding-right: var(--top-unwrap-x);\r\n\tpadding-left: var(--top-unwrap-x);\r\n\tmargin-right: calc(0px - var(--top-unwrap-x));\r\n\tmargin-left: calc(0px - var(--top-unwrap-x));\r\n}\r\n*/\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport type { EmitsItemMulti, PropsItemMulti } from './types';\r\n\r\ndefineProps<PropsItemMulti>();\r\ndefineEmits<EmitsItemMulti>();\r\n</script>\r\n\r\n<template>\r\n\t<div class=\"top-selector2_itemMulti top-ellipsis\">\r\n\t\t{{ name }}\r\n\r\n\t\t<span\r\n\t\t\tclass=\"top-selector2_itemMultiDelete\"\r\n\t\t\tdata-top-icon=\"\"\r\n\t\t\t@click=\"$emit('delete', {id, name})\"\r\n\t\t\t@mousedown.stop\r\n\t\t></span>\r\n\t</div>\r\n</template>\r\n\r\n<style>\r\n.top-selector2_itemMulti {\r\n\tbox-sizing: border-box;\r\n\tpadding-left: var(--top-padding-2);\r\n\tborder-radius: var(--top-radius-1, 4px);\r\n\tborder: 1px solid var(--color-line-primary-1);\r\n\tbackground: var(--color-layer-primary-2);\r\n\tmin-height: 22px;\r\n\tmax-width: 100%;\r\n\tcolor: var(--color-text-1);\r\n\tflex-grow: 0;\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: var(--top-gap-1);\r\n}\r\n\r\n.top-selector2_itemMultiDelete {\r\n\t--top-icon-size: 14px;\r\n\t--top-icon-width: 18px;\r\n\t--top-icon-color: var(--color-text-1);\r\n\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\theight: 100%;\r\n\tcursor: pointer;\r\n}\r\n\r\n.top-selector2_itemMultiDelete:hover {\r\n\tbackground: var(--color-layer-primary-2);\r\n}\r\n\r\n@media screen and (min-width: 900px) {\r\n\t.top-selector2.top-active .top-selector2_itemMultiDelete {\r\n\t\tz-index: calc(var(--top-popup-z-index) + 1);\r\n\t}\r\n}\r\n</style>\r\n","import type { Props } from './types';\r\n\r\n/**\r\n * Список кешей для конкретного API метода\r\n */\r\nexport const cacheByMethod = new Map<Api.PathAbstract, Map<string, any>>();\r\n\r\n/**\r\n * Сброс кеша конкретного API метода\r\n */\r\nexport const clearCache = (apiPath: Api.PathAbstract) => {\r\n\tcacheByMethod.get(apiPath)?.clear();\r\n};\r\n\r\nexport const genCacheKey = (api: NonNullable<Props['api']>) => {\r\n\tconst userId = window['mo']?.user?.id;\r\n\r\n\tconst cacheKey = JSON.stringify(api.params) + ':' + api.url + ':' + userId;\r\n\r\n\treturn cacheKey;\r\n};\r\n\r\nexport const getCache = (cacheKey: string, apiPath: Api.PathAbstract) => {\r\n\treturn cacheByMethod.get(apiPath)?.get(cacheKey);\r\n};\r\n\r\nexport const setCache = (cacheKey: string, apiPath: Api.PathAbstract, data: any) => {\r\n\tif (!cacheByMethod.has(apiPath)) {\r\n\t\tcacheByMethod.set(apiPath, new Map());\r\n\t}\r\n\r\n\tcacheByMethod.get(apiPath)?.set(cacheKey, data);\r\n};\r\n","import { ref } from 'vue';\r\nimport { debounce } from '../../../../core/utils/lodash';\r\nimport type { Item, Props } from '../types';\r\nimport { genCacheKey, getCache, setCache } from '../cache';\r\n\r\nexport type API = ReturnType<typeof useAPI>;\r\n\r\nexport const useAPI = (\r\n\tapi: Props['api'],\r\n\tapiSetSearchParams: Props['apiSetSearchParams'],\r\n\tminLength: number,\r\n\tuseCache: Props['useCache'],\r\n) => {\r\n\t/**\r\n\t * Список, полученный через API\r\n\t */\r\n\tconst items = ref<Item[]>([]);\r\n\r\n\t/**\r\n\t * Флаг - идет загрузка\r\n\t */\r\n\tconst isLoading = ref(false);\r\n\r\n\tconst countLoading = ref(0);\r\n\r\n\tlet searchText = '';\r\n\tlet nextOffset: number | null | undefined;\r\n\r\n\tif (api && !api.params.limit) {\r\n\t\tapi.params.limit = 100;\r\n\t}\r\n\r\n\t/**\r\n\t * Выполнить обращение к API\r\n\t *\r\n\t * При ошибке вернет undefined\r\n\t */\r\n\tconst callAPI = async (): Promise<Api.ResponseSuccess<any, 'get'> | undefined> => {\r\n\t\tif (!api) return;\r\n\r\n\t\tconst cacheKey = useCache ? genCacheKey(api) : undefined;\r\n\r\n\t\tif (cacheKey) {\r\n\t\t\tconst cache = getCache(cacheKey, api.path);\r\n\t\t\tif (cache) {\r\n\t\t\t\t// остановить запущенные api запросы\r\n\t\t\t\tapi.abortByFingerprint();\r\n\r\n\t\t\t\treturn cache;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst res = await api.call();\r\n\r\n\t\tif (res.errors) return;\r\n\r\n\t\tif (!Array.isArray(res.result)) {\r\n\t\t\tconsole.warn('Array expected in `res.result`');\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst indexWithError = (res.result as Array<Item | any>).findIndex(item => item.id === undefined || item.name === undefined);\r\n\t\tif (indexWithError !== -1) {\r\n\t\t\tconsole.warn(`В result[${indexWithError}] нет id или name`);\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (cacheKey) {\r\n\t\t\tsetCache(cacheKey, api.path, res);\r\n\t\t}\r\n\r\n\t\treturn res as Api.ResponseSuccess<any, 'get'>;\r\n\t};\r\n\r\n\t/**\r\n\t * Загрузить items\r\n\t */\r\n\tconst load = async (append: boolean) => {\r\n\t\tif (!api) return;\r\n\r\n\t\tif (append) {\r\n\t\t\t// данных о следующих страницах не обнаружено\r\n\t\t\tif (!nextOffset) return;\r\n\r\n\t\t\t// дозагружать нельзя, если не завершена предыдущая загрузка\r\n\t\t\tif (isLoading.value) return;\r\n\r\n\t\t\tapi.params.offset = nextOffset;\r\n\t\t} else {\r\n\t\t\tapi.params.offset = 0;\r\n\t\t}\r\n\r\n\t\tapiSetSearchParams?.(api, searchText);\r\n\r\n\t\tisLoading.value = true;\r\n\t\tconst res = await callAPI();\r\n\t\tisLoading.value = false;\r\n\r\n\t\tcountLoading.value++;\r\n\r\n\t\tif (!res) return;\r\n\r\n\t\tnextOffset = res.nextOffset;\r\n\r\n\t\tif (append) {\r\n\t\t\titems.value = items.value.concat(res.result);\r\n\t\t} else {\r\n\t\t\titems.value = res.result;\r\n\t\t}\r\n\t};\r\n\r\n\tconst loadDebounce = debounce(() => load(false), 200);\r\n\r\n\t/**\r\n\t * Выполнить поиск по указанному тексту\r\n\t *\r\n\t * Если длина текста меньше minLength, поиск не будет произведен\r\n\t *\r\n\t * Если текст не изменился, поиск не будет произведен\r\n\t *\r\n\t * @param newSearchText - текст поиска\r\n\t * @param useDebounce - дедупликация загрузки списка\r\n\t */\r\n\tconst setSearchTextAndLoad = (newSearchText: string, useDebounce = true) => {\r\n\t\tif (!api) return;\r\n\r\n\t\t// остановить начатый поиск и сбросить результаты\r\n\t\tif (newSearchText.length < minLength) {\r\n\t\t\tapi.abortByFingerprint();\r\n\r\n\t\t\titems.value = [];\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// условия поиска не поменялись, данные загружены\r\n\t\tif (newSearchText === searchText && items.value.length) return;\r\n\r\n\t\tsearchText = newSearchText;\r\n\r\n\t\tif (useDebounce) {\r\n\t\t\tvoid loadDebounce();\r\n\t\t} else {\r\n\t\t\tvoid load(false);\r\n\t\t}\r\n\t};\r\n\r\n\treturn {\r\n\t\tapiRequest: api,\r\n\t\titems,\r\n\t\tisLoading,\r\n\t\tcountLoading,\r\n\t\tload,\r\n\t\tsetSearchTextAndLoad,\r\n\t};\r\n};\r\n","import type { Item, Props } from './types';\r\nimport { genFieldFilter } from '@/api/api';\r\n\r\n/**\r\n * Универсальный id для всех элементов \"Все элементы\" / \"Без фильтра\" в `TopSelector`\r\n */\r\nexport const ITEM_ID_ALL = 0;\r\n\r\n/**\r\n * Универсальный id для всех добавляемых элементов через `TopSelector`\r\n */\r\nexport const ITEM_ID_NEW = null;\r\n\r\n/**\r\n * Выбран ли элемент\r\n */\r\nexport const isSelected = (modelValue: Props['modelValue'], item: Item, checkNameForNullId = true) => {\r\n\tif (checkNameForNullId && item.id === ITEM_ID_NEW) {\r\n\t\tif (Array.isArray(modelValue)) {\r\n\t\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id && itemSelected.name === item.name);\r\n\t\t} else {\r\n\t\t\treturn item.name === modelValue.name;\r\n\t\t}\r\n\t}\r\n\r\n\tif (Array.isArray(modelValue)) {\r\n\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id);\r\n\t} else {\r\n\t\treturn item.id === modelValue.id;\r\n\t}\r\n};\r\n\r\n/**\r\n * Вспомогательная утилита для создания `callback` функции на добавление фильтра по полю в api запрос\r\n *\r\n * Другие фильтры по указанному полю будут удалены\r\n *\r\n * @param api - api, которое используется в `TopSelector`\r\n * @param search - введенная строка поиска\r\n * @param fieldName - имя поля, по которому надо добавить фильтр на поиск по нестрогому соответствию\r\n */\r\nexport const apiSetSearchParamsFilter = (api: NonNullable<Props['api']>, search: string, fieldName: string) => {\r\n\tlet filters = api.params.filters ?? [];\r\n\r\n\t// удаление других фильтров по этому полю\r\n\tfilters = filters.filter((filter) => filter.name !== fieldName);\r\n\r\n\tif (search) {\r\n\t\tfilters.push(genFieldFilter(fieldName, 'CONTAINS', [search]));\r\n\t}\r\n\r\n\tapi.changeParams({ filters });\r\n};\r\n","import { computed, type ComputedRef, ref, type Ref, watch } from 'vue';\nimport { invertKeyboardLayout } from '@/core/utils/keyboard';\nimport type { Item, Props } from '../types';\nimport { type API } from './useAPI';\nimport { isSelected, ITEM_ID_ALL, ITEM_ID_NEW } from '../utils';\nimport { useI18n } from '@/core/plugins/i18n';\n\n/**\n * Функционал поиска\n */\nexport const useMenu = (\n\tmodel: Ref<Props['modelValue']>,\n\temits: ReturnType<typeof defineEmits>,\n\titems: Ref<Props['items']>,\n\tmultiselect: Props['multiselect'],\n\tuseAllItem: Ref<Props['useAllItem']>,\n\tappendSearchToResult: Ref<Props['appendSearchToResult']>,\n\tappendSearchToResultCond: Ref<Props['appendSearchToResultCond']>,\n\tsearchType: Ref<Props['searchType']>,\n\tminLength: number,\n\tapi: API,\n) => {\n\t/**\n\t * Текст поиска по результатам\n\t */\n\tconst searchText = ref('');\n\n\t/**\n\t * Объект, представляющий опцию \"Все\"\n\t */\n\tconst itemAll = {\n\t\tid: ITEM_ID_ALL,\n\t\tname: useI18n().Common.All as string,\n\t};\n\n\t/**\n\t * Сброс поиска\n\t */\n\tconst resetSearch = () => {\n\t\tsearchText.value = '';\n\t};\n\n\t/**\n\t * Является ли строка поиска достаточной длины для отображения меню\n\t */\n\tconst genIsShort = () => {\n\t\tif (!api.apiRequest) return false;\n\t\tif (searchText.value.length >= minLength) return false;\n\n\t\treturn true;\n\t};\n\n\t/**\n\t * Варианты выбора: props.items + \"Выбрать все\"\n\t */\n\tconst localItems: ComputedRef<Item[]> = computed(() => {\n\t\tconst localItems: Item[] = [];\n\n\t\tif (!multiselect && useAllItem.value) {\n\t\t\tif (typeof useAllItem.value === 'string') {\n\t\t\t\titemAll.name = useAllItem.value;\n\t\t\t}\n\n\t\t\tlocalItems.push(itemAll);\n\t\t}\n\n\t\titems.value?.forEach(item => localItems.push({ ...item }));\n\n\t\treturn localItems;\n\t});\n\n\t/**\n\t * Не используем `computed` в пользу ручного порядка пересчета значения\n\t */\n\tconst itemsForShow = ref<Item[]>([]);\n\n\tconst recalcItemsForShow = () => {\n\t\titemsForShow.value = genItemsForShow();\n\t};\n\n\t/**\n\t * Подготовленный список меню, который содержит в сумме:\n\t * - prop.items: указанный список с учетом фильтра и опций компонента\n\t * - api.items: результаты api запроса, если используется api\n\t *\n\t * @returns Отфильтрованный массив элементов для отображения\n\t */\n\tconst genItemsForShow = () => {\n\t\tconst searchString = searchText.value.toLowerCase();\n\t\tconst searchStringInvertKeyboard = invertKeyboardLayout(searchString);\n\t\tconst searchStringNormalized = searchString.replace(/^https?:\\/\\/(www\\.)?|\\/$/g, '');\n\n\t\tlet items: Item[] = [];\n\n\t\t/**\n\t\t * Элемент текущего разделителя в цикле\n\t\t *\n\t\t * Для скрытия / отображения только нужных заголовков и разделителей при поиске\n\t\t *\n\t\t * Логика для `api.items` должна реализовываться в api или api клиенте при генерации элементов\n\t\t */\n\t\tlet itemTitleCategory: Item | undefined;\n\t\tconst itemsCategory: Item[] = [];\n\n\t\t/**\n\t\t * Добавить элементы в результирующий список\n\t\t */\n\t\tconst flushCategory = () => {\n\t\t\t// крайний разделитель не выводить\n\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') {\n\t\t\t\titemsCategory.pop();\n\t\t\t}\n\n\t\t\tif (itemsCategory.length) {\n\t\t\t\tif (itemTitleCategory) {\n\t\t\t\t\titems.push(itemTitleCategory);\n\t\t\t\t}\n\n\t\t\t\titems.push(...itemsCategory);\n\n\t\t\t\titemsCategory.length = 0;\n\t\t\t}\n\t\t};\n\n\t\tfor (const item of localItems.value) {\n\t\t\tswitch (item.listItemProps?.type) {\n\t\t\t\tcase 'title':\n\t\t\t\t\tflushCategory();\n\n\t\t\t\t\titemTitleCategory = item;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'delimiter':\n\t\t\t\t\t// вставить разделитель один раз и только если категория не пуста\n\t\t\t\t\tif (itemsCategory.length) {\n\t\t\t\t\t\tlet index = itemsCategory.length;\n\t\t\t\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') index--;\n\n\t\t\t\t\t\titemsCategory[index] = item;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tconst name = item.name.toLowerCase();\n\t\t\t\t\tif (\n\t\t\t\t\t\tString(item.id).includes(searchString) ||\n\t\t\t\t\t\tname.includes(searchString) ||\n\t\t\t\t\t\tname.includes(searchStringInvertKeyboard) ||\n\t\t\t\t\t\tname.includes(searchStringNormalized)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (name === searchString || name === searchStringInvertKeyboard) {\n\t\t\t\t\t\t\t// точные совпадения в начало\n\t\t\t\t\t\t\titemsCategory.unshift(item);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titemsCategory.push(item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tflushCategory();\n\n\t\titems.push(...api.items.value);\n\n\t\t// ввод произвольного значения\n\t\tif (\n\t\t\tappendSearchToResult.value &&\n\t\t\t!!searchText.value &&\n\t\t\t(!appendSearchToResultCond.value || appendSearchToResultCond.value(searchString)) &&\n\n\t\t\t// результаты могут быть найдены, но не точные, тогда предложить добавить элемент\n\t\t\t!items.find((item) => item.name.toLowerCase() === searchString)\n\t\t) {\n\t\t\tconst itemNew = {\n\t\t\t\tid: ITEM_ID_NEW,\n\t\t\t\tname: searchText.value,\n\t\t\t};\n\n\t\t\t// предложение всегда отображается внизу, чтобы не мешать результатам поиска\n\t\t\titems.push(itemNew);\n\t\t}\n\n\t\tif (multiselect) {\n\t\t\titems = items.filter(item => !isSelected(model.value, item));\n\t\t}\n\n\t\treturn items;\n\t};\n\n\t/**\n\t * Выбрать элемент\n\t *\n\t * @param item Элемент для выбора\n\t */\n\tconst selectItem = (item: Item) => {\n\t\t// это невыбираемый элемент\n\t\tif (item.listItemProps?.type === 'title' || item.listItemProps?.type === 'delimiter') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (multiselect && Array.isArray(model.value)) {\n\t\t\tif (!isSelected(model.value, item)) {\n\t\t\t\tmodel.value = [...model.value, item];\n\t\t\t}\n\t\t} else {\n\t\t\tmodel.value = item;\n\t\t}\n\n\t\tif (item.id === ITEM_ID_NEW) {\n\t\t\temits('appendItem', item);\n\t\t}\n\n\t\t/**\n\t\t * Отложить перерисовку\n\t\t *\n\t\t * fix: Перерисовка меню выполняется раньше, чем срабатывает `click`.\n\t\t * Из-за этого обработчик кликов думает, что клик был вне меню и не закрывает окно\n\t\t *\n\t\t * Файл: @/components/popup/lib/popup.globalEvents.ts\n\t\t *\n\t\t * Функция: onclick()\n\t\t *\n\t\t * ```\n\t\t * const elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\t\t * ```\n\t\t */\n\t\tsetTimeout(() => {\n\t\t\t/**\n\t\t\t * Завершить поиск после выбора\n\t\t\t */\n\t\t\tresetSearch();\n\t\t});\n\n\t\t// /**\n\t\t// * При изменении значения модели в режиме inline необходимо очистить поле поиска,\n\t\t// * так как поиск больше не актуален после выбора значения\n\t\t// */\n\t\t// if (searchType.value === 'inline') {\n\t\t// \tresetSearch();\n\t\t// }\n\t};\n\n\tif (api.apiRequest) {\n\t\t// загрузка только при открытии popup\n\t\tconst fieldsForWatch: any = [items, api.items];\n\n\t\t// model нужен только для multiselect, без необходимости не использовать для улучшения UX при работе с API\n\t\tif (multiselect) {\n\t\t\tfieldsForWatch.push(model);\n\t\t}\n\n\t\twatch(fieldsForWatch, () => {\n\t\t\trecalcItemsForShow();\n\t\t});\n\t} else {\n\t\twatch([model, items, searchText], () => {\n\t\t\trecalcItemsForShow();\n\t\t}, {\n\t\t\timmediate: true,\n\n\t\t\t// слежение за изменениями `items`\n\t\t\tdeep: 2,\n\t\t});\n\t}\n\n\t/**\n\t * Выбрать следующее значение\n\t */\n\tconst selectNextItem = () => {\n\t\tif (Array.isArray(model.value)) return;\n\n\t\tconst selectableItems = itemsForShow.value.filter((item) => !['title', 'delimiter'].includes(item.listItemProps?.type ?? ''));\n\n\t\tconst currentIndex = selectableItems.findIndex(item => item.id === (model.value as Item).id);\n\t\tconst nextIndex = (currentIndex + 1) % selectableItems.length;\n\t\tmodel.value = { ...selectableItems[nextIndex] };\n\t};\n\n\t/**\n\t * Удалить элемент, `id` и `name` которого равны указанному `item`\n\t */\n\tconst deleteItemByItem = async (item: Item) => {\n\t\tif (Array.isArray(model.value)) {\n\t\t\tmodel.value = model.value.filter((itemI) => itemI.id !== item.id || itemI.name !== item.name);\n\t\t}\n\t};\n\n\treturn {\n\t\tsearchText,\n\t\tresetSearch,\n\t\tgenIsShort,\n\t\titemsForShow,\n\t\tselectItem,\n\t\tselectNextItem,\n\t\tdeleteItemByItem,\n\t};\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, toRef, watch } from 'vue';\nimport Core from '@/core/core/core';\nimport { TopPopup, TopPopupListItem, TopPopupWidgetInput } from '@/components/popup/popup';\nimport { TopPreloader } from '@/components/forms/forms';\nimport type { Emits, Item, Props, Slots } from './types';\nimport Selector2ItemMulti from './itemMulti.vue';\nimport { useAPI } from './composables/useAPI';\nimport { useMenu } from './composables/useMenu';\nimport type { TopLibPopup } from '../../popup/lib/popup';\nimport { clearCache } from './cache';\nimport { ITEM_ID_ALL, ITEM_ID_NEW } from './utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\titems: () => [] as Item[],\n\tsize: 's',\n\tminLength: 0,\n\tsearchType: 'popup',\n\topenByFocusInput: undefined,\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\ndefineSlots<Slots>();\n\nconst emits = defineEmits<Emits>();\n\ndefineExpose({\n\t/**\n\t * Сброс локального кеша и кеша api\n\t *\n\t * @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными\n\t */\n\tresetCache: (resetAPICache: boolean = false) => {\n\t\tif (!api.apiRequest) return;\n\n\t\t// сброс кеша api\n\t\tif (resetAPICache) {\n\t\t\tclearCache(api.apiRequest.path);\n\t\t}\n\n\t\t// сброс кеша списка\n\t\tapi.items.value = [];\n\n\t\t// сброс флага первичной загрузки\n\t\tapi.countLoading.value = 0;\n\n\t\t// сброс параметров дозагрузки\n\t\tapi.apiRequest.params.offset = 0;\n\n\t\t// сброс кеша локального списка с дополнительными элементами, например `useAllItem`\n\t\trequestAnimationFrame(() => {\n\t\t\tmenu.itemsForShow.value = [];\n\t\t});\n\n\t\t// сразу загрузить данные после сброса, если popup уже открыт\n\t\tif (getPopup()?.elPopup) {\n\t\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t\t}\n\t},\n});\n\nconst searchTypeLocal = computed(() => {\n\t// multiselect не поддерживает inline ввода\n\tif (props.searchType === 'inline' && props.multiselect) return 'popup';\n\n\t// В мобильной версии popup работает в полноэкранном режиме\n\tif (props.searchType === 'inline' && Core.state.isMobile) return 'popup';\n\n\treturn props.searchType;\n});\n\n/**\n * Объект для работы с API\n */\nconst api = useAPI(props.api, props.apiSetSearchParams, props.minLength, props.useCache);\n\n/**\n * Объект для работы с меню\n */\nconst menu = useMenu(\n\tmodel,\n\temits,\n\ttoRef(props, 'items'),\n\tprops.multiselect,\n\ttoRef(props, 'useAllItem'),\n\ttoRef(props, 'appendSearchToResult'),\n\ttoRef(props, 'appendSearchToResultCond'),\n\tsearchTypeLocal,\n\tprops.minLength,\n\tapi,\n);\n\nconst component = computed(() => {\n\tif (props.buttonProps) return 'TopButton';\n\tif (searchTypeLocal.value === 'inline') return 'TopInput';\n\n\treturn 'div';\n});\n\n/**\n * Экземпляр компонента Popup\n */\nconst popupRef = ref<any>(null);\n\n/**\n * Получить доступ к объекту popup\n */\nconst getPopup = (): TopLibPopup | undefined => {\n\treturn popupRef.value?.popup;\n};\n\nif (api.apiRequest) {\n\t// отложенный поиск при вводе текста\n\twatch(menu.searchText, () => {\n\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t});\n}\n\nconst placeholder = computed(() => {\n\tif (Array.isArray(model.value) || props.multiselect || !props.selectedAsPlaceholder && searchTypeLocal.value !== 'inline') {\n\t\treturn props.placeholder;\n\t}\n\n\treturn model.value?.name || props.placeholder;\n});\n\n/**\n * Обработчик ввода клавиш на кнопке или поле ввода\n */\nconst onOpenerKeydown = (e: KeyboardEvent) => {\n\tlet needOpen = false;\n\n\tswitch (e.key) {\n\t\tcase 'Delete':\n\t\tcase 'Backspace':\n\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tmodel.value.pop();\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\tcase 'ArrowRight':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowLeft':\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\tneedOpen = true;\n\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tif (searchTypeLocal.value === 'inline') {\n\t\t\t\t// очистка введенного текста\n\t\t\t\tmenu.resetSearch();\n\t\t\t}\n\n\t\t\tbreak;\n\t}\n\n\t// введен символ\n\tconst symbolPressed = e.key.length === 1 && !e.ctrlKey && !e.metaKey;\n\n\t// введен символ\n\tif (searchTypeLocal.value === 'popup' || searchTypeLocal.value === 'inline') {\n\t\tif (symbolPressed) {\n\t\t\tneedOpen = true;\n\t\t}\n\t}\n\n\t// popup уже открыт\n\tif (getPopup()?.elPopup) {\n\t\tneedOpen = false;\n\t}\n\n\tif (needOpen) {\n\t\tif (searchTypeLocal.value === 'popup') {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// введен символ\n\t\t\tif (symbolPressed) {\n\t\t\t\t// начало ввода, сразу ввести первый символ вместе с открытием popup\n\t\t\t\tif (!menu.searchText.value) {\n\t\t\t\t\tmenu.searchText.value = e.key;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(e.currentTarget as HTMLElement)?.click();\n\t}\n};\n\nconst onClickChanger = (e: MouseEvent) => {\n\te.preventDefault();\n\n\tmenu.selectNextItem();\n};\n\n/**\n * Обработчик открытия попапа\n */\nconst onOpen = () => {\n\tif (api.apiRequest) {\n\t\t// при открытии сразу выполнить поиск\n\t\tapi.setSearchTextAndLoad(menu.searchText.value, false);\n\t}\n};\n\n/**\n * Обработчик закрытия попапа\n */\nconst onClose = () => {\n\t// очистка введенного текста, в режиме `inline` input вызывается при `blur`\n\tif (searchTypeLocal.value === 'popup') {\n\t\tif (menu.searchText.value) menu.resetSearch();\n\t}\n};\n\n/**\n * Обработчик прокрутки списка контента\n *\n * Для дозагрузки элеменов через api\n *\n * @param {Event} e - Событие прокрутки\n */\nconst onScrollContentList = (e: Event) => {\n\tconst el = e.target as HTMLElement;\n\n\tif (el.scrollTop / (el.scrollHeight - el.offsetHeight) > 0.8) {\n\t\tapi.load(true);\n\t}\n};\n\nif (import.meta.env.STORYBOOK) {\n\twatch(\n\t\t() => props.multiselect,\n\t\t() => {\n\t\t\tif (props.multiselect) {\n\t\t\t\tif (!Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Выбери меня',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = {\n\t\t\t\t\t\tid: null,\n\t\t\t\t\t\tname: '',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ immediate: true },\n\t);\n\n\twatch(\n\t\t() => props.searchType,\n\t\t() => {\n\t\t\t// пауза для установки props в адресной строке\n\t\t\tsetTimeout(() => {\n\t\t\t\tlocation.reload();\n\t\t\t}, 500);\n\t\t},\n\t);\n}\n</script>\n\n<template>\n\t<TopPopup\n\t\tref=\"popupRef\"\n\t\t@open=\"onOpen()\"\n\t\t@close=\"onClose()\"\n\t\t@scrollContentList=\"api ? onScrollContentList($event) : undefined\"\n\t\t:notch=\"false\"\n\t\t:transitionDuration=\"0\"\n\t\t:openByFocusInput=\"searchTypeLocal === 'inline' && (openByFocusInput ?? true)\"\n\t\t:disabled=\"searchTypeLocal === 'inline' && menu.genIsShort()\"\n\t>\n\t\t<template #opener>\n\t\t\t<component\n\t\t\t\t:is=\"component\"\n\n\t\t\t\t:=\"buttonProps\"\n\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-selector2': true,\n\t\t\t\t\t'top-selector2-multiselect': multiselect,\n\t\t\t\t\t['top-selector2-' + modificator]: !!modificator,\n\t\t\t\t\t'top-as-input': !buttonProps && searchTypeLocal !== 'inline',\n\t\t\t\t\t'top-as-selector': true,\n\t\t\t\t\t['top-size_' + size]: true,\n\t\t\t\t\t['top-disabled']: disabled,\n\t\t\t\t\t['top-forms-focusable']: !disabled,\n\t\t\t\t\t['top-error']: isError,\n\t\t\t\t}\"\n\t\t\t\t:icon\n\t\t\t\ttabindex=\"0\"\n\t\t\t\t@keydown=\"onOpenerKeydown\"\n\t\t\t\t@blur=\"searchTypeLocal === 'inline' && menu.resetSearch()\"\n\t\t\t\tv-top-focus.onupdate=\"isError\"\n\t\t\t\tv-top-shortcut=\"openerShortcut\"\n\n\t\t\t\t:placeholder\n\t\t\t\t:title\n\t\t\t\t:captionType=\"searchTypeLocal === 'inline' && title !== undefined ? 'top' : undefined\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t>\n\t\t\t\t<template v-if=\"multiselect\">\n\t\t\t\t\t<div class=\"top-selector2_activeItems\">\n\t\t\t\t\t\t<Selector2ItemMulti\n\t\t\t\t\t\t\tv-for=\"item of model as Item[]\"\n\t\t\t\t\t\t\t:id=\"item.id\"\n\t\t\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t\t\t@delete=\"menu.deleteItemByItem\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<span v-if=\"searchTypeLocal !== 'inline' && !multiselect\" class=\"top-selector2_activeName top-ellipsis\">\n\t\t\t\t\t{{ !Array.isArray(model) ? model.name : '' }}\n\t\t\t\t</span>\n\n\t\t\t\t<span v-if=\"multiselect && !model.length\" class=\"top-selector2_placeholder top-ellipsis\">\n\t\t\t\t\t{{ placeholder }}\n\t\t\t\t</span>\n\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"addChanger && !buttonProps && !multiselect && menu.itemsForShow.value.length > 1 && !disabled\"\n\t\t\t\t\tclass=\"top-changer top-changer-selector\"\n\t\t\t\t\tdata-top-popup-disabled=\"true\"\n\t\t\t\t\t@click=\"onClickChanger\"\n\t\t\t\t></span>\n\t\t\t</component>\n\t\t</template>\n\n\t\t<template #widget v-if=\"searchTypeLocal === 'popup'\">\n\t\t\t<div class=\"top-selector2_searchWidget\">\n\t\t\t\t<TopPopupWidgetInput\n\t\t\t\t\ttitle=\"Поиск\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t\t\tv-top-focus.onupdate=\"model\"\n\t\t\t\t\t:isLoading=\"!!api.countLoading.value && api.isLoading.value\"\n\t\t\t\t\t:placeholder\n\t\t\t\t/>\n\n\t\t\t\t<slot name=\"widgetAction\"\n\t\t\t\t></slot>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopPopupListItem\n\t\t\t\tv-for=\"item of menu.itemsForShow.value\"\n\t\t\t\t:key=\"item.id ?? undefined\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-active': !Array.isArray(model) && !multiselect && model.id === item.id && model.name === item.name,\n\t\t\t\t\t'top-selector2_item-all':item.id === ITEM_ID_ALL,\n\t\t\t\t\t'top-selector2_item-new':item.id === ITEM_ID_NEW,\n\t\t\t\t}\"\n\t\t\t\t:=\"item.listItemProps\"\n\t\t\t\t:closeByClick=\"!multiselect || Core.state.isMobile\"\n\t\t\t\t@click=\"menu.selectItem(item)\"\n\t\t\t>\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"$slots.item\"\n\t\t\t\t\tname=\"item\"\n\t\t\t\t\t:item\n\t\t\t\t></slot>\n\n\t\t\t\t<template\n\t\t\t\t\tv-else\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</template>\n\t\t\t</TopPopupListItem>\n\n\t\t\t<!-- Элементов для отображения нет -->\n\t\t\t<template v-if=\"!menu.itemsForShow.value.length && !menu.genIsShort()\">\n\t\t\t\t<TopPopupListItem type=\"regular\">\n\t\t\t\t\t<template v-if=\"!api.isLoading.value || api.countLoading.value\">\n\t\t\t\t\t\t{{ $i18n.Common.No_results }}\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<!-- Индикатор первичной загрузки -->\n\t\t\t\t\t<TopPreloader\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"circles\"\n\t\t\t\t\t/>\n\t\t\t\t</TopPopupListItem>\n\t\t\t</template>\n\n\t\t\t<!-- Индикатор повторной загрузки -->\n\t\t\t<TopLoadbar v-if=\"!!api.countLoading.value && api.isLoading.value && searchTypeLocal === 'inline'\"/>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-selector2 {\n\twidth: 180px;\n}\n\n.top-selector2::placeholder,\n.top-selector2_placeholder {\n\tcolor: var(--color-text-2);\n}\n\n.top-selector2_placeholder {\n\tpadding-left: var(--top-padding-1);\n}\n\n.top-selector2.top-as-input {\n\tpadding: var(--top-padding-1) var(--top-forms-padding);\n}\n\n.top-selector2.top-selector2-multiselect {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tflex-grow: 1;\n}\n\n.top-selector2.top-active {\n\t--top-forms-border-color: var(--top-forms-border-color-hover);\n}\n\n.top-selector2_searchWidget {\n\tdisplay: flex;\n\tgap: var(--top-gap-2);\n}\n\n.top-selector2_activeItems {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--top-padding-1);\n\tmax-width: 100%;\n}\n\n.top-selector2_activeName {\n\twhite-space: nowrap;\n}\n\n.top-changer-selector {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tmargin: calc(0px - var(--top-padding-1));\n\ttransform: translateX(0);\n}\n\n.top-selector2.top-button {\n\tjustify-content: start;\n}\n\n.top-selector2.top-input_input ~ .top-changer-selector {\n\ttransform: translateX(-52px);\n}\n\n.top-selector2.top-as-selector {\n\tpadding-right: calc(var(--top-selector-arrow-width) + var(--top-padding-2));\n}\n</style>\n"],"names":["props","__props","model","_useModel","el","ref","itemIsActive","item","select","toggle","modelNew","index","onWheel","event","delta","scrollIntoView","isSmooth","elBtn","gap","leftMargin","rightMargin","leftMarginParent","rightMarginParent","scrollLeft","isSafari","Core","selectAll","onMounted","onUpdated","_createElementBlock","_normalizeClass","_Fragment","_renderList","_createBlock","TopButton","_mergeProps","$event","_createTextVNode","_toDisplayString","_openBlock","_hoisted_1","_createVNode","_createElementVNode","_cache","$emit","cacheByMethod","clearCache","apiPath","genCacheKey","api","userId","getCache","cacheKey","setCache","data","useAPI","apiSetSearchParams","minLength","useCache","items","isLoading","countLoading","searchText","nextOffset","callAPI","cache","res","indexWithError","load","append","loadDebounce","debounce","newSearchText","useDebounce","ITEM_ID_ALL","ITEM_ID_NEW","isSelected","modelValue","checkNameForNullId","itemSelected","apiSetSearchParamsFilter","search","fieldName","filters","filter","genFieldFilter","useMenu","emits","multiselect","useAllItem","appendSearchToResult","appendSearchToResultCond","searchType","itemAll","useI18n","resetSearch","genIsShort","localItems","computed","itemsForShow","recalcItemsForShow","genItemsForShow","searchString","searchStringInvertKeyboard","invertKeyboardLayout","searchStringNormalized","itemTitleCategory","itemsCategory","flushCategory","name","itemNew","selectItem","fieldsForWatch","watch","selectableItems","nextIndex","itemI","__emit","__expose","resetAPICache","menu","getPopup","searchTypeLocal","toRef","component","popupRef","placeholder","onOpenerKeydown","e","needOpen","symbolPressed","onClickChanger","onOpen","onClose","onScrollContentList","_unref","TopPopup","_withDirectives","_resolveDynamicComponent","Selector2ItemMulti","_hoisted_2","_hoisted_3","$slots","_renderSlot","_ctx","TopPopupListItem","$i18n","TopPreloader","_component_TopLoadbar","_hoisted_4","TopPopupWidgetInput"],"mappings":"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"}
|