* add manager change memberName and update inform UI

* change icon and some inform ui

* change for comment

* fix for comment
This commit is contained in:
gggaaallleee
2025-03-27 10:04:29 +08:00
committed by GitHub
parent 29a10c1389
commit cb29076e5b
25 changed files with 474 additions and 189 deletions

View File

@@ -0,0 +1,73 @@
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useTranslation } from 'next-i18next';
import Markdown from '@/components/Markdown';
import React from 'react';
import { Box, Flex } from '@chakra-ui/react';
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
import MyTag from '@fastgpt/web/components/common/Tag/index';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
const NotificationDetailsModal = ({ inform, onClose }: { inform: any; onClose: () => void }) => {
const { t } = useTranslation();
const textStyles = {
title: {
color: 'grayModern.900',
fontSize: '20px',
fontWeight: 'medium',
lineHeight: 6,
letterSpacing: '0.15px'
},
time: {
color: 'grayModern.500',
fontSize: '12px',
lineHeight: 5,
letterSpacing: '0.25px'
}
};
return (
<MyModal
isOpen={!!inform}
iconSrc={'support/user/informLight'}
title={t('account_inform:notification_detail')}
onClose={onClose}
iconColor="blue.600"
maxW="680px"
maxH="80vh"
>
<Flex flexDirection="column" p={8}>
<Flex
{...textStyles.time}
fontFamily="PingFang SC"
display="flex"
justifyContent="space-between"
alignItems="center"
alignSelf="stretch"
>
<Box {...textStyles.title} fontFamily="PingFang SC">
{inform.title}
</Box>
<Box {...textStyles.time} ml={3} flex={1} fontFamily="PingFang SC">
{t(formatTimeToChatTime(inform.time) as any).replace('#', ':')}
</Box>
<MyTag
colorSchema={inform.teamId ? 'green' : 'blue'}
mr={2}
fontSize="xs"
fontWeight="medium"
showDot={false}
type="fill"
>
{inform.teamId ? t('account_inform:team') : t('account_inform:system')}
</MyTag>
</Flex>
<MyDivider my={4} />
<Box fontSize="sm" lineHeight={1.8}>
<Markdown source={inform?.content} />
</Box>
</Flex>
</MyModal>
);
};
export default React.memo(NotificationDetailsModal);

View File

@@ -17,7 +17,12 @@ import {
import { useTranslation } from 'next-i18next';
import { useUserStore } from '@/web/support/user/useUserStore';
import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import { delRemoveMember, postRestoreMember } from '@/web/support/user/team/api';
import { useEditTextarea } from '@fastgpt/web/hooks/useEditTextarea';
import {
delRemoveMember,
postRestoreMember,
putUpdateMemberNameByManager
} from '@/web/support/user/team/api';
import Tag from '@fastgpt/web/components/common/Tag';
import Icon from '@fastgpt/web/components/common/Icon';
import { useContextSelector } from 'use-context-selector';
@@ -40,6 +45,7 @@ import OrgTags from '@/components/support/user/team/OrgTags';
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
import { useState } from 'react';
import { downloadFetch } from '@/web/common/system/utils';
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
const InviteModal = dynamic(() => import('./Invite/InviteModal'));
const TeamTagModal = dynamic(() => import('@/components/support/user/team/TeamTagModal'));
@@ -128,6 +134,30 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
const isLoading = isUpdateInvite || isSyncing;
const { EditModal: EditMemberNameModal, onOpenModal: openEditMemberName } = useEditTextarea({
title: t('account_team:edit_member'),
tip: t('account_team:edit_member_tip'),
canEmpty: false,
rows: 1
});
const handleEditMemberName = (tmbId: string, memberName: string) => {
openEditMemberName({
defaultVal: memberName,
onSuccess: (newName: string) => {
return putUpdateMemberNameByManager(tmbId, newName).then(() => {
Promise.all([refetchGroups(), refetchMembers()]);
});
},
onError: (err) => {
toast({
title: '',
status: 'error'
});
}
});
};
return (
<>
{isLoading && <MyLoading />}
@@ -222,7 +252,9 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{t('account_team:user_name')}
</Th>
<Th bgColor="myGray.100">{t('common:contact_way')}</Th>
<Th bgColor="myGray.100">{t('account_team:org')}</Th>
<Th bgColor="myGray.100" pl={9}>
{t('account_team:org')}
</Th>
<Th bgColor="myGray.100">{t('account_team:join_update_time')}</Th>
<Th borderRightRadius="6px" bgColor="myGray.100">
{t('common:common.Action')}
@@ -262,7 +294,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
})()}
</Td>
<Td maxW={'300px'}>
<VStack gap={0}>
<VStack gap={0} alignItems="flex-start">
<Box>{format(new Date(member.createTime), 'yyyy-MM-dd HH:mm:ss')}</Box>
<Box>
{member.updateTime
@@ -276,29 +308,45 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
member.role !== TeamMemberRoleEnum.owner &&
member.tmbId !== userInfo?.team.tmbId &&
(member.status === TeamMemberStatusEnum.active ? (
<Icon
name={'common/trash'}
cursor={'pointer'}
w="1rem"
p="1"
borderRadius="sm"
_hover={{
color: 'red.600',
bgColor: 'myGray.100'
}}
onClick={() => {
openRemoveMember(
() =>
delRemoveMember(member.tmbId).then(() =>
Promise.all([refetchGroups(), refetchMembers()])
),
undefined,
t('account_team:remove_tip', {
username: member.memberName
})
)();
}}
/>
<>
<Icon
name={'edit'}
cursor={'pointer'}
w="1rem"
p="1"
borderRadius="sm"
_hover={{
color: 'blue.600',
bgColor: 'myGray.100'
}}
onClick={() =>
handleEditMemberName(member.tmbId, member.memberName)
}
/>
<Icon
name={'common/trash'}
cursor={'pointer'}
w="1rem"
p="1"
borderRadius="sm"
_hover={{
color: 'red.600',
bgColor: 'myGray.100'
}}
onClick={() => {
openRemoveMember(
() =>
delRemoveMember(member.tmbId).then(() =>
Promise.all([refetchGroups(), refetchMembers()])
),
undefined,
t('account_team:remove_tip', {
username: member.memberName
})
)();
}}
/>
</>
) : (
member.status === TeamMemberStatusEnum.forbidden && (
<Icon
@@ -331,6 +379,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
</Table>
<ConfirmRemoveMemberModal />
<ConfirmRestoreMemberModal />
<EditMemberNameModal />
</TableContainer>
</MemberScrollData>
</Box>