Enhance project member drawer localization and UI
- Added new localization strings for "members" and "copy project link" in multiple languages (Albanian, German, English, Spanish, Portuguese, Chinese). - Updated the project member invite drawer to use a modal instead of a drawer for improved user experience. - Included a button in the modal footer for copying the project link, enhancing functionality for users.
This commit is contained in:
@@ -3,5 +3,7 @@
|
||||
"searchLabel": "Shtoni anëtarë duke shkruar emrin ose email-in e tyre",
|
||||
"searchPlaceholder": "Shkruani emrin ose email-in",
|
||||
"inviteAsAMember": "Fto si anëtar",
|
||||
"inviteNewMemberByEmail": "Fto anëtar të ri me email"
|
||||
"inviteNewMemberByEmail": "Fto anëtar të ri me email",
|
||||
"members": "Anëtarë",
|
||||
"copyProjectLink": "Kopjo lidhjen e projektit"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
"searchLabel": "Mitglieder hinzufügen durch Eingabe von Name oder E-Mail",
|
||||
"searchPlaceholder": "Name oder E-Mail eingeben",
|
||||
"inviteAsAMember": "Als Mitglied einladen",
|
||||
"inviteNewMemberByEmail": "Neues Mitglied per E-Mail einladen"
|
||||
"inviteNewMemberByEmail": "Neues Mitglied per E-Mail einladen",
|
||||
"members": "Mitglieder",
|
||||
"copyProjectLink": "Projektlink kopieren"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"title": "Project Members",
|
||||
"title": "Share Project",
|
||||
"searchLabel": "Add members by adding their name or email",
|
||||
"searchPlaceholder": "Type name or email",
|
||||
"inviteAsAMember": "Invite as a member",
|
||||
"inviteNewMemberByEmail": "Invite new member by email"
|
||||
"inviteNewMemberByEmail": "Invite new member by email",
|
||||
"members": "Members",
|
||||
"copyProjectLink": "Copy project link"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
"searchLabel": "Agregar miembros ingresando su nombre o correo electrónico",
|
||||
"searchPlaceholder": "Escriba nombre o correo electrónico",
|
||||
"inviteAsAMember": "Invitar como miembro",
|
||||
"inviteNewMemberByEmail": "Invitar nuevo miembro por correo electrónico"
|
||||
"inviteNewMemberByEmail": "Invitar nuevo miembro por correo electrónico",
|
||||
"members": "Miembros",
|
||||
"copyProjectLink": "Copiar enlace del proyecto"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
"searchLabel": "Adicionar membros inserindo nome ou e-mail",
|
||||
"searchPlaceholder": "Digite nome ou e-mail",
|
||||
"inviteAsAMember": "Convidar como membro",
|
||||
"inviteNewMemberByEmail": "Convidar novo membro por e-mail"
|
||||
"inviteNewMemberByEmail": "Convidar novo membro por e-mail",
|
||||
"members": "Membros",
|
||||
"copyProjectLink": "Copiar link do projeto"
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
"searchLabel": "通过添加名称或电子邮件添加成员",
|
||||
"searchPlaceholder": "输入名称或电子邮件",
|
||||
"inviteAsAMember": "邀请为成员",
|
||||
"inviteNewMemberByEmail": "通过电子邮件邀请新成员"
|
||||
"inviteNewMemberByEmail": "通过电子邮件邀请新成员",
|
||||
"members": "成员",
|
||||
"copyProjectLink": "复制项目链接"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Drawer, Flex, Form, Select, Typography, List, Button } from 'antd/es';
|
||||
import { Drawer, Flex, Form, Select, Typography, List, Button, Modal, Divider } from 'antd/es';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from '@/features/projects/singleProject/members/projectMembersSlice';
|
||||
import SingleAvatar from '@/components/common/single-avatar/single-avatar';
|
||||
import { DeleteOutlined, MailOutlined } from '@ant-design/icons';
|
||||
import { LinkOutlined } from '@ant-design/icons';
|
||||
import { getTeamMembers } from '@/features/team-members/team-members.slice';
|
||||
import logger from '@/utils/errorLogger';
|
||||
import { validateEmail } from '@/utils/validateEmail';
|
||||
@@ -192,56 +193,63 @@ const ProjectMemberDrawer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
title={
|
||||
<Typography.Text style={{ fontWeight: 500, fontSize: 16 }}>{t('title')}</Typography.Text>
|
||||
}
|
||||
open={isDrawerOpen}
|
||||
onClose={() => dispatch(toggleProjectMemberDrawer())}
|
||||
afterOpenChange={handleOpenChange}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleSelectChange}>
|
||||
<Form.Item name="memberName" label={t('searchLabel')}>
|
||||
<Select
|
||||
loading={teamMembersLoading}
|
||||
placeholder={t('searchPlaceholder')}
|
||||
showSearch
|
||||
onSearch={handleSearch}
|
||||
onChange={handleSelectChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
options={members?.data?.map(member => ({
|
||||
key: member.id,
|
||||
value: member.id,
|
||||
name: member.name,
|
||||
label: renderMemberOption(member),
|
||||
}))}
|
||||
filterOption={false}
|
||||
notFoundContent={renderNotFoundContent()}
|
||||
optionLabelProp="name"
|
||||
<Modal
|
||||
title={
|
||||
<Typography.Text style={{ fontWeight: 500, fontSize: 16 }}>{t('title')}</Typography.Text>
|
||||
}
|
||||
open={isDrawerOpen}
|
||||
onCancel={() => dispatch(toggleProjectMemberDrawer())}
|
||||
afterOpenChange={handleOpenChange}
|
||||
footer={
|
||||
<Button
|
||||
style={{ width: 140, fontSize: 12 }}
|
||||
block
|
||||
icon={<LinkOutlined />}
|
||||
disabled
|
||||
>
|
||||
{t('copyProjectLink')}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleSelectChange}>
|
||||
<Form.Item name="memberName" label={t('searchLabel')}>
|
||||
<Select
|
||||
loading={teamMembersLoading}
|
||||
placeholder={t('searchPlaceholder')}
|
||||
showSearch
|
||||
onSearch={handleSearch}
|
||||
onChange={handleSelectChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
options={members?.data?.map(member => ({
|
||||
key: member.id,
|
||||
value: member.id,
|
||||
name: member.name,
|
||||
label: renderMemberOption(member),
|
||||
}))}
|
||||
filterOption={false}
|
||||
notFoundContent={renderNotFoundContent()}
|
||||
optionLabelProp="name"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8 }}>{t('members')}</div>
|
||||
<div style={{ maxHeight: 360, minHeight: 120, overflowY: 'auto', marginBottom: 16 }}>
|
||||
<List
|
||||
loading={isLoading}
|
||||
bordered
|
||||
size="small"
|
||||
itemLayout="horizontal"
|
||||
dataSource={currentMembersList}
|
||||
renderItem={member => (
|
||||
<List.Item key={member.id} >
|
||||
<Flex gap={4} align="center" justify="space-between" style={{ width: '100%' }}>
|
||||
{renderMemberOption(member)}
|
||||
</Flex>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
|
||||
<List
|
||||
loading={isLoading}
|
||||
bordered
|
||||
size="small"
|
||||
itemLayout="horizontal"
|
||||
dataSource={currentMembersList}
|
||||
renderItem={member => (
|
||||
<List.Item key={member.id}>
|
||||
<Flex gap={4} align="center" justify="space-between" style={{ width: '100%' }}>
|
||||
{renderMemberOption(member)}
|
||||
<Button
|
||||
onClick={() => handleDeleteMember(member.id)}
|
||||
size="small"
|
||||
icon={<DeleteOutlined />}
|
||||
/>
|
||||
</Flex>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Drawer>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user