@blueking/bk-user-selector 0.1.8 → 0.1.9
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 +31 -30
- package/package.json +1 -1
- package/typings/components/selection-popover.vue.d.ts +6 -0
- package/typings/components/user-selector.vue.d.ts +1 -0
- package/typings/hooks/use-input-handler.d.ts +2 -0
- package/typings/hooks/use-user-selection.d.ts +8 -0
- package/typings/types/index.d.ts +4 -0
- package/vue2/index.es.min.js +95 -17
- package/vue2/index.iife.min.js +96 -18
- package/vue2/index.umd.min.js +96 -18
- package/vue2/vue2.css +7 -0
- package/vue3/index.es.min.js +95 -17
- package/vue3/index.iife.min.js +96 -18
- package/vue3/index.umd.min.js +96 -18
- package/vue3/vue3.css +7 -0
package/vue3/index.umd.min.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.lesscodeCustomComponentLibrary = {}, global.Vue, global.bkui_vue));
|
|
7
7
|
})(this, function(exports, vue, bkui_vue) {
|
|
8
8
|
var __vite_style__ = document.createElement("style");
|
|
9
|
-
__vite_style__.textContent = "@charset \"UTF-8\";.me-tag[data-v-a1054364] {\n position: absolute;\n top: 50%;\n right: 8px;\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0 8px;\n font-size: 12px;\n color: #4d4f56;\n white-space: nowrap;\n cursor: pointer;\n background-color: #e1ecff;\n border-radius: 50%;\n transform: translateY(-50%);\n}\n.me-tag[data-v-a1054364]:hover {\n color: #3a84ff;\n background-color: #cddffe;\n}\n.me-tag.disabled[data-v-a1054364] {\n color: #c4c6cc;\n cursor: not-allowed;\n background-color: #f0f1f5;\n}.dropdown-content[data-v-9173accf] {\n min-height: 40px;\n max-height: 300px;\n padding: 5px 0;\n}\n.dropdown-content .no-data[data-v-9173accf] {\n padding: 10px;\n color: #979ba5;\n text-align: center;\n}\n.dropdown-panels[data-v-9173accf] {\n display: block;\n}\n.dropdown-panel[data-v-9173accf] {\n min-width: 0;\n max-height: 290px;\n overflow-y: auto;\n}\n.dropdown-panels.is-two-column[data-v-9173accf] {\n display: flex;\n}\n.dropdown-panels.is-two-column .dropdown-panel[data-v-9173accf] {\n width: 50%;\n}\n.dropdown-panels.is-two-column .dropdown-panel + .dropdown-panel[data-v-9173accf] {\n border-left: 1px solid #eaebf0;\n}\n.group-header[data-v-9173accf] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n color: #979ba5;\n}\n.group-header .group-name[data-v-9173accf],\n.group-header .group-count[data-v-9173accf] {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-group[data-v-9173accf],\n.dropdown-panel-main[data-v-9173accf],\n.dropdown-panel-recent[data-v-9173accf] {\n min-width: 0;\n}\n.user-option[data-v-9173accf] {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 32px;\n padding: 8px 12px;\n cursor: pointer;\n}\n.user-option[data-v-9173accf]:hover, .user-option.is-highlighted[data-v-9173accf] {\n background-color: #f5f7fa;\n}\n.dropdown-panel[data-v-9173accf] .user-render,\n.dropdown-panel[data-v-9173accf] .user-main,\n.dropdown-panel[data-v-9173accf] .user-name,\n.dropdown-panel[data-v-9173accf] .tenant-name,\n.user-option[data-v-9173accf] .user-render,\n.user-option[data-v-9173accf] .user-main,\n.user-option[data-v-9173accf] .user-name,\n.user-option[data-v-9173accf] .tenant-name {\n min-width: 0;\n}\n.dropdown-panel[data-v-9173accf] .user-name,\n.dropdown-panel[data-v-9173accf] .tenant-name,\n.user-option[data-v-9173accf] .user-name,\n.user-option[data-v-9173accf] .tenant-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.user-tag[data-v-d1173d20] {\n height: 24px;\n margin-right: 4px;\n margin-left: 0;\n}\n.user-tag.draggable[data-v-d1173d20] {\n cursor: move;\n}\n.user-tag.active[data-v-d1173d20] {\n background-color: #e1ecff;\n border-color: #3a84ff;\n}\n.user-tag.is-custom[data-v-d1173d20] {\n color: #ea3636;\n background-color: #feebea;\n border-color: rgba(234, 53, 54, 0.3019607843);\n}\n.user-tag.is-custom[data-v-d1173d20]:hover {\n background-color: #fedddc;\n}\n.user-tag .tag-content .user-name[data-v-d1173d20] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 12px;\n white-space: nowrap;\n}\n.bk-user-selector[data-v-089550be] {\n position: relative;\n width: 100%;\n height: 32px;\n font-size: 12px;\n}\n.bk-user-selector.is-disabled[data-v-089550be] {\n pointer-events: none;\n cursor: not-allowed;\n background-color: #dcdee5;\n}\n.bk-user-selector.is-textarea[data-v-089550be] {\n height: auto;\n min-height: 32px;\n}\n.bk-user-selector .tags-container[data-v-089550be] {\n position: relative;\n min-height: 32px;\n padding: 3px 10px 3px 8px;\n background-color: #fff;\n border: 1px solid #c4c6cc;\n border-radius: 2px;\n transition: all 0.2s ease;\n}\n.bk-user-selector .tags-container.focused[data-v-089550be] {\n border-color: #3a84ff;\n box-shadow: 0 0 0 2px rgba(58, 132, 255, 0.1);\n}\n.bk-user-selector .tags-container.tags-container-collapsed[data-v-089550be] {\n display: flex;\n flex-wrap: wrap;\n row-gap: 4px;\n /* 与 .tag-list 一致:避免默认 stretch 拉高行高后 align-items:center 把首行顶离上边框 */\n align-content: flex-start;\n align-items: center;\n}\n.bk-user-selector .tag-list[data-v-089550be] {\n display: flex;\n flex-wrap: wrap;\n row-gap: 4px;\n align-content: flex-start;\n align-items: center;\n}\n.bk-user-selector .tag-wrapper[data-v-089550be] {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n}\n.bk-user-selector .search-input[data-v-089550be] {\n min-width: 20px;\n height: 24px;\n outline: none;\n background: transparent;\n border: none;\n}\n.bk-user-selector .search-input[data-v-089550be]::placeholder {\n color: #c4c6cc;\n}\n.bk-user-selector .search-input.input-inline[data-v-089550be] {\n min-width: 20px;\n}\n.bk-user-selector .search-input.input-last[data-v-089550be], .bk-user-selector .search-input.search-input-collapsed[data-v-089550be] {\n flex: 1;\n}\n.hidden-users[data-v-089550be] {\n padding: 6px 10px;\n}.bk-user-selector-popover {\n padding: 0 !important;\n}\n.bk-user-selector.is-textarea .me-tag {\n top: 4px;\n transform: none;\n}/*$vite$:1*/";
|
|
9
|
+
__vite_style__.textContent = "@charset \"UTF-8\";.me-tag[data-v-a1054364] {\n position: absolute;\n top: 50%;\n right: 8px;\n z-index: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0 8px;\n font-size: 12px;\n color: #4d4f56;\n white-space: nowrap;\n cursor: pointer;\n background-color: #e1ecff;\n border-radius: 50%;\n transform: translateY(-50%);\n}\n.me-tag[data-v-a1054364]:hover {\n color: #3a84ff;\n background-color: #cddffe;\n}\n.me-tag.disabled[data-v-a1054364] {\n color: #c4c6cc;\n cursor: not-allowed;\n background-color: #f0f1f5;\n}.dropdown-content[data-v-9173accf] {\n min-height: 40px;\n max-height: 300px;\n padding: 5px 0;\n}\n.dropdown-content .no-data[data-v-9173accf] {\n padding: 10px;\n color: #979ba5;\n text-align: center;\n}\n.dropdown-panels[data-v-9173accf] {\n display: block;\n}\n.dropdown-panel[data-v-9173accf] {\n min-width: 0;\n max-height: 290px;\n overflow-y: auto;\n}\n.dropdown-panels.is-two-column[data-v-9173accf] {\n display: flex;\n}\n.dropdown-panels.is-two-column .dropdown-panel[data-v-9173accf] {\n width: 50%;\n}\n.dropdown-panels.is-two-column .dropdown-panel + .dropdown-panel[data-v-9173accf] {\n border-left: 1px solid #eaebf0;\n}\n.group-header[data-v-9173accf] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n color: #979ba5;\n}\n.group-header .group-name[data-v-9173accf],\n.group-header .group-count[data-v-9173accf] {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.user-group[data-v-9173accf],\n.dropdown-panel-main[data-v-9173accf],\n.dropdown-panel-recent[data-v-9173accf] {\n min-width: 0;\n}\n.user-option[data-v-9173accf] {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 32px;\n padding: 8px 12px;\n cursor: pointer;\n}\n.user-option[data-v-9173accf]:hover, .user-option.is-highlighted[data-v-9173accf] {\n background-color: #f5f7fa;\n}\n.user-option.is-disabled[data-v-9173accf] {\n cursor: not-allowed;\n opacity: 0.5;\n}\n.user-option.is-disabled[data-v-9173accf]:hover, .user-option.is-disabled.is-highlighted[data-v-9173accf] {\n background-color: transparent;\n}\n.dropdown-panel[data-v-9173accf] .user-render,\n.dropdown-panel[data-v-9173accf] .user-main,\n.dropdown-panel[data-v-9173accf] .user-name,\n.dropdown-panel[data-v-9173accf] .tenant-name,\n.user-option[data-v-9173accf] .user-render,\n.user-option[data-v-9173accf] .user-main,\n.user-option[data-v-9173accf] .user-name,\n.user-option[data-v-9173accf] .tenant-name {\n min-width: 0;\n}\n.dropdown-panel[data-v-9173accf] .user-name,\n.dropdown-panel[data-v-9173accf] .tenant-name,\n.user-option[data-v-9173accf] .user-name,\n.user-option[data-v-9173accf] .tenant-name {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}.user-tag[data-v-d1173d20] {\n height: 24px;\n margin-right: 4px;\n margin-left: 0;\n}\n.user-tag.draggable[data-v-d1173d20] {\n cursor: move;\n}\n.user-tag.active[data-v-d1173d20] {\n background-color: #e1ecff;\n border-color: #3a84ff;\n}\n.user-tag.is-custom[data-v-d1173d20] {\n color: #ea3636;\n background-color: #feebea;\n border-color: rgba(234, 53, 54, 0.3019607843);\n}\n.user-tag.is-custom[data-v-d1173d20]:hover {\n background-color: #fedddc;\n}\n.user-tag .tag-content .user-name[data-v-d1173d20] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 12px;\n white-space: nowrap;\n}\n.bk-user-selector[data-v-089550be] {\n position: relative;\n width: 100%;\n height: 32px;\n font-size: 12px;\n}\n.bk-user-selector.is-disabled[data-v-089550be] {\n pointer-events: none;\n cursor: not-allowed;\n background-color: #dcdee5;\n}\n.bk-user-selector.is-textarea[data-v-089550be] {\n height: auto;\n min-height: 32px;\n}\n.bk-user-selector .tags-container[data-v-089550be] {\n position: relative;\n min-height: 32px;\n padding: 3px 10px 3px 8px;\n background-color: #fff;\n border: 1px solid #c4c6cc;\n border-radius: 2px;\n transition: all 0.2s ease;\n}\n.bk-user-selector .tags-container.focused[data-v-089550be] {\n border-color: #3a84ff;\n box-shadow: 0 0 0 2px rgba(58, 132, 255, 0.1);\n}\n.bk-user-selector .tags-container.tags-container-collapsed[data-v-089550be] {\n display: flex;\n flex-wrap: wrap;\n row-gap: 4px;\n /* 与 .tag-list 一致:避免默认 stretch 拉高行高后 align-items:center 把首行顶离上边框 */\n align-content: flex-start;\n align-items: center;\n}\n.bk-user-selector .tag-list[data-v-089550be] {\n display: flex;\n flex-wrap: wrap;\n row-gap: 4px;\n align-content: flex-start;\n align-items: center;\n}\n.bk-user-selector .tag-wrapper[data-v-089550be] {\n display: inline-flex;\n align-items: center;\n max-width: 100%;\n}\n.bk-user-selector .search-input[data-v-089550be] {\n min-width: 20px;\n height: 24px;\n outline: none;\n background: transparent;\n border: none;\n}\n.bk-user-selector .search-input[data-v-089550be]::placeholder {\n color: #c4c6cc;\n}\n.bk-user-selector .search-input.input-inline[data-v-089550be] {\n min-width: 20px;\n}\n.bk-user-selector .search-input.input-last[data-v-089550be], .bk-user-selector .search-input.search-input-collapsed[data-v-089550be] {\n flex: 1;\n}\n.hidden-users[data-v-089550be] {\n padding: 6px 10px;\n}.bk-user-selector-popover {\n padding: 0 !important;\n}\n.bk-user-selector.is-textarea .me-tag {\n top: 4px;\n transform: none;\n}/*$vite$:1*/";
|
|
10
10
|
document.head.appendChild(__vite_style__);
|
|
11
11
|
Object.defineProperties(exports, {
|
|
12
12
|
__esModule: { value: true },
|
|
@@ -3008,7 +3008,7 @@
|
|
|
3008
3008
|
* @returns 输入处理相关方法
|
|
3009
3009
|
*/
|
|
3010
3010
|
var useInputHandler = (options) => {
|
|
3011
|
-
const { apiBaseUrl, tenantId, searchQuery, selectedUsers, allowCreate = false, freePaste = false, enableMultiTenantMode = true, maxCount = 0, onAddUser, onBatchAddUsers } = options;
|
|
3011
|
+
const { apiBaseUrl, tenantId, searchQuery, selectedUsers, allowCreate = false, freePaste = false, enableMultiTenantMode = true, maxCount = 0, isUserDisabled = () => false, onAddUser, onBatchAddUsers } = options;
|
|
3012
3012
|
const isPasting = (0, vue.ref)(false);
|
|
3013
3013
|
/** 单次粘贴最多处理数量(后端限制) */
|
|
3014
3014
|
const MAX_PASTE_USERS = 100;
|
|
@@ -3060,7 +3060,7 @@
|
|
|
3060
3060
|
const handleEnterCreate = (event) => {
|
|
3061
3061
|
if (event.key !== "Enter" || !allowCreate || !searchQuery.value.trim()) return;
|
|
3062
3062
|
const customUser = createCustomUser(searchQuery.value.trim());
|
|
3063
|
-
if (!selectedUsers.value.some((user) => user.id === customUser.id)) onAddUser(customUser);
|
|
3063
|
+
if (!selectedUsers.value.some((user) => user.id === customUser.id) && !isUserDisabled(customUser)) onAddUser(customUser);
|
|
3064
3064
|
};
|
|
3065
3065
|
/**
|
|
3066
3066
|
* 处理粘贴事件
|
|
@@ -3086,11 +3086,11 @@
|
|
|
3086
3086
|
});
|
|
3087
3087
|
lookupResults.push(...result);
|
|
3088
3088
|
}
|
|
3089
|
-
const formattedUsers = formatUsers(lookupResults, enableMultiTenantMode);
|
|
3089
|
+
const formattedUsers = formatUsers(lookupResults, enableMultiTenantMode).filter((user) => !isUserDisabled(user));
|
|
3090
3090
|
if (onBatchAddUsers) {
|
|
3091
3091
|
let mergedUsers = mergeUsers(selectedUsers.value, formattedUsers);
|
|
3092
3092
|
if (freePaste) {
|
|
3093
|
-
for (const loginName of usersList) if (!mergedUsers.some((item) => item.login_name === loginName || item.id === loginName)) mergedUsers.push(createCustomUser(loginName));
|
|
3093
|
+
for (const loginName of usersList) if (!mergedUsers.some((item) => item.login_name === loginName || item.id === loginName) && !isUserDisabled(loginName)) mergedUsers.push(createCustomUser(loginName));
|
|
3094
3094
|
}
|
|
3095
3095
|
if (maxCount > 0 && mergedUsers.length > maxCount) mergedUsers = mergedUsers.slice(0, maxCount);
|
|
3096
3096
|
onBatchAddUsers(mergedUsers);
|
|
@@ -3337,7 +3337,7 @@
|
|
|
3337
3337
|
* @returns 用户选择相关方法
|
|
3338
3338
|
*/
|
|
3339
3339
|
var useUserSelection = (options) => {
|
|
3340
|
-
const { selectedUserIds, excludeUserIds, userGroup, searchQuery } = options;
|
|
3340
|
+
const { selectedUserIds, excludeUserIds, disabledUserFields, disabledUserIds, userGroup, searchQuery } = options;
|
|
3341
3341
|
/**
|
|
3342
3342
|
* 创建自定义用户对象
|
|
3343
3343
|
* @param loginName - 用户登录名
|
|
@@ -3357,15 +3357,38 @@
|
|
|
3357
3357
|
return selectedUserIds.value.includes(userId);
|
|
3358
3358
|
};
|
|
3359
3359
|
/**
|
|
3360
|
+
* 检查用户是否被禁用
|
|
3361
|
+
* @param user - 用户对象或用户ID
|
|
3362
|
+
*/
|
|
3363
|
+
const isUserDisabled = (user) => {
|
|
3364
|
+
const ids = disabledUserIds?.value ?? [];
|
|
3365
|
+
if (typeof user === "string") return ids.includes(user);
|
|
3366
|
+
const fields = disabledUserFields?.value?.length ? disabledUserFields.value : ["id"];
|
|
3367
|
+
const indexedUser = user;
|
|
3368
|
+
return fields.some((field) => {
|
|
3369
|
+
const value = field === "id" ? user.id : indexedUser[field];
|
|
3370
|
+
return value !== void 0 && value !== null && ids.includes(String(value));
|
|
3371
|
+
});
|
|
3372
|
+
};
|
|
3373
|
+
/**
|
|
3360
3374
|
* 过滤选项(排除已选和排除列表)
|
|
3361
3375
|
* @param options - 原始选项列表
|
|
3362
3376
|
*/
|
|
3363
3377
|
const filterOptions = (options) => {
|
|
3364
3378
|
return options.filter((user) => !isUserSelected(user.id)).filter((user) => !excludeUserIds?.value?.includes(user.id));
|
|
3365
3379
|
};
|
|
3380
|
+
/**
|
|
3381
|
+
* 过滤可导航选项(排除已选、排除列表和禁用列表)
|
|
3382
|
+
* @param options - 原始选项列表
|
|
3383
|
+
*/
|
|
3384
|
+
const filterNavigableOptions = (options) => {
|
|
3385
|
+
return filterOptions(options).filter((user) => !isUserDisabled(user));
|
|
3386
|
+
};
|
|
3366
3387
|
return {
|
|
3367
3388
|
createCustomUser,
|
|
3389
|
+
filterNavigableOptions,
|
|
3368
3390
|
isUserSelected,
|
|
3391
|
+
isUserDisabled,
|
|
3369
3392
|
filterOptions,
|
|
3370
3393
|
filteredUserGroup: (0, vue.computed)(() => {
|
|
3371
3394
|
if (!userGroup?.value?.length) return [];
|
|
@@ -3546,6 +3569,16 @@
|
|
|
3546
3569
|
required: false,
|
|
3547
3570
|
default: "auto"
|
|
3548
3571
|
},
|
|
3572
|
+
disabledUserFields: {
|
|
3573
|
+
type: Array,
|
|
3574
|
+
required: false,
|
|
3575
|
+
default: () => ["id"]
|
|
3576
|
+
},
|
|
3577
|
+
disabledUserIds: {
|
|
3578
|
+
type: Array,
|
|
3579
|
+
required: false,
|
|
3580
|
+
default: () => []
|
|
3581
|
+
},
|
|
3549
3582
|
emptyText: {
|
|
3550
3583
|
type: String,
|
|
3551
3584
|
required: false,
|
|
@@ -3666,9 +3699,20 @@
|
|
|
3666
3699
|
return props.flatOptions[props.highlightedIndex] === user;
|
|
3667
3700
|
};
|
|
3668
3701
|
/**
|
|
3702
|
+
* 判断用户是否禁用
|
|
3703
|
+
*/
|
|
3704
|
+
const isUserDisabled = (user) => {
|
|
3705
|
+
const indexedUser = user;
|
|
3706
|
+
return props.disabledUserFields.some((field) => {
|
|
3707
|
+
const value = field === "id" ? user.id : indexedUser[field];
|
|
3708
|
+
return value !== void 0 && value !== null && props.disabledUserIds.includes(String(value));
|
|
3709
|
+
});
|
|
3710
|
+
};
|
|
3711
|
+
/**
|
|
3669
3712
|
* 选择用户
|
|
3670
3713
|
*/
|
|
3671
3714
|
const selectUser = (user) => {
|
|
3715
|
+
if (isUserDisabled(user)) return;
|
|
3672
3716
|
emit("select-user", user);
|
|
3673
3717
|
};
|
|
3674
3718
|
/**
|
|
@@ -3705,6 +3749,7 @@
|
|
|
3705
3749
|
hasRecentUsers,
|
|
3706
3750
|
hasDropdownOptions,
|
|
3707
3751
|
isHighlighted,
|
|
3752
|
+
isUserDisabled,
|
|
3708
3753
|
selectUser,
|
|
3709
3754
|
handleClickOutside,
|
|
3710
3755
|
get Loading() {
|
|
@@ -3737,14 +3782,14 @@
|
|
|
3737
3782
|
};
|
|
3738
3783
|
var _hoisted_4$1 = { class: "group-name" };
|
|
3739
3784
|
var _hoisted_5 = { class: "group-count" };
|
|
3740
|
-
var _hoisted_6 = ["onClick"];
|
|
3785
|
+
var _hoisted_6 = ["aria-disabled", "onClick"];
|
|
3741
3786
|
var _hoisted_7 = {
|
|
3742
3787
|
key: 1,
|
|
3743
3788
|
class: "dropdown-panel dropdown-panel-recent"
|
|
3744
3789
|
};
|
|
3745
3790
|
var _hoisted_8 = { class: "group-name" };
|
|
3746
3791
|
var _hoisted_9 = { class: "group-count" };
|
|
3747
|
-
var _hoisted_10 = ["onClick"];
|
|
3792
|
+
var _hoisted_10 = ["aria-disabled", "onClick"];
|
|
3748
3793
|
var _hoisted_11 = { ref: "slotContainerRef" };
|
|
3749
3794
|
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
|
3750
3795
|
return (0, vue.openBlock)(), (0, vue.createBlock)($setup["Popover"], {
|
|
@@ -3778,7 +3823,11 @@
|
|
|
3778
3823
|
}, [(0, vue.createElementVNode)("span", _hoisted_4$1, (0, vue.toDisplayString)(groupName), 1), (0, vue.createElementVNode)("span", _hoisted_5, "(" + (0, vue.toDisplayString)(group.length) + ")", 1)])) : (0, vue.createCommentVNode)("v-if", true), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(group, (user) => {
|
|
3779
3824
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
3780
3825
|
key: user.id,
|
|
3781
|
-
|
|
3826
|
+
"aria-disabled": $setup.isUserDisabled(user),
|
|
3827
|
+
class: (0, vue.normalizeClass)(["user-option", {
|
|
3828
|
+
"is-highlighted": $setup.isHighlighted(user),
|
|
3829
|
+
"is-disabled": $setup.isUserDisabled(user)
|
|
3830
|
+
}]),
|
|
3782
3831
|
onClick: (0, vue.withModifiers)(($event) => $setup.selectUser(user), ["prevent"]),
|
|
3783
3832
|
onMousedown: _cache[1] || (_cache[1] = (0, vue.withModifiers)(() => {}, ["prevent"]))
|
|
3784
3833
|
}, [(0, vue.createVNode)($setup["UserRender"], {
|
|
@@ -3804,7 +3853,11 @@
|
|
|
3804
3853
|
}, [(0, vue.createElementVNode)("span", _hoisted_8, (0, vue.toDisplayString)($props.recentUsersName), 1), (0, vue.createElementVNode)("span", _hoisted_9, "(" + (0, vue.toDisplayString)($props.recentUsers.length) + ")", 1)])) : (0, vue.createCommentVNode)("v-if", true), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)($props.recentUsers, (user) => {
|
|
3805
3854
|
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
3806
3855
|
key: user.id,
|
|
3807
|
-
|
|
3856
|
+
"aria-disabled": $setup.isUserDisabled(user),
|
|
3857
|
+
class: (0, vue.normalizeClass)(["user-option", {
|
|
3858
|
+
"is-highlighted": $setup.isHighlighted(user),
|
|
3859
|
+
"is-disabled": $setup.isUserDisabled(user)
|
|
3860
|
+
}]),
|
|
3808
3861
|
onClick: (0, vue.withModifiers)(($event) => $setup.selectUser(user), ["prevent"]),
|
|
3809
3862
|
onMousedown: _cache[3] || (_cache[3] = (0, vue.withModifiers)(() => {}, ["prevent"]))
|
|
3810
3863
|
}, [(0, vue.createVNode)($setup["UserRender"], {
|
|
@@ -4043,6 +4096,11 @@
|
|
|
4043
4096
|
required: false,
|
|
4044
4097
|
default: false
|
|
4045
4098
|
},
|
|
4099
|
+
disabledUserIds: {
|
|
4100
|
+
type: Array,
|
|
4101
|
+
required: false,
|
|
4102
|
+
default: () => []
|
|
4103
|
+
},
|
|
4046
4104
|
emptyText: {
|
|
4047
4105
|
type: String,
|
|
4048
4106
|
required: false,
|
|
@@ -4234,6 +4292,13 @@
|
|
|
4234
4292
|
const getLookupFields = (exactSearchKey) => {
|
|
4235
4293
|
return exactSearchKey.split(",").map((field) => field.trim()).filter(Boolean);
|
|
4236
4294
|
};
|
|
4295
|
+
const disabledUserFields = (0, vue.computed)(() => [...new Set([
|
|
4296
|
+
"id",
|
|
4297
|
+
...getLookupFields(props.exactSearchKey),
|
|
4298
|
+
DEFAULT_EXACT_SEARCH_KEY,
|
|
4299
|
+
"login_name",
|
|
4300
|
+
"username"
|
|
4301
|
+
])]);
|
|
4237
4302
|
const findUserByLookupId = (users, lookupId, lookupFields) => {
|
|
4238
4303
|
return users.find((user) => {
|
|
4239
4304
|
if (user.id === lookupId) return true;
|
|
@@ -4278,7 +4343,7 @@
|
|
|
4278
4343
|
/**
|
|
4279
4344
|
* "我"标签是否禁用(已选中当前用户时禁用,或已达到最大数量)
|
|
4280
4345
|
*/
|
|
4281
|
-
const isMeTagDisabled = (0, vue.computed)(() => isMaxCountReached.value || !!props.currentUserId && selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId));
|
|
4346
|
+
const isMeTagDisabled = (0, vue.computed)(() => isMaxCountReached.value || !!props.currentUserId && props.disabledUserIds.includes(props.currentUserId) || !!props.currentUserId && selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId));
|
|
4282
4347
|
/**
|
|
4283
4348
|
* UserTag 公共属性
|
|
4284
4349
|
*/
|
|
@@ -4292,8 +4357,10 @@
|
|
|
4292
4357
|
/**
|
|
4293
4358
|
* 使用用户选择公共逻辑 hook
|
|
4294
4359
|
*/
|
|
4295
|
-
const { filteredUserGroup, filterOptions, createCustomUser } = useUserSelection({
|
|
4360
|
+
const { filteredUserGroup, filterOptions, filterNavigableOptions, createCustomUser, isUserDisabled } = useUserSelection({
|
|
4296
4361
|
selectedUserIds,
|
|
4362
|
+
disabledUserFields,
|
|
4363
|
+
disabledUserIds: (0, vue.toRef)(props, "disabledUserIds"),
|
|
4297
4364
|
excludeUserIds: (0, vue.toRef)(props, "excludeUserIds"),
|
|
4298
4365
|
userGroup: (0, vue.toRef)(props, "userGroup"),
|
|
4299
4366
|
searchQuery
|
|
@@ -4310,6 +4377,7 @@
|
|
|
4310
4377
|
freePaste: props.freePaste,
|
|
4311
4378
|
enableMultiTenantMode: props.enableMultiTenantMode,
|
|
4312
4379
|
maxCount: props.maxCount,
|
|
4380
|
+
isUserDisabled,
|
|
4313
4381
|
onAddUser: addUser,
|
|
4314
4382
|
onBatchAddUsers: props.multiple ? updateSelectedUsers : void 0
|
|
4315
4383
|
});
|
|
@@ -4318,13 +4386,14 @@
|
|
|
4318
4386
|
*/
|
|
4319
4387
|
const displayOptions = (0, vue.computed)(() => filterOptions(searchResults.value));
|
|
4320
4388
|
const mainNavigableUsers = (0, vue.computed)(() => {
|
|
4321
|
-
const userGroupOptions = filteredUserGroup.value.map((group) => ({
|
|
4389
|
+
const userGroupOptions = filterNavigableOptions(filteredUserGroup.value.map((group) => ({
|
|
4322
4390
|
...group,
|
|
4323
4391
|
tenantId: "",
|
|
4324
4392
|
type: USER_TYPE.USER_GROUP
|
|
4325
|
-
}));
|
|
4326
|
-
const
|
|
4327
|
-
const
|
|
4393
|
+
})));
|
|
4394
|
+
const selectableOptions = filterNavigableOptions(displayOptions.value);
|
|
4395
|
+
const normalUsers = selectableOptions.filter((user) => user.data_source_type !== USER_TYPE.VIRTUAL);
|
|
4396
|
+
const virtualUsers = selectableOptions.filter((user) => user.data_source_type === USER_TYPE.VIRTUAL);
|
|
4328
4397
|
return [
|
|
4329
4398
|
...userGroupOptions,
|
|
4330
4399
|
...normalUsers,
|
|
@@ -4347,7 +4416,7 @@
|
|
|
4347
4416
|
* 用户群组 → 普通用户 → 虚拟账号 → 最近选择
|
|
4348
4417
|
*/
|
|
4349
4418
|
const flatOptions = (0, vue.computed)(() => {
|
|
4350
|
-
return [...mainNavigableUsers.value, ...filteredRecentUsers.value];
|
|
4419
|
+
return [...mainNavigableUsers.value, ...filterNavigableOptions(filteredRecentUsers.value)];
|
|
4351
4420
|
});
|
|
4352
4421
|
/**
|
|
4353
4422
|
* 输入框宽度(根据输入内容动态计算)
|
|
@@ -4549,10 +4618,11 @@
|
|
|
4549
4618
|
* 添加当前用户("我")
|
|
4550
4619
|
*/
|
|
4551
4620
|
const addCurrentUser = async () => {
|
|
4552
|
-
if (!props.currentUserId || selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId)) return;
|
|
4621
|
+
if (!props.currentUserId || props.disabledUserIds.includes(props.currentUserId) || selectedUsers.value.some((user) => user[props.exactSearchKey] === props.currentUserId)) return;
|
|
4553
4622
|
if (props.multiple && isMaxCountReached.value) return;
|
|
4554
4623
|
const currentUser = await fetchCurrentUser();
|
|
4555
4624
|
if (currentUser) {
|
|
4625
|
+
if (isUserDisabled(currentUser)) return;
|
|
4556
4626
|
if (!props.multiple) updateSelectedUsers([currentUser]);
|
|
4557
4627
|
else if (!selectedUsers.value.some((item) => item.id === currentUser.id)) updateSelectedUsers([...selectedUsers.value, currentUser]);
|
|
4558
4628
|
clearSearch();
|
|
@@ -4624,6 +4694,7 @@
|
|
|
4624
4694
|
*/
|
|
4625
4695
|
function addUser(user) {
|
|
4626
4696
|
if (!user?.id) return;
|
|
4697
|
+
if (isUserDisabled(user)) return;
|
|
4627
4698
|
if (props.multiple && isMaxCountReached.value) {
|
|
4628
4699
|
clearSearch();
|
|
4629
4700
|
highlightedIndex.value = -1;
|
|
@@ -4795,6 +4866,7 @@
|
|
|
4795
4866
|
selectedUserIds,
|
|
4796
4867
|
isUserMatchedByQuery,
|
|
4797
4868
|
getLookupFields,
|
|
4869
|
+
disabledUserFields,
|
|
4798
4870
|
findUserByLookupId,
|
|
4799
4871
|
sortUsersByLookupIds,
|
|
4800
4872
|
lookupFormattedUsersByIds,
|
|
@@ -4803,7 +4875,9 @@
|
|
|
4803
4875
|
userTagCommonProps,
|
|
4804
4876
|
filteredUserGroup,
|
|
4805
4877
|
filterOptions,
|
|
4878
|
+
filterNavigableOptions,
|
|
4806
4879
|
createCustomUser,
|
|
4880
|
+
isUserDisabled,
|
|
4807
4881
|
handlePaste,
|
|
4808
4882
|
displayOptions,
|
|
4809
4883
|
mainNavigableUsers,
|
|
@@ -4875,6 +4949,8 @@
|
|
|
4875
4949
|
}, [(0, vue.createCommentVNode)(" 下拉选项列表 "), (0, vue.createVNode)($setup["SelectionPopover"], {
|
|
4876
4950
|
"avatar-base-url": $props.avatarBaseUrl,
|
|
4877
4951
|
"container-width": $setup.containerRef ? $setup.containerRef.offsetWidth : "auto",
|
|
4952
|
+
"disabled-user-fields": $setup.disabledUserFields,
|
|
4953
|
+
"disabled-user-ids": $props.disabledUserIds,
|
|
4878
4954
|
"empty-text": $setup.computedEmptyText,
|
|
4879
4955
|
"flat-options": $setup.flatOptions,
|
|
4880
4956
|
"has-avatar": $props.hasAvatar,
|
|
@@ -5028,6 +5104,8 @@
|
|
|
5028
5104
|
}, 8, [
|
|
5029
5105
|
"avatar-base-url",
|
|
5030
5106
|
"container-width",
|
|
5107
|
+
"disabled-user-fields",
|
|
5108
|
+
"disabled-user-ids",
|
|
5031
5109
|
"empty-text",
|
|
5032
5110
|
"flat-options",
|
|
5033
5111
|
"has-avatar",
|
package/vue3/vue3.css
CHANGED
|
@@ -82,6 +82,13 @@
|
|
|
82
82
|
.user-option[data-v-9173accf]:hover, .user-option.is-highlighted[data-v-9173accf] {
|
|
83
83
|
background-color: #f5f7fa;
|
|
84
84
|
}
|
|
85
|
+
.user-option.is-disabled[data-v-9173accf] {
|
|
86
|
+
cursor: not-allowed;
|
|
87
|
+
opacity: 0.5;
|
|
88
|
+
}
|
|
89
|
+
.user-option.is-disabled[data-v-9173accf]:hover, .user-option.is-disabled.is-highlighted[data-v-9173accf] {
|
|
90
|
+
background-color: transparent;
|
|
91
|
+
}
|
|
85
92
|
.dropdown-panel[data-v-9173accf] .user-render,
|
|
86
93
|
.dropdown-panel[data-v-9173accf] .user-main,
|
|
87
94
|
.dropdown-panel[data-v-9173accf] .user-name,
|