This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
people/src/frontend/apps/desk/src/features/mail-domains/components/MailDomainsContent.tsx
daproclaima 45dbdd6c4c (frontend) restrict mailbox creation
- update mailbox creation feature by introducing the use of
new mail domain ability field to hide or show
mailbox creation button
- update related e2e tests
2024-08-08 13:53:07 +02:00

165 lines
4.4 KiB
TypeScript

import {
Button,
DataGrid,
Loader,
SortModel,
usePagination,
} from '@openfun/cunningham-react';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Box, Card, Text, TextErrors } from '@/components';
import { useMailboxes } from '../api/useMailboxes';
import { default as MailDomainsLogo } from '../assets/mail-domains-logo.svg';
import { PAGE_SIZE } from '../conf';
import { MailDomain, MailDomainMailbox } from '../types';
import { CreateMailboxForm } from './forms/CreateMailboxForm';
export type ViewMailbox = { email: string; id: string };
// FIXME : ask Cunningham to export this type
type SortModelItem = {
field: string;
sort: 'asc' | 'desc' | null;
};
const defaultOrderingMapping: Record<string, string> = {
email: 'local_part',
};
/**
* Formats the sorting model based on a given mapping.
* @param {SortModelItem} sortModel The sorting model item containing field and sort direction.
* @param {Record<string, string>} mapping The mapping object to map field names.
* @returns {string} The formatted sorting string.
*/
function formatSortModel(
sortModel: SortModelItem,
mapping = defaultOrderingMapping,
) {
const { field, sort } = sortModel;
const orderingField = mapping[field] || field;
return sort === 'desc' ? `-${orderingField}` : orderingField;
}
export function MailDomainsContent({ mailDomain }: { mailDomain: MailDomain }) {
const [sortModel, setSortModel] = useState<SortModel>([]);
const [isCreateMailboxFormVisible, setIsCreateMailboxFormVisible] =
useState(false);
const { t } = useTranslation();
const pagination = usePagination({
defaultPage: 1,
pageSize: PAGE_SIZE,
});
const { page, pageSize, setPagesCount } = pagination;
const ordering = sortModel.length ? formatSortModel(sortModel[0]) : undefined;
const { data, isLoading, error } = useMailboxes({
mailDomainSlug: mailDomain.slug,
page,
ordering,
});
const viewMailboxes: ViewMailbox[] =
mailDomain && data?.results?.length
? data.results.map((mailbox: MailDomainMailbox) => ({
email: `${mailbox.local_part}@${mailDomain.name}`,
id: mailbox.id,
}))
: [];
useEffect(() => {
setPagesCount(data?.count ? Math.ceil(data.count / pageSize) : 0);
}, [data?.count, pageSize, setPagesCount]);
return isLoading ? (
<Box $align="center" $justify="center" $height="100%">
<Loader />
</Box>
) : (
<>
{isCreateMailboxFormVisible && mailDomain ? (
<CreateMailboxForm
mailDomain={mailDomain}
closeModal={() => setIsCreateMailboxFormVisible(false)}
/>
) : null}
<TopBanner
name={mailDomain.name}
setIsFormVisible={setIsCreateMailboxFormVisible}
abilities={mailDomain.abilities}
/>
<Card
$padding={{ bottom: 'small' }}
$margin={{ all: 'big', top: 'none' }}
$overflow="auto"
>
{error && <TextErrors causes={error.cause} />}
<DataGrid
columns={[
{
field: 'email',
headerName: t('Emails'),
},
]}
rows={viewMailboxes}
isLoading={isLoading}
onSortModelChange={setSortModel}
sortModel={sortModel}
pagination={{
...pagination,
displayGoto: false,
}}
aria-label={t('Mailboxes list')}
hideEmptyPlaceholderImage={true}
emptyPlaceholderLabel={t(
'No mail box was created with this mail domain.',
)}
/>
</Card>
</>
);
}
const TopBanner = ({
name,
setIsFormVisible,
abilities,
}: {
name: string;
setIsFormVisible: (value: boolean) => void;
abilities: MailDomain['abilities'];
}) => {
const { t } = useTranslation();
return (
<>
<Box
$direction="row"
$align="center"
$margin={{ all: 'big', vertical: 'xbig' }}
$gap="2.25rem"
>
<MailDomainsLogo aria-hidden="true" />
<Text $margin="none" as="h3" $size="h3">
{name}
</Text>
</Box>
<Box $margin={{ all: 'big', bottom: 'small' }} $align="flex-end">
{abilities.post ? (
<Button
aria-label={t(`Create a mailbox in {{name}} domain`, { name })}
onClick={() => setIsFormVisible(true)}
>
{t('Create a mailbox')}
</Button>
) : null}
</Box>
</>
);
};