(app-desk) add role option to modal add members

When adding members to a team, the user can now
select the role of the members.
Only admin and owner can add new members to a team.
This commit is contained in:
Anthony LC
2024-03-21 12:11:18 +01:00
committed by Anthony LC
parent faf699544b
commit 159f112713
6 changed files with 71 additions and 20 deletions

View File

@@ -37,6 +37,9 @@ describe('MemberGrid', () => {
);
expect(screen.getByText('This table is empty')).toBeInTheDocument();
expect(
screen.getByLabelText('Add members to the team'),
).toBeInTheDocument();
});
it('checks the render with members', async () => {
@@ -202,4 +205,14 @@ describe('MemberGrid', () => {
expect(await screen.findByText('All broken :(')).toBeInTheDocument();
});
it('cannot add members when current role is member', () => {
render(<MemberGrid team={team} currentRole={Role.MEMBER} />, {
wrapper: AppWrapper,
});
expect(
screen.queryByLabelText('Add members to the team'),
).not.toBeInTheDocument();
});
});

View File

@@ -5,9 +5,9 @@ import { useTranslation } from 'react-i18next';
import IconUser from '@/assets/icons/icon-user.svg';
import { Box, Card, TextErrors } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { Team } from '@/features/teams/api';
import { Team } from '@/features/teams';
import { useTeamAccesses } from '../api/useTeamsAccesses';
import { useTeamAccesses } from '../api/';
import { PAGE_SIZE } from '../conf';
import { Role } from '../types';
@@ -46,19 +46,21 @@ export const MemberGrid = ({ team, currentRole }: MemberGridProps) => {
return (
<>
<Box className="m-b mb-s" $align="flex-end">
<Button
aria-label={t('Add members to the team')}
style={{
width: 'fit-content',
minWidth: '8rem',
justifyContent: 'center',
}}
onClick={() => setIsModalMemberOpen(true)}
>
{t('Add')}
</Button>
</Box>
{currentRole !== Role.MEMBER && (
<Box className="m-b mb-s" $align="flex-end">
<Button
aria-label={t('Add members to the team')}
style={{
width: 'fit-content',
minWidth: '8rem',
justifyContent: 'center',
}}
onClick={() => setIsModalMemberOpen(true)}
>
{t('Add')}
</Button>
</Box>
)}
<Card
className="m-b pb-s"
$overflow="auto"
@@ -129,6 +131,7 @@ export const MemberGrid = ({ team, currentRole }: MemberGridProps) => {
</Card>
{isModalMemberOpen && (
<ModalAddMembers
currentRole={currentRole}
onClose={() => setIsModalMemberOpen(false)}
team={team}
/>

View File

@@ -3,9 +3,12 @@ import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { createGlobalStyle } from 'styled-components';
import { Box } from '@/components';
import { Box, Text } from '@/components';
import { Team } from '@/features/teams';
import { Role } from '../types';
import { ChooseRole } from './ChooseRole';
import { OptionSelect, SearchMembers } from './SearchMembers';
const GlobalStyle = createGlobalStyle`
@@ -15,13 +18,19 @@ const GlobalStyle = createGlobalStyle`
`;
interface ModalAddMembersProps {
currentRole: Role;
onClose: () => void;
team: Team;
}
export const ModalAddMembers = ({ onClose, team }: ModalAddMembersProps) => {
export const ModalAddMembers = ({
currentRole,
onClose,
team,
}: ModalAddMembersProps) => {
const { t } = useTranslation();
const [, setSelectedMembers] = useState<OptionSelect>([]);
const [selectedMembers, setSelectedMembers] = useState<OptionSelect>([]);
const [, setSelectedRole] = useState<Role>(Role.MEMBER);
return (
<Modal
@@ -35,7 +44,12 @@ export const ModalAddMembers = ({ onClose, team }: ModalAddMembersProps) => {
closeOnClickOutside
hideCloseButton
rightActions={
<Button color="primary" fullWidth onClick={() => {}}>
<Button
color="primary"
fullWidth
disabled={!selectedMembers.length}
onClick={() => {}}
>
{t('Validate')}
</Button>
}
@@ -45,6 +59,19 @@ export const ModalAddMembers = ({ onClose, team }: ModalAddMembersProps) => {
<GlobalStyle />
<Box className="mb-xl mt-l">
<SearchMembers team={team} setSelectedMembers={setSelectedMembers} />
{selectedMembers.length > 0 && (
<Box className="mt-s">
<Text as="h4" $textAlign="left" className="mb-t">
{t('Choose a role')}
</Text>
<ChooseRole
currentRole={currentRole}
disabled={false}
defaultRole={Role.MEMBER}
setRole={setSelectedRole}
/>
</Box>
)}
</Box>
</Modal>
);

View File

@@ -12,6 +12,7 @@
"Admin": "Admin",
"Cancel": "Annuler",
"Cells icon": "Icône Cellules",
"Choose a role": "Choisissez un rôle",
"Contacts": "Contacts",
"Create a new team": "Créer un nouveau groupe",
"Create new team card": "Carte créer une nouvelle équipe",

View File

@@ -57,7 +57,7 @@ const Team = ({ id }: TeamProps) => {
return (
<>
<TeamInfo team={team} />
<MemberGrid teamId={team.id} currentRole={currentRole} />
<MemberGrid team={team} currentRole={currentRole} />
</>
);
};

View File

@@ -34,6 +34,8 @@ test.describe('Members Create', () => {
await page.getByLabel('Add members to the team').click();
await expect(page.getByRole('radio', { name: 'Owner' })).toBeHidden();
const inputSearch = page.getByLabel(/Find a member to add to the team/);
for (let i = 0; i < 2; i++) {
@@ -51,6 +53,11 @@ test.describe('Members Create', () => {
).toBeVisible();
await expect(page.getByLabel(`Remove ${users[i].name}`)).toBeVisible();
}
await expect(page.getByText(/Choose a role/)).toBeVisible();
await expect(page.getByRole('radio', { name: 'Member' })).toBeChecked();
await expect(page.getByRole('radio', { name: 'Owner' })).toBeVisible();
await expect(page.getByRole('radio', { name: 'Admin' })).toBeVisible();
});
test('it selects non existing email', async ({ page, browserName }) => {