@lark-apaas/client-toolkit 0.1.0-alpha.1 → 0.2.0-alpha.user.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/lib/components/User/UserDisplay.d.ts +1 -1
- package/lib/components/User/UserDisplay.js +101 -25
- package/lib/components/User/UserProfile/UserProfile.css +1 -1
- package/lib/components/User/UserProfile/UserProfileContainer.d.ts +1 -1
- package/lib/components/User/UserProfile/UserProfileSkeleton.d.ts +0 -1
- package/lib/components/User/UserProfile/UserProfileSkeleton.js +21 -29
- package/lib/components/User/UserProfile/UserProfileUI.d.ts +1 -2
- package/lib/components/User/UserProfile/UserProfileUI.js +106 -92
- package/lib/components/User/UserSelect.d.ts +1 -1
- package/lib/components/User/UserSelect.js +17 -143
- package/lib/components/User/UserSelectUI/ActionButtons.d.ts +11 -0
- package/lib/components/User/UserSelectUI/ActionButtons.js +44 -0
- package/lib/components/User/UserSelectUI/Dropdown.d.ts +12 -0
- package/lib/components/User/UserSelectUI/Dropdown.js +66 -0
- package/lib/components/User/UserSelectUI/MultipleSelectionTags.d.ts +14 -0
- package/lib/components/User/UserSelectUI/MultipleSelectionTags.js +48 -0
- package/lib/components/User/UserSelectUI/SingleSelectionPreview.d.ts +9 -0
- package/lib/components/User/UserSelectUI/SingleSelectionPreview.js +37 -0
- package/lib/components/User/UserSelectUI/Spinner.d.ts +2 -0
- package/lib/components/User/UserSelectUI/Spinner.js +13 -0
- package/lib/components/User/UserSelectUI/UserSelectUI.d.ts +5 -0
- package/lib/components/User/UserSelectUI/UserSelectUI.js +230 -0
- package/lib/components/User/UserSelectUI/index.d.ts +2 -0
- package/lib/components/User/UserSelectUI/index.js +2 -0
- package/lib/components/User/UserSelectUI/types.d.ts +14 -0
- package/lib/components/User/UserSelectUI/types.js +0 -0
- package/lib/components/User/UserWithAvatar.js +38 -21
- package/lib/components/index.d.ts +2 -5
- package/lib/components/index.js +2 -3
- package/lib/components/ui/avatar.d.ts +6 -0
- package/lib/components/ui/avatar.js +27 -0
- package/lib/components/ui/badge.d.ts +9 -0
- package/lib/components/ui/badge.js +29 -0
- package/lib/components/ui/button.d.ts +10 -0
- package/lib/components/ui/button.js +42 -0
- package/lib/components/ui/input.d.ts +3 -0
- package/lib/components/ui/input.js +12 -0
- package/lib/components/ui/overflow-tooltip-text.d.ts +8 -0
- package/lib/components/ui/overflow-tooltip-text.js +66 -0
- package/lib/components/ui/popover.d.ts +7 -0
- package/lib/components/ui/popover.js +35 -0
- package/lib/components/ui/skeleton.d.ts +7 -0
- package/lib/components/ui/skeleton.js +10 -0
- package/lib/components/ui/tooltip.d.ts +7 -0
- package/lib/components/ui/tooltip.js +24 -0
- package/lib/override.css +0 -16
- package/lib/types/index.d.ts +0 -29
- package/package.json +9 -3
- package/lib/apis/components/SidebarNav.d.ts +0 -1
- package/lib/apis/components/SidebarNav.js +0 -2
- package/lib/components/SidebarNav/DrawerNav.d.ts +0 -3
- package/lib/components/SidebarNav/DrawerNav.js +0 -64
- package/lib/components/SidebarNav/DropdownNav.d.ts +0 -3
- package/lib/components/SidebarNav/DropdownNav.js +0 -40
- package/lib/components/SidebarNav/Sidebar.d.ts +0 -3
- package/lib/components/SidebarNav/Sidebar.js +0 -33
- package/lib/components/SidebarNav/index.d.ts +0 -5
- package/lib/components/SidebarNav/index.js +0 -61
- package/lib/components/User/UserSelect.css +0 -11
- package/lib/components/common/LogoInfo.d.ts +0 -5
- package/lib/components/common/LogoInfo.js +0 -30
- package/lib/components/common/NavItem.d.ts +0 -20
- package/lib/components/common/NavItem.js +0 -112
- package/lib/components/common/NavMenu.d.ts +0 -9
- package/lib/components/common/NavMenu.js +0 -50
- package/lib/components/common/UserAvatarLayout.d.ts +0 -4
- package/lib/components/common/UserAvatarLayout.js +0 -41
- package/lib/components/common/UserAvatarMenu.d.ts +0 -4
- package/lib/components/common/UserAvatarMenu.js +0 -58
- package/lib/components/common/index.d.ts +0 -9
- package/lib/components/common/index.js +0 -10
|
@@ -1,38 +1,114 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { UserWithAvatar } from "./UserWithAvatar.js";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { getDataloom } from "../../integrations/dataloom.js";
|
|
5
4
|
import { clsxWithTw } from "../../utils/utils.js";
|
|
6
5
|
import { UserProfile } from "./UserProfile/index.js";
|
|
6
|
+
import { UserWithAvatar } from "./UserWithAvatar.js";
|
|
7
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
|
|
7
8
|
const UserDisplay = ({ users, size, className, style })=>{
|
|
8
|
-
const
|
|
9
|
+
const normalizedUsers = useMemo(()=>Array.isArray(users) ? users : [
|
|
9
10
|
users
|
|
10
11
|
].filter(Boolean), [
|
|
11
12
|
users
|
|
12
13
|
]);
|
|
13
|
-
|
|
14
|
+
const [resolvedUsers, setResolvedUsers] = useState(normalizedUsers);
|
|
15
|
+
const [loadingProfiles, setLoadingProfiles] = useState(false);
|
|
16
|
+
useEffect(()=>{
|
|
17
|
+
let isCancelled = false;
|
|
18
|
+
if (!normalizedUsers.length) {
|
|
19
|
+
setResolvedUsers([]);
|
|
20
|
+
setLoadingProfiles(false);
|
|
21
|
+
return ()=>{
|
|
22
|
+
isCancelled = true;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const usersNeedingDetails = normalizedUsers.filter((user)=>!user?.name?.trim());
|
|
26
|
+
if (!usersNeedingDetails.length) {
|
|
27
|
+
setResolvedUsers(normalizedUsers);
|
|
28
|
+
setLoadingProfiles(false);
|
|
29
|
+
return ()=>{
|
|
30
|
+
isCancelled = true;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const fetchProfiles = async ()=>{
|
|
34
|
+
try {
|
|
35
|
+
setLoadingProfiles(true);
|
|
36
|
+
const dataloom = await getDataloom();
|
|
37
|
+
if (!dataloom) throw new Error('dataloom client is unavailable');
|
|
38
|
+
const ids = usersNeedingDetails.map((user)=>Number(user.user_id)).filter((id)=>Number.isFinite(id));
|
|
39
|
+
if (!ids.length) {
|
|
40
|
+
setResolvedUsers(normalizedUsers);
|
|
41
|
+
setLoadingProfiles(false);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const response = await dataloom.service.user.getByIds(ids);
|
|
45
|
+
const fetchedList = Array.isArray(response?.data) ? response?.data : Array.isArray(response?.data?.user_list) ? response?.data?.user_list : [];
|
|
46
|
+
const fetchedMap = new Map();
|
|
47
|
+
fetchedList.forEach((profile)=>{
|
|
48
|
+
const id = String(profile?.user_id ?? '');
|
|
49
|
+
if (!id) return;
|
|
50
|
+
fetchedMap.set(id, {
|
|
51
|
+
user_id: id,
|
|
52
|
+
name: profile?.name ?? '',
|
|
53
|
+
avatar: profile?.avatar ?? '',
|
|
54
|
+
email: profile?.email,
|
|
55
|
+
status: profile?.status,
|
|
56
|
+
...profile
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
const mergedUsers = normalizedUsers.map((user)=>{
|
|
60
|
+
const id = String(user.user_id);
|
|
61
|
+
const fetched = fetchedMap.get(id);
|
|
62
|
+
if (!fetched) return user;
|
|
63
|
+
return {
|
|
64
|
+
...fetched,
|
|
65
|
+
...user,
|
|
66
|
+
name: user?.name?.trim() ? user.name : fetched.name,
|
|
67
|
+
avatar: user.avatar || fetched.avatar,
|
|
68
|
+
email: user.email || fetched.email,
|
|
69
|
+
status: user.status ?? fetched.status
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
if (!isCancelled) setResolvedUsers(mergedUsers);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Failed to resolve user profiles:', error);
|
|
75
|
+
if (!isCancelled) setResolvedUsers(normalizedUsers);
|
|
76
|
+
} finally{
|
|
77
|
+
if (!isCancelled) setLoadingProfiles(false);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
fetchProfiles();
|
|
81
|
+
return ()=>{
|
|
82
|
+
isCancelled = true;
|
|
83
|
+
};
|
|
84
|
+
}, [
|
|
85
|
+
normalizedUsers.length
|
|
86
|
+
]);
|
|
87
|
+
if (!resolvedUsers.length || loadingProfiles) return null;
|
|
14
88
|
return /*#__PURE__*/ jsx("div", {
|
|
15
|
-
className: clsxWithTw('flex gap-1
|
|
89
|
+
className: clsxWithTw('flex flex-wrap gap-1', className),
|
|
16
90
|
style: style,
|
|
17
|
-
children:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
91
|
+
children: resolvedUsers.map((user)=>/*#__PURE__*/ jsxs(Popover, {
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ jsx(PopoverTrigger, {
|
|
94
|
+
asChild: true,
|
|
95
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
96
|
+
children: /*#__PURE__*/ jsx(UserWithAvatar, {
|
|
97
|
+
data: user,
|
|
98
|
+
size: size,
|
|
99
|
+
className: "cursor-pointer hover:bg-[rgba(31,35,41,0.15)] active:bg-[rgba(31,35,41,0.2)]"
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ jsx(PopoverContent, {
|
|
104
|
+
align: "start",
|
|
105
|
+
sideOffset: 8,
|
|
106
|
+
className: "w-[320px] border-border/50 bg-card p-0 border-0 shadow-[0px_8px_24px_8px_rgba(31,35,41,0.04),0px_6px_12px_rgba(31,35,41,0.04),0px_4px_8px_-8px_rgba(31,35,41,0.06)]",
|
|
107
|
+
children: /*#__PURE__*/ jsx(UserProfile, {
|
|
108
|
+
user_id: user.user_id
|
|
109
|
+
})
|
|
34
110
|
})
|
|
35
|
-
|
|
111
|
+
]
|
|
36
112
|
}, user.user_id))
|
|
37
113
|
});
|
|
38
114
|
};
|
|
@@ -1,36 +1,28 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import "react";
|
|
3
|
-
import { Skeleton } from "
|
|
4
|
-
import "./UserProfile.css";
|
|
3
|
+
import { Skeleton } from "../../ui/skeleton.js";
|
|
5
4
|
function UserProfileSkeleton() {
|
|
6
|
-
return /*#__PURE__*/
|
|
7
|
-
className: "p-5 bg-
|
|
8
|
-
children:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
title: false,
|
|
24
|
-
paragraph: {
|
|
25
|
-
rows: 2,
|
|
26
|
-
width: [
|
|
27
|
-
'120px',
|
|
28
|
-
'180px'
|
|
5
|
+
return /*#__PURE__*/ jsx("div", {
|
|
6
|
+
className: "p-5 bg-background",
|
|
7
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
8
|
+
className: "pt-0",
|
|
9
|
+
children: [
|
|
10
|
+
/*#__PURE__*/ jsx(Skeleton, {
|
|
11
|
+
className: "h-[90px] w-[90px] rounded-full mt-[68px]"
|
|
12
|
+
}),
|
|
13
|
+
/*#__PURE__*/ jsxs("div", {
|
|
14
|
+
className: "mt-[22px] flex flex-col gap-4",
|
|
15
|
+
children: [
|
|
16
|
+
/*#__PURE__*/ jsx(Skeleton, {
|
|
17
|
+
className: "h-4 w-[120px] rounded-full"
|
|
18
|
+
}),
|
|
19
|
+
/*#__PURE__*/ jsx(Skeleton, {
|
|
20
|
+
className: "h-4 w-[180px] rounded-full"
|
|
21
|
+
})
|
|
29
22
|
]
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
]
|
|
23
|
+
})
|
|
24
|
+
]
|
|
25
|
+
})
|
|
34
26
|
});
|
|
35
27
|
}
|
|
36
28
|
export { UserProfileSkeleton };
|
|
@@ -1,107 +1,121 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
3
|
-
import { Avatar, Button, Card, Tag, Typography } from "antd";
|
|
4
|
-
import "./UserProfile.css";
|
|
5
|
-
import { getChatAppLink } from "./utils.js";
|
|
2
|
+
import { useState } from "react";
|
|
6
3
|
import { clsxWithTw } from "../../../utils/utils.js";
|
|
4
|
+
import { getChatAppLink } from "./utils.js";
|
|
5
|
+
import { OverflowTooltipText } from "../../ui/overflow-tooltip-text.js";
|
|
7
6
|
function UserProfileUI({ user }) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/default-cover.png",
|
|
13
|
-
className: "h-[136px] w-full object-cover"
|
|
14
|
-
}),
|
|
15
|
-
bodyStyle: {
|
|
16
|
-
padding: '16px'
|
|
17
|
-
},
|
|
7
|
+
const [avatarError, setAvatarError] = useState(false);
|
|
8
|
+
const canShowAvatar = Boolean(user.avatar) && !avatarError;
|
|
9
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
10
|
+
className: "overflow-hidden rounded-[8px] border-0 bg-card text-card-foreground h-full",
|
|
18
11
|
children: [
|
|
19
|
-
/*#__PURE__*/
|
|
20
|
-
className: "
|
|
21
|
-
children:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
children: [
|
|
30
|
-
/*#__PURE__*/ jsx(Typography.Title, {
|
|
31
|
-
level: 2,
|
|
32
|
-
ellipsis: {
|
|
33
|
-
rows: 1,
|
|
34
|
-
tooltip: user.name
|
|
35
|
-
},
|
|
36
|
-
className: "user-profile-name",
|
|
37
|
-
children: user.name
|
|
38
|
-
}),
|
|
39
|
-
'inactive' === user.status && /*#__PURE__*/ jsx(Tag, {
|
|
40
|
-
color: "#f50",
|
|
41
|
-
style: {
|
|
42
|
-
marginRight: 0
|
|
43
|
-
},
|
|
44
|
-
children: "暂停使用"
|
|
45
|
-
})
|
|
46
|
-
]
|
|
47
|
-
}),
|
|
48
|
-
user.feishu_open_id ? /*#__PURE__*/ jsx("div", {
|
|
49
|
-
className: "w-ful mt-2",
|
|
50
|
-
children: /*#__PURE__*/ jsx(Button, {
|
|
51
|
-
type: "primary",
|
|
52
|
-
icon: /*#__PURE__*/ jsx("svg", {
|
|
53
|
-
width: "24",
|
|
54
|
-
height: "24",
|
|
55
|
-
viewBox: "0 0 24 24",
|
|
56
|
-
fill: "none",
|
|
57
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
58
|
-
className: "w-[18px] h-[18px]",
|
|
59
|
-
children: /*#__PURE__*/ jsx("path", {
|
|
60
|
-
d: "M4.44576 19.2236L3.39131 20.7324C2.86623 21.4838 3.41996 22.5 4.35448 22.5H11.7556C11.7556 22.5 11.7593 22.4996 11.7661 22.4995C11.8225 22.4984 12.094 22.4991 12.2975 22.4996L12.5 22.5C12.9236 22.5 13.3414 22.4749 13.7519 22.4261L13.7544 22.4258C18.962 21.8059 23 17.3745 23 12C23 10.567 22.5218 8.58544 22.5 8.52497C21.8654 6.76558 20.7624 5.22024 19.3364 4.03023C17.4995 2.45304 15.111 1.5 12.5 1.5C12.4676 1.5 12.4352 1.50015 12.4028 1.50044C12.3695 1.50015 12.3362 1.5 12.3028 1.5C6.33659 1.5 1.5 6.20101 1.5 12C1.5 12.197 1.50558 12.3928 1.5166 12.5871C1.65458 15.1526 2.74286 17.4735 4.44576 19.2236ZM17 10C17 10.5 16.6133 11 16 11H9.01953C8.39798 11 8 10.5 8 10C8 9.39844 8.5 9 9 9H16C16.5 9 17 9.39844 17 10ZM12.9883 13C13.6055 13 14 13.5 14 14C14 14.5 13.6055 15 13 15H9C8.5 15 8 14.6018 8 14C8 13.3982 8.5 13 9 13H12.9883Z",
|
|
61
|
-
fill: "#2B2F36"
|
|
62
|
-
})
|
|
63
|
-
}),
|
|
64
|
-
className: "gap-1 rounded-[10px] h-[42px] w-full bg-[#F5F6F7] text-[#2B2F36] hover:bg-[rgba(31,35,41,0.08)] active:bg-[rgba(31,35,41,0.12)] border-none",
|
|
65
|
-
href: getChatAppLink(user.feishu_open_id),
|
|
66
|
-
target: "_blank",
|
|
67
|
-
rel: "noopener noreferrer",
|
|
68
|
-
children: "消息"
|
|
69
|
-
})
|
|
70
|
-
}) : null
|
|
71
|
-
]
|
|
12
|
+
/*#__PURE__*/ jsx("div", {
|
|
13
|
+
className: "mt-[-1px] ms-[-1px] me-[-1px]",
|
|
14
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
15
|
+
className: "h-[136px] w-full",
|
|
16
|
+
children: /*#__PURE__*/ jsx("img", {
|
|
17
|
+
alt: "cover",
|
|
18
|
+
src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/default-cover.png",
|
|
19
|
+
className: "h-full w-full object-cover"
|
|
20
|
+
})
|
|
21
|
+
})
|
|
72
22
|
}),
|
|
73
23
|
/*#__PURE__*/ jsxs("div", {
|
|
74
|
-
className: "
|
|
24
|
+
className: "p-4",
|
|
75
25
|
children: [
|
|
76
|
-
/*#__PURE__*/
|
|
77
|
-
className: "flex
|
|
78
|
-
children:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
26
|
+
/*#__PURE__*/ jsx("div", {
|
|
27
|
+
className: "relative flex flex-col -mt-16 user-profile-button",
|
|
28
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
29
|
+
className: "-mx-1 flex flex-col items-start",
|
|
30
|
+
children: [
|
|
31
|
+
/*#__PURE__*/ jsx("div", {
|
|
32
|
+
className: "flex items-center",
|
|
33
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
34
|
+
className: "h-24 w-24 overflow-hidden rounded-full border-4 border-white bg-muted shadow-[0px_6px_18px_6px_rgba(31,35,41,0.03),0px_3px_6px_-6px_rgba(31,35,41,0.05),0px_4px_8px_rgba(31,35,41,0.03)]",
|
|
35
|
+
children: canShowAvatar ? /*#__PURE__*/ jsx("img", {
|
|
36
|
+
src: user.avatar,
|
|
37
|
+
alt: user.name,
|
|
38
|
+
className: "h-full w-full object-cover",
|
|
39
|
+
onError: ()=>setAvatarError(true)
|
|
40
|
+
}) : null
|
|
41
|
+
})
|
|
86
42
|
}),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
43
|
+
/*#__PURE__*/ jsxs("div", {
|
|
44
|
+
className: "flex w-full items-center gap-2 user-profile-name-container",
|
|
45
|
+
children: [
|
|
46
|
+
/*#__PURE__*/ jsx("h2", {
|
|
47
|
+
className: "min-w-0",
|
|
48
|
+
children: /*#__PURE__*/ jsx(OverflowTooltipText, {
|
|
49
|
+
text: user.name,
|
|
50
|
+
className: "block truncate text-[22px] font-semibold leading-[28px] text-card-foreground"
|
|
51
|
+
})
|
|
52
|
+
}),
|
|
53
|
+
'inactive' === user.status && /*#__PURE__*/ jsx("span", {
|
|
54
|
+
className: "shrink-0 inline-flex items-center rounded-sm bg-destructive px-2 py-0.5 text-xs font-medium text-white",
|
|
55
|
+
children: "暂停使用"
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
}),
|
|
59
|
+
user.feishu_open_id ? /*#__PURE__*/ jsx("div", {
|
|
60
|
+
className: "w-full mt-2",
|
|
61
|
+
children: /*#__PURE__*/ jsxs("a", {
|
|
62
|
+
className: "inline-flex h-[42px] w-full items-center justify-center gap-2 rounded-[10px] border border-transparent bg-muted text-sm font-medium text-foreground transition-colors focus-visible:outline-none hover:bg-foreground/10 active:bg-foreground/15",
|
|
63
|
+
href: getChatAppLink(user.feishu_open_id),
|
|
64
|
+
target: "_blank",
|
|
65
|
+
rel: "noopener noreferrer",
|
|
66
|
+
children: [
|
|
67
|
+
/*#__PURE__*/ jsx("svg", {
|
|
68
|
+
width: "18",
|
|
69
|
+
height: "18",
|
|
70
|
+
viewBox: "0 0 24 24",
|
|
71
|
+
fill: "none",
|
|
72
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
73
|
+
children: /*#__PURE__*/ jsx("path", {
|
|
74
|
+
d: "M4.44576 19.2236L3.39131 20.7324C2.86623 21.4838 3.41996 22.5 4.35448 22.5H11.7556C11.7556 22.5 11.7593 22.4996 11.7661 22.4995C11.8225 22.4984 12.094 22.4991 12.2975 22.4996L12.5 22.5C12.9236 22.5 13.3414 22.4749 13.7519 22.4261L13.7544 22.4258C18.962 21.8059 23 17.3745 23 12C23 10.567 22.5218 8.58544 22.5 8.52497C21.8654 6.76558 20.7624 5.22024 19.3364 4.03023C17.4995 2.45304 15.111 1.5 12.5 1.5C12.4676 1.5 12.4352 1.50015 12.4028 1.50044C12.3695 1.50015 12.3362 1.5 12.3028 1.5C6.33659 1.5 1.5 6.20101 1.5 12C1.5 12.197 1.50558 12.3928 1.5166 12.5871C1.65458 15.1526 2.74286 17.4735 4.44576 19.2236ZM17 10C17 10.5 16.6133 11 16 11H9.01953C8.39798 11 8 10.5 8 10C8 9.39844 8.5 9 9 9H16C16.5 9 17 9.39844 17 10ZM12.9883 13C13.6055 13 14 13.5 14 14C14 14.5 13.6055 15 13 15H9C8.5 15 8 14.6018 8 14C8 13.3982 8.5 13 9 13H12.9883Z",
|
|
75
|
+
fill: "currentColor"
|
|
76
|
+
})
|
|
77
|
+
}),
|
|
78
|
+
"消息"
|
|
79
|
+
]
|
|
80
|
+
})
|
|
81
|
+
}) : null
|
|
82
|
+
]
|
|
83
|
+
})
|
|
90
84
|
}),
|
|
91
85
|
/*#__PURE__*/ jsxs("div", {
|
|
92
|
-
className: "
|
|
86
|
+
className: "mt-2",
|
|
93
87
|
children: [
|
|
94
|
-
/*#__PURE__*/
|
|
95
|
-
className: "
|
|
96
|
-
children:
|
|
88
|
+
/*#__PURE__*/ jsxs("div", {
|
|
89
|
+
className: "flex items-start gap-4 py-2",
|
|
90
|
+
children: [
|
|
91
|
+
/*#__PURE__*/ jsx("span", {
|
|
92
|
+
className: "min-w-[74px] text-sm text-muted-foreground",
|
|
93
|
+
children: "部门"
|
|
94
|
+
}),
|
|
95
|
+
/*#__PURE__*/ jsx("span", {
|
|
96
|
+
className: clsxWithTw('flex-1 break-all text-sm text-foreground', {
|
|
97
|
+
'text-muted-foreground': !user.department
|
|
98
|
+
}),
|
|
99
|
+
children: user.department || '--'
|
|
100
|
+
})
|
|
101
|
+
]
|
|
97
102
|
}),
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
/*#__PURE__*/ jsxs("div", {
|
|
104
|
+
className: "flex items-start gap-4 py-2",
|
|
105
|
+
children: [
|
|
106
|
+
/*#__PURE__*/ jsx("span", {
|
|
107
|
+
className: "min-w-[74px] text-sm text-muted-foreground",
|
|
108
|
+
children: "邮箱"
|
|
109
|
+
}),
|
|
110
|
+
user.email ? /*#__PURE__*/ jsx("a", {
|
|
111
|
+
href: `mailto:${user.email}`,
|
|
112
|
+
className: "flex-1 break-all text-sm text-primary",
|
|
113
|
+
children: user.email
|
|
114
|
+
}) : /*#__PURE__*/ jsx("span", {
|
|
115
|
+
className: "flex-1 break-all text-sm text-muted-foreground",
|
|
116
|
+
children: "--"
|
|
117
|
+
})
|
|
118
|
+
]
|
|
105
119
|
})
|
|
106
120
|
]
|
|
107
121
|
})
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { IUserProfile } from '../../apis/udt-types';
|
|
3
|
-
import './UserSelect.css';
|
|
4
3
|
export interface UserSelectProps {
|
|
5
4
|
value?: IUserProfile | IUserProfile[];
|
|
6
5
|
onChange?: (value: IUserProfile | IUserProfile[]) => void;
|
|
7
6
|
defaultValue?: IUserProfile | IUserProfile[];
|
|
8
7
|
mode?: 'single' | 'multiple';
|
|
9
8
|
placeholder?: string;
|
|
9
|
+
fetchUsers?: (keyword: string) => Promise<IUserProfile[]>;
|
|
10
10
|
}
|
|
11
11
|
export declare const UserSelect: React.FC<UserSelectProps>;
|
|
@@ -1,61 +1,10 @@
|
|
|
1
|
-
import { jsx
|
|
2
|
-
import
|
|
3
|
-
import { Avatar, Select, Spin } from "antd";
|
|
4
|
-
import { LoaderCircle } from "lucide-react";
|
|
5
|
-
import { debounce } from "lodash";
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import react from "react";
|
|
6
3
|
import { getDataloom } from "../../integrations/dataloom.js";
|
|
7
|
-
import "./
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const unifiedValue = Array.isArray(value) ? value : [
|
|
12
|
-
value
|
|
13
|
-
];
|
|
14
|
-
return unifiedValue.map((user)=>({
|
|
15
|
-
value: user.user_id,
|
|
16
|
-
label: /*#__PURE__*/ jsx(UserWithAvatar, {
|
|
17
|
-
data: user,
|
|
18
|
-
mode: "plain",
|
|
19
|
-
className: "p-[1px] pr-0"
|
|
20
|
-
}),
|
|
21
|
-
avatar: user.avatar,
|
|
22
|
-
name: user.name,
|
|
23
|
-
rawValue: user
|
|
24
|
-
}));
|
|
25
|
-
};
|
|
26
|
-
const mapValueToSelectValue = (value)=>{
|
|
27
|
-
if (!value) return;
|
|
28
|
-
if (Array.isArray(value)) return value.map((user)=>({
|
|
29
|
-
value: user.user_id,
|
|
30
|
-
label: /*#__PURE__*/ jsx(UserWithAvatar, {
|
|
31
|
-
data: user,
|
|
32
|
-
mode: "plain",
|
|
33
|
-
className: "p-[1px] pr-0"
|
|
34
|
-
}),
|
|
35
|
-
avatar: user.avatar,
|
|
36
|
-
name: user.name,
|
|
37
|
-
rawValue: user
|
|
38
|
-
}));
|
|
39
|
-
return {
|
|
40
|
-
value: value.user_id,
|
|
41
|
-
label: /*#__PURE__*/ jsx(UserWithAvatar, {
|
|
42
|
-
data: value,
|
|
43
|
-
mode: "plain",
|
|
44
|
-
className: "p-[1px] pr-0"
|
|
45
|
-
}),
|
|
46
|
-
avatar: value.avatar,
|
|
47
|
-
name: value.name,
|
|
48
|
-
rawValue: value
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
const UserSelect = ({ mode = 'single', defaultValue, value, onChange, placeholder })=>{
|
|
52
|
-
const defaultOptions = useMemo(()=>mapValueToOptions(defaultValue), [
|
|
53
|
-
defaultValue
|
|
54
|
-
]);
|
|
55
|
-
const [options, setOptions] = useState(defaultOptions);
|
|
56
|
-
const [fetching, setFetching] = useState(false);
|
|
57
|
-
const fetchRef = useRef(0);
|
|
58
|
-
const fetchUsers = async (search)=>{
|
|
4
|
+
import { UserSelectUI } from "./UserSelectUI/index.js";
|
|
5
|
+
const UserSelect = ({ mode = 'single', defaultValue, value, onChange, placeholder, fetchUsers })=>{
|
|
6
|
+
const fetchUsersImpl = react.useCallback(async (search)=>{
|
|
7
|
+
if (fetchUsers) return fetchUsers(search);
|
|
59
8
|
try {
|
|
60
9
|
const dataloom = await getDataloom();
|
|
61
10
|
const { data } = await dataloom.service.user.search({
|
|
@@ -74,98 +23,23 @@ const UserSelect = ({ mode = 'single', defaultValue, value, onChange, placeholde
|
|
|
74
23
|
console.error('Failed to fetch users:', error);
|
|
75
24
|
return [];
|
|
76
25
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (!value) return;
|
|
81
|
-
fetchRef.current += 1;
|
|
82
|
-
const fetchId = fetchRef.current;
|
|
83
|
-
setOptions([]);
|
|
84
|
-
setFetching(true);
|
|
85
|
-
fetchUsers(value).then((newOptions)=>{
|
|
86
|
-
if (fetchId !== fetchRef.current) return;
|
|
87
|
-
setOptions(newOptions.map((v)=>({
|
|
88
|
-
value: v.user_id,
|
|
89
|
-
label: /*#__PURE__*/ jsx(UserWithAvatar, {
|
|
90
|
-
data: v,
|
|
91
|
-
mode: "plain",
|
|
92
|
-
className: "p-[1px] pr-0"
|
|
93
|
-
}),
|
|
94
|
-
avatar: v.avatar,
|
|
95
|
-
name: v.name,
|
|
96
|
-
rawValue: v
|
|
97
|
-
})));
|
|
98
|
-
setFetching(false);
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
return debounce(loadOptions, 500);
|
|
102
|
-
}, []);
|
|
103
|
-
const optionRender = (option)=>{
|
|
104
|
-
const user = option.data;
|
|
105
|
-
return /*#__PURE__*/ jsxs("div", {
|
|
106
|
-
className: "flex items-center gap-2",
|
|
107
|
-
children: [
|
|
108
|
-
/*#__PURE__*/ jsx(Avatar, {
|
|
109
|
-
src: user.avatar,
|
|
110
|
-
size: "small",
|
|
111
|
-
className: "shrink-0 !border-0"
|
|
112
|
-
}),
|
|
113
|
-
/*#__PURE__*/ jsx("span", {
|
|
114
|
-
className: "text-sm",
|
|
115
|
-
children: user.name
|
|
116
|
-
})
|
|
117
|
-
]
|
|
118
|
-
});
|
|
119
|
-
};
|
|
26
|
+
}, [
|
|
27
|
+
fetchUsers
|
|
28
|
+
]);
|
|
120
29
|
const selectMode = 'multiple' === mode ? 'multiple' : void 0;
|
|
121
30
|
return /*#__PURE__*/ jsx("div", {
|
|
122
31
|
className: "user-select-container",
|
|
123
|
-
children: /*#__PURE__*/ jsx(
|
|
124
|
-
|
|
125
|
-
showSearch: true,
|
|
126
|
-
className: "w-full",
|
|
127
|
-
maxTagCount: "responsive",
|
|
128
|
-
defaultValue: defaultOptions,
|
|
32
|
+
children: /*#__PURE__*/ jsx(UserSelectUI, {
|
|
33
|
+
defaultValue: defaultValue,
|
|
129
34
|
mode: selectMode,
|
|
130
|
-
|
|
131
|
-
onSearch: debounceFetcher,
|
|
35
|
+
onSearch: fetchUsersImpl,
|
|
132
36
|
allowClear: true,
|
|
133
37
|
placeholder: placeholder,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
className: "!text-[16px] animate-spin"
|
|
140
|
-
})
|
|
141
|
-
})
|
|
142
|
-
}) : /*#__PURE__*/ jsx("span", {
|
|
143
|
-
className: "py-[1px] px-1 text-[#8F959E]",
|
|
144
|
-
children: "无结果,建议更换搜索词"
|
|
145
|
-
}),
|
|
146
|
-
optionRender: optionRender,
|
|
147
|
-
options: options,
|
|
148
|
-
dropdownStyle: {
|
|
149
|
-
boxShadow: '0px 8px 24px 8px rgba(31, 35, 41, 0.04), 0px 6px 12px 0px rgba(31, 35, 41, 0.04), 0px 4px 8px -8px rgba(31, 35, 41, 0.06)',
|
|
150
|
-
padding: '3px'
|
|
151
|
-
},
|
|
152
|
-
value: mapValueToSelectValue(value),
|
|
153
|
-
maxTagPlaceholder: (omittedValues)=>/*#__PURE__*/ jsxs("span", {
|
|
154
|
-
className: "pl-2",
|
|
155
|
-
children: [
|
|
156
|
-
"+ ",
|
|
157
|
-
omittedValues.length
|
|
158
|
-
]
|
|
159
|
-
}),
|
|
160
|
-
onChange: onChange ? (_, options)=>{
|
|
161
|
-
if (Array.isArray(options)) {
|
|
162
|
-
const selectedUsers = options.map((opt)=>opt.rawValue);
|
|
163
|
-
onChange(selectedUsers);
|
|
164
|
-
} else {
|
|
165
|
-
const selectedUser = options?.rawValue;
|
|
166
|
-
if (selectedUser) onChange(selectedUser);
|
|
167
|
-
}
|
|
168
|
-
} : void 0
|
|
38
|
+
value: value,
|
|
39
|
+
onChange: (value)=>{
|
|
40
|
+
if ('multiple' === selectMode) onChange?.(value ?? []);
|
|
41
|
+
else onChange?.(value);
|
|
42
|
+
}
|
|
169
43
|
})
|
|
170
44
|
});
|
|
171
45
|
};
|