feat: add fast change role group with group member right click menu manage #171

pull/147/merge
moonrailgun 1 year ago
parent ba37f36817
commit ed3e9ca6d7

@ -138,6 +138,7 @@
"k5d2a6631": "Allow to manage channels", "k5d2a6631": "Allow to manage channels",
"k5f91e72c": "Built Plugins", "k5f91e72c": "Built Plugins",
"k5fc9ccb6": "Operation too frequently", "k5fc9ccb6": "Operation too frequently",
"k5fde4f8e": "Assign roles",
"k609d9f28": "Please enter the server address (example: http://127.0.0.1:11000)", "k609d9f28": "Please enter the server address (example: http://127.0.0.1:11000)",
"k61a1db2": "Already applied", "k61a1db2": "Already applied",
"k62051fcc": "Upload failed", "k62051fcc": "Upload failed",
@ -165,7 +166,7 @@
"k6cc401b0": "No role groups are currently selected", "k6cc401b0": "No role groups are currently selected",
"k6cd79ab": "Click for details", "k6cd79ab": "Click for details",
"k6e4e3d7a": "All messages in this group are marked as read", "k6e4e3d7a": "All messages in this group are marked as read",
"k6eac768d": "Add Members", "k6eac768d": "Add Roles",
"k6ee71a71": "Global Configuration", "k6ee71a71": "Global Configuration",
"k6efe275c": "Mark as read", "k6efe275c": "Mark as read",
"k6fb230da": "Pending friend request", "k6fb230da": "Pending friend request",
@ -225,6 +226,7 @@
"k8f6ab535": "Unable to install", "k8f6ab535": "Unable to install",
"k8f6dfd40": "Current members", "k8f6dfd40": "Current members",
"k9179206d": "Reconnecting", "k9179206d": "Reconnecting",
"k924278f0": "Remove user [{{name}}] role [{{roleName}}] success",
"k9277af78": "Retry", "k9277af78": "Retry",
"k92a84117": "Claim account", "k92a84117": "Claim account",
"k95222176": "Unread", "k95222176": "Unread",
@ -328,6 +330,7 @@
"kc74e5f62": "Search for members", "kc74e5f62": "Search for members",
"kc77e00c7": "Allow members to view the panel", "kc77e00c7": "Allow members to view the panel",
"kc7cc96c8": "From", "kc7cc96c8": "From",
"kc8c4ccbb": "Grant user [{{name}}] role [{{roleName}}] success",
"kc9283683": "Are you sure you want to delete the panel [{{name}}]", "kc9283683": "Are you sure you want to delete the panel [{{name}}]",
"kc9bd3ad6": "Reset to default permissions", "kc9bd3ad6": "Reset to default permissions",
"kc9cc6154": "Friends", "kc9cc6154": "Friends",

@ -138,6 +138,7 @@
"k5d2a6631": "允许管理频道", "k5d2a6631": "允许管理频道",
"k5f91e72c": "内置插件", "k5f91e72c": "内置插件",
"k5fc9ccb6": "操作过于频繁", "k5fc9ccb6": "操作过于频繁",
"k5fde4f8e": "分配身份组",
"k609d9f28": "请输入服务器地址(示例: http://127.0.0.1:11000)", "k609d9f28": "请输入服务器地址(示例: http://127.0.0.1:11000)",
"k61a1db2": "已申请", "k61a1db2": "已申请",
"k62051fcc": "上传失败", "k62051fcc": "上传失败",
@ -165,7 +166,7 @@
"k6cc401b0": "当前没有选择任何角色组", "k6cc401b0": "当前没有选择任何角色组",
"k6cd79ab": "点击查看详情", "k6cd79ab": "点击查看详情",
"k6e4e3d7a": "已标记该群组所有消息已读", "k6e4e3d7a": "已标记该群组所有消息已读",
"k6eac768d": "添加角色", "k6eac768d": "添加身份组",
"k6ee71a71": "全局配置", "k6ee71a71": "全局配置",
"k6efe275c": "标记为已读", "k6efe275c": "标记为已读",
"k6fb230da": "等待处理的好友请求", "k6fb230da": "等待处理的好友请求",
@ -225,6 +226,7 @@
"k8f6ab535": "无法安装", "k8f6ab535": "无法安装",
"k8f6dfd40": "当前成员数", "k8f6dfd40": "当前成员数",
"k9179206d": "正在重新链接", "k9179206d": "正在重新链接",
"k924278f0": "移除用户 [{{name}}] 身份组 [{{roleName}}] 成功",
"k9277af78": "重试", "k9277af78": "重试",
"k92a84117": "认领账号", "k92a84117": "认领账号",
"k95222176": "未读", "k95222176": "未读",
@ -328,6 +330,7 @@
"kc74e5f62": "搜索成员", "kc74e5f62": "搜索成员",
"kc77e00c7": "允许成员查看面板", "kc77e00c7": "允许成员查看面板",
"kc7cc96c8": "来自", "kc7cc96c8": "来自",
"kc8c4ccbb": "授予用户 [{{name}}] 身份组 [{{roleName}}] 成功",
"kc9283683": "确定要删除面板 【{{name}}】 么", "kc9283683": "确定要删除面板 【{{name}}】 么",
"kc9bd3ad6": "重置为默认权限", "kc9bd3ad6": "重置为默认权限",
"kc9cc6154": "好友", "kc9cc6154": "好友",

