✨(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:
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -57,7 +57,7 @@ const Team = ({ id }: TeamProps) => {
|
||||
return (
|
||||
<>
|
||||
<TeamInfo team={team} />
|
||||
<MemberGrid teamId={team.id} currentRole={currentRole} />
|
||||
<MemberGrid team={team} currentRole={currentRole} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
Reference in New Issue
Block a user