Enhance project member invitation feature with new localization and UI updates
- Added new localization strings for "invite member" and "also invite to project" across multiple languages (Albanian, German, English, Spanish, Portuguese, Chinese). - Updated the project member invite drawer to conditionally display UI elements based on the context of the invitation (from assigner or not). - Introduced a new state management feature to track if the invitation is initiated from the assignee selector, improving user experience.
This commit is contained in:
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "Fto si anëtar",
|
||||
"inviteNewMemberByEmail": "Fto anëtar të ri me email",
|
||||
"members": "Anëtarë",
|
||||
"copyProjectLink": "Kopjo lidhjen e projektit"
|
||||
"copyProjectLink": "Kopjo lidhjen e projektit",
|
||||
"inviteMember": "Fto anëtar",
|
||||
"alsoInviteToProject": "Fto edhe në projekt"
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "Als Mitglied einladen",
|
||||
"inviteNewMemberByEmail": "Neues Mitglied per E-Mail einladen",
|
||||
"members": "Mitglieder",
|
||||
"copyProjectLink": "Projektlink kopieren"
|
||||
"copyProjectLink": "Projektlink kopieren",
|
||||
"inviteMember": "Mitglied einladen",
|
||||
"alsoInviteToProject": "Auch zum Projekt einladen"
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "Invite as a member",
|
||||
"inviteNewMemberByEmail": "Invite new member by email",
|
||||
"members": "Members",
|
||||
"copyProjectLink": "Copy project link"
|
||||
"copyProjectLink": "Copy project link",
|
||||
"inviteMember": "Invite Member",
|
||||
"alsoInviteToProject": "Also invite to project"
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "Invitar como miembro",
|
||||
"inviteNewMemberByEmail": "Invitar nuevo miembro por correo electrónico",
|
||||
"members": "Miembros",
|
||||
"copyProjectLink": "Copiar enlace del proyecto"
|
||||
"copyProjectLink": "Copiar enlace del proyecto",
|
||||
"inviteMember": "Invitar miembro",
|
||||
"alsoInviteToProject": "También invitar al proyecto"
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "Convidar como membro",
|
||||
"inviteNewMemberByEmail": "Convidar novo membro por e-mail",
|
||||
"members": "Membros",
|
||||
"copyProjectLink": "Copiar link do projeto"
|
||||
"copyProjectLink": "Copiar link do projeto",
|
||||
"inviteMember": "Convidar membro",
|
||||
"alsoInviteToProject": "Convidar também para o projeto"
|
||||
}
|
||||
|
||||
@@ -5,5 +5,7 @@
|
||||
"inviteAsAMember": "邀请为成员",
|
||||
"inviteNewMemberByEmail": "通过电子邮件邀请新成员",
|
||||
"members": "成员",
|
||||
"copyProjectLink": "复制项目链接"
|
||||
"copyProjectLink": "复制项目链接",
|
||||
"inviteMember": "邀请成员",
|
||||
"alsoInviteToProject": "也邀请到项目"
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { useAuthService } from '@/hooks/useAuth';
|
||||
import { Avatar, Button, Checkbox } from '@/components';
|
||||
import { sortTeamMembers } from '@/utils/sort-team-members';
|
||||
import { useAppDispatch } from '@/hooks/useAppDispatch';
|
||||
import { toggleProjectMemberDrawer } from '@/features/projects/singleProject/members/projectMembersSlice';
|
||||
import { setIsFromAssigner, toggleProjectMemberDrawer } from '@/features/projects/singleProject/members/projectMembersSlice';
|
||||
import { updateEnhancedKanbanTaskAssignees } from '@/features/enhanced-kanban/enhanced-kanban.slice';
|
||||
|
||||
interface AssigneeSelectorProps {
|
||||
@@ -206,6 +206,7 @@ const AssigneeSelector: React.FC<AssigneeSelectorProps> = ({
|
||||
|
||||
const handleInviteProjectMemberDrawer = () => {
|
||||
setIsOpen(false); // Close the assignee dropdown first
|
||||
dispatch(setIsFromAssigner(true));
|
||||
dispatch(toggleProjectMemberDrawer()); // Then open the invite drawer
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { teamMembersApiService } from '@/api/team-members/teamMembers.api.servic
|
||||
|
||||
const ProjectMemberDrawer = () => {
|
||||
const { t } = useTranslation('project-view/project-member-drawer');
|
||||
const { isDrawerOpen, currentMembersList, isLoading } = useAppSelector(
|
||||
const { isDrawerOpen, currentMembersList, isLoading, isFromAssigner } = useAppSelector(
|
||||
state => state.projectMemberReducer
|
||||
);
|
||||
const { projectId } = useAppSelector(state => state.projectReducer);
|
||||
@@ -176,8 +176,9 @@ const ProjectMemberDrawer = () => {
|
||||
);
|
||||
|
||||
const renderNotFoundContent = () => (
|
||||
<Flex>
|
||||
<Flex style={{ display: 'block'}}>
|
||||
<Button
|
||||
className='mb-2'
|
||||
block
|
||||
type="primary"
|
||||
onClick={sendInviteToProject}
|
||||
@@ -189,19 +190,23 @@ const ProjectMemberDrawer = () => {
|
||||
{validateEmail(searchTerm) ? t('inviteAsAMember') : t('inviteNewMemberByEmail')}
|
||||
</span>
|
||||
</Button>
|
||||
{isFromAssigner && <Flex>
|
||||
<input className='mr-2' type="checkbox" checked={true} name={t('alsoInviteToProject')} id="AlsoInviteToProject" />
|
||||
<label htmlFor={t('alsoInviteToProject')}>{t('alsoInviteToProject')}</label>
|
||||
</Flex>}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
<Typography.Text style={{ fontWeight: 500, fontSize: 16 }}>{t('title')}</Typography.Text>
|
||||
<Typography.Text style={{ fontWeight: 500, fontSize: 16 }}>{isFromAssigner ? t('inviteMember') : t('title')}</Typography.Text>
|
||||
}
|
||||
open={isDrawerOpen}
|
||||
onCancel={() => dispatch(toggleProjectMemberDrawer())}
|
||||
afterOpenChange={handleOpenChange}
|
||||
footer={
|
||||
<Button
|
||||
!isFromAssigner && <Button
|
||||
style={{ width: 140, fontSize: 12 }}
|
||||
block
|
||||
icon={<LinkOutlined />}
|
||||
@@ -232,7 +237,7 @@ const ProjectMemberDrawer = () => {
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8 }}>{t('members')}</div>
|
||||
{!isFromAssigner && <><div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8 }}>{t('members')}</div>
|
||||
<div style={{ maxHeight: 360, minHeight: 120, overflowY: 'auto', marginBottom: 16 }}>
|
||||
<List
|
||||
loading={isLoading}
|
||||
@@ -248,7 +253,8 @@ const ProjectMemberDrawer = () => {
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div></>
|
||||
}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ interface ProjectMembersState {
|
||||
currentMembersList: IMentionMemberViewModel[];
|
||||
isDrawerOpen: boolean;
|
||||
isLoading: boolean;
|
||||
isFromAssigner: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
@@ -16,6 +17,7 @@ const initialState: ProjectMembersState = {
|
||||
currentMembersList: [],
|
||||
isDrawerOpen: false,
|
||||
isLoading: false,
|
||||
isFromAssigner: false,
|
||||
error: null,
|
||||
};
|
||||
|
||||
@@ -89,6 +91,12 @@ const projectMembersSlice = createSlice({
|
||||
reducers: {
|
||||
toggleProjectMemberDrawer: state => {
|
||||
state.isDrawerOpen = !state.isDrawerOpen;
|
||||
if (state.isDrawerOpen === false) {
|
||||
state.isFromAssigner = false;
|
||||
}
|
||||
},
|
||||
setIsFromAssigner: (state, action: PayloadAction<boolean>) => {
|
||||
state.isFromAssigner = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: builder => {
|
||||
@@ -139,7 +147,7 @@ const projectMembersSlice = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const { toggleProjectMemberDrawer } = projectMembersSlice.actions;
|
||||
export const { toggleProjectMemberDrawer, setIsFromAssigner } = projectMembersSlice.actions;
|
||||
export {
|
||||
getProjectMembers,
|
||||
getAllProjectMembers,
|
||||
|
||||
Reference in New Issue
Block a user