@droppii-org/chat-sdk 0.1.97 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/compose/ComposeNewMessageModal.d.ts.map +1 -1
- package/dist/components/compose/ComposeNewMessageModal.js +1 -1
- package/dist/components/conversation/ThreadCard.js +1 -1
- package/dist/components/group/AddMemberModal.d.ts +9 -0
- package/dist/components/group/AddMemberModal.d.ts.map +1 -0
- package/dist/components/group/AddMemberModal.js +70 -0
- package/dist/components/group/AdminPermissionModal.d.ts +9 -0
- package/dist/components/group/AdminPermissionModal.d.ts.map +1 -0
- package/dist/components/group/AdminPermissionModal.js +63 -0
- package/dist/components/group/CreateGroupForm.d.ts +1 -2
- package/dist/components/group/CreateGroupForm.d.ts.map +1 -1
- package/dist/components/group/CreateGroupForm.js +4 -4
- package/dist/components/group/GroupMemberPicker.d.ts.map +1 -1
- package/dist/components/group/GroupMemberPicker.js +16 -8
- package/dist/components/group/MemberPermissionPanel.d.ts +8 -0
- package/dist/components/group/MemberPermissionPanel.d.ts.map +1 -0
- package/dist/components/group/MemberPermissionPanel.js +53 -0
- package/dist/components/media-resources/FileResourceList.js +1 -1
- package/dist/components/media-resources/LinkResourceItem.js +1 -1
- package/dist/components/message/GroupMembersDrawer.d.ts.map +1 -1
- package/dist/components/message/GroupMembersDrawer.js +210 -28
- package/dist/components/message/MessageHeader.d.ts +2 -1
- package/dist/components/message/MessageHeader.d.ts.map +1 -1
- package/dist/components/message/MessageHeader.js +7 -2
- package/dist/components/message/MessageList.d.ts +1 -0
- package/dist/components/message/MessageList.d.ts.map +1 -1
- package/dist/components/message/MessageList.js +7 -2
- package/dist/components/message/SelectSession.d.ts.map +1 -1
- package/dist/components/message/SelectSession.js +3 -3
- package/dist/components/session/DeskTeamInbox.js +1 -1
- package/dist/components/thread/GroupThreadInfo.d.ts +11 -0
- package/dist/components/thread/GroupThreadInfo.d.ts.map +1 -0
- package/dist/components/thread/GroupThreadInfo.js +156 -0
- package/dist/components/thread/ManualAssignPopover.js +2 -2
- package/dist/components/thread/SessionSection.d.ts.map +1 -1
- package/dist/components/thread/SessionSection.js +2 -8
- package/dist/components/thread/SingleThreadInfo.d.ts +6 -0
- package/dist/components/thread/SingleThreadInfo.d.ts.map +1 -0
- package/dist/components/thread/SingleThreadInfo.js +70 -0
- package/dist/components/thread/ThreadInfo.d.ts +7 -1
- package/dist/components/thread/ThreadInfo.d.ts.map +1 -1
- package/dist/components/thread/ThreadInfo.js +14 -2
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +3 -0
- package/dist/hooks/global/useGlobalEvent.d.ts.map +1 -1
- package/dist/hooks/global/useGlobalEvent.js +27 -0
- package/dist/hooks/group/useAddGroupMember.d.ts +7 -0
- package/dist/hooks/group/useAddGroupMember.d.ts.map +1 -0
- package/dist/hooks/group/useAddGroupMember.js +20 -0
- package/dist/hooks/group/useDismissGroup.d.ts +4 -0
- package/dist/hooks/group/useDismissGroup.d.ts.map +1 -0
- package/dist/hooks/group/useDismissGroup.js +22 -0
- package/dist/hooks/group/useEligibleAccounts.d.ts +3 -0
- package/dist/hooks/group/useEligibleAccounts.d.ts.map +1 -1
- package/dist/hooks/group/useEligibleAccounts.js +9 -9
- package/dist/hooks/group/useEligibleAccountsForGroup.d.ts +9 -0
- package/dist/hooks/group/useEligibleAccountsForGroup.d.ts.map +1 -0
- package/dist/hooks/group/useEligibleAccountsForGroup.js +26 -0
- package/dist/hooks/group/useGetGroupCandidates.d.ts +7 -2
- package/dist/hooks/group/useGetGroupCandidates.d.ts.map +1 -1
- package/dist/hooks/group/useGetGroupCandidates.js +33 -16
- package/dist/hooks/group/useGroupMemberActions.d.ts +25 -0
- package/dist/hooks/group/useGroupMemberActions.d.ts.map +1 -0
- package/dist/hooks/group/useGroupMemberActions.js +54 -0
- package/dist/hooks/group/useGroupPermission.d.ts +15 -0
- package/dist/hooks/group/useGroupPermission.d.ts.map +1 -0
- package/dist/hooks/group/useGroupPermission.js +70 -0
- package/dist/hooks/group/useSearchGroupMembers.d.ts +8 -0
- package/dist/hooks/group/useSearchGroupMembers.d.ts.map +1 -0
- package/dist/hooks/group/useSearchGroupMembers.js +37 -0
- package/dist/hooks/group/useSetMemberPermission.d.ts +12 -0
- package/dist/hooks/group/useSetMemberPermission.d.ts.map +1 -0
- package/dist/hooks/group/useSetMemberPermission.js +32 -0
- package/dist/hooks/group/useToggleGroupSendMessage.d.ts +7 -0
- package/dist/hooks/group/useToggleGroupSendMessage.d.ts.map +1 -0
- package/dist/hooks/group/useToggleGroupSendMessage.js +22 -0
- package/dist/hooks/group/useUpdateGroupInfo.d.ts +7 -0
- package/dist/hooks/group/useUpdateGroupInfo.d.ts.map +1 -0
- package/dist/hooks/group/useUpdateGroupInfo.js +15 -0
- package/dist/hooks/session/useBlockUser.d.ts +10 -0
- package/dist/hooks/session/useBlockUser.d.ts.map +1 -0
- package/dist/hooks/session/useBlockUser.js +49 -0
- package/dist/hooks/session/useDeleteConversation.d.ts +4 -0
- package/dist/hooks/session/useDeleteConversation.d.ts.map +1 -0
- package/dist/hooks/session/useDeleteConversation.js +20 -0
- package/dist/hooks/session/useGetListSessionByConversation.d.ts +2 -1
- package/dist/hooks/session/useGetListSessionByConversation.d.ts.map +1 -1
- package/dist/hooks/session/useGetListSessionByConversation.js +2 -2
- package/dist/hooks/session/useToggleConversationNotification.d.ts +7 -0
- package/dist/hooks/session/useToggleConversationNotification.d.ts.map +1 -0
- package/dist/hooks/session/useToggleConversationNotification.js +15 -0
- package/dist/locales/vi/common.json +63 -1
- package/dist/locales/vi/conversation-inbox.json +6 -0
- package/dist/screens/desk-message/index.d.ts +3 -1
- package/dist/screens/desk-message/index.d.ts.map +1 -1
- package/dist/screens/desk-message/index.js +4 -5
- package/dist/services/query.d.ts +2 -0
- package/dist/services/query.d.ts.map +1 -1
- package/dist/services/query.js +2 -0
- package/dist/store/groupPermissionOverrides.d.ts +23 -0
- package/dist/store/groupPermissionOverrides.d.ts.map +1 -0
- package/dist/store/groupPermissionOverrides.js +12 -0
- package/dist/styles/global.css +1 -1
- package/dist/utils/events.d.ts +1 -0
- package/dist/utils/events.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComposeNewMessageModal.d.ts","sourceRoot":"","sources":["../../../src/components/compose/ComposeNewMessageModal.tsx"],"names":[],"mappings":"AAeA,UAAU,2BAA2B;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAID,QAAA,MAAM,sBAAsB,GAAI,oBAG7B,2BAA2B,
|
|
1
|
+
{"version":3,"file":"ComposeNewMessageModal.d.ts","sourceRoot":"","sources":["../../../src/components/compose/ComposeNewMessageModal.tsx"],"names":[],"mappings":"AAeA,UAAU,2BAA2B;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAID,QAAA,MAAM,sBAAsB,GAAI,oBAG7B,2BAA2B,4CAwI7B,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -56,6 +56,6 @@ const ComposeNewMessageModal = ({ open, onClose, }) => {
|
|
|
56
56
|
setOpeningUserID(null);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
return (_jsx(Modal, { title: step === "create-group" ? t("create_group.title") : t("compose.title"), open: open, onCancel: handleClose, afterClose: handleAfterClose, footer: null, centered: true, forceRender: true, width: step === "create-group" ? 720 : undefined, getContainer: false, children: step === "compose" ? (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Input, { size: "large", value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("compose.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }) }), _jsxs("button", { type: "button", className: "flex items-center gap-3 rounded-xl bg-primary-50 px-4 py-3.5 text-left transition-colors hover:bg-primary-100", onClick: () => setStep("create-group"), children: [_jsx("span", { className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-white", children: _jsx(Icon, { icon: "user-three-b", size: 22, className: "text-primary-400" }) }), _jsx("span", { className: "flex-1 text-base font-semibold text-gray-900", children: t("compose.create_group") }), _jsx(Icon, { icon: "angle-right-o", size: 18, className: "text-gray-400" })] }), !debouncedSearch && (_jsxs("div", { className: "flex items-center gap-2 px-1", children: [_jsx("span", { className: "shrink-0 text-xs font-semibold uppercase tracking-wide text-gray-400", children: t("compose.recent_suggestions") }), _jsx("span", { className: "h-px flex-1 bg-gray-100" })] })), _jsx("div", { className: "max-h-80 overflow-y-auto", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("compose.no_member_found") })) : (accounts.map((account) => (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 border-b border-gray-50 px-1 py-3 transition-colors last:border-b-0 hover:bg-
|
|
59
|
+
return (_jsx(Modal, { title: step === "create-group" ? t("create_group.title") : t("compose.title"), open: open, onCancel: handleClose, afterClose: handleAfterClose, footer: null, centered: true, forceRender: true, width: step === "create-group" ? 720 : undefined, getContainer: false, children: step === "compose" ? (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(Input, { size: "large", value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("compose.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 18, className: "text-gray-400" }) }), _jsxs("button", { type: "button", className: "flex items-center gap-3 rounded-xl bg-primary-50 px-4 py-3.5 text-left transition-colors hover:bg-primary-100", onClick: () => setStep("create-group"), children: [_jsx("span", { className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-white", children: _jsx(Icon, { icon: "user-three-b", size: 22, className: "text-primary-400" }) }), _jsx("span", { className: "flex-1 text-base font-semibold text-gray-900", children: t("compose.create_group") }), _jsx(Icon, { icon: "angle-right-o", size: 18, className: "text-gray-400" })] }), !debouncedSearch && (_jsxs("div", { className: "flex items-center gap-2 px-1", children: [_jsx("span", { className: "shrink-0 text-xs font-semibold uppercase tracking-wide text-gray-400", children: t("compose.recent_suggestions") }), _jsx("span", { className: "h-px flex-1 bg-gray-100" })] })), _jsx("div", { className: "max-h-80 overflow-y-auto", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("compose.no_member_found") })) : (accounts.map((account) => (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 border-b border-gray-50 px-1 py-3 transition-colors last:border-b-0 hover:bg-[#f5f5f5]", onClick: () => handleOpenDirectMessage(account), children: [_jsx(Avatar, { src: account.avatar, size: 44, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: account.displayName }), openingUserID === account.userID && _jsx(Spin, { size: "small" })] }, account.userID)))) })] })) : (_jsx(CreateGroupForm, { onDone: handleClose })) }));
|
|
60
60
|
};
|
|
61
61
|
export default ComposeNewMessageModal;
|
|
@@ -9,7 +9,7 @@ const UnreadBadge = ({ count }) => {
|
|
|
9
9
|
};
|
|
10
10
|
const ThreadCard = ({ avatar, title, preview, time, unreadCount = 0, isSelected = false, onClick, testId, }) => {
|
|
11
11
|
const hasUnread = unreadCount > 0;
|
|
12
|
-
return (_jsxs("button", { type: "button", onClick: onClick, "data-testid": testId, className: clsx("relative flex w-full shrink-0 items-start gap-2 border-b border-gray-25 p-3 text-left transition-colors hover:bg-
|
|
12
|
+
return (_jsxs("button", { type: "button", onClick: onClick, "data-testid": testId, className: clsx("relative flex w-full shrink-0 items-start gap-2 border-b border-gray-25 p-3 text-left transition-colors hover:bg-[#f5f5f5] focus:outline-none focus-visible:ring-2 focus-visible:ring-chat-ring", isSelected ? "bg-blue-50" : "bg-white"), children: [isSelected && (_jsx("span", { className: "absolute bottom-0 left-0 top-0 w-1 bg-blue-500" })), avatar, _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsxs("div", { className: "flex min-h-[25.6px] items-center justify-between gap-1", children: [_jsx("div", { className: "min-w-0 flex-1", children: title }), time && (_jsx("span", { className: "shrink-0 text-[12px] font-normal leading-[160%] text-gray-400 [font-feature-settings:'liga'_off,'clig'_off]", children: time }))] }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("p", { className: clsx("min-w-0 flex-1 truncate text-[14px] leading-[160%] [font-feature-settings:'liga'_off,'clig'_off]", hasUnread
|
|
13
13
|
? "font-[510] text-black"
|
|
14
14
|
: "font-normal tracking-[0.14px] text-gray-600"), children: preview }), hasUnread && _jsx(UnreadBadge, { count: unreadCount })] })] })] }));
|
|
15
15
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface AddMemberModalProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
groupID: string;
|
|
4
|
+
existingMemberIDs: string[];
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
}
|
|
7
|
+
declare const AddMemberModal: ({ open, groupID, existingMemberIDs, onClose, }: AddMemberModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export default AddMemberModal;
|
|
9
|
+
//# sourceMappingURL=AddMemberModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddMemberModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AddMemberModal.tsx"],"names":[],"mappings":"AAYA,UAAU,mBAAmB;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,cAAc,GAAI,gDAKrB,mBAAmB,4CA2LrB,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useDebounce } from "ahooks";
|
|
4
|
+
import { Avatar, Button, Empty, Input, Modal, Spin, message } from "antd";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { useTranslation } from "react-i18next";
|
|
8
|
+
import { Icon } from "../../components/icon";
|
|
9
|
+
import { useEligibleAccountsForGroup } from "../../hooks/group/useEligibleAccountsForGroup";
|
|
10
|
+
import { useAddGroupMember } from "../../hooks/group/useAddGroupMember";
|
|
11
|
+
const AddMemberModal = ({ open, groupID, existingMemberIDs, onClose, }) => {
|
|
12
|
+
const { t } = useTranslation("conversation-inbox");
|
|
13
|
+
const { t: tCommon } = useTranslation();
|
|
14
|
+
const [search, setSearch] = useState("");
|
|
15
|
+
const [selectedMembers, setSelectedMembers] = useState([]);
|
|
16
|
+
const debouncedSearch = useDebounce(search, { wait: 300 });
|
|
17
|
+
const { accounts, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = useEligibleAccountsForGroup(debouncedSearch, existingMemberIDs, open);
|
|
18
|
+
const { mutateAsync: addGroupMember, isPending: isSubmitting } = useAddGroupMember();
|
|
19
|
+
const selectedIds = new Set(selectedMembers.map((member) => member.userID));
|
|
20
|
+
const toggleMember = (account) => {
|
|
21
|
+
if (selectedIds.has(account.userID)) {
|
|
22
|
+
setSelectedMembers((prev) => prev.filter((member) => member.userID !== account.userID));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setSelectedMembers((prev) => [...prev, account]);
|
|
26
|
+
};
|
|
27
|
+
const handleRemoveMember = (userID) => {
|
|
28
|
+
setSelectedMembers((prev) => prev.filter((member) => member.userID !== userID));
|
|
29
|
+
};
|
|
30
|
+
const handleClearAll = () => {
|
|
31
|
+
setSelectedMembers([]);
|
|
32
|
+
};
|
|
33
|
+
const handleClose = () => {
|
|
34
|
+
setSearch("");
|
|
35
|
+
setSelectedMembers([]);
|
|
36
|
+
onClose();
|
|
37
|
+
};
|
|
38
|
+
const handleListScroll = (event) => {
|
|
39
|
+
if (!hasNextPage || isFetchingNextPage)
|
|
40
|
+
return;
|
|
41
|
+
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
|
|
42
|
+
if (scrollHeight - scrollTop - clientHeight < 80) {
|
|
43
|
+
void fetchNextPage();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const handleSubmit = async () => {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
if (!groupID || selectedMembers.length === 0)
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
await addGroupMember({
|
|
52
|
+
groupID,
|
|
53
|
+
userIDList: selectedMembers.map((member) => member.userID),
|
|
54
|
+
});
|
|
55
|
+
message.success(t("add_member.add_member_success"));
|
|
56
|
+
handleClose();
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const errorMessage = ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("add_member.add_member_failed");
|
|
60
|
+
message.error(errorMessage);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return (_jsx(Modal, { centered: true, open: open, onCancel: handleClose, footer: null, title: t("add_member.title"), getContainer: false, children: _jsxs("div", { className: "flex flex-col gap-3 pt-2", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), selectedMembers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2", children: selectedMembers.map((member) => (_jsxs("span", { className: "flex items-center gap-1.5 rounded-full bg-gray-100 pl-1 pr-2 py-1", children: [_jsx(Avatar, { src: member.avatar, size: 20, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "max-w-[120px] truncate text-sm text-gray-900", children: member.displayName }), _jsx(Icon, { icon: "close-b", size: 12, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID))) })), _jsx("div", { className: "max-h-72 overflow-y-auto", onScroll: handleListScroll, children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (_jsxs(_Fragment, { children: [accounts.map((account) => {
|
|
64
|
+
const isSelected = selectedIds.has(account.userID);
|
|
65
|
+
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: account.displayName }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
66
|
+
? "border-primary-400 bg-primary-400"
|
|
67
|
+
: "border-gray-300 bg-white"), children: isSelected && (_jsx(Icon, { icon: "check-b", size: 11, className: "text-white" })) })] }, account.userID));
|
|
68
|
+
}), isFetchingNextPage && (_jsx("div", { className: "flex items-center justify-center py-3", children: _jsx(Spin, { size: "small" }) }))] })) }), _jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [_jsx(Button, { onClick: handleClose, children: tCommon("cancel") }), _jsx(Button, { type: "primary", disabled: selectedMembers.length === 0, loading: isSubmitting, onClick: handleSubmit, children: t("add_member.confirm") })] })] }) }));
|
|
69
|
+
};
|
|
70
|
+
export default AddMemberModal;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface AdminPermissionModalProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
groupID: string;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
inline?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare const AdminPermissionModal: ({ open, groupID, onClose, inline, }: AdminPermissionModalProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export default AdminPermissionModal;
|
|
9
|
+
//# sourceMappingURL=AdminPermissionModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminPermissionModal.d.ts","sourceRoot":"","sources":["../../../src/components/group/AdminPermissionModal.tsx"],"names":[],"mappings":"AAYA,UAAU,yBAAyB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IAIpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAMD,QAAA,MAAM,oBAAoB,GAAI,qCAK3B,yBAAyB,mDA0J3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { ConfigProvider, Modal, Switch, message } from "antd";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import { useGroupPermission } from "../../hooks/group/useGroupPermission";
|
|
7
|
+
import { Icon } from "../../components/icon";
|
|
8
|
+
import { PERMISSION_SWITCH_COLOR } from "../../constants";
|
|
9
|
+
import useGroupPermissionOverridesStore from "../../store/groupPermissionOverrides";
|
|
10
|
+
// Mocked config UI (DROPPII-30248 follow-up, "Configure Admin Permissions")
|
|
11
|
+
// — applies to the whole Admin role in the group, not a per-member override
|
|
12
|
+
// (confirmed with PO). No BE persistence yet, committed to the in-memory
|
|
13
|
+
// override store on "Lưu" only.
|
|
14
|
+
const AdminPermissionModal = ({ open, groupID, onClose, inline = false, }) => {
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const permissions = useGroupPermission(groupID);
|
|
17
|
+
const setAdminOverrides = useGroupPermissionOverridesStore((state) => state.setAdminOverrides);
|
|
18
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
19
|
+
const [pending, setPending] = useState({
|
|
20
|
+
sendMessage: permissions.sendMessage,
|
|
21
|
+
pinMessage: permissions.pinMessage,
|
|
22
|
+
viewMemberInformation: permissions.viewMemberInformation,
|
|
23
|
+
addMember: permissions.addMember,
|
|
24
|
+
removeMember: permissions.removeMember,
|
|
25
|
+
updateGroupInfo: permissions.updateGroupName,
|
|
26
|
+
});
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!open)
|
|
29
|
+
return;
|
|
30
|
+
setPending({
|
|
31
|
+
sendMessage: permissions.sendMessage,
|
|
32
|
+
pinMessage: permissions.pinMessage,
|
|
33
|
+
viewMemberInformation: permissions.viewMemberInformation,
|
|
34
|
+
addMember: permissions.addMember,
|
|
35
|
+
removeMember: permissions.removeMember,
|
|
36
|
+
updateGroupInfo: permissions.updateGroupName,
|
|
37
|
+
});
|
|
38
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39
|
+
}, [open]);
|
|
40
|
+
const hasChanges = pending.sendMessage !== permissions.sendMessage ||
|
|
41
|
+
pending.pinMessage !== permissions.pinMessage ||
|
|
42
|
+
pending.viewMemberInformation !== permissions.viewMemberInformation ||
|
|
43
|
+
pending.addMember !== permissions.addMember ||
|
|
44
|
+
pending.removeMember !== permissions.removeMember ||
|
|
45
|
+
pending.updateGroupInfo !== permissions.updateGroupName;
|
|
46
|
+
const handleSave = async () => {
|
|
47
|
+
if (!groupID)
|
|
48
|
+
return;
|
|
49
|
+
setIsSaving(true);
|
|
50
|
+
setAdminOverrides(groupID, pending);
|
|
51
|
+
message.success(t("update_admin_permissions_success"));
|
|
52
|
+
setIsSaving(false);
|
|
53
|
+
onClose();
|
|
54
|
+
};
|
|
55
|
+
const rows = (_jsx(ConfigProvider, { theme: { token: { colorPrimary: PERMISSION_SWITCH_COLOR } }, children: _jsxs("div", { className: "flex flex-col py-2", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_send_message") }), _jsx(Switch, { checked: pending.sendMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { sendMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_pin_unpin_message") }), _jsx(Switch, { checked: pending.pinMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { pinMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_view_member_info") }), _jsx(Switch, { checked: pending.viewMemberInformation, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { viewMemberInformation: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_add_member") }), _jsx(Switch, { checked: pending.addMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { addMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_remove_member") }), _jsx(Switch, { checked: pending.removeMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { removeMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_update_group_info") }), _jsx(Switch, { checked: pending.updateGroupInfo, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { updateGroupInfo: checked }))) })] })] }) }));
|
|
56
|
+
if (inline) {
|
|
57
|
+
if (!open)
|
|
58
|
+
return null;
|
|
59
|
+
return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-primary-400", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("admin_permission_settings") })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [rows, _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-primary-400 text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] })] }));
|
|
60
|
+
}
|
|
61
|
+
return (_jsx(Modal, { centered: true, open: open, onOk: handleSave, onCancel: onClose, title: t("admin_permission_settings"), okText: t("save"), cancelText: t("cancel"), confirmLoading: isSaving, okButtonProps: { disabled: !hasChanges }, getContainer: false, children: _jsx("div", { className: "mt-2", children: rows }) }));
|
|
62
|
+
};
|
|
63
|
+
export default AdminPermissionModal;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
interface CreateGroupFormProps {
|
|
2
|
-
onBack: () => void;
|
|
3
2
|
onDone: () => void;
|
|
4
3
|
}
|
|
5
|
-
declare const CreateGroupForm: ({
|
|
4
|
+
declare const CreateGroupForm: ({ onDone }: CreateGroupFormProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
5
|
export default CreateGroupForm;
|
|
7
6
|
//# sourceMappingURL=CreateGroupForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateGroupForm.d.ts","sourceRoot":"","sources":["../../../src/components/group/CreateGroupForm.tsx"],"names":[],"mappings":"AAcA,UAAU,oBAAoB;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"CreateGroupForm.d.ts","sourceRoot":"","sources":["../../../src/components/group/CreateGroupForm.tsx"],"names":[],"mappings":"AAcA,UAAU,oBAAoB;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,QAAA,MAAM,eAAe,GAAI,YAAY,oBAAoB,4CAqKxD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -8,7 +8,7 @@ import { Icon } from "../../components/icon";
|
|
|
8
8
|
import { useCreateGroup } from "../../hooks/group/useCreateGroup";
|
|
9
9
|
import GroupMemberPicker from "./GroupMemberPicker";
|
|
10
10
|
const GROUP_NAME_MAX_LENGTH = 255;
|
|
11
|
-
const CreateGroupForm = ({
|
|
11
|
+
const CreateGroupForm = ({ onDone }) => {
|
|
12
12
|
const { t } = useTranslation("conversation-inbox");
|
|
13
13
|
const { createGroup } = useCreateGroup();
|
|
14
14
|
const [groupName, setGroupName] = useState("");
|
|
@@ -63,12 +63,12 @@ const CreateGroupForm = ({ onBack, onDone }) => {
|
|
|
63
63
|
description: t("create_group.privacy_public_desc"),
|
|
64
64
|
},
|
|
65
65
|
], [t]);
|
|
66
|
-
return (_jsxs("div", { className: "flex max-h-[70vh] flex-col", children: [_jsxs("
|
|
66
|
+
return (_jsxs("div", { className: "flex max-h-[70vh] flex-col", children: [_jsxs("div", { className: "flex flex-col overflow-y-auto pr-1", children: [_jsxs("div", { className: "flex items-center gap-4 py-6", children: [_jsx(Upload, { accept: "image/jpeg, image/png, image/jpg", showUploadList: false, beforeUpload: handleAvatarSelect, children: _jsxs("div", { className: "relative flex h-20 w-20 shrink-0 cursor-pointer items-center justify-center rounded-2xl bg-primary-50", children: [avatarPreviewUrl ? (
|
|
67
67
|
// eslint-disable-next-line @next/next/no-img-element
|
|
68
|
-
_jsx("img", { src: avatarPreviewUrl, alt: "", className: "h-full w-full rounded-2xl object-cover" })) : (_jsx(Icon, { icon: "user-three-b", size: 32, className: "text-primary-400" })), _jsx("span", { className: "absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-gray-500", children: _jsx(Icon, { icon: "camera-b", size: 14, className: "text-white" }) })] }) }), _jsx(Input, { size: "large", value: groupName, onChange: (event) => setGroupName(event.target.value.slice(0, GROUP_NAME_MAX_LENGTH)), maxLength: GROUP_NAME_MAX_LENGTH, placeholder: t("create_group.name_placeholder"), className: "flex-1 text-base" })] }), _jsxs("div", { className: "flex flex-col gap-3 border-t border-gray-100 py-6", children: [_jsx("span", { className: "text-
|
|
68
|
+
_jsx("img", { src: avatarPreviewUrl, alt: "", className: "h-full w-full rounded-2xl object-cover" })) : (_jsx(Icon, { icon: "user-three-b", size: 32, className: "text-primary-400" })), _jsx("span", { className: "absolute -bottom-1 -right-1 flex h-7 w-7 items-center justify-center rounded-full bg-gray-500", children: _jsx(Icon, { icon: "camera-b", size: 14, className: "text-white" }) })] }) }), _jsx(Input, { size: "large", value: groupName, onChange: (event) => setGroupName(event.target.value.slice(0, GROUP_NAME_MAX_LENGTH)), maxLength: GROUP_NAME_MAX_LENGTH, placeholder: t("create_group.name_placeholder"), className: "flex-1 text-base" })] }), _jsxs("div", { className: "flex flex-col gap-3 border-t border-gray-100 py-6", children: [_jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-gray-400", children: t("create_group.privacy_label") }), _jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: privacyOptions.map((option) => (_jsxs("button", { type: "button", onClick: () => setIsPublic(option.value), className: clsx("rounded-xl border-2 p-4 text-left transition-colors", isPublic === option.value
|
|
69
69
|
? "border-primary-400 bg-primary-50"
|
|
70
70
|
: "border-gray-200 bg-white"), children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Icon, { icon: option.icon, size: 18, className: isPublic === option.value
|
|
71
71
|
? "text-primary-400"
|
|
72
|
-
: "text-gray-400" }), _jsx("span", { className: "text-base font-semibold text-gray-900", children: option.label })] }), _jsx("p", { className: "mt-
|
|
72
|
+
: "text-gray-400" }), _jsx("span", { className: "text-base font-semibold text-gray-900", children: option.label })] }), _jsx("p", { className: "mt-2 text-sm text-gray-500", children: option.description })] }, String(option.value)))) })] }), _jsx("div", { className: "border-t border-gray-100 py-6", children: _jsx(GroupMemberPicker, { selectedMembers: selectedMembers, onChangeSelectedMembers: setSelectedMembers }) })] }), _jsxs("div", { className: "flex shrink-0 justify-end gap-2 pt-4", children: [_jsx(Button, { onClick: onDone, children: t("create_group.cancel") }), _jsx(Button, { type: "primary", disabled: !canSubmit, loading: isSubmitting, onClick: handleSubmit, children: t("create_group.submit") })] })] }));
|
|
73
73
|
};
|
|
74
74
|
export default CreateGroupForm;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMemberPicker.d.ts","sourceRoot":"","sources":["../../../src/components/group/GroupMemberPicker.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,UAAU,sBAAsB;IAC9B,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uBAAuB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,iBAAiB,GAAI,+CAGxB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"GroupMemberPicker.d.ts","sourceRoot":"","sources":["../../../src/components/group/GroupMemberPicker.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,UAAU,sBAAsB;IAC9B,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uBAAuB,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,iBAAiB,GAAI,+CAGxB,sBAAsB,4CAoJxB,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useDebounce } from "ahooks";
|
|
4
4
|
import { Avatar, Empty, Input, Spin } from "antd";
|
|
5
5
|
import clsx from "clsx";
|
|
@@ -11,7 +11,15 @@ const GroupMemberPicker = ({ selectedMembers, onChangeSelectedMembers, }) => {
|
|
|
11
11
|
const { t } = useTranslation("conversation-inbox");
|
|
12
12
|
const [search, setSearch] = useState("");
|
|
13
13
|
const debouncedSearch = useDebounce(search, { wait: 300 });
|
|
14
|
-
const { accounts, isLoading } = useEligibleAccounts(debouncedSearch);
|
|
14
|
+
const { accounts, isLoading, fetchNextPage, hasNextPage, isFetchingNextPage } = useEligibleAccounts(debouncedSearch);
|
|
15
|
+
const handleListScroll = (event) => {
|
|
16
|
+
if (!hasNextPage || isFetchingNextPage)
|
|
17
|
+
return;
|
|
18
|
+
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
|
|
19
|
+
if (scrollHeight - scrollTop - clientHeight < 80) {
|
|
20
|
+
void fetchNextPage();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
15
23
|
const selectedIds = new Set(selectedMembers.map((member) => member.userID));
|
|
16
24
|
const toggleMember = (account) => {
|
|
17
25
|
if (selectedIds.has(account.userID)) {
|
|
@@ -26,11 +34,11 @@ const GroupMemberPicker = ({ selectedMembers, onChangeSelectedMembers, }) => {
|
|
|
26
34
|
const handleClearAll = () => {
|
|
27
35
|
onChangeSelectedMembers([]);
|
|
28
36
|
};
|
|
29
|
-
return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsx("div", { className: "max-h-64 overflow-y-auto", children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (accounts.map((account) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
return (_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsx(Input, { value: search, onChange: (event) => setSearch(event.target.value), placeholder: t("create_group.search_member_placeholder"), prefix: _jsx(Icon, { icon: "search-o", size: 16, className: "text-gray-400" }) }), _jsx("div", { className: "max-h-64 overflow-y-auto", onScroll: handleListScroll, children: isLoading ? (_jsx("div", { className: "flex items-center justify-center py-6", children: _jsx(Spin, {}) })) : accounts.length === 0 ? (_jsx(Empty, { description: t("create_group.no_member_found") })) : (_jsxs(_Fragment, { children: [accounts.map((account) => {
|
|
38
|
+
const isSelected = selectedIds.has(account.userID);
|
|
39
|
+
return (_jsxs("div", { className: "flex cursor-pointer items-center gap-3 rounded-lg px-3 py-3 transition-colors duration-150 hover:bg-[#f5f5f5]", onClick: () => toggleMember(account), children: [_jsx(Avatar, { src: account.avatar, size: 40, className: "shrink-0", children: account.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: account.displayName }), _jsx("span", { className: clsx("flex h-4 w-4 shrink-0 items-center justify-center rounded border", isSelected
|
|
40
|
+
? "border-primary-400 bg-primary-400"
|
|
41
|
+
: "border-gray-300 bg-white"), children: isSelected && (_jsx(Icon, { icon: "check-b", size: 11, className: "text-white" })) })] }, account.userID));
|
|
42
|
+
}), isFetchingNextPage && (_jsx("div", { className: "flex items-center justify-center py-3", children: _jsx(Spin, { size: "small" }) }))] })) })] }), _jsxs("div", { className: "flex flex-col gap-2 rounded-xl border border-gray-200 p-3", children: [_jsxs("div", { className: "flex items-center justify-between px-1", children: [_jsx("span", { className: "text-sm text-gray-500", children: t("create_group.selected_count", { count: selectedMembers.length }) }), selectedMembers.length > 0 && (_jsx("button", { type: "button", className: "text-sm text-primary-400 hover:text-primary-500 hover:underline", onClick: handleClearAll, children: t("create_group.clear_all") }))] }), _jsx("div", { className: "max-h-64 overflow-y-auto", children: selectedMembers.length === 0 ? (_jsxs("div", { className: "flex h-full min-h-[200px] flex-col items-center justify-center gap-2 text-center", children: [_jsx(Icon, { icon: "user-three-b", size: 28, className: "text-gray-300" }), _jsx("span", { className: "text-sm text-gray-400", children: t("create_group.no_member_selected") })] })) : (selectedMembers.map((member) => (_jsxs("div", { className: "flex items-center gap-3 rounded-lg px-3 py-3", children: [_jsx(Avatar, { src: member.avatar, size: 40, className: "shrink-0", children: member.displayName.charAt(0) || "A" }), _jsx("span", { className: "flex-1 truncate text-base font-medium text-gray-900", children: member.displayName }), _jsx(Icon, { icon: "close-b", size: 14, className: "shrink-0 cursor-pointer text-gray-400", onClick: () => handleRemoveMember(member.userID) })] }, member.userID)))) })] })] }));
|
|
35
43
|
};
|
|
36
44
|
export default GroupMemberPicker;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface MemberPermissionPanelProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
groupID: string;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
}
|
|
6
|
+
declare const MemberPermissionPanel: ({ open, groupID, onClose }: MemberPermissionPanelProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export default MemberPermissionPanel;
|
|
8
|
+
//# sourceMappingURL=MemberPermissionPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemberPermissionPanel.d.ts","sourceRoot":"","sources":["../../../src/components/group/MemberPermissionPanel.tsx"],"names":[],"mappings":"AAYA,UAAU,0BAA0B;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAMD,QAAA,MAAM,qBAAqB,GAAI,4BAA4B,0BAA0B,mDAqHpF,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { ConfigProvider, Switch, message } from "antd";
|
|
5
|
+
import { useTranslation } from "react-i18next";
|
|
6
|
+
import { useGroupPermission } from "../../hooks/group/useGroupPermission";
|
|
7
|
+
import { Icon } from "../../components/icon";
|
|
8
|
+
import { PERMISSION_SWITCH_COLOR } from "../../constants";
|
|
9
|
+
import useGroupPermissionOverridesStore from "../../store/groupPermissionOverrides";
|
|
10
|
+
// Mocked config UI (DROPPII-30248 follow-up, "Configure Member Permissions")
|
|
11
|
+
// — renders inline within the "Thông tin" sidebar (back arrow, no gray
|
|
12
|
+
// background) per the reference recording, not as a Modal popup. No BE
|
|
13
|
+
// persistence yet, committed to the in-memory override store on "Lưu" only.
|
|
14
|
+
const MemberPermissionPanel = ({ open, groupID, onClose }) => {
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const permissions = useGroupPermission(groupID);
|
|
17
|
+
const setMemberOverrides = useGroupPermissionOverridesStore((state) => state.setMemberOverrides);
|
|
18
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
19
|
+
const [pending, setPending] = useState({
|
|
20
|
+
sendMessage: permissions.sendMessage,
|
|
21
|
+
addMember: permissions.addMember,
|
|
22
|
+
pinMessage: permissions.pinMessage,
|
|
23
|
+
viewMemberInformation: permissions.viewMemberInformation,
|
|
24
|
+
});
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!open)
|
|
27
|
+
return;
|
|
28
|
+
setPending({
|
|
29
|
+
sendMessage: permissions.sendMessage,
|
|
30
|
+
addMember: permissions.addMember,
|
|
31
|
+
pinMessage: permissions.pinMessage,
|
|
32
|
+
viewMemberInformation: permissions.viewMemberInformation,
|
|
33
|
+
});
|
|
34
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35
|
+
}, [open]);
|
|
36
|
+
const hasChanges = pending.sendMessage !== permissions.sendMessage ||
|
|
37
|
+
pending.addMember !== permissions.addMember ||
|
|
38
|
+
pending.pinMessage !== permissions.pinMessage ||
|
|
39
|
+
pending.viewMemberInformation !== permissions.viewMemberInformation;
|
|
40
|
+
const handleSave = async () => {
|
|
41
|
+
if (!groupID)
|
|
42
|
+
return;
|
|
43
|
+
setIsSaving(true);
|
|
44
|
+
setMemberOverrides(groupID, pending);
|
|
45
|
+
message.success(t("update_member_permissions_success"));
|
|
46
|
+
setIsSaving(false);
|
|
47
|
+
onClose();
|
|
48
|
+
};
|
|
49
|
+
if (!open)
|
|
50
|
+
return null;
|
|
51
|
+
return (_jsxs("div", { className: "absolute inset-0 bg-white flex flex-col z-10", children: [_jsxs("div", { className: "flex w-full items-center border-b border-gray-100 p-2", children: [_jsx("button", { type: "button", className: "flex shrink-0 cursor-pointer items-center justify-center p-2 text-primary-400", onClick: onClose, children: _jsx(Icon, { icon: "arrow-left-o", size: 24 }) }), _jsx("p", { className: "min-w-0 flex-1 truncate px-2 text-[18px] font-bold leading-[1.6] text-gray-900", children: t("member_permission_settings") })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx(ConfigProvider, { theme: { token: { colorPrimary: PERMISSION_SWITCH_COLOR } }, children: _jsxs("div", { className: "flex flex-col py-2", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_send_message") }), _jsx(Switch, { checked: pending.sendMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { sendMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_add_member") }), _jsx(Switch, { checked: pending.addMember, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { addMember: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_pin_message") }), _jsx(Switch, { checked: pending.pinMessage, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { pinMessage: checked }))) })] }), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("span", { className: "text-sm", children: t("permission_view_member_info") }), _jsx(Switch, { checked: pending.viewMemberInformation, onChange: (checked) => setPending((prev) => (Object.assign(Object.assign({}, prev), { viewMemberInformation: checked }))) })] })] }) }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 px-4 py-3 border-t border-gray-100", children: [_jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full border border-gray-300 text-gray-700 text-sm font-medium", onClick: onClose, children: t("cancel") }), _jsx("button", { type: "button", className: "px-4 py-1.5 rounded-full bg-primary-400 text-white text-sm font-medium disabled:bg-gray-200 disabled:text-gray-400", disabled: !hasChanges || isSaving, onClick: handleSave, children: t("save") })] })] }));
|
|
52
|
+
};
|
|
53
|
+
export default MemberPermissionPanel;
|
|
@@ -11,7 +11,7 @@ const FileResourceList = () => {
|
|
|
11
11
|
return (_jsx(ResourceScrollContainer, Object.assign({}, containerProps, { itemCount: items.length, children: _jsx("div", { className: "flex flex-col gap-2 p-3", children: items.map((item) => {
|
|
12
12
|
var _a, _b;
|
|
13
13
|
const fileContent = parseMessageContent((_a = item === null || item === void 0 ? void 0 : item.chatLog) === null || _a === void 0 ? void 0 : _a.content);
|
|
14
|
-
return (_jsxs("div", { className: "flex w-full cursor-pointer items-center gap-2 rounded-[12px] bg-
|
|
14
|
+
return (_jsxs("div", { className: "flex w-full cursor-pointer items-center gap-2 rounded-[12px] bg-[#f5f5f5]/20 p-3", onClick: () => downloadFileFromUrl((fileContent === null || fileContent === void 0 ? void 0 : fileContent.sourceUrl) || "", (fileContent === null || fileContent === void 0 ? void 0 : fileContent.fileName) || ""), children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center [&>svg]:h-full [&>svg]:w-auto", children: documentIcon }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "truncate text-[16px] font-medium leading-[1.6] text-gray-900", children: shortenFileName(fileContent === null || fileContent === void 0 ? void 0 : fileContent.fileName) }), _jsx("span", { className: "text-[13px] font-normal leading-[1.6] text-gray-400", children: renderFileSize((fileContent === null || fileContent === void 0 ? void 0 : fileContent.fileSize) || 0) })] })] }, (_b = item.chatLog) === null || _b === void 0 ? void 0 : _b.clientMsgID));
|
|
15
15
|
}) }) })));
|
|
16
16
|
};
|
|
17
17
|
export default FileResourceList;
|
|
@@ -17,6 +17,6 @@ const LinkResourceItem = ({ url, messageMetadata }) => {
|
|
|
17
17
|
const handleOpen = () => {
|
|
18
18
|
openLink(url, t);
|
|
19
19
|
};
|
|
20
|
-
return (_jsxs("div", { "data-testid": "link-resource-item", className: "flex w-full cursor-pointer items-center gap-2 rounded-[12px] bg-
|
|
20
|
+
return (_jsxs("div", { "data-testid": "link-resource-item", className: "flex w-full cursor-pointer items-center gap-2 rounded-[12px] bg-[#f5f5f5]/20 p-3", onClick: handleOpen, children: [_jsx("div", { className: "flex h-[76px] w-[76px] shrink-0 items-center justify-center", children: shouldShowImage ? (_jsx("img", { src: imageUrl, alt: "", className: "h-full w-full rounded-[8px] object-cover", onError: () => setFailedImageUrl(imageUrl) })) : (_jsx("div", { className: "flex h-full w-full items-center justify-center rounded-[12px] bg-gray-200", children: _jsx(Icon, { icon: "link-b", size: 24, color: "white" }) })) }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center", children: [_jsx("p", { className: "truncate text-[14px] font-normal leading-[1.6] tracking-[-0.14px] text-gray-600", children: stripProtocol(url) }), _jsx("p", { className: "line-clamp-2 text-[16px] font-medium leading-[1.6] text-gray-900", children: title || url })] })] }));
|
|
21
21
|
};
|
|
22
22
|
export default LinkResourceItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GroupMembersDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/message/GroupMembersDrawer.tsx"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAe/C,UAAU,uBAAuB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA4CD,QAAA,MAAM,kBAAkB,GAAI,wDAKzB,uBAAuB,4CAuezB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|