(app-desk) add modal for adding members to a team

Create the button to open the modal.
Add a modal for adding members to a team.
This modal will open thanks to a dedicated page.
This commit is contained in:
Anthony LC
2024-03-18 11:36:48 +01:00
committed by Anthony LC
parent 4a141736ff
commit 2f8801f7eb
6 changed files with 148 additions and 66 deletions

View File

@@ -441,3 +441,8 @@ input:-webkit-autofill:focus {
.c__modal__backdrop {
z-index: 1000;
}
.c__modal__close .c__button--tertiary-text:hover,
.c__modal__close .c__button--tertiary-text:focus-visible {
box-shadow: none;
}

View File

@@ -1,5 +1,5 @@
import { DataGrid, usePagination } from '@openfun/cunningham-react';
import React, { useEffect } from 'react';
import { Button, DataGrid, usePagination } from '@openfun/cunningham-react';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import IconUser from '@/assets/icons/icon-user.svg';
@@ -11,6 +11,7 @@ import { PAGE_SIZE } from '../conf';
import { Role } from '../types';
import { MemberAction } from './MemberAction';
import { ModalAddMembers } from './ModalAddMembers';
interface MemberGridProps {
teamId: string;
@@ -18,6 +19,7 @@ interface MemberGridProps {
}
export const MemberGrid = ({ teamId, currentRole }: MemberGridProps) => {
const [isModalMemberOpen, setIsModalMemberOpen] = useState(false);
const { t } = useTranslation();
const { colorsTokens } = useCunninghamTheme();
const pagination = usePagination({
@@ -42,73 +44,91 @@ export const MemberGrid = ({ teamId, currentRole }: MemberGridProps) => {
};
return (
<Card
className="m-b pb-s"
$overflow="auto"
$css={`
margin-top:0;
& .c__pagination__goto {
display: none;
}
& table th:first-child,
& table td:first-child {
padding-right: 0;
width: 0;
}
<>
<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"
$css={`
margin-top:0;
& .c__pagination__goto {
display: none;
}
& table th:first-child,
& table td:first-child {
padding-right: 0;
width: 0;
}
`}
aria-label={t('List members card')}
>
{error && <TextErrors causes={error.cause} />}
aria-label={t('List members card')}
>
{error && <TextErrors causes={error.cause} />}
<DataGrid
columns={[
{
id: 'icon-user',
renderCell() {
return (
<Box $direction="row" $align="center">
<IconUser
aria-label={t('Member icon')}
width={20}
height={20}
color={colorsTokens()['primary-600']}
<DataGrid
columns={[
{
id: 'icon-user',
renderCell() {
return (
<Box $direction="row" $align="center">
<IconUser
aria-label={t('Member icon')}
width={20}
height={20}
color={colorsTokens()['primary-600']}
/>
</Box>
);
},
},
{
headerName: t('Names'),
field: 'user.name',
},
{
field: 'user.email',
headerName: t('Emails'),
},
{
id: 'role',
headerName: t('Roles'),
renderCell({ row }) {
return dictRole[row.role];
},
},
{
id: 'column-actions',
renderCell: ({ row }) => {
return (
<MemberAction
teamId={teamId}
access={row}
currentRole={currentRole}
/>
</Box>
);
);
},
},
},
{
headerName: t('Names'),
field: 'user.name',
},
{
field: 'user.email',
headerName: t('Emails'),
},
{
id: 'role',
headerName: t('Roles'),
renderCell({ row }) {
return dictRole[row.role];
},
},
{
id: 'column-actions',
renderCell: ({ row }) => {
return (
<MemberAction
teamId={teamId}
access={row}
currentRole={currentRole}
/>
);
},
},
]}
rows={accesses || []}
isLoading={isLoading}
pagination={pagination}
/>
</Card>
]}
rows={accesses || []}
isLoading={isLoading}
pagination={pagination}
/>
</Card>
{isModalMemberOpen && (
<ModalAddMembers onClose={() => setIsModalMemberOpen(false)} />
)}
</>
);
};

View File

@@ -0,0 +1,31 @@
import { Button, Modal, ModalSize } from '@openfun/cunningham-react';
import { useTranslation } from 'react-i18next';
interface ModalAddMembersProps {
onClose: () => void;
}
export const ModalAddMembers = ({ onClose }: ModalAddMembersProps) => {
const { t } = useTranslation();
return (
<Modal
isOpen
leftActions={
<Button color="secondary" fullWidth onClick={onClose}>
{t('Cancel')}
</Button>
}
onClose={onClose}
closeOnClickOutside
hideCloseButton
rightActions={
<Button color="primary" fullWidth onClick={() => {}}>
{t('Validate')}
</Button>
}
size={ModalSize.MEDIUM}
title={t('Add members to the team')}
></Modal>
);
};

View File

@@ -1,2 +1,3 @@
export * from './types';
export * from './components/MemberGrid';
export * from './components/ModalAddMembers';

View File

@@ -4,7 +4,9 @@
"0 group to display.": "0 groupe à afficher.",
"404 - Page not found": "404 - Page introuvable",
"Access to the cells menu": "Accès au menu cellules",
"Add": "Ajouter",
"Add a team": "Ajouter un groupe",
"Add members to the team": "Ajoutez des membres à votre groupe",
"Add people to the “{{teamName}}“ group.": "Ajouter des personnes au groupe “{{teamName}}“.",
"Add team icon": "Icône ajout de groupe",
"Admin": "Admin",

View File

@@ -0,0 +1,23 @@
import { expect, test } from '@playwright/test';
import { createTeam, keyCloakSignIn } from './common';
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/');
await keyCloakSignIn(page, browserName);
});
test.describe('Members Create', () => {
test('it opens the modals to add a member to the team', async ({
page,
browserName,
}) => {
await createTeam(page, 'member-open-modal', browserName, 1);
await page.getByLabel('Add members to the team').click();
await expect(page.getByText('Add members to the team')).toBeVisible();
await expect(page.getByRole('button', { name: 'Validate' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Cancel' })).toBeVisible();
});
});