@blueking/bk-user-selector 0.0.1-beta.2 → 0.0.2-beta.1
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/README.md +127 -1
- package/package.json +1 -1
- package/typings/api/user.d.ts +34 -0
- package/typings/components/multiple-selector.vue.d.ts +104 -0
- package/typings/components/single-selector.vue.d.ts +18 -0
- package/typings/components/user-selector.vue.d.ts +53 -0
- package/typings/components/user-tag.vue.d.ts +68 -0
- package/typings/hooks/useTenantData.d.ts +16 -0
- package/typings/hooks/useUserSearch.d.ts +20 -0
- package/typings/hooks/useUserSelection.d.ts +23 -0
- package/typings/index.d.ts +18 -0
- package/typings/types/index.d.ts +121 -0
- package/typings/utils/common.d.ts +33 -0
- package/typings/vue3.d.ts +1 -1
- package/vue2/index.es.min.js +13312 -13086
- package/vue2/index.iife.min.js +13312 -13092
- package/vue2/index.umd.min.js +13311 -13085
- package/vue2/vue2.css +88 -179
- package/vue3/index.es.min.js +846 -620
- package/vue3/index.iife.min.js +13311 -13085
- package/vue3/index.umd.min.js +845 -619
- package/vue3/vue3.css +89 -180
- package/typings/index.vue.d.ts +0 -22
- package/typings/single.vue.d.ts +0 -12
- package/typings/utils/index.d.ts +0 -59
- package/typings/utils/jsonp.d.ts +0 -4
- package/typings/utils/lang.d.ts +0 -3
- package/typings/utils/service.d.ts +0 -36
package/vue3/index.es.min.js
CHANGED
|
@@ -1,5 +1,236 @@
|
|
|
1
|
-
import { ref, onBeforeMount, watch, createBlock, openBlock, unref, withCtx, createElementBlock, Fragment, renderList,
|
|
2
|
-
import { Select,
|
|
1
|
+
import { ref, onBeforeMount, defineComponent, watch, createBlock, openBlock, unref, withCtx, createElementBlock, Fragment, renderList, createElementVNode, createCommentVNode, toDisplayString, withModifiers, normalizeClass, nextTick, onMounted, withDirectives, createVNode, isRef, vModelText, createTextVNode, computed } from "vue";
|
|
2
|
+
import { Select, Tag, Popover, Loading, clickoutside } from "bkui-vue";
|
|
3
|
+
const getTenants = async (apiBaseUrl, tenantId) => {
|
|
4
|
+
if (!apiBaseUrl || !tenantId) {
|
|
5
|
+
console.warn("获取租户信息需要提供有效的API基础URL和租户ID");
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
const url = `${apiBaseUrl}/api/v3/open-web/tenant/data-source-owner-tenants/`;
|
|
10
|
+
const response = await fetch(url, {
|
|
11
|
+
method: "GET",
|
|
12
|
+
headers: {
|
|
13
|
+
"x-bk-tenant-id": tenantId
|
|
14
|
+
},
|
|
15
|
+
credentials: "include"
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error(`获取租户信息失败: ${response.status} ${response.statusText}`);
|
|
19
|
+
}
|
|
20
|
+
const data = await response.json();
|
|
21
|
+
return data.data || [];
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error("获取租户信息失败:", error);
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const searchUsers = async (apiBaseUrl, tenantId, keyword = "") => {
|
|
28
|
+
if (!keyword || !apiBaseUrl || !tenantId) {
|
|
29
|
+
console.warn("搜索用户需要提供有效的API基础URL、租户ID和关键词");
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/search/?keyword=${encodeURIComponent(keyword)}`;
|
|
34
|
+
const response = await fetch(url, {
|
|
35
|
+
method: "GET",
|
|
36
|
+
headers: {
|
|
37
|
+
"x-bk-tenant-id": tenantId
|
|
38
|
+
},
|
|
39
|
+
credentials: "include"
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`搜索用户失败: ${response.status} ${response.statusText}`);
|
|
43
|
+
}
|
|
44
|
+
const data = await response.json();
|
|
45
|
+
return data.data || [];
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("搜索用户失败:", error);
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const lookupUsers = async (apiBaseUrl, tenantId, users = []) => {
|
|
52
|
+
if (users.length === 0 || !apiBaseUrl || !tenantId) {
|
|
53
|
+
console.warn("批量查找用户需要提供有效的API基础URL、租户ID和至少一个用户名");
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const url = `${apiBaseUrl}/api/v3/open-web/tenant/users/-/lookup/?lookups=${users.join(",")}&lookup_fields=bk_username`;
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method: "GET",
|
|
60
|
+
headers: {
|
|
61
|
+
"x-bk-tenant-id": tenantId
|
|
62
|
+
},
|
|
63
|
+
credentials: "include"
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new Error(`批量查找用户失败: ${response.status} ${response.statusText}`);
|
|
67
|
+
}
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
return data.data || [];
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error("批量查找用户失败:", error);
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const formatUsers = (users) => {
|
|
76
|
+
if (!users || !Array.isArray(users)) return [];
|
|
77
|
+
return users.map((user) => ({
|
|
78
|
+
id: user.bk_username,
|
|
79
|
+
name: user.display_name,
|
|
80
|
+
tenantId: user.owner_tenant_id
|
|
81
|
+
}));
|
|
82
|
+
};
|
|
83
|
+
const useTenantData = (apiBaseUrl, tenantId) => {
|
|
84
|
+
const tenants = ref({});
|
|
85
|
+
const loading = ref(false);
|
|
86
|
+
const fetchTenants = async () => {
|
|
87
|
+
if (!apiBaseUrl || !tenantId) {
|
|
88
|
+
console.warn("获取租户需要提供有效的API基础URL和租户ID");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
loading.value = true;
|
|
92
|
+
try {
|
|
93
|
+
const result = await getTenants(apiBaseUrl, tenantId);
|
|
94
|
+
const tenantMap = {};
|
|
95
|
+
result.forEach((item) => {
|
|
96
|
+
if (item.id && item.name) {
|
|
97
|
+
tenantMap[item.id] = item.name;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
tenants.value = tenantMap;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error("获取租户数据失败:", error);
|
|
103
|
+
} finally {
|
|
104
|
+
loading.value = false;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
onBeforeMount(() => {
|
|
108
|
+
fetchTenants();
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
tenants,
|
|
112
|
+
loading,
|
|
113
|
+
fetchTenants
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
const _hoisted_1$3 = { class: "user-option" };
|
|
117
|
+
const _hoisted_2$2 = { class: "user-name" };
|
|
118
|
+
const _hoisted_3$2 = {
|
|
119
|
+
key: 0,
|
|
120
|
+
class: "tenant-name"
|
|
121
|
+
};
|
|
122
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
123
|
+
...{
|
|
124
|
+
name: "BkUserSelectorSingle"
|
|
125
|
+
},
|
|
126
|
+
__name: "single-selector",
|
|
127
|
+
props: {
|
|
128
|
+
modelValue: {},
|
|
129
|
+
placeholder: {},
|
|
130
|
+
apiBaseUrl: {},
|
|
131
|
+
tenantId: {},
|
|
132
|
+
tenants: {}
|
|
133
|
+
},
|
|
134
|
+
emits: ["update:modelValue", "change"],
|
|
135
|
+
setup(__props, { emit: __emit }) {
|
|
136
|
+
const props = __props;
|
|
137
|
+
const emit = __emit;
|
|
138
|
+
const { tenants } = useTenantData(props.apiBaseUrl || "", props.tenantId || "");
|
|
139
|
+
const options = ref([]);
|
|
140
|
+
const loading = ref(false);
|
|
141
|
+
const selectedUser = ref(props.modelValue || "");
|
|
142
|
+
onBeforeMount(async () => {
|
|
143
|
+
if (typeof props.modelValue === "string" && props.modelValue) {
|
|
144
|
+
try {
|
|
145
|
+
loading.value = true;
|
|
146
|
+
const result = await lookupUsers(props.apiBaseUrl || "", props.tenantId || "", [props.modelValue]);
|
|
147
|
+
options.value = formatUsers(result);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error("获取用户信息失败:", error);
|
|
150
|
+
} finally {
|
|
151
|
+
loading.value = false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const fetchUsers = async (keyword = "") => {
|
|
156
|
+
if (!keyword || keyword.length < 2) return [];
|
|
157
|
+
loading.value = true;
|
|
158
|
+
try {
|
|
159
|
+
const result = await searchUsers(props.apiBaseUrl || "", props.tenantId || "", keyword);
|
|
160
|
+
const formattedResults = formatUsers(result);
|
|
161
|
+
options.value = formattedResults;
|
|
162
|
+
return formattedResults;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error("获取用户列表失败:", error);
|
|
165
|
+
return [];
|
|
166
|
+
} finally {
|
|
167
|
+
loading.value = false;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
watch(selectedUser, (newVal) => {
|
|
171
|
+
emit("update:modelValue", newVal);
|
|
172
|
+
const selectedUserInfo = options.value.find((user) => user.id === newVal);
|
|
173
|
+
emit("change", selectedUserInfo || null);
|
|
174
|
+
});
|
|
175
|
+
return (_ctx, _cache) => {
|
|
176
|
+
return openBlock(), createBlock(unref(Select), {
|
|
177
|
+
modelValue: selectedUser.value,
|
|
178
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedUser.value = $event),
|
|
179
|
+
placeholder: _ctx.placeholder,
|
|
180
|
+
"input-search": true,
|
|
181
|
+
"remote-method": fetchUsers,
|
|
182
|
+
filterable: ""
|
|
183
|
+
}, {
|
|
184
|
+
default: withCtx(() => [
|
|
185
|
+
(openBlock(true), createElementBlock(
|
|
186
|
+
Fragment,
|
|
187
|
+
null,
|
|
188
|
+
renderList(options.value, (item) => {
|
|
189
|
+
return openBlock(), createBlock(unref(Select).Option, {
|
|
190
|
+
key: item.id,
|
|
191
|
+
label: item.name,
|
|
192
|
+
value: item.id
|
|
193
|
+
}, {
|
|
194
|
+
default: withCtx(() => [
|
|
195
|
+
createElementVNode("div", _hoisted_1$3, [
|
|
196
|
+
createElementVNode(
|
|
197
|
+
"span",
|
|
198
|
+
_hoisted_2$2,
|
|
199
|
+
toDisplayString(item.name),
|
|
200
|
+
1
|
|
201
|
+
/* TEXT */
|
|
202
|
+
),
|
|
203
|
+
item.tenantId !== props.tenantId && item.tenantId && unref(tenants)[item.tenantId] ? (openBlock(), createElementBlock(
|
|
204
|
+
"span",
|
|
205
|
+
_hoisted_3$2,
|
|
206
|
+
"@" + toDisplayString(unref(tenants)[item.tenantId]),
|
|
207
|
+
1
|
|
208
|
+
/* TEXT */
|
|
209
|
+
)) : createCommentVNode("v-if", true)
|
|
210
|
+
])
|
|
211
|
+
]),
|
|
212
|
+
_: 2
|
|
213
|
+
/* DYNAMIC */
|
|
214
|
+
}, 1032, ["label", "value"]);
|
|
215
|
+
}),
|
|
216
|
+
128
|
|
217
|
+
/* KEYED_FRAGMENT */
|
|
218
|
+
))
|
|
219
|
+
]),
|
|
220
|
+
_: 1
|
|
221
|
+
/* STABLE */
|
|
222
|
+
}, 8, ["modelValue", "placeholder"]);
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
const _export_sfc = (sfc, props) => {
|
|
227
|
+
const target = sfc.__vccOpts || sfc;
|
|
228
|
+
for (const [key, val] of props) {
|
|
229
|
+
target[key] = val;
|
|
230
|
+
}
|
|
231
|
+
return target;
|
|
232
|
+
};
|
|
233
|
+
const SingleSelector = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-0ae61279"]]);
|
|
3
234
|
/**!
|
|
4
235
|
* Sortable 1.15.6
|
|
5
236
|
* @author RubaXa <trash@rubaxa.org>
|
|
@@ -2157,716 +2388,711 @@ _extends(Remove, {
|
|
|
2157
2388
|
});
|
|
2158
2389
|
Sortable.mount(new AutoScrollPlugin());
|
|
2159
2390
|
Sortable.mount(Remove, Revert);
|
|
2160
|
-
const
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2391
|
+
const debounce = (fn, delay) => {
|
|
2392
|
+
let timer = null;
|
|
2393
|
+
return function(...args) {
|
|
2394
|
+
if (timer) {
|
|
2395
|
+
clearTimeout(timer);
|
|
2396
|
+
}
|
|
2397
|
+
timer = window.setTimeout(() => {
|
|
2398
|
+
fn(...args);
|
|
2399
|
+
timer = null;
|
|
2400
|
+
}, delay);
|
|
2401
|
+
};
|
|
2402
|
+
};
|
|
2403
|
+
const calculateVisibleTags = (container, items, containerWidth) => {
|
|
2404
|
+
if (!container || !items.length) return 0;
|
|
2405
|
+
let totalWidth = 0;
|
|
2406
|
+
let visibleCount = 0;
|
|
2407
|
+
for (let i = 0; i < items.length; i++) {
|
|
2408
|
+
const item = items[i];
|
|
2409
|
+
if (!item) continue;
|
|
2410
|
+
const style = window.getComputedStyle(item);
|
|
2411
|
+
const width = item.offsetWidth;
|
|
2412
|
+
const marginLeft = parseInt(style.marginLeft, 10) || 0;
|
|
2413
|
+
const marginRight = parseInt(style.marginRight, 10) || 0;
|
|
2414
|
+
totalWidth += width + marginLeft + marginRight;
|
|
2415
|
+
if (totalWidth > containerWidth) {
|
|
2416
|
+
break;
|
|
2417
|
+
}
|
|
2418
|
+
visibleCount++;
|
|
2419
|
+
}
|
|
2420
|
+
return Math.max(1, visibleCount);
|
|
2421
|
+
};
|
|
2422
|
+
const useUserSearch = (apiBaseUrl, tenantId) => {
|
|
2423
|
+
const searchResults = ref([]);
|
|
2424
|
+
const loading = ref(false);
|
|
2425
|
+
const searchQuery = ref("");
|
|
2426
|
+
const performSearch = async (keyword) => {
|
|
2427
|
+
if (!keyword || keyword.length < 2) {
|
|
2428
|
+
searchResults.value = [];
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
if (!apiBaseUrl || !tenantId) {
|
|
2432
|
+
console.warn("执行用户搜索需要提供有效的API基础URL和租户ID");
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
loading.value = true;
|
|
2436
|
+
try {
|
|
2437
|
+
const results = await searchUsers(apiBaseUrl, tenantId, keyword);
|
|
2438
|
+
searchResults.value = formatUsers(results);
|
|
2439
|
+
} catch (error) {
|
|
2440
|
+
console.error("用户搜索失败:", error);
|
|
2441
|
+
searchResults.value = [];
|
|
2442
|
+
} finally {
|
|
2443
|
+
loading.value = false;
|
|
2174
2444
|
}
|
|
2445
|
+
};
|
|
2446
|
+
const debouncedSearch = debounce(performSearch, 300);
|
|
2447
|
+
const handleSearchInput = (value) => {
|
|
2448
|
+
searchQuery.value = value;
|
|
2449
|
+
debouncedSearch(value);
|
|
2450
|
+
};
|
|
2451
|
+
const clearSearch = () => {
|
|
2452
|
+
searchQuery.value = "";
|
|
2453
|
+
searchResults.value = [];
|
|
2454
|
+
};
|
|
2455
|
+
return {
|
|
2456
|
+
searchResults,
|
|
2457
|
+
loading,
|
|
2458
|
+
searchQuery,
|
|
2459
|
+
performSearch,
|
|
2460
|
+
handleSearchInput,
|
|
2461
|
+
clearSearch
|
|
2462
|
+
};
|
|
2463
|
+
};
|
|
2464
|
+
const _hoisted_1$2 = { class: "tag-content" };
|
|
2465
|
+
const _hoisted_2$1 = { class: "user-name" };
|
|
2466
|
+
const _hoisted_3$1 = {
|
|
2467
|
+
key: 0,
|
|
2468
|
+
class: "tenant-name"
|
|
2469
|
+
};
|
|
2470
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
2471
|
+
...{
|
|
2472
|
+
name: "UserTag"
|
|
2175
2473
|
},
|
|
2176
|
-
|
|
2474
|
+
__name: "user-tag",
|
|
2475
|
+
props: {
|
|
2476
|
+
user: {},
|
|
2477
|
+
tenants: {},
|
|
2478
|
+
currentTenantId: {},
|
|
2479
|
+
draggable: { type: Boolean },
|
|
2480
|
+
active: { type: Boolean },
|
|
2481
|
+
showTenant: { type: Boolean }
|
|
2482
|
+
},
|
|
2483
|
+
emits: ["click", "close"],
|
|
2177
2484
|
setup(__props, { emit: __emit }) {
|
|
2178
|
-
const props = __props;
|
|
2179
2485
|
const emit = __emit;
|
|
2180
|
-
const
|
|
2181
|
-
|
|
2182
|
-
const selectedUser = ref(props.modelValue);
|
|
2183
|
-
onBeforeMount(async () => {
|
|
2184
|
-
if (props.modelValue) {
|
|
2185
|
-
const url = `${props.apiBaseUrl}/api/v3/open-web/tenant/users/-/lookup/?lookups=${props.modelValue}&lookup_fields=bk_username`;
|
|
2186
|
-
const response = await fetch(url, {
|
|
2187
|
-
method: "GET",
|
|
2188
|
-
headers: {
|
|
2189
|
-
...apiConfig.headers
|
|
2190
|
-
},
|
|
2191
|
-
credentials: "include"
|
|
2192
|
-
// 包含cookie
|
|
2193
|
-
});
|
|
2194
|
-
const data = await response.json();
|
|
2195
|
-
console.log("data", data);
|
|
2196
|
-
options.value = data.data.map((item) => ({
|
|
2197
|
-
id: item.bk_username,
|
|
2198
|
-
name: item.display_name
|
|
2199
|
-
}));
|
|
2200
|
-
}
|
|
2201
|
-
});
|
|
2202
|
-
const apiConfig = {
|
|
2203
|
-
baseUrl: `${props.apiBaseUrl}/api/v3/open-web/tenant/users/-/search/`,
|
|
2204
|
-
headers: {
|
|
2205
|
-
"x-bk-tenant-id": props.tenantId
|
|
2206
|
-
}
|
|
2486
|
+
const handleClick = () => {
|
|
2487
|
+
emit("click");
|
|
2207
2488
|
};
|
|
2208
|
-
const
|
|
2209
|
-
|
|
2210
|
-
if (!keyword || keyword.length < 2) return [];
|
|
2211
|
-
loading.value = true;
|
|
2212
|
-
try {
|
|
2213
|
-
const url = `${apiConfig.baseUrl}?keyword=${encodeURIComponent(keyword)}`;
|
|
2214
|
-
const response = await fetch(url, {
|
|
2215
|
-
method: "GET",
|
|
2216
|
-
headers: {
|
|
2217
|
-
...apiConfig.headers
|
|
2218
|
-
},
|
|
2219
|
-
credentials: "include"
|
|
2220
|
-
// 包含cookie
|
|
2221
|
-
});
|
|
2222
|
-
const data = await response.json();
|
|
2223
|
-
console.log("data", data);
|
|
2224
|
-
const result = ((_a = data.data) == null ? void 0 : _a.filter((item) => {
|
|
2225
|
-
var _a2;
|
|
2226
|
-
return !((_a2 = selectedUser.value) == null ? void 0 : _a2.includes(item.bk_username));
|
|
2227
|
-
}).map((item) => ({
|
|
2228
|
-
id: item.bk_username,
|
|
2229
|
-
name: item.display_name
|
|
2230
|
-
}))) || [];
|
|
2231
|
-
options.value = result;
|
|
2232
|
-
return result;
|
|
2233
|
-
} catch (error) {
|
|
2234
|
-
console.error("获取用户列表失败:", error);
|
|
2235
|
-
return [];
|
|
2236
|
-
} finally {
|
|
2237
|
-
loading.value = false;
|
|
2238
|
-
}
|
|
2489
|
+
const handleClose = () => {
|
|
2490
|
+
emit("close");
|
|
2239
2491
|
};
|
|
2240
|
-
watch(selectedUser, (newVal) => {
|
|
2241
|
-
console.log("newVal", newVal);
|
|
2242
|
-
emit("update:modelValue", newVal);
|
|
2243
|
-
});
|
|
2244
2492
|
return (_ctx, _cache) => {
|
|
2245
|
-
return openBlock(), createBlock(unref(
|
|
2246
|
-
|
|
2247
|
-
"
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedUser.value = $event)
|
|
2493
|
+
return openBlock(), createBlock(unref(Tag), {
|
|
2494
|
+
class: normalizeClass(["user-tag", { draggable: _ctx.draggable, active: _ctx.active }]),
|
|
2495
|
+
closable: "",
|
|
2496
|
+
onClick: withModifiers(handleClick, ["stop"]),
|
|
2497
|
+
onClose: handleClose
|
|
2251
2498
|
}, {
|
|
2252
2499
|
default: withCtx(() => [
|
|
2253
|
-
(
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2500
|
+
createElementVNode("div", _hoisted_1$2, [
|
|
2501
|
+
createElementVNode(
|
|
2502
|
+
"span",
|
|
2503
|
+
_hoisted_2$1,
|
|
2504
|
+
toDisplayString(_ctx.user.name),
|
|
2505
|
+
1
|
|
2506
|
+
/* TEXT */
|
|
2507
|
+
),
|
|
2508
|
+
_ctx.showTenant && _ctx.user.tenantId && _ctx.tenants[_ctx.user.tenantId] ? (openBlock(), createElementBlock(
|
|
2509
|
+
"span",
|
|
2510
|
+
_hoisted_3$1,
|
|
2511
|
+
" @" + toDisplayString(_ctx.tenants[_ctx.user.tenantId]),
|
|
2512
|
+
1
|
|
2513
|
+
/* TEXT */
|
|
2514
|
+
)) : createCommentVNode("v-if", true)
|
|
2515
|
+
])
|
|
2266
2516
|
]),
|
|
2267
2517
|
_: 1
|
|
2268
2518
|
/* STABLE */
|
|
2269
|
-
}, 8, ["
|
|
2519
|
+
}, 8, ["class"]);
|
|
2270
2520
|
};
|
|
2271
2521
|
}
|
|
2522
|
+
});
|
|
2523
|
+
const UserTag = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-cf26d9e2"]]);
|
|
2524
|
+
const _hoisted_1$1 = ["onClick"];
|
|
2525
|
+
const _hoisted_2 = ["placeholder"];
|
|
2526
|
+
const _hoisted_3 = ["placeholder"];
|
|
2527
|
+
const _hoisted_4 = {
|
|
2528
|
+
key: 0,
|
|
2529
|
+
class: "no-data"
|
|
2272
2530
|
};
|
|
2273
|
-
const _export_sfc = (sfc, props) => {
|
|
2274
|
-
const target = sfc.__vccOpts || sfc;
|
|
2275
|
-
for (const [key, val] of props) {
|
|
2276
|
-
target[key] = val;
|
|
2277
|
-
}
|
|
2278
|
-
return target;
|
|
2279
|
-
};
|
|
2280
|
-
const _withScopeId = (n) => (pushScopeId("data-v-5e8a952d"), n = n(), popScopeId(), n);
|
|
2281
|
-
const _hoisted_1 = { class: "popover-content" };
|
|
2282
|
-
const _hoisted_2 = { key: 0 };
|
|
2283
|
-
const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ createElementVNode(
|
|
2284
|
-
"div",
|
|
2285
|
-
{ class: "no-data" },
|
|
2286
|
-
[
|
|
2287
|
-
/* @__PURE__ */ createElementVNode("span", null, "暂无数据")
|
|
2288
|
-
],
|
|
2289
|
-
-1
|
|
2290
|
-
/* HOISTED */
|
|
2291
|
-
));
|
|
2292
|
-
const _hoisted_4 = [
|
|
2293
|
-
_hoisted_3
|
|
2294
|
-
];
|
|
2295
2531
|
const _hoisted_5 = ["onMousedown"];
|
|
2296
|
-
const _hoisted_6 =
|
|
2532
|
+
const _hoisted_6 = { class: "user-name" };
|
|
2297
2533
|
const _hoisted_7 = {
|
|
2298
|
-
key:
|
|
2299
|
-
class: "
|
|
2534
|
+
key: 0,
|
|
2535
|
+
class: "tenant-name"
|
|
2300
2536
|
};
|
|
2301
|
-
const
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
const _hoisted_10 = ["onClick"];
|
|
2307
|
-
const _hoisted_11 = { class: "tag-content" };
|
|
2308
|
-
const _hoisted_12 = { class: "user-name" };
|
|
2309
|
-
const _hoisted_13 = ["placeholder"];
|
|
2310
|
-
const _hoisted_14 = ["placeholder"];
|
|
2311
|
-
const _hoisted_15 = { class: "tag-content" };
|
|
2312
|
-
const _hoisted_16 = { class: "user-name" };
|
|
2313
|
-
const _hoisted_17 = ["placeholder"];
|
|
2314
|
-
const _sfc_main = {
|
|
2315
|
-
__name: "index",
|
|
2537
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
2538
|
+
...{
|
|
2539
|
+
name: "BkUserSelectorMultiple"
|
|
2540
|
+
},
|
|
2541
|
+
__name: "multiple-selector",
|
|
2316
2542
|
props: {
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
required: {
|
|
2324
|
-
type: Boolean,
|
|
2325
|
-
default: false
|
|
2543
|
+
/**
|
|
2544
|
+
* 绑定值
|
|
2545
|
+
*/
|
|
2546
|
+
modelValue: {
|
|
2547
|
+
type: Array,
|
|
2548
|
+
default: () => []
|
|
2326
2549
|
},
|
|
2327
|
-
|
|
2550
|
+
/**
|
|
2551
|
+
* 占位文本
|
|
2552
|
+
*/
|
|
2328
2553
|
placeholder: {
|
|
2329
2554
|
type: String,
|
|
2330
2555
|
default: "请输入人员名称搜索"
|
|
2331
2556
|
},
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
default: ""
|
|
2336
|
-
},
|
|
2337
|
-
// 是否支持拖拽排序
|
|
2557
|
+
/**
|
|
2558
|
+
* 是否可拖拽
|
|
2559
|
+
*/
|
|
2338
2560
|
draggable: {
|
|
2339
2561
|
type: Boolean,
|
|
2340
2562
|
default: false
|
|
2341
2563
|
},
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
default: false
|
|
2346
|
-
},
|
|
2347
|
-
// 接口基础URL
|
|
2564
|
+
/**
|
|
2565
|
+
* API 基础 URL
|
|
2566
|
+
*/
|
|
2348
2567
|
apiBaseUrl: {
|
|
2349
2568
|
type: String,
|
|
2350
2569
|
default: ""
|
|
2351
2570
|
},
|
|
2352
|
-
|
|
2571
|
+
/**
|
|
2572
|
+
* 租户 ID
|
|
2573
|
+
*/
|
|
2353
2574
|
tenantId: {
|
|
2354
2575
|
type: String,
|
|
2355
2576
|
default: ""
|
|
2577
|
+
},
|
|
2578
|
+
/**
|
|
2579
|
+
* 已选用户
|
|
2580
|
+
*/
|
|
2581
|
+
selectedUsers: {
|
|
2582
|
+
type: Array,
|
|
2583
|
+
default: () => []
|
|
2356
2584
|
}
|
|
2357
2585
|
},
|
|
2358
|
-
emits: ["update:
|
|
2586
|
+
emits: ["update:selectedUsers", "add-user", "remove-user"],
|
|
2359
2587
|
setup(__props, { emit: __emit }) {
|
|
2360
|
-
const vClickoutside = clickoutside;
|
|
2361
|
-
const vLoading = Loading;
|
|
2362
2588
|
const props = __props;
|
|
2363
2589
|
const emit = __emit;
|
|
2364
|
-
const
|
|
2365
|
-
const
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2590
|
+
const { tenants } = useTenantData(props.apiBaseUrl, props.tenantId);
|
|
2591
|
+
const {
|
|
2592
|
+
searchResults,
|
|
2593
|
+
loading: searchLoading,
|
|
2594
|
+
searchQuery,
|
|
2595
|
+
handleSearchInput
|
|
2596
|
+
} = useUserSearch(props.apiBaseUrl, props.tenantId);
|
|
2369
2597
|
const containerRef = ref(null);
|
|
2370
|
-
const
|
|
2598
|
+
const tagsContainerRef = ref(null);
|
|
2599
|
+
const sortableContainerRef = ref(null);
|
|
2600
|
+
const collapsedContainerRef = ref(null);
|
|
2601
|
+
const inlineInputRef = ref(null);
|
|
2602
|
+
const lastInputRef = ref(null);
|
|
2603
|
+
const collapsedInputRef = ref(null);
|
|
2371
2604
|
const isFocused = ref(false);
|
|
2372
|
-
const
|
|
2373
|
-
const hiddenCount = ref(0);
|
|
2374
|
-
const userList = ref([]);
|
|
2375
|
-
let searchTimer = null;
|
|
2605
|
+
const showDropdown = ref(false);
|
|
2376
2606
|
const activeTagIndex = ref(-1);
|
|
2377
|
-
const measureEl = ref(null);
|
|
2378
2607
|
const sortableInstance = ref(null);
|
|
2379
|
-
const
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2608
|
+
const visibleUsers = ref([]);
|
|
2609
|
+
const hiddenCount = ref(0);
|
|
2610
|
+
const initSortable = () => {
|
|
2611
|
+
if (!props.draggable || !sortableContainerRef.value) return;
|
|
2612
|
+
if (sortableInstance.value) {
|
|
2613
|
+
sortableInstance.value.destroy();
|
|
2614
|
+
}
|
|
2615
|
+
sortableInstance.value = new Sortable(sortableContainerRef.value, {
|
|
2616
|
+
animation: 150,
|
|
2617
|
+
draggable: ".tag-wrapper",
|
|
2618
|
+
onEnd: (evt) => {
|
|
2619
|
+
const { oldIndex: oldIndex2, newIndex: newIndex2 } = evt;
|
|
2620
|
+
if (oldIndex2 === newIndex2 || oldIndex2 === void 0 || newIndex2 === void 0) return;
|
|
2621
|
+
const updatedUsers = [...props.selectedUsers];
|
|
2622
|
+
const [movedUser] = updatedUsers.splice(oldIndex2, 1);
|
|
2623
|
+
updatedUsers.splice(newIndex2, 0, movedUser);
|
|
2624
|
+
emit("update:selectedUsers", updatedUsers);
|
|
2625
|
+
activeTagIndex.value = newIndex2;
|
|
2626
|
+
}
|
|
2627
|
+
});
|
|
2384
2628
|
};
|
|
2385
|
-
const
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
const url = `${apiConfig.baseUrl}?keyword=${encodeURIComponent(keyword)}`;
|
|
2391
|
-
const response = await fetch(url, {
|
|
2392
|
-
method: "GET",
|
|
2393
|
-
headers: {
|
|
2394
|
-
...apiConfig.headers
|
|
2395
|
-
},
|
|
2396
|
-
credentials: "include"
|
|
2397
|
-
// 包含cookie
|
|
2398
|
-
});
|
|
2399
|
-
const data = await response.json();
|
|
2400
|
-
const selectedIds = selectedUsers.value.map((user) => user.id);
|
|
2401
|
-
return ((_a = data.data) == null ? void 0 : _a.filter((item) => !selectedIds.includes(item.bk_username)).map((item) => ({
|
|
2402
|
-
id: item.bk_username,
|
|
2403
|
-
name: item.login_name,
|
|
2404
|
-
avatar: item.avatar_url || ""
|
|
2405
|
-
}))) || [];
|
|
2406
|
-
} catch (error) {
|
|
2407
|
-
console.error("获取用户列表失败:", error);
|
|
2408
|
-
return [];
|
|
2409
|
-
} finally {
|
|
2410
|
-
loading.value = false;
|
|
2629
|
+
const calculateVisibleUsers = () => {
|
|
2630
|
+
if (!collapsedContainerRef.value || !props.selectedUsers.length) {
|
|
2631
|
+
visibleUsers.value = [];
|
|
2632
|
+
hiddenCount.value = 0;
|
|
2633
|
+
return;
|
|
2411
2634
|
}
|
|
2635
|
+
const containerWidth = collapsedContainerRef.value.offsetWidth;
|
|
2636
|
+
const tagElements = collapsedContainerRef.value.querySelectorAll(".user-tag");
|
|
2637
|
+
const visibleCount = calculateVisibleTags(
|
|
2638
|
+
collapsedContainerRef.value,
|
|
2639
|
+
tagElements,
|
|
2640
|
+
containerWidth - 100
|
|
2641
|
+
// 为输入框和更多标签预留空间
|
|
2642
|
+
);
|
|
2643
|
+
visibleUsers.value = props.selectedUsers.slice(0, visibleCount);
|
|
2644
|
+
hiddenCount.value = Math.max(0, props.selectedUsers.length - visibleCount);
|
|
2412
2645
|
};
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
measureEl.value.textContent = searchQuery.value || searchInput.value.placeholder || "";
|
|
2423
|
-
const width = Math.max(20, measureEl.value.offsetWidth + 10);
|
|
2424
|
-
searchInput.value.style.width = `${width}px`;
|
|
2646
|
+
const handleFocus = () => {
|
|
2647
|
+
isFocused.value = true;
|
|
2648
|
+
showDropdown.value = false;
|
|
2649
|
+
activeTagIndex.value = -1;
|
|
2650
|
+
nextTick(() => {
|
|
2651
|
+
if (lastInputRef.value) {
|
|
2652
|
+
lastInputRef.value.focus();
|
|
2653
|
+
}
|
|
2654
|
+
});
|
|
2425
2655
|
};
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2656
|
+
const handleClickOutside = () => {
|
|
2657
|
+
isFocused.value = false;
|
|
2658
|
+
showDropdown.value = false;
|
|
2659
|
+
activeTagIndex.value = -1;
|
|
2660
|
+
searchQuery.value = "";
|
|
2661
|
+
nextTick(() => {
|
|
2662
|
+
calculateVisibleUsers();
|
|
2663
|
+
});
|
|
2664
|
+
};
|
|
2665
|
+
const handleContainerClick = () => {
|
|
2666
|
+
activeTagIndex.value = -1;
|
|
2667
|
+
nextTick(() => {
|
|
2668
|
+
if (lastInputRef.value) {
|
|
2669
|
+
lastInputRef.value.focus();
|
|
2437
2670
|
}
|
|
2438
|
-
|
|
2439
|
-
}, 300);
|
|
2440
|
-
updateInputWidth();
|
|
2671
|
+
});
|
|
2441
2672
|
};
|
|
2442
2673
|
const handleTagClick = (index2) => {
|
|
2443
2674
|
activeTagIndex.value = index2;
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2675
|
+
nextTick(() => {
|
|
2676
|
+
if (activeTagIndex.value === props.selectedUsers.length - 1) {
|
|
2677
|
+
if (lastInputRef.value) {
|
|
2678
|
+
lastInputRef.value.focus();
|
|
2679
|
+
}
|
|
2680
|
+
} else if (inlineInputRef.value) {
|
|
2681
|
+
inlineInputRef.value.focus();
|
|
2682
|
+
}
|
|
2683
|
+
});
|
|
2448
2684
|
};
|
|
2449
|
-
const
|
|
2685
|
+
const handleInputFocus = () => {
|
|
2450
2686
|
if (!isFocused.value) {
|
|
2451
2687
|
isFocused.value = true;
|
|
2452
|
-
activeTagIndex.value = selectedUsers.value.length - 1;
|
|
2453
2688
|
}
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
(_a = searchInput.value) == null ? void 0 : _a.focus();
|
|
2458
|
-
}, 0);
|
|
2689
|
+
if (searchQuery.value.length >= 2) {
|
|
2690
|
+
showDropdown.value = true;
|
|
2691
|
+
}
|
|
2459
2692
|
};
|
|
2460
|
-
const
|
|
2461
|
-
|
|
2693
|
+
const handleInput = () => {
|
|
2694
|
+
handleSearchInput(searchQuery.value);
|
|
2695
|
+
showDropdown.value = searchQuery.value.length >= 2;
|
|
2696
|
+
};
|
|
2697
|
+
const handlePaste = (event) => {
|
|
2698
|
+
var _a;
|
|
2699
|
+
const pastedText = ((_a = event.clipboardData) == null ? void 0 : _a.getData("text")) || "";
|
|
2700
|
+
if (pastedText.trim()) {
|
|
2701
|
+
searchQuery.value = pastedText.trim();
|
|
2702
|
+
handleInput();
|
|
2703
|
+
}
|
|
2704
|
+
};
|
|
2705
|
+
const handleKeyDown = (event) => {
|
|
2706
|
+
if (event.key === "Backspace" && !searchQuery.value && props.selectedUsers.length > 0) {
|
|
2462
2707
|
if (activeTagIndex.value >= 0) {
|
|
2463
|
-
const
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2708
|
+
const userToRemove = props.selectedUsers[activeTagIndex.value];
|
|
2709
|
+
removeUser(userToRemove);
|
|
2710
|
+
if (activeTagIndex.value > 0) {
|
|
2711
|
+
activeTagIndex.value = activeTagIndex.value - 1;
|
|
2712
|
+
} else {
|
|
2713
|
+
activeTagIndex.value = -1;
|
|
2714
|
+
}
|
|
2467
2715
|
} else {
|
|
2468
|
-
|
|
2469
|
-
|
|
2716
|
+
const lastUser = props.selectedUsers[props.selectedUsers.length - 1];
|
|
2717
|
+
removeUser(lastUser);
|
|
2470
2718
|
}
|
|
2471
|
-
|
|
2719
|
+
}
|
|
2720
|
+
};
|
|
2721
|
+
const addUser = (user) => {
|
|
2722
|
+
if (!user || !user.id) return;
|
|
2723
|
+
if (!props.selectedUsers.some((item) => item.id === user.id)) {
|
|
2724
|
+
const updatedUsers = [...props.selectedUsers, user];
|
|
2725
|
+
emit("update:selectedUsers", updatedUsers);
|
|
2726
|
+
emit("add-user", user);
|
|
2472
2727
|
}
|
|
2473
2728
|
searchQuery.value = "";
|
|
2474
|
-
|
|
2475
|
-
setTimeout(() => {
|
|
2476
|
-
var _a;
|
|
2477
|
-
(_a = searchInput.value) == null ? void 0 : _a.focus();
|
|
2478
|
-
}, 0);
|
|
2729
|
+
showDropdown.value = false;
|
|
2479
2730
|
};
|
|
2480
2731
|
const removeUser = (user) => {
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
if (
|
|
2486
|
-
|
|
2487
|
-
}
|
|
2488
|
-
await nextTick();
|
|
2489
|
-
if (selectedUsers.value.length === 0) {
|
|
2490
|
-
visibleUsers.value = [];
|
|
2491
|
-
hiddenCount.value = 0;
|
|
2492
|
-
return;
|
|
2732
|
+
if (!user || !user.id) return;
|
|
2733
|
+
const updatedUsers = props.selectedUsers.filter((item) => item.id !== user.id);
|
|
2734
|
+
emit("update:selectedUsers", updatedUsers);
|
|
2735
|
+
emit("remove-user", user);
|
|
2736
|
+
if (activeTagIndex.value >= updatedUsers.length) {
|
|
2737
|
+
activeTagIndex.value = updatedUsers.length - 1;
|
|
2493
2738
|
}
|
|
2494
|
-
if (isFocused.value) {
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2739
|
+
if (!isFocused.value) {
|
|
2740
|
+
nextTick(() => {
|
|
2741
|
+
calculateVisibleUsers();
|
|
2742
|
+
});
|
|
2498
2743
|
}
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
container.style.flexWrap = "wrap";
|
|
2507
|
-
container.style.height = "auto";
|
|
2508
|
-
container.style.whiteSpace = "normal";
|
|
2509
|
-
container.style.overflow = "visible";
|
|
2510
|
-
const tagElements = container.querySelectorAll(".tag-item");
|
|
2511
|
-
if (tagElements.length === 0) {
|
|
2512
|
-
Object.assign(container.style, originalStyle);
|
|
2513
|
-
visibleUsers.value = [];
|
|
2514
|
-
hiddenCount.value = 0;
|
|
2515
|
-
return;
|
|
2744
|
+
};
|
|
2745
|
+
watch(() => props.selectedUsers, () => {
|
|
2746
|
+
visibleUsers.value = [...props.selectedUsers];
|
|
2747
|
+
if (!isFocused.value) {
|
|
2748
|
+
nextTick(() => {
|
|
2749
|
+
calculateVisibleUsers();
|
|
2750
|
+
});
|
|
2516
2751
|
}
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
}
|
|
2523
|
-
break;
|
|
2524
|
-
}
|
|
2752
|
+
}, { deep: true });
|
|
2753
|
+
watch(isFocused, (newVal) => {
|
|
2754
|
+
if (newVal) {
|
|
2755
|
+
nextTick(() => {
|
|
2756
|
+
initSortable();
|
|
2757
|
+
});
|
|
2525
2758
|
}
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
moreTagElement.textContent = `+${selectedUsers.value.length - visibleCount}`;
|
|
2531
|
-
container.appendChild(moreTagElement);
|
|
2532
|
-
if (moreTagElement.offsetTop > firstRowTop) {
|
|
2533
|
-
visibleCount = Math.max(0, visibleCount - 1);
|
|
2534
|
-
}
|
|
2535
|
-
container.removeChild(moreTagElement);
|
|
2759
|
+
});
|
|
2760
|
+
const handleResize = () => {
|
|
2761
|
+
if (!isFocused.value) {
|
|
2762
|
+
calculateVisibleUsers();
|
|
2536
2763
|
}
|
|
2537
|
-
Object.assign(container.style, originalStyle);
|
|
2538
|
-
visibleUsers.value = selectedUsers.value.slice(0, visibleCount);
|
|
2539
|
-
hiddenCount.value = selectedUsers.value.length - visibleCount;
|
|
2540
2764
|
};
|
|
2541
|
-
watch(() => selectedUsers.value.length, () => {
|
|
2542
|
-
calculateVisibleTags();
|
|
2543
|
-
});
|
|
2544
2765
|
onMounted(() => {
|
|
2545
|
-
window.addEventListener("resize", calculateVisibleTags);
|
|
2546
|
-
calculateVisibleTags();
|
|
2547
|
-
updateInputWidth();
|
|
2548
2766
|
initSortable();
|
|
2767
|
+
calculateVisibleUsers();
|
|
2768
|
+
window.addEventListener("resize", handleResize);
|
|
2769
|
+
nextTick(() => {
|
|
2770
|
+
calculateVisibleUsers();
|
|
2771
|
+
});
|
|
2549
2772
|
});
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2773
|
+
return (_ctx, _cache) => {
|
|
2774
|
+
return withDirectives((openBlock(), createElementBlock("div", {
|
|
2775
|
+
ref_key: "containerRef",
|
|
2776
|
+
ref: containerRef,
|
|
2777
|
+
class: "multiple-selector"
|
|
2778
|
+
}, [
|
|
2779
|
+
createCommentVNode(" 聚焦状态 - 可编辑模式 "),
|
|
2780
|
+
isFocused.value ? (openBlock(), createElementBlock(
|
|
2781
|
+
"div",
|
|
2782
|
+
{
|
|
2783
|
+
key: 0,
|
|
2784
|
+
ref_key: "tagsContainerRef",
|
|
2785
|
+
ref: tagsContainerRef,
|
|
2786
|
+
class: "tags-container focused",
|
|
2787
|
+
onClick: withModifiers(handleContainerClick, ["stop"])
|
|
2788
|
+
},
|
|
2789
|
+
[
|
|
2790
|
+
createCommentVNode(" 用户标签列表 "),
|
|
2791
|
+
createElementVNode(
|
|
2792
|
+
"div",
|
|
2793
|
+
{
|
|
2794
|
+
ref_key: "sortableContainerRef",
|
|
2795
|
+
ref: sortableContainerRef,
|
|
2796
|
+
class: "tag-list"
|
|
2797
|
+
},
|
|
2798
|
+
[
|
|
2799
|
+
(openBlock(true), createElementBlock(
|
|
2800
|
+
Fragment,
|
|
2801
|
+
null,
|
|
2802
|
+
renderList(__props.selectedUsers, (user, index2) => {
|
|
2803
|
+
return openBlock(), createElementBlock("div", {
|
|
2804
|
+
key: user.id,
|
|
2805
|
+
class: "tag-wrapper",
|
|
2806
|
+
onClick: withModifiers(($event) => handleTagClick(index2), ["stop"])
|
|
2807
|
+
}, [
|
|
2808
|
+
createVNode(UserTag, {
|
|
2809
|
+
user,
|
|
2810
|
+
tenants: unref(tenants),
|
|
2811
|
+
"current-tenant-id": __props.tenantId,
|
|
2812
|
+
draggable: __props.draggable,
|
|
2813
|
+
active: index2 === activeTagIndex.value,
|
|
2814
|
+
"show-tenant": true,
|
|
2815
|
+
onClick: ($event) => handleTagClick(index2),
|
|
2816
|
+
onClose: ($event) => removeUser(user)
|
|
2817
|
+
}, null, 8, ["user", "tenants", "current-tenant-id", "draggable", "active", "onClick", "onClose"]),
|
|
2818
|
+
createCommentVNode(" 在当前激活标签后插入输入框 "),
|
|
2819
|
+
index2 === activeTagIndex.value && activeTagIndex.value !== __props.selectedUsers.length - 1 ? withDirectives((openBlock(), createElementBlock(
|
|
2820
|
+
"input",
|
|
2821
|
+
{
|
|
2822
|
+
key: 0,
|
|
2823
|
+
ref_for: true,
|
|
2824
|
+
ref_key: "inlineInputRef",
|
|
2825
|
+
ref: inlineInputRef,
|
|
2826
|
+
class: "search-input inline",
|
|
2827
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
|
|
2828
|
+
onFocus: handleInputFocus,
|
|
2829
|
+
onInput: handleInput,
|
|
2830
|
+
onKeydown: handleKeyDown,
|
|
2831
|
+
onPaste: handlePaste
|
|
2832
|
+
},
|
|
2833
|
+
null,
|
|
2834
|
+
544
|
|
2835
|
+
/* NEED_HYDRATION, NEED_PATCH */
|
|
2836
|
+
)), [
|
|
2837
|
+
[vModelText, unref(searchQuery)]
|
|
2838
|
+
]) : createCommentVNode("v-if", true)
|
|
2839
|
+
], 8, _hoisted_1$1);
|
|
2840
|
+
}),
|
|
2841
|
+
128
|
|
2842
|
+
/* KEYED_FRAGMENT */
|
|
2843
|
+
)),
|
|
2844
|
+
createCommentVNode(" 最后一个输入框 "),
|
|
2845
|
+
activeTagIndex.value === -1 || activeTagIndex.value === __props.selectedUsers.length - 1 ? withDirectives((openBlock(), createElementBlock("input", {
|
|
2846
|
+
key: 0,
|
|
2847
|
+
ref_key: "lastInputRef",
|
|
2848
|
+
ref: lastInputRef,
|
|
2849
|
+
class: "search-input last",
|
|
2850
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
|
|
2851
|
+
placeholder: !__props.selectedUsers.length ? __props.placeholder : "",
|
|
2852
|
+
onFocus: handleInputFocus,
|
|
2853
|
+
onInput: handleInput,
|
|
2854
|
+
onKeydown: handleKeyDown,
|
|
2855
|
+
onPaste: handlePaste
|
|
2856
|
+
}, null, 40, _hoisted_2)), [
|
|
2857
|
+
[vModelText, unref(searchQuery)]
|
|
2858
|
+
]) : createCommentVNode("v-if", true)
|
|
2859
|
+
],
|
|
2860
|
+
512
|
|
2861
|
+
/* NEED_PATCH */
|
|
2862
|
+
)
|
|
2863
|
+
],
|
|
2864
|
+
512
|
|
2865
|
+
/* NEED_PATCH */
|
|
2866
|
+
)) : (openBlock(), createElementBlock(
|
|
2867
|
+
Fragment,
|
|
2868
|
+
{ key: 1 },
|
|
2869
|
+
[
|
|
2870
|
+
createCommentVNode(" 未聚焦状态 - 只读展示模式 "),
|
|
2871
|
+
createElementVNode(
|
|
2872
|
+
"div",
|
|
2873
|
+
{
|
|
2874
|
+
ref_key: "collapsedContainerRef",
|
|
2875
|
+
ref: collapsedContainerRef,
|
|
2876
|
+
class: "tags-container collapsed",
|
|
2877
|
+
onClick: withModifiers(handleFocus, ["stop"])
|
|
2878
|
+
},
|
|
2879
|
+
[
|
|
2880
|
+
(openBlock(true), createElementBlock(
|
|
2881
|
+
Fragment,
|
|
2882
|
+
null,
|
|
2883
|
+
renderList(visibleUsers.value, (user) => {
|
|
2884
|
+
return openBlock(), createBlock(UserTag, {
|
|
2885
|
+
key: user.id,
|
|
2886
|
+
user,
|
|
2887
|
+
tenants: unref(tenants),
|
|
2888
|
+
"current-tenant-id": __props.tenantId,
|
|
2889
|
+
"show-tenant": true,
|
|
2890
|
+
onClick: handleFocus,
|
|
2891
|
+
onClose: ($event) => removeUser(user)
|
|
2892
|
+
}, null, 8, ["user", "tenants", "current-tenant-id", "onClose"]);
|
|
2893
|
+
}),
|
|
2894
|
+
128
|
|
2895
|
+
/* KEYED_FRAGMENT */
|
|
2896
|
+
)),
|
|
2897
|
+
createCommentVNode(" 显示折叠标签数量 "),
|
|
2898
|
+
hiddenCount.value > 0 ? (openBlock(), createBlock(unref(Tag), {
|
|
2899
|
+
key: 0,
|
|
2900
|
+
class: "tag-more",
|
|
2901
|
+
onClick: withModifiers(handleFocus, ["stop"])
|
|
2902
|
+
}, {
|
|
2903
|
+
default: withCtx(() => [
|
|
2904
|
+
createTextVNode(
|
|
2905
|
+
" +" + toDisplayString(hiddenCount.value),
|
|
2906
|
+
1
|
|
2907
|
+
/* TEXT */
|
|
2908
|
+
)
|
|
2909
|
+
]),
|
|
2910
|
+
_: 1
|
|
2911
|
+
/* STABLE */
|
|
2912
|
+
})) : createCommentVNode("v-if", true),
|
|
2913
|
+
createCommentVNode(" 搜索输入框 "),
|
|
2914
|
+
withDirectives(createElementVNode("input", {
|
|
2915
|
+
ref_key: "collapsedInputRef",
|
|
2916
|
+
ref: collapsedInputRef,
|
|
2917
|
+
class: "search-input collapsed",
|
|
2918
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isRef(searchQuery) ? searchQuery.value = $event : null),
|
|
2919
|
+
placeholder: !__props.selectedUsers.length ? __props.placeholder : "",
|
|
2920
|
+
onFocus: handleFocus
|
|
2921
|
+
}, null, 40, _hoisted_3), [
|
|
2922
|
+
[vModelText, unref(searchQuery)]
|
|
2923
|
+
])
|
|
2924
|
+
],
|
|
2925
|
+
512
|
|
2926
|
+
/* NEED_PATCH */
|
|
2927
|
+
)
|
|
2928
|
+
],
|
|
2929
|
+
2112
|
|
2930
|
+
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
|
2931
|
+
)),
|
|
2932
|
+
createCommentVNode(" 下拉选项列表 "),
|
|
2933
|
+
createVNode(unref(Popover), {
|
|
2934
|
+
"ext-cls": "bk-user-selector-popover",
|
|
2935
|
+
arrow: false,
|
|
2936
|
+
disabled: !showDropdown.value,
|
|
2937
|
+
"is-show": showDropdown.value,
|
|
2938
|
+
width: containerRef.value ? containerRef.value.offsetWidth : "auto",
|
|
2939
|
+
boundary: "document.body",
|
|
2940
|
+
placement: "bottom-start",
|
|
2941
|
+
theme: "light",
|
|
2942
|
+
trigger: "manual"
|
|
2943
|
+
}, {
|
|
2944
|
+
content: withCtx(() => [
|
|
2945
|
+
createVNode(unref(Loading), {
|
|
2946
|
+
class: "dropdown-content",
|
|
2947
|
+
loading: unref(searchLoading),
|
|
2948
|
+
size: "small",
|
|
2949
|
+
mode: "spin"
|
|
2950
|
+
}, {
|
|
2951
|
+
default: withCtx(() => [
|
|
2952
|
+
unref(searchResults).length === 0 ? (openBlock(), createElementBlock("div", _hoisted_4, [
|
|
2953
|
+
createElementVNode(
|
|
2954
|
+
"span",
|
|
2955
|
+
null,
|
|
2956
|
+
toDisplayString(unref(searchQuery).length > 1 ? "未找到匹配用户" : "请输入关键词搜索"),
|
|
2957
|
+
1
|
|
2958
|
+
/* TEXT */
|
|
2959
|
+
)
|
|
2960
|
+
])) : (openBlock(true), createElementBlock(
|
|
2961
|
+
Fragment,
|
|
2962
|
+
{ key: 1 },
|
|
2963
|
+
renderList(unref(searchResults), (user) => {
|
|
2964
|
+
return openBlock(), createElementBlock("div", {
|
|
2965
|
+
class: "user-option",
|
|
2966
|
+
key: user.id,
|
|
2967
|
+
onMousedown: withModifiers(($event) => addUser(user), ["prevent"])
|
|
2968
|
+
}, [
|
|
2969
|
+
createElementVNode(
|
|
2970
|
+
"span",
|
|
2971
|
+
_hoisted_6,
|
|
2972
|
+
toDisplayString(user.name),
|
|
2973
|
+
1
|
|
2974
|
+
/* TEXT */
|
|
2975
|
+
),
|
|
2976
|
+
user.tenantId !== __props.tenantId && user.tenantId && unref(tenants)[user.tenantId] ? (openBlock(), createElementBlock(
|
|
2977
|
+
"span",
|
|
2978
|
+
_hoisted_7,
|
|
2979
|
+
"@" + toDisplayString(unref(tenants)[user.tenantId]),
|
|
2980
|
+
1
|
|
2981
|
+
/* TEXT */
|
|
2982
|
+
)) : createCommentVNode("v-if", true)
|
|
2983
|
+
], 40, _hoisted_5);
|
|
2984
|
+
}),
|
|
2985
|
+
128
|
|
2986
|
+
/* KEYED_FRAGMENT */
|
|
2987
|
+
))
|
|
2988
|
+
]),
|
|
2989
|
+
_: 1
|
|
2990
|
+
/* STABLE */
|
|
2991
|
+
}, 8, ["loading"])
|
|
2992
|
+
]),
|
|
2993
|
+
_: 1
|
|
2994
|
+
/* STABLE */
|
|
2995
|
+
}, 8, ["disabled", "is-show", "width"])
|
|
2996
|
+
])), [
|
|
2997
|
+
[unref(clickoutside), handleClickOutside]
|
|
2998
|
+
]);
|
|
2556
2999
|
};
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
3000
|
+
}
|
|
3001
|
+
});
|
|
3002
|
+
const MultipleSelector = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-6a1779a9"]]);
|
|
3003
|
+
const _hoisted_1 = { class: "bk-user-selector" };
|
|
3004
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
3005
|
+
...{
|
|
3006
|
+
name: "BkUserSelector"
|
|
3007
|
+
},
|
|
3008
|
+
__name: "user-selector",
|
|
3009
|
+
props: {
|
|
3010
|
+
label: { default: "人员选择" },
|
|
3011
|
+
required: { type: Boolean, default: false },
|
|
3012
|
+
placeholder: { default: "请输入人员名称搜索" },
|
|
3013
|
+
modelValue: { default: "" },
|
|
3014
|
+
draggable: { type: Boolean, default: false },
|
|
3015
|
+
multiple: { type: Boolean, default: false },
|
|
3016
|
+
apiBaseUrl: { default: "" },
|
|
3017
|
+
tenantId: { default: "" }
|
|
3018
|
+
},
|
|
3019
|
+
emits: ["update:modelValue", "change"],
|
|
3020
|
+
setup(__props, { emit: __emit }) {
|
|
3021
|
+
const props = __props;
|
|
3022
|
+
const emit = __emit;
|
|
3023
|
+
const { tenants } = useTenantData(props.apiBaseUrl, props.tenantId);
|
|
3024
|
+
const selectedUsers = ref([]);
|
|
3025
|
+
const selectedUser = ref(props.multiple ? "" : props.modelValue);
|
|
3026
|
+
const selectedUserIds = computed(() => {
|
|
3027
|
+
return props.multiple ? selectedUsers.value.map((user) => user.id) : [];
|
|
3028
|
+
});
|
|
3029
|
+
const initSelectedUsers = async () => {
|
|
3030
|
+
if (props.multiple) {
|
|
3031
|
+
const ids = Array.isArray(props.modelValue) ? props.modelValue : [];
|
|
3032
|
+
if (ids.length > 0) {
|
|
3033
|
+
try {
|
|
3034
|
+
const result = await lookupUsers(props.apiBaseUrl, props.tenantId, ids);
|
|
3035
|
+
selectedUsers.value = formatUsers(result);
|
|
3036
|
+
} catch (error) {
|
|
3037
|
+
console.error("获取选中用户信息失败:", error);
|
|
2573
3038
|
}
|
|
2574
|
-
sortableInstance.value = Sortable.create(sortableContainerEl, {
|
|
2575
|
-
...dragOptions.value,
|
|
2576
|
-
onEnd: (evt) => {
|
|
2577
|
-
const newOrder = [...selectedUsers.value];
|
|
2578
|
-
const { oldIndex: oldIndex2, newIndex: newIndex2 } = evt;
|
|
2579
|
-
if (oldIndex2 !== newIndex2) {
|
|
2580
|
-
const movedItem = newOrder.splice(oldIndex2, 1)[0];
|
|
2581
|
-
newOrder.splice(newIndex2, 0, movedItem);
|
|
2582
|
-
selectedUsers.value = newOrder;
|
|
2583
|
-
handleDragChange();
|
|
2584
|
-
}
|
|
2585
|
-
}
|
|
2586
|
-
});
|
|
2587
3039
|
}
|
|
2588
|
-
}
|
|
3040
|
+
} else {
|
|
3041
|
+
selectedUser.value = props.modelValue;
|
|
3042
|
+
}
|
|
2589
3043
|
};
|
|
2590
|
-
|
|
2591
|
-
()
|
|
2592
|
-
() => props.draggable,
|
|
2593
|
-
() => isFocused.value
|
|
2594
|
-
], () => {
|
|
2595
|
-
initSortable();
|
|
2596
|
-
}, { deep: true });
|
|
2597
|
-
const handleDragChange = () => {
|
|
2598
|
-
emit("change", selectedUsers.value);
|
|
3044
|
+
const handleUpdateUser = (user) => {
|
|
3045
|
+
emit("change", user);
|
|
2599
3046
|
};
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
selectedUsers.value = [user];
|
|
3047
|
+
const handleUpdateSelectedUsers = (users) => {
|
|
3048
|
+
selectedUsers.value = users;
|
|
3049
|
+
emit("update:modelValue", users.map((user) => user.id));
|
|
3050
|
+
emit("change", users);
|
|
2605
3051
|
};
|
|
3052
|
+
watch(selectedUser, (newVal) => {
|
|
3053
|
+
if (!props.multiple) {
|
|
3054
|
+
emit("update:modelValue", newVal);
|
|
3055
|
+
}
|
|
3056
|
+
});
|
|
3057
|
+
onBeforeMount(() => {
|
|
3058
|
+
initSelectedUsers();
|
|
3059
|
+
});
|
|
2606
3060
|
return (_ctx, _cache) => {
|
|
2607
|
-
return
|
|
3061
|
+
return openBlock(), createElementBlock("section", _hoisted_1, [
|
|
2608
3062
|
createCommentVNode(" 单选模式 "),
|
|
2609
|
-
!
|
|
3063
|
+
!_ctx.multiple ? (openBlock(), createBlock(SingleSelector, {
|
|
2610
3064
|
key: 0,
|
|
2611
|
-
modelValue:
|
|
2612
|
-
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) =>
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
"tenant-id":
|
|
2616
|
-
|
|
2617
|
-
|
|
3065
|
+
modelValue: selectedUser.value,
|
|
3066
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => selectedUser.value = $event),
|
|
3067
|
+
"api-base-url": _ctx.apiBaseUrl,
|
|
3068
|
+
placeholder: _ctx.placeholder,
|
|
3069
|
+
"tenant-id": _ctx.tenantId,
|
|
3070
|
+
tenants: unref(tenants),
|
|
3071
|
+
onChange: handleUpdateUser
|
|
3072
|
+
}, null, 8, ["modelValue", "api-base-url", "placeholder", "tenant-id", "tenants"])) : (openBlock(), createElementBlock(
|
|
2618
3073
|
Fragment,
|
|
2619
3074
|
{ key: 1 },
|
|
2620
3075
|
[
|
|
2621
|
-
createCommentVNode("
|
|
2622
|
-
createVNode(
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
"
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
withDirectives((openBlock(), createElementBlock("div", _hoisted_1, [
|
|
2633
|
-
userList.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_2, _hoisted_4)) : (openBlock(true), createElementBlock(
|
|
2634
|
-
Fragment,
|
|
2635
|
-
{ key: 1 },
|
|
2636
|
-
renderList(userList.value, (item) => {
|
|
2637
|
-
return openBlock(), createElementBlock("div", {
|
|
2638
|
-
key: item.id,
|
|
2639
|
-
class: "user-option",
|
|
2640
|
-
onMousedown: withModifiers(($event) => addUser(item), ["prevent"])
|
|
2641
|
-
}, [
|
|
2642
|
-
item.avatar ? (openBlock(), createElementBlock("img", {
|
|
2643
|
-
key: 0,
|
|
2644
|
-
class: "user-avatar",
|
|
2645
|
-
src: item.avatar,
|
|
2646
|
-
alt: "用户头像"
|
|
2647
|
-
}, null, 8, _hoisted_6)) : (openBlock(), createElementBlock(
|
|
2648
|
-
"span",
|
|
2649
|
-
_hoisted_7,
|
|
2650
|
-
toDisplayString(getAvatarText(item.name)),
|
|
2651
|
-
1
|
|
2652
|
-
/* TEXT */
|
|
2653
|
-
)),
|
|
2654
|
-
createElementVNode(
|
|
2655
|
-
"span",
|
|
2656
|
-
_hoisted_8,
|
|
2657
|
-
toDisplayString(item.name),
|
|
2658
|
-
1
|
|
2659
|
-
/* TEXT */
|
|
2660
|
-
)
|
|
2661
|
-
], 40, _hoisted_5);
|
|
2662
|
-
}),
|
|
2663
|
-
128
|
|
2664
|
-
/* KEYED_FRAGMENT */
|
|
2665
|
-
))
|
|
2666
|
-
])), [
|
|
2667
|
-
[unref(vLoading), { mode: "spin", size: "small", loading: loading.value }]
|
|
2668
|
-
])
|
|
2669
|
-
]),
|
|
2670
|
-
default: withCtx(() => [
|
|
2671
|
-
createElementVNode(
|
|
2672
|
-
"div",
|
|
2673
|
-
{
|
|
2674
|
-
ref_key: "containerRef",
|
|
2675
|
-
ref: containerRef,
|
|
2676
|
-
class: normalizeClass(["tag-input-container", { "is-focused": isFocused.value, "is-single": !__props.multiple }])
|
|
2677
|
-
},
|
|
2678
|
-
[
|
|
2679
|
-
createCommentVNode(" 多选模式 "),
|
|
2680
|
-
createCommentVNode(" 聚焦状态 - 使用单一draggable "),
|
|
2681
|
-
isFocused.value ? (openBlock(), createElementBlock(
|
|
2682
|
-
Fragment,
|
|
2683
|
-
{ key: 0 },
|
|
2684
|
-
[
|
|
2685
|
-
createCommentVNode(" 多选模式 "),
|
|
2686
|
-
createElementVNode(
|
|
2687
|
-
"div",
|
|
2688
|
-
_hoisted_9,
|
|
2689
|
-
[
|
|
2690
|
-
(openBlock(true), createElementBlock(
|
|
2691
|
-
Fragment,
|
|
2692
|
-
null,
|
|
2693
|
-
renderList(selectedUsers.value, (element, index2) => {
|
|
2694
|
-
return openBlock(), createElementBlock("div", {
|
|
2695
|
-
key: element.id,
|
|
2696
|
-
class: "tag-wrapper",
|
|
2697
|
-
onClick: withModifiers(($event) => handleTagClick(index2), ["stop"])
|
|
2698
|
-
}, [
|
|
2699
|
-
createVNode(unref(Tag), {
|
|
2700
|
-
class: normalizeClass(["tag-item", { "draggable": __props.draggable, "active": index2 === activeTagIndex.value }]),
|
|
2701
|
-
size: "small",
|
|
2702
|
-
closable: "",
|
|
2703
|
-
onClose: ($event) => removeUser(element),
|
|
2704
|
-
onClick: withModifiers(($event) => handleTagClick(index2), ["stop"])
|
|
2705
|
-
}, {
|
|
2706
|
-
default: withCtx(() => [
|
|
2707
|
-
createElementVNode("div", _hoisted_11, [
|
|
2708
|
-
createElementVNode(
|
|
2709
|
-
"span",
|
|
2710
|
-
_hoisted_12,
|
|
2711
|
-
toDisplayString(element.name),
|
|
2712
|
-
1
|
|
2713
|
-
/* TEXT */
|
|
2714
|
-
)
|
|
2715
|
-
])
|
|
2716
|
-
]),
|
|
2717
|
-
_: 2
|
|
2718
|
-
/* DYNAMIC */
|
|
2719
|
-
}, 1032, ["class", "onClose", "onClick"]),
|
|
2720
|
-
createCommentVNode(" 在当前激活的标签后插入输入框 "),
|
|
2721
|
-
createElementVNode(
|
|
2722
|
-
"span",
|
|
2723
|
-
{
|
|
2724
|
-
ref_for: true,
|
|
2725
|
-
ref_key: "measureEl",
|
|
2726
|
-
ref: measureEl,
|
|
2727
|
-
class: "measure-text",
|
|
2728
|
-
"aria-hidden": "true"
|
|
2729
|
-
},
|
|
2730
|
-
null,
|
|
2731
|
-
512
|
|
2732
|
-
/* NEED_PATCH */
|
|
2733
|
-
),
|
|
2734
|
-
index2 === activeTagIndex.value && activeTagIndex.value !== selectedUsers.value.length - 1 ? withDirectives((openBlock(), createElementBlock("input", {
|
|
2735
|
-
key: 0,
|
|
2736
|
-
ref_for: true,
|
|
2737
|
-
ref_key: "searchInput",
|
|
2738
|
-
ref: searchInput,
|
|
2739
|
-
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => searchQuery.value = $event),
|
|
2740
|
-
placeholder: selectedUsers.value.length ? "" : __props.placeholder,
|
|
2741
|
-
class: "tag-input inline-input",
|
|
2742
|
-
onInput: handleInput,
|
|
2743
|
-
onFocus: handleFocus
|
|
2744
|
-
}, null, 40, _hoisted_13)), [
|
|
2745
|
-
[vModelText, searchQuery.value]
|
|
2746
|
-
]) : createCommentVNode("v-if", true)
|
|
2747
|
-
], 8, _hoisted_10);
|
|
2748
|
-
}),
|
|
2749
|
-
128
|
|
2750
|
-
/* KEYED_FRAGMENT */
|
|
2751
|
-
))
|
|
2752
|
-
],
|
|
2753
|
-
512
|
|
2754
|
-
/* NEED_PATCH */
|
|
2755
|
-
),
|
|
2756
|
-
createCommentVNode(" 如果激活索引是最后一个或没有激活的标签,将输入框放在最后 "),
|
|
2757
|
-
activeTagIndex.value === -1 || activeTagIndex.value === selectedUsers.value.length - 1 ? withDirectives((openBlock(), createElementBlock("input", {
|
|
2758
|
-
key: 0,
|
|
2759
|
-
ref_key: "searchInput",
|
|
2760
|
-
ref: searchInput,
|
|
2761
|
-
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => searchQuery.value = $event),
|
|
2762
|
-
placeholder: selectedUsers.value.length ? "" : __props.placeholder,
|
|
2763
|
-
class: "tag-input single-input",
|
|
2764
|
-
onInput: handleInput,
|
|
2765
|
-
onFocus: handleFocus
|
|
2766
|
-
}, null, 40, _hoisted_14)), [
|
|
2767
|
-
[vModelText, searchQuery.value]
|
|
2768
|
-
]) : createCommentVNode("v-if", true)
|
|
2769
|
-
],
|
|
2770
|
-
64
|
|
2771
|
-
/* STABLE_FRAGMENT */
|
|
2772
|
-
)) : (openBlock(), createElementBlock(
|
|
2773
|
-
Fragment,
|
|
2774
|
-
{ key: 1 },
|
|
2775
|
-
[
|
|
2776
|
-
createCommentVNode(" 失焦状态 "),
|
|
2777
|
-
createCommentVNode(" 多选模式 "),
|
|
2778
|
-
createElementVNode(
|
|
2779
|
-
"div",
|
|
2780
|
-
{
|
|
2781
|
-
ref_key: "tagInlineContainerRef",
|
|
2782
|
-
ref: tagInlineContainerRef,
|
|
2783
|
-
class: "tag-inline-container",
|
|
2784
|
-
onClick: withModifiers(handleFocus, ["stop"])
|
|
2785
|
-
},
|
|
2786
|
-
[
|
|
2787
|
-
(openBlock(true), createElementBlock(
|
|
2788
|
-
Fragment,
|
|
2789
|
-
null,
|
|
2790
|
-
renderList(visibleUsers.value, (user) => {
|
|
2791
|
-
return openBlock(), createBlock(unref(Tag), {
|
|
2792
|
-
key: user.id,
|
|
2793
|
-
class: "tag-item",
|
|
2794
|
-
closable: "",
|
|
2795
|
-
onClose: ($event) => removeUser(user),
|
|
2796
|
-
onClick: withModifiers(handleFocus, ["stop"])
|
|
2797
|
-
}, {
|
|
2798
|
-
default: withCtx(() => [
|
|
2799
|
-
createElementVNode("div", _hoisted_15, [
|
|
2800
|
-
createElementVNode(
|
|
2801
|
-
"span",
|
|
2802
|
-
_hoisted_16,
|
|
2803
|
-
toDisplayString(user.name),
|
|
2804
|
-
1
|
|
2805
|
-
/* TEXT */
|
|
2806
|
-
)
|
|
2807
|
-
])
|
|
2808
|
-
]),
|
|
2809
|
-
_: 2
|
|
2810
|
-
/* DYNAMIC */
|
|
2811
|
-
}, 1032, ["onClose"]);
|
|
2812
|
-
}),
|
|
2813
|
-
128
|
|
2814
|
-
/* KEYED_FRAGMENT */
|
|
2815
|
-
)),
|
|
2816
|
-
createCommentVNode(" 显示折叠标签数量 "),
|
|
2817
|
-
hiddenCount.value > 0 ? (openBlock(), createBlock(unref(Tag), {
|
|
2818
|
-
key: 0,
|
|
2819
|
-
class: "tag-item tag-more",
|
|
2820
|
-
onClick: withModifiers(handleFocus, ["stop"])
|
|
2821
|
-
}, {
|
|
2822
|
-
default: withCtx(() => [
|
|
2823
|
-
createTextVNode(
|
|
2824
|
-
" +" + toDisplayString(hiddenCount.value),
|
|
2825
|
-
1
|
|
2826
|
-
/* TEXT */
|
|
2827
|
-
)
|
|
2828
|
-
]),
|
|
2829
|
-
_: 1
|
|
2830
|
-
/* STABLE */
|
|
2831
|
-
})) : createCommentVNode("v-if", true),
|
|
2832
|
-
createCommentVNode(" 修改这里的输入框样式 "),
|
|
2833
|
-
withDirectives(createElementVNode("input", {
|
|
2834
|
-
ref_key: "searchInput",
|
|
2835
|
-
ref: searchInput,
|
|
2836
|
-
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => searchQuery.value = $event),
|
|
2837
|
-
placeholder: selectedUsers.value.length ? "" : __props.placeholder,
|
|
2838
|
-
class: normalizeClass(["tag-input full-width", { "placeholder-style": !selectedUsers.value.length }]),
|
|
2839
|
-
onFocus: handleFocus
|
|
2840
|
-
}, null, 42, _hoisted_17), [
|
|
2841
|
-
[vModelText, searchQuery.value]
|
|
2842
|
-
])
|
|
2843
|
-
],
|
|
2844
|
-
512
|
|
2845
|
-
/* NEED_PATCH */
|
|
2846
|
-
)
|
|
2847
|
-
],
|
|
2848
|
-
64
|
|
2849
|
-
/* STABLE_FRAGMENT */
|
|
2850
|
-
))
|
|
2851
|
-
],
|
|
2852
|
-
2
|
|
2853
|
-
/* CLASS */
|
|
2854
|
-
)
|
|
2855
|
-
]),
|
|
2856
|
-
_: 1
|
|
2857
|
-
/* STABLE */
|
|
2858
|
-
}, 8, ["is-show", "width", "disabled"])
|
|
3076
|
+
createCommentVNode(" 多选模式 "),
|
|
3077
|
+
createVNode(MultipleSelector, {
|
|
3078
|
+
modelValue: selectedUserIds.value,
|
|
3079
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => selectedUserIds.value = $event),
|
|
3080
|
+
"api-base-url": _ctx.apiBaseUrl,
|
|
3081
|
+
placeholder: _ctx.placeholder,
|
|
3082
|
+
"tenant-id": _ctx.tenantId,
|
|
3083
|
+
draggable: _ctx.draggable,
|
|
3084
|
+
"selected-users": selectedUsers.value,
|
|
3085
|
+
"onUpdate:selectedUsers": handleUpdateSelectedUsers
|
|
3086
|
+
}, null, 8, ["modelValue", "api-base-url", "placeholder", "tenant-id", "draggable", "selected-users"])
|
|
2859
3087
|
],
|
|
2860
3088
|
2112
|
|
2861
3089
|
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
|
2862
3090
|
))
|
|
2863
|
-
])), [
|
|
2864
|
-
[unref(vClickoutside), handleBlur]
|
|
2865
3091
|
]);
|
|
2866
3092
|
};
|
|
2867
3093
|
}
|
|
2868
|
-
};
|
|
2869
|
-
const BkUserSelector = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
3094
|
+
});
|
|
3095
|
+
const BkUserSelector = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-144c2518"]]);
|
|
2870
3096
|
export {
|
|
2871
3097
|
BkUserSelector,
|
|
2872
3098
|
BkUserSelector as default
|