@blueking/bk-user-selector 0.0.39-beta.2 → 0.1.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.
@@ -1,11 +1,37 @@
1
+ import { FormattedUser, RenderFunction, TenantMap, UserGroupConfig } from '../types';
1
2
  /**
2
- * 用户选择器下拉菜单组件
3
+ * 组件属性
3
4
  */
4
- import { createVNode, VNode } from 'vue';
5
- import { FormattedUser } from '../types';
5
+ interface SelectionPopoverProps {
6
+ /** 容器宽度 */
7
+ containerWidth?: number | string;
8
+ /** 无匹配人员时的提示文本 */
9
+ emptyText?: string;
10
+ /** 是否显示下拉菜单 */
11
+ isShow?: boolean;
12
+ /** 是否加载中 */
13
+ loading?: boolean;
14
+ /** 搜索结果选项 */
15
+ options?: FormattedUser[];
16
+ /** 渲染列表项 */
17
+ renderListItem?: RenderFunction;
18
+ /** 搜索关键词 */
19
+ searchQuery?: string;
20
+ /** 当前租户ID */
21
+ tenantId?: string;
22
+ /** 租户信息映射 */
23
+ tenants?: TenantMap;
24
+ /** 用户组 */
25
+ userGroup?: UserGroupConfig[];
26
+ /** 用户组名称 */
27
+ userGroupName?: string;
28
+ }
6
29
  declare var __VLS_20: {};
7
30
  declare var __VLS_inheritedAttrs: {};
8
- declare const __VLS_refs: {};
31
+ declare const __VLS_refs: {
32
+ contentContainerRef: any;
33
+ slotContainerRef: any;
34
+ };
9
35
  declare const __VLS_templateResult: {
10
36
  slots: {
11
37
  default?(_: typeof __VLS_20): any;
@@ -14,205 +40,24 @@ declare const __VLS_templateResult: {
14
40
  attrs: Partial<typeof __VLS_inheritedAttrs>;
15
41
  };
16
42
  type __VLS_Slots = typeof __VLS_templateResult['slots'];
17
- declare const __VLS_component: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
18
- /**
19
- * 是否显示下拉菜单
20
- */
21
- isShow: {
22
- type: BooleanConstructor;
23
- default: boolean;
24
- };
25
- /**
26
- * 容器宽度
27
- */
28
- containerWidth: {
29
- type: (StringConstructor | NumberConstructor)[];
30
- default: string;
31
- };
32
- /**
33
- * popover crossAxis 偏移量
34
- */
35
- crossAxisOffset: {
36
- type: NumberConstructor;
37
- default: number;
38
- };
39
- /**
40
- * 是否加载中
41
- */
42
- loading: {
43
- type: BooleanConstructor;
44
- default: boolean;
45
- };
46
- /**
47
- * 搜索结果选项
48
- */
49
- options: {
50
- type: () => FormattedUser[];
51
- default: () => never[];
52
- };
53
- /**
54
- * 搜索关键词
55
- */
56
- searchQuery: {
57
- type: StringConstructor;
58
- default: string;
59
- };
60
- /**
61
- * 当前租户ID
62
- */
63
- tenantId: {
64
- type: StringConstructor;
65
- default: string;
66
- };
67
- /**
68
- * 租户信息映射
69
- */
70
- tenants: {
71
- type: () => Record<string, string>;
72
- default: () => {};
73
- };
74
- /**
75
- * 用户组
76
- */
77
- userGroup: {
78
- type: () => {
79
- hidden?: boolean;
80
- id: string;
81
- name: string;
82
- }[];
83
- default: () => never[];
84
- };
85
- /**
86
- * 用户组名称
87
- */
88
- userGroupName: {
89
- type: StringConstructor;
90
- default: string;
91
- };
92
- /**
93
- * 无匹配人员时的提示文本
94
- */
95
- emptyText: {
96
- type: StringConstructor;
97
- default: string;
98
- };
99
- /**
100
- * 渲染列表项
101
- */
102
- renderListItem: {
103
- type: () => (h: typeof createVNode, item: FormattedUser) => VNode;
104
- };
105
- }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
106
- "select-user": (...args: any[]) => void;
107
- "click-outside": (...args: any[]) => void;
108
- }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
109
- /**
110
- * 是否显示下拉菜单
111
- */
112
- isShow: {
113
- type: BooleanConstructor;
114
- default: boolean;
115
- };
116
- /**
117
- * 容器宽度
118
- */
119
- containerWidth: {
120
- type: (StringConstructor | NumberConstructor)[];
121
- default: string;
122
- };
123
- /**
124
- * popover crossAxis 偏移量
125
- */
126
- crossAxisOffset: {
127
- type: NumberConstructor;
128
- default: number;
129
- };
130
- /**
131
- * 是否加载中
132
- */
133
- loading: {
134
- type: BooleanConstructor;
135
- default: boolean;
136
- };
137
- /**
138
- * 搜索结果选项
139
- */
140
- options: {
141
- type: () => FormattedUser[];
142
- default: () => never[];
143
- };
144
- /**
145
- * 搜索关键词
146
- */
147
- searchQuery: {
148
- type: StringConstructor;
149
- default: string;
150
- };
151
- /**
152
- * 当前租户ID
153
- */
154
- tenantId: {
155
- type: StringConstructor;
156
- default: string;
157
- };
158
- /**
159
- * 租户信息映射
160
- */
161
- tenants: {
162
- type: () => Record<string, string>;
163
- default: () => {};
164
- };
165
- /**
166
- * 用户组
167
- */
168
- userGroup: {
169
- type: () => {
170
- hidden?: boolean;
171
- id: string;
172
- name: string;
173
- }[];
174
- default: () => never[];
175
- };
176
- /**
177
- * 用户组名称
178
- */
179
- userGroupName: {
180
- type: StringConstructor;
181
- default: string;
182
- };
183
- /**
184
- * 无匹配人员时的提示文本
185
- */
186
- emptyText: {
187
- type: StringConstructor;
188
- default: string;
189
- };
190
- /**
191
- * 渲染列表项
192
- */
193
- renderListItem: {
194
- type: () => (h: typeof createVNode, item: FormattedUser) => VNode;
195
- };
196
- }>> & Readonly<{
197
- "onSelect-user"?: ((...args: any[]) => any) | undefined;
198
- "onClick-outside"?: ((...args: any[]) => any) | undefined;
43
+ declare const __VLS_component: import("vue").DefineComponent<SelectionPopoverProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
44
+ "click-outside": (event: MouseEvent) => any;
45
+ "select-user": (user: FormattedUser) => any;
46
+ }, string, import("vue").PublicProps, Readonly<SelectionPopoverProps> & Readonly<{
47
+ "onClick-outside"?: ((event: MouseEvent) => any) | undefined;
48
+ "onSelect-user"?: ((user: FormattedUser) => any) | undefined;
199
49
  }>, {
50
+ userGroup: UserGroupConfig[];
200
51
  tenantId: string;
201
- tenants: Record<string, string>;
52
+ searchQuery: string;
53
+ tenants: TenantMap;
54
+ containerWidth: number | string;
55
+ emptyText: string;
202
56
  isShow: boolean;
203
- containerWidth: string | number;
204
- crossAxisOffset: number;
205
57
  loading: boolean;
206
58
  options: FormattedUser[];
207
- searchQuery: string;
208
- userGroup: {
209
- hidden?: boolean;
210
- id: string;
211
- name: string;
212
- }[];
213
59
  userGroupName: string;
214
- emptyText: string;
215
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
60
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
216
61
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_Slots>;
217
62
  export default _default;
218
63
  type __VLS_PickRefsExpose<T> = T extends object ? {
@@ -1,43 +1,35 @@
1
- import { UserSelectorProps } from '../types';
1
+ import { FormattedUser, UserSelectorProps } from '../types';
2
2
  declare const _default: import("vue").DefineComponent<UserSelectorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
3
- blur: (...args: any[]) => void;
4
- change: (...args: any[]) => void;
5
- focus: (...args: any[]) => void;
6
- dragStart: (...args: any[]) => void;
7
- dragEnd: (...args: any[]) => void;
8
- "update:modelValue": (...args: any[]) => void;
3
+ blur: () => any;
4
+ change: (user: FormattedUser | FormattedUser[] | null) => any;
5
+ focus: () => any;
6
+ dragEnd: (event: Sortable.SortableEvent) => any;
7
+ dragStart: (event: Sortable.SortableEvent) => any;
8
+ "update:modelValue": (value: string | string[]) => any;
9
9
  }, string, import("vue").PublicProps, Readonly<UserSelectorProps> & Readonly<{
10
- onBlur?: ((...args: any[]) => any) | undefined;
11
- onChange?: ((...args: any[]) => any) | undefined;
12
- onFocus?: ((...args: any[]) => any) | undefined;
13
- onDragStart?: ((...args: any[]) => any) | undefined;
14
- onDragEnd?: ((...args: any[]) => any) | undefined;
15
- "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
10
+ onBlur?: (() => any) | undefined;
11
+ onChange?: ((user: FormattedUser | FormattedUser[] | null) => any) | undefined;
12
+ onFocus?: (() => any) | undefined;
13
+ onDragEnd?: ((event: Sortable.SortableEvent) => any) | undefined;
14
+ onDragStart?: ((event: Sortable.SortableEvent) => any) | undefined;
15
+ "onUpdate:modelValue"?: ((value: string | string[]) => any) | undefined;
16
16
  }>, {
17
- tenantId: string;
17
+ userGroup: import("../types").UserGroupConfig[];
18
18
  apiBaseUrl: string;
19
+ tenantId: string;
19
20
  enableMultiTenantMode: boolean;
20
21
  exactSearchKey: string;
21
22
  currentUserId: string;
23
+ allowCreate: boolean;
24
+ freePaste: boolean;
25
+ maxCount: number;
26
+ excludeUserIds: string[];
22
27
  disabled: boolean;
23
- userGroup: {
24
- hidden
25
- /**
26
- * 蓝鲸用户选择器组件
27
- * @module components/UserSelector
28
- */
29
- ?: boolean;
30
- id: string;
31
- name: string;
32
- }[];
33
- userGroupName: string;
34
28
  emptyText: string;
29
+ userGroupName: string;
35
30
  draggable: boolean;
36
- freePaste: boolean;
37
31
  modelValue: string | string[];
38
- allowCreate: boolean;
39
- excludeUserIds: string[];
40
- placeholder: string;
41
32
  multiple: boolean;
33
+ placeholder: string;
42
34
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
43
35
  export default _default;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * 常量定义
3
+ * @module constants
4
+ */
5
+ /** 为输入框和更多标签预留的空间 */
6
+ export declare const RESERVED_SPACE_FOR_INPUT = 100;
7
+ /** 搜索防抖延迟时间(毫秒) */
8
+ export declare const SEARCH_DEBOUNCE_DELAY = 300;
9
+ /** 默认精确搜索字段 */
10
+ export declare const DEFAULT_EXACT_SEARCH_KEY = "bk_username";
11
+ /** 用户类型 */
12
+ export declare const USER_TYPE: {
13
+ /** 普通用户 */
14
+ readonly USER: "user";
15
+ /** 虚拟账号 */
16
+ readonly VIRTUAL: "virtual";
17
+ /** 自定义用户 */
18
+ readonly CUSTOM: "custom";
19
+ /** 用户群组 */
20
+ readonly USER_GROUP: "userGroup";
21
+ };
22
+ /** API 请求超时时间(毫秒) */
23
+ export declare const API_TIMEOUT: number;
24
+ /** 默认分页大小 */
25
+ export declare const DEFAULT_PAGE_SIZE = 100;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 当前用户处理 Hook
3
+ * @module hooks/useCurrentUser
4
+ */
5
+ import { ref } from 'vue';
6
+ import type { FormattedUser } from '../types';
7
+ export interface UseCurrentUserOptions {
8
+ /** API 基础 URL */
9
+ apiBaseUrl: string;
10
+ /** 当前用户 ID */
11
+ currentUserId: string;
12
+ /** 是否启用多租户模式 */
13
+ enableMultiTenantMode?: boolean;
14
+ /** 精确搜索字段 */
15
+ exactSearchKey?: string;
16
+ /** 租户 ID */
17
+ tenantId: string;
18
+ }
19
+ export interface UseCurrentUserReturn {
20
+ /** 加载状态 */
21
+ loading: ReturnType<typeof ref<boolean>>;
22
+ /** 获取当前用户信息 */
23
+ fetchCurrentUser: () => Promise<FormattedUser | null>;
24
+ }
25
+ /**
26
+ * 当前用户处理 Hook
27
+ * @param options - 配置选项
28
+ * @returns 当前用户相关方法
29
+ */
30
+ export declare const useCurrentUser: (options: UseCurrentUserOptions) => UseCurrentUserReturn;
@@ -0,0 +1,48 @@
1
+ import { type Ref } from 'vue';
2
+ export interface UseFocusStateOptions {
3
+ /**
4
+ * 当前激活的标签索引
5
+ */
6
+ activeTagIndex: Ref<number>;
7
+ /**
8
+ * 容器引用
9
+ */
10
+ containerRef: Ref<HTMLDivElement | null>;
11
+ /**
12
+ * 最后一个输入框引用
13
+ */
14
+ lastInputRef: Ref<HTMLInputElement | null>;
15
+ /**
16
+ * 用户群组长度
17
+ */
18
+ userGroupLength: number;
19
+ /**
20
+ * 失焦事件回调
21
+ */
22
+ onBlur: () => void;
23
+ /**
24
+ * 清除搜索回调
25
+ */
26
+ onClearSearch: () => void;
27
+ /**
28
+ * 聚焦事件回调
29
+ */
30
+ onFocus: () => void;
31
+ /**
32
+ * 可见用户计算回调
33
+ */
34
+ onScheduleVisibleUsersCalculation: () => void;
35
+ }
36
+ /**
37
+ * 聚焦状态管理 hook
38
+ */
39
+ export declare function useFocusState(options: UseFocusStateOptions): {
40
+ isFocused: Ref<boolean, boolean>;
41
+ showDropdown: Ref<boolean, boolean>;
42
+ handleFocus: () => void;
43
+ handleClickOutside: (event: MouseEvent) => void;
44
+ handleContainerClick: () => void;
45
+ handleInputFocus: () => void;
46
+ setShowDropdown: (value: boolean) => void;
47
+ setIsFocused: (value: boolean) => void;
48
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * 输入处理公共逻辑 Hook
3
+ * @module hooks/useInputHandler
4
+ */
5
+ import { type Ref } from 'vue';
6
+ import type { FormattedUser } from '../types';
7
+ export interface UseInputHandlerOptions {
8
+ /** 是否允许创建自定义用户 */
9
+ allowCreate?: boolean;
10
+ /** API 基础 URL */
11
+ apiBaseUrl: string;
12
+ /** 是否启用多租户模式 */
13
+ enableMultiTenantMode?: boolean;
14
+ /** 是否允许自由粘贴 */
15
+ freePaste?: boolean;
16
+ /** 最大可选数量(0 表示不限制) */
17
+ maxCount?: number;
18
+ /** 搜索关键词 */
19
+ searchQuery: Ref<string>;
20
+ /** 已选用户列表(用于去重) */
21
+ selectedUsers: Ref<FormattedUser[]>;
22
+ /** 租户 ID */
23
+ tenantId: string;
24
+ /** 添加用户回调 */
25
+ onAddUser: (user: FormattedUser) => void;
26
+ /** 批量添加用户回调(用于粘贴) */
27
+ onBatchAddUsers?: (users: FormattedUser[]) => void;
28
+ }
29
+ export interface UseInputHandlerReturn {
30
+ /** 粘贴处理中状态 */
31
+ isPasting: Ref<boolean>;
32
+ /** 处理 Enter 键创建自定义用户 */
33
+ handleEnterCreate: (event: KeyboardEvent) => void;
34
+ /** 处理粘贴事件 */
35
+ handlePaste: (event: ClipboardEvent) => Promise<void>;
36
+ /** 解析粘贴文本为用户列表 */
37
+ parsePastedText: (text: string) => string[];
38
+ }
39
+ /**
40
+ * 输入处理公共逻辑 Hook
41
+ * @param options - 配置选项
42
+ * @returns 输入处理相关方法
43
+ */
44
+ export declare const useInputHandler: (options: UseInputHandlerOptions) => UseInputHandlerReturn;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ResizeObserver Hook
3
+ * @module hooks/useResizeObserver
4
+ */
5
+ import { type Ref } from 'vue';
6
+ export interface UseResizeObserverOptions {
7
+ /** 是否立即执行回调 */
8
+ immediate?: boolean;
9
+ }
10
+ /**
11
+ * 监听元素大小变化的 Hook
12
+ * @param target - 目标元素引用
13
+ * @param callback - 大小变化时的回调函数
14
+ * @param options - 配置选项
15
+ * @returns 停止观察的函数
16
+ */
17
+ export declare const useResizeObserver: (target: Ref<HTMLElement | null | undefined>, callback: (entry: ResizeObserverEntry) => void, options?: UseResizeObserverOptions) => (() => void);
@@ -0,0 +1,78 @@
1
+ import type { FormattedUser, UserGroupConfig } from '../types';
2
+ export interface UseSelectedUsersOptions {
3
+ /**
4
+ * 是否允许创建
5
+ */
6
+ allowCreate: boolean;
7
+ /**
8
+ * 接口基础URL
9
+ */
10
+ apiBaseUrl: string;
11
+ /**
12
+ * 是否启用多租户模式
13
+ */
14
+ enableMultiTenantMode: boolean;
15
+ /**
16
+ * 模型值
17
+ */
18
+ modelValue: string | string[];
19
+ /**
20
+ * 是否多选
21
+ */
22
+ multiple: boolean;
23
+ /**
24
+ * 租户ID
25
+ */
26
+ tenantId: string;
27
+ /**
28
+ * 用户群组
29
+ */
30
+ userGroup: UserGroupConfig[];
31
+ /**
32
+ * 变更回调
33
+ */
34
+ onChange: (user: FormattedUser | FormattedUser[] | null) => void;
35
+ /**
36
+ * 更新模型值回调
37
+ */
38
+ onUpdateModelValue: (value: string | string[]) => void;
39
+ }
40
+ /**
41
+ * 选中用户状态管理 hook
42
+ */
43
+ export declare function useSelectedUsers(options: UseSelectedUsersOptions): {
44
+ selectedUsers: import("vue").Ref<{
45
+ bk_username?: string | undefined;
46
+ data_source_type?: string | undefined;
47
+ display_name?: string | undefined;
48
+ full_name?: string | undefined;
49
+ hidden?: boolean | undefined;
50
+ id: string;
51
+ login_name?: string | undefined;
52
+ name: string;
53
+ owner_tenant_id?: string | undefined;
54
+ tenantId: string;
55
+ type?: import("../types").UserType | undefined;
56
+ username?: string | undefined;
57
+ }[], FormattedUser[] | {
58
+ bk_username?: string | undefined;
59
+ data_source_type?: string | undefined;
60
+ display_name?: string | undefined;
61
+ full_name?: string | undefined;
62
+ hidden?: boolean | undefined;
63
+ id: string;
64
+ login_name?: string | undefined;
65
+ name: string;
66
+ owner_tenant_id?: string | undefined;
67
+ tenantId: string;
68
+ type?: import("../types").UserType | undefined;
69
+ username?: string | undefined;
70
+ }[]>;
71
+ selectedUserIds: import("vue").ComputedRef<string[]>;
72
+ activeTagIndex: import("vue").Ref<number, number>;
73
+ modelValueIds: import("vue").ComputedRef<string[]>;
74
+ initSelectedUsers: () => Promise<void>;
75
+ updateSelectedUsers: (users: FormattedUser[]) => void;
76
+ addUser: (user: FormattedUser) => void;
77
+ removeUser: (user: FormattedUser) => void;
78
+ };
@@ -0,0 +1,41 @@
1
+ import { type Ref } from 'vue';
2
+ import Sortable from 'sortablejs/Sortable.js';
3
+ import type { FormattedUser } from '../types';
4
+ export interface UseSortableOptions {
5
+ /**
6
+ * 是否可拖拽
7
+ */
8
+ draggable: boolean;
9
+ /**
10
+ * 是否多选
11
+ */
12
+ multiple: boolean;
13
+ /**
14
+ * 已选用户列表
15
+ */
16
+ selectedUsers: Ref<FormattedUser[]>;
17
+ /**
18
+ * 排序容器引用
19
+ */
20
+ sortableContainerRef: Ref<HTMLDivElement | null>;
21
+ /**
22
+ * 拖拽结束回调
23
+ */
24
+ onDragEnd: (event: Sortable.SortableEvent) => void;
25
+ /**
26
+ * 拖拽开始回调
27
+ */
28
+ onDragStart: (event: Sortable.SortableEvent) => void;
29
+ /**
30
+ * 更新选中用户回调
31
+ */
32
+ onUpdateSelectedUsers: (users: FormattedUser[]) => void;
33
+ }
34
+ /**
35
+ * 拖拽排序 hook
36
+ */
37
+ export declare function useSortable(options: UseSortableOptions): {
38
+ sortableInstance: any;
39
+ initSortable: () => void;
40
+ destroySortable: () => void;
41
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 租户数据处理 Hook
3
+ * @module hooks/useTenantData
4
+ */
5
+ import { type Ref } from 'vue';
6
+ /**
7
+ * 使用租户数据的Hook
8
+ * @param apiBaseUrl - API基础URL
9
+ * @param tenantId - 租户ID
10
+ * @param enableMultiTenantMode - 是否启用多租户模式
11
+ * @returns 租户数据和加载状态
12
+ */
13
+ export declare const useTenantData: (apiBaseUrl: string, tenantId: string, enableMultiTenantMode?: boolean) => {
14
+ tenants: Ref<Record<string, string>, Record<string, string>>;
15
+ loading: Ref<boolean, boolean>;
16
+ fetchTenants: () => Promise<void>;
17
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 用户搜索 Hook
3
+ * @module hooks/useUserSearch
4
+ */
5
+ import { type Ref } from 'vue';
6
+ import type { FormattedUser } from '../types';
7
+ export interface UseUserSearchOptions {
8
+ /** API 基础 URL */
9
+ apiBaseUrl: string;
10
+ /** 防抖延迟时间(毫秒) */
11
+ debounceDelay?: number;
12
+ /** 是否启用多租户模式 */
13
+ enableMultiTenantMode?: boolean;
14
+ /** 租户 ID */
15
+ tenantId: string;
16
+ }
17
+ export interface UseUserSearchReturn {
18
+ /** 加载状态 */
19
+ loading: Ref<boolean>;
20
+ /** 搜索关键词 */
21
+ searchQuery: Ref<string>;
22
+ /** 搜索结果 */
23
+ searchResults: Ref<FormattedUser[]>;
24
+ /** 清空搜索 */
25
+ clearSearch: () => void;
26
+ /** 处理输入变化(带防抖) */
27
+ handleSearchInput: (value: string) => void;
28
+ /** 执行搜索 */
29
+ performSearch: (keyword: string) => Promise<void>;
30
+ }
31
+ /**
32
+ * 使用用户搜索的Hook
33
+ * @param apiBaseUrl - API基础URL
34
+ * @param tenantId - 租户ID
35
+ * @param enableMultiTenantMode - 是否启用多租户模式
36
+ * @returns 用户搜索相关状态和方法
37
+ */
38
+ export declare const useUserSearch: (apiBaseUrl: string, tenantId: string, enableMultiTenantMode?: boolean) => UseUserSearchReturn;