@ -33,9 +33,6 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
const membersOnlineStatus = useCachedOnlineStatus( const membersOnlineStatus = useCachedOnlineStatus(
members.map((m) => m.userId) members.map((m) => m.userId)
); );
const [allowManageUser] = useHasGroupPermission(groupId, [
PERMISSION.core.manageUser,
]);
const { hideGroupMemberDiscriminator } = getGroupConfigWithInfo(groupInfo); const { hideGroupMemberDiscriminator } = getGroupConfigWithInfo(groupInfo);
const { const {
@ -102,9 +99,8 @@ export const MembersPanel: React.FC<MembersPanelProps> = React.memo((props) => {
return <div />; return <div />;
} }
if (allowManageUser) { const menu = generateActionMenu(member);
const menu: MenuProps = generateActionMenu(member); if ((menu.items ?? []).length > 0) {
return ( return (
<Dropdown key={member._id} trigger={['contextMenu']} menu={menu}> <Dropdown key={member._id} trigger={['contextMenu']} menu={menu}>
<div> <div>

@ -1,16 +1,17 @@
import { openReconfirmModalP } from '@/components/Modal'; import { openReconfirmModalP } from '@/components/Modal';
import type { MenuProps } from 'antd'; import type { MenuProps } from 'antd';
import { useCallback } from 'react';
import { import {
formatFullTime, formatFullTime,
humanizeMsDuration, humanizeMsDuration,
model, model,
PERMISSION,
showSuccessToasts, showSuccessToasts,
t, t,
useAsyncRequest, useAsyncRequest,
useEvent,
useGroupInfo, useGroupInfo,
useGroupMemberInfos, useGroupMemberInfos,
useMemoizedFn, useHasGroupPermission,
UserBaseInfo, UserBaseInfo,
useSearch, useSearch,
} from 'tailchat-shared'; } from 'tailchat-shared';
@ -23,8 +24,13 @@ import { useFriendNicknameMap } from 'tailchat-shared/redux/hooks/useFriendNickn
export function useGroupMemberAction(groupId: string) { export function useGroupMemberAction(groupId: string) {
const groupInfo = useGroupInfo(groupId); const groupInfo = useGroupInfo(groupId);
const members = groupInfo?.members ?? []; const members = groupInfo?.members ?? [];
const roles = groupInfo?.roles ?? [];
const userInfos = useGroupMemberInfos(groupId); const userInfos = useGroupMemberInfos(groupId);
const friendNicknameMap = useFriendNicknameMap(); const friendNicknameMap = useFriendNicknameMap();
const [allowManageUser, allowManageRoles] = useHasGroupPermission(groupId, [
PERMISSION.core.manageUser,
PERMISSION.core.manageRoles,
]);
const { handleMuteMember, handleUnmuteMember } = useMemberMuteAction( const { handleMuteMember, handleUnmuteMember } = useMemberMuteAction(
groupId, groupId,
@ -64,26 +70,31 @@ export function useGroupMemberAction(groupId: string) {
[groupId] [groupId]
); );
const getMemberHasMute = useCallback( const getMemberHasMute = useEvent((userId: string): boolean => {
(userId: string): boolean => { const member = members.find((m) => m.userId === userId);
const member = members.find((m) => m.userId === userId);
if (!member || !member.muteUntil) { if (!member || !member.muteUntil) {
return false; return false;
} }
const muteUntil = member.muteUntil; const muteUntil = member.muteUntil;
return new Date(muteUntil).valueOf() > new Date().valueOf(); return new Date(muteUntil).valueOf() > new Date().valueOf();
}, });
[members]
);
const generateActionMenu = useMemoizedFn( const getMemberRoles = useEvent((userId: string): string[] => {
(member: UserBaseInfo): MenuProps => { return members.find((m) => m.userId === userId)?.roles ?? [];
const hasMute = getMemberHasMute(member._id); });
const muteItems: MenuProps['items'] = hasMute /**
*
*/
const generateActionMenu = useEvent((member: UserBaseInfo): MenuProps => {
const hasMute = getMemberHasMute(member._id);
const memberRoles = getMemberRoles(member._id);
const muteItems: MenuProps['items'] = allowManageUser
? hasMute
? [ ? [
{ {
key: 'unmute', key: 'unmute',
@ -136,23 +147,71 @@ export function useGroupMemberAction(groupId: string) {
}, },
], ],
}, },
]; ]
: [];
const menu: MenuProps = {
items: _compact([ const roleItems: MenuProps['items'] =
...muteItems, allowManageRoles && roles.length > 0
{ ? [
key: 'delete', {
label: t('移出群组'), key: 'manageRole',
danger: true, label: t('分配身份组'),
onClick: () => handleRemoveGroupMember(member._id), children: roles.map((role) => ({
}, key: role._id,
] as MenuProps['items']), label: role.name,
}; className: memberRoles.includes(role._id)
? 'underline'
return menu; : undefined,
} onClick: async () => {
); // switch member role
if (memberRoles.includes(role._id)) {
// 已拥有该身份
await model.group.removeGroupMemberRoles(
groupId,
[member._id],
[role._id]
);
showSuccessToasts(
t('移除用户 [{{name}}] 身份组 [{{roleName}}] 成功', {
name: member.nickname,
roleName: role.name,
})
);
} else {
// 没有该身份
await model.group.appendGroupMemberRoles(
groupId,
[member._id],
[role._id]
);
showSuccessToasts(
t('授予用户 [{{name}}] 身份组 [{{roleName}}] 成功', {
name: member.nickname,
roleName: role.name,
})
);
}
},
})),
},
]
: [];
const menu: MenuProps = {
items: _compact([
...muteItems,
...roleItems,
allowManageUser && {
key: 'delete',
label: t('移出群组'),
danger: true,
onClick: () => handleRemoveGroupMember(member._id),
},
] as MenuProps['items']),
};
return menu;
});
return { return {
userInfos, userInfos,

Loading…
Cancel
Save