✨(app-desk) integrate teams panel design
- Integrate teams panel design based from the mockup. - List teams from the API.
This commit is contained in:
@@ -3,6 +3,7 @@ const config = {
|
||||
default: {
|
||||
theme: {
|
||||
colors: {
|
||||
'primary-bg': '#FAFAFA',
|
||||
'primary-100': '#EDF5FA',
|
||||
'primary-150': '#E5EEFA',
|
||||
'info-150': '#E5EEFA',
|
||||
@@ -259,6 +260,16 @@ const config = {
|
||||
},
|
||||
button: {
|
||||
'border-radius': '2px',
|
||||
primary: {
|
||||
background: {
|
||||
color: 'var(--c--theme--colors--primary-text)',
|
||||
'color-hover': 'var(--c--theme--colors--primary-700)',
|
||||
'color-active': 'var(--c--theme--colors--primary-900)',
|
||||
},
|
||||
color: '#ffffff',
|
||||
'color-hover': '#ffffff',
|
||||
'color-active': '#ffffff',
|
||||
},
|
||||
},
|
||||
'forms-checkbox': {
|
||||
'border-radius': '0',
|
||||
|
||||
@@ -11,8 +11,10 @@ describe('Page', () => {
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
|
||||
'Hello Desk !',
|
||||
);
|
||||
expect(
|
||||
screen.getByRole('button', {
|
||||
name: /Create a new team/i,
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
'use client';
|
||||
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Box } from '@/components';
|
||||
import { Teams } from '@/features';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
import { Panel } from '@/features';
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
width: fit-content;
|
||||
`;
|
||||
|
||||
export default function Home() {
|
||||
const { t } = useTranslation();
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
|
||||
return (
|
||||
<Box className="p-b">
|
||||
<h1>{t('Hello Desk !')}</h1>
|
||||
<Teams />
|
||||
<Box $height="inherit" $direction="row">
|
||||
<Panel />
|
||||
<Box
|
||||
$background={colorsTokens()['primary-bg']}
|
||||
$justify="center"
|
||||
$align="center"
|
||||
$width="100%"
|
||||
>
|
||||
<StyledButton>{t('Create a new group')}</StyledButton>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1020 B After Width: | Height: | Size: 1020 B |
@@ -14,6 +14,7 @@ export interface TextProps extends BoxProps {
|
||||
'p' | 'span' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
|
||||
>;
|
||||
$weight?: CSSProperties['fontWeight'];
|
||||
$textAlign?: CSSProperties['textAlign'];
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
$size?: TextSizes | (string & {});
|
||||
$theme?:
|
||||
@@ -38,6 +39,7 @@ export interface TextProps extends BoxProps {
|
||||
}
|
||||
|
||||
export const TextStyled = styled(Box)<TextProps>`
|
||||
${({ $textAlign }) => $textAlign && `text-align: ${$textAlign};`}
|
||||
${({ $weight }) => $weight && `font-weight: ${$weight};`}
|
||||
${({ $size }) =>
|
||||
$size &&
|
||||
|
||||
@@ -272,6 +272,13 @@ input:-webkit-autofill:focus {
|
||||
color: var(--c--components--button--primary--color);
|
||||
}
|
||||
|
||||
.c__button--primary:hover {
|
||||
background-color: var(
|
||||
--c--components--button--primary--background--color-hover
|
||||
);
|
||||
color: var(--c--components--button--primary--color-hover);
|
||||
}
|
||||
|
||||
.c__button--primary:active,
|
||||
.c__button--primary.c__button--active {
|
||||
background-color: var(
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
--c--theme--colors--success-text: var(--c--theme--colors--greyscale-000);
|
||||
--c--theme--colors--warning-text: var(--c--theme--colors--greyscale-000);
|
||||
--c--theme--colors--danger-text: var(--c--theme--colors--greyscale-000);
|
||||
--c--theme--colors--primary-bg: #fafafa;
|
||||
--c--theme--colors--primary-150: #e5eefa;
|
||||
--c--theme--colors--info-150: #e5eefa;
|
||||
--c--theme--font--sizes--h1: 2.2rem;
|
||||
@@ -387,6 +388,18 @@
|
||||
--c--theme--font--families--base: marianne;
|
||||
--c--components--alert--border-radius: 0;
|
||||
--c--components--button--border-radius: 2px;
|
||||
--c--components--button--primary--background--color: var(
|
||||
--c--theme--colors--primary-text
|
||||
);
|
||||
--c--components--button--primary--background--color-hover: var(
|
||||
--c--theme--colors--primary-700
|
||||
);
|
||||
--c--components--button--primary--background--color-active: var(
|
||||
--c--theme--colors--primary-900
|
||||
);
|
||||
--c--components--button--primary--color: #fff;
|
||||
--c--components--button--primary--color-hover: #fff;
|
||||
--c--components--button--primary--color-active: #fff;
|
||||
--c--components--forms-checkbox--border-radius: 0;
|
||||
--c--components--forms-switch--handle-border-radius: 2px;
|
||||
--c--components--forms-switch--rail-border-radius: 4px;
|
||||
@@ -677,6 +690,10 @@
|
||||
color: var(--c--theme--colors--danger-text);
|
||||
}
|
||||
|
||||
.clr-primary-bg {
|
||||
color: var(--c--theme--colors--primary-bg);
|
||||
}
|
||||
|
||||
.clr-primary-150 {
|
||||
color: var(--c--theme--colors--primary-150);
|
||||
}
|
||||
@@ -965,6 +982,10 @@
|
||||
background-color: var(--c--theme--colors--danger-text);
|
||||
}
|
||||
|
||||
.bg-primary-bg {
|
||||
background-color: var(--c--theme--colors--primary-bg);
|
||||
}
|
||||
|
||||
.bg-primary-150 {
|
||||
background-color: var(--c--theme--colors--primary-150);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ export const tokens = {
|
||||
'success-text': '#FFFFFF',
|
||||
'warning-text': '#FFFFFF',
|
||||
'danger-text': '#FFFFFF',
|
||||
'primary-bg': '#FAFAFA',
|
||||
'primary-150': '#E5EEFA',
|
||||
'info-150': '#E5EEFA',
|
||||
},
|
||||
@@ -396,7 +397,19 @@ export const tokens = {
|
||||
},
|
||||
components: {
|
||||
alert: { 'border-radius': '0' },
|
||||
button: { 'border-radius': '2px' },
|
||||
button: {
|
||||
'border-radius': '2px',
|
||||
primary: {
|
||||
background: {
|
||||
color: 'var(--c--theme--colors--primary-text)',
|
||||
'color-hover': 'var(--c--theme--colors--primary-700)',
|
||||
'color-active': 'var(--c--theme--colors--primary-900)',
|
||||
},
|
||||
color: '#ffffff',
|
||||
'color-hover': '#ffffff',
|
||||
'color-active': '#ffffff',
|
||||
},
|
||||
},
|
||||
'forms-checkbox': { 'border-radius': '0' },
|
||||
'forms-switch': {
|
||||
'handle-border-radius': '2px',
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import IconGroup from '@/assets/icons/icon-group.svg';
|
||||
import { Box } from '@/components/';
|
||||
import useCunninghamTheme from '@/cunningham/useCunninghamTheme';
|
||||
|
||||
import MenuItem from './MenuItems';
|
||||
import IconRecent from './assets/icon-clock.svg';
|
||||
import IconContacts from './assets/icon-contacts.svg';
|
||||
import IconGroup from './assets/icon-group.svg';
|
||||
import IconSearch from './assets/icon-search.svg';
|
||||
import IconFavorite from './assets/icon-stars.svg';
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
import { PanelTeams } from '../components/PanelTeams';
|
||||
|
||||
describe('PanelTeams', () => {
|
||||
afterEach(() => {
|
||||
fetchMock.restore();
|
||||
});
|
||||
|
||||
it('renders with no team to display', async () => {
|
||||
fetchMock.mock(`/api/teams/?page=1&ordering=-created_at`, {
|
||||
count: 0,
|
||||
results: [],
|
||||
});
|
||||
|
||||
render(<PanelTeams />, { wrapper: AppWrapper });
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
'Create your first team by clicking on the "Create a new team" button.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders with empty team to display', async () => {
|
||||
fetchMock.mock(`/api/teams/?page=1&ordering=-created_at`, {
|
||||
count: 1,
|
||||
results: [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Team 1',
|
||||
accesses: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
render(<PanelTeams />, { wrapper: AppWrapper });
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByLabelText('Empty team icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders with not team to display', async () => {
|
||||
fetchMock.mock(`/api/teams/?page=1&ordering=-created_at`, {
|
||||
count: 1,
|
||||
results: [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Team 1',
|
||||
accesses: [
|
||||
{
|
||||
id: '1',
|
||||
role: 'admin',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
render(<PanelTeams />, { wrapper: AppWrapper });
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(await screen.findByLabelText('Team icon')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the error', async () => {
|
||||
fetchMock.mock(`/api/teams/?page=1&ordering=-created_at`, {
|
||||
status: 500,
|
||||
});
|
||||
|
||||
render(<PanelTeams />, { wrapper: AppWrapper });
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
'Something bad happens, please refresh the page.',
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import fetchMock from 'fetch-mock';
|
||||
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
import { Teams } from '..';
|
||||
|
||||
describe('Teams', () => {
|
||||
afterEach(() => {
|
||||
fetchMock.restore();
|
||||
});
|
||||
|
||||
it('checks Teams rendering', async () => {
|
||||
fetchMock.mock(`/api/teams/`, {
|
||||
results: [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Team 1',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Team 2',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
render(<Teams />, { wrapper: AppWrapper });
|
||||
|
||||
expect(screen.getByRole('status')).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
await screen.findByRole('button', {
|
||||
name: 'Create Team',
|
||||
}),
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText(/Team 1/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Team 2/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -2,9 +2,22 @@ import { UseQueryOptions, useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { APIList, fetchAPI } from '@/api';
|
||||
|
||||
enum Role {
|
||||
MEMBER = 'member',
|
||||
ADMIN = 'administrator',
|
||||
OWNER = 'owner',
|
||||
}
|
||||
|
||||
interface Access {
|
||||
id: string;
|
||||
role: Role;
|
||||
user: string;
|
||||
}
|
||||
|
||||
interface TeamResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
accesses: Access[];
|
||||
}
|
||||
|
||||
type TeamsResponse = APIList<TeamResponse>;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_178_17838)">
|
||||
<path
|
||||
d="M16.25 8.75H13.75V13.75H8.75V16.25H13.75V21.25H16.25V16.25H21.25V13.75H16.25V8.75ZM15 2.5C8.1 2.5 2.5 8.1 2.5 15C2.5 21.9 8.1 27.5 15 27.5C21.9 27.5 27.5 21.9 27.5 15C27.5 8.1 21.9 2.5 15 2.5ZM15 25C9.4875 25 5 20.5125 5 15C5 9.4875 9.4875 5 15 5C20.5125 5 25 9.4875 25 15C25 20.5125 20.5125 25 15 25Z"
|
||||
fill="#000091"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_178_17838">
|
||||
<rect width="30" height="30" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 633 B |
@@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_508_5524)">
|
||||
<path
|
||||
d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM4 12C4 7.58 7.58 4 12 4C13.85 4 15.55 4.63 16.9 5.69L5.69 16.9C4.63 15.55 4 13.85 4 12ZM12 20C10.15 20 8.45 19.37 7.1 18.31L18.31 7.1C19.37 8.45 20 10.15 20 12C20 16.42 16.42 20 12 20Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_508_5524">
|
||||
<rect width="24" height="24" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 578 B |
@@ -0,0 +1,19 @@
|
||||
<svg
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_178_17837)">
|
||||
<path
|
||||
d="M11.25 3.75L6.25 8.7375H10V17.5H12.5V8.7375H16.25L11.25 3.75ZM20 21.2625V12.5H17.5V21.2625H13.75L18.75 26.25L23.75 21.2625H20Z"
|
||||
fill="#000091"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_178_17837">
|
||||
<rect width="30" height="30" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 458 B |
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box, Text } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
|
||||
import { PanelActions } from './PanelActions';
|
||||
import { PanelTeams } from './PanelTeams';
|
||||
|
||||
export const Panel = () => {
|
||||
const { t } = useTranslation();
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
$width="28rem"
|
||||
$css={`
|
||||
border-right: 1px solid ${colorsTokens()['primary-300']};
|
||||
`}
|
||||
$height="inherit"
|
||||
aria-label="Teams panel"
|
||||
>
|
||||
<Box
|
||||
className="p-s"
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$justify="space-between"
|
||||
$css={`
|
||||
border-bottom: 1px solid ${colorsTokens()['primary-300']};
|
||||
`}
|
||||
>
|
||||
<Text $weight="bold" $size="1.25rem">
|
||||
{t('Recents')}
|
||||
</Text>
|
||||
<PanelActions />
|
||||
</Box>
|
||||
<PanelTeams />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Button } from '@openfun/cunningham-react';
|
||||
import Image from 'next/image';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Box } from '@/components';
|
||||
|
||||
import { default as IconAdd } from '../assets/icon-add.svg?url';
|
||||
import { default as IconSort } from '../assets/icon-sort.svg?url';
|
||||
|
||||
export const PanelActions = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Box
|
||||
$direction="row"
|
||||
$gap="1rem"
|
||||
$css={`
|
||||
& > button {
|
||||
padding: 0;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
aria-label={t('Sort the teams')}
|
||||
icon={<Image priority src={IconSort} alt={t('Sort teams icon')} />}
|
||||
color="tertiary"
|
||||
className="c__button-no-bg p-0 m-0"
|
||||
/>
|
||||
<Button
|
||||
aria-label={t('Add a team')}
|
||||
icon={<Image priority src={IconAdd} alt={t('Add team icon')} />}
|
||||
color="tertiary"
|
||||
className="c__button-no-bg p-0 m-0"
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Loader } from '@openfun/cunningham-react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import IconGroup from '@/assets/icons/icon-group.svg';
|
||||
import { Box, Text } from '@/components';
|
||||
import { useCunninghamTheme } from '@/cunningham';
|
||||
|
||||
import { useTeams } from '../api/useTeams';
|
||||
import IconNone from '../assets/icon-none.svg';
|
||||
|
||||
export const PanelTeams = () => {
|
||||
const { data, isPending, isError } = useTeams();
|
||||
const { t } = useTranslation();
|
||||
const { colorsTokens } = useCunninghamTheme();
|
||||
|
||||
if (isPending) {
|
||||
return (
|
||||
<Box $align="center" className="m-l">
|
||||
<Loader />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
<Box $justify="center" className="m-b">
|
||||
<Text $theme="danger" $align="center" $textAlign="center">
|
||||
{t('Something bad happens, please refresh the page.')}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data.count) {
|
||||
return (
|
||||
<Box $justify="center" className="m-b">
|
||||
<Text as="p" className="mb-0 mt-0" $theme="greyscale" $variation="500">
|
||||
{t('0 group to display.')}
|
||||
</Text>
|
||||
<Text as="p" $theme="greyscale" $variation="500">
|
||||
{t(
|
||||
'Create your first team by clicking on the "Create a new team" button.',
|
||||
)}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box as="ul" $gap="1rem" className="p-s mt-t">
|
||||
{data?.results.map((team) => (
|
||||
<Box
|
||||
as="li"
|
||||
key={team.id}
|
||||
$direction="row"
|
||||
$align="center"
|
||||
$gap="0.5rem"
|
||||
>
|
||||
{team.accesses.length ? (
|
||||
<IconGroup
|
||||
className="p-t"
|
||||
width={36}
|
||||
aria-label={t(`Team icon`)}
|
||||
color={colorsTokens()['primary-500']}
|
||||
style={{
|
||||
borderRadius: '10px',
|
||||
border: `1px solid ${colorsTokens()['primary-300']}`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<IconNone
|
||||
className="p-t"
|
||||
width={36}
|
||||
aria-label={t(`Empty team icon`)}
|
||||
color={colorsTokens()['greyscale-500']}
|
||||
style={{
|
||||
borderRadius: '10px',
|
||||
border: `1px solid ${colorsTokens()['greyscale-300']}`,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Text $weight="bold">{team.name}</Text>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './Panel';
|
||||
@@ -1,49 +1 @@
|
||||
import { Button, Field, Input, Loader } from '@openfun/cunningham-react';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useCreateTeam } from './api/useCreateTeam';
|
||||
import { useTeams } from './api/useTeams';
|
||||
|
||||
export const Teams = () => {
|
||||
const { data, isPending } = useTeams();
|
||||
const { mutate: createTeam } = useCreateTeam();
|
||||
const [teamName, setTeamName] = useState('');
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (isPending) {
|
||||
return (
|
||||
<div>
|
||||
<Loader />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Field>
|
||||
<Input
|
||||
type="text"
|
||||
label={t('Team name')}
|
||||
onChange={(e) => setTeamName(e.target.value)}
|
||||
/>
|
||||
<Button fullWidth onClick={() => createTeam(teamName)} className="mt-s">
|
||||
{t('Create Team')}
|
||||
</Button>
|
||||
</Field>
|
||||
<section>
|
||||
<ul>
|
||||
{data?.results.map((post, index) => (
|
||||
<li key={post.id}>
|
||||
<div>
|
||||
<span>
|
||||
{index + 1}. {post.name}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
export * from './components/Panel';
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
"{{label}} button": "Bouton {{label}}",
|
||||
"{{label}} icon": "Icône {{label}}",
|
||||
"Team name": "Nom de l’équipe",
|
||||
"Create Team": "Créer une équipe"
|
||||
"Create Team": "Créer une équipe",
|
||||
"Create a new team": "Créer un nouveau groupe"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { keyCloakSignIn } from './common';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page);
|
||||
});
|
||||
|
||||
test.describe('App', () => {
|
||||
test('should display the main elements', async ({ page }) => {
|
||||
await expect(page.locator('header').first()).toContainText('Desk');
|
||||
await expect(page.getByLabel('Team name')).toBeVisible();
|
||||
});
|
||||
|
||||
test('creates 2 teams and displayed them', async ({ page }) => {
|
||||
await page.getByLabel('Team name').fill('My new team');
|
||||
await page.click('button:has-text("Create Team")');
|
||||
await page.getByLabel('Team name').fill('My second new team');
|
||||
await page.click('button:has-text("Create Team")');
|
||||
|
||||
await expect(
|
||||
page.locator('li').getByText('My new team').first(),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator('li').getByText('My second new team').first(),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -24,7 +24,7 @@ test.describe('Header', () => {
|
||||
);
|
||||
await expect(header.locator('h2').getByText('Desk')).toHaveCSS(
|
||||
'font-family',
|
||||
'marianne',
|
||||
/Marianne/i,
|
||||
);
|
||||
|
||||
await expect(
|
||||
|
||||
@@ -10,7 +10,9 @@ test.beforeEach(async ({ page }) => {
|
||||
test.describe('Language', () => {
|
||||
test('checks the language picker', async ({ page }) => {
|
||||
await expect(
|
||||
page.locator('h1').first().getByText('Hello Desk !'),
|
||||
page.getByRole('button', {
|
||||
name: 'Create a new team',
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
const header = page.locator('header').first();
|
||||
@@ -19,7 +21,9 @@ test.describe('Language', () => {
|
||||
await expect(header.getByRole('combobox').getByText('FR')).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.locator('h1').first().getByText('Bonjour Desk !'),
|
||||
page.getByRole('button', {
|
||||
name: 'Créer un nouveau groupe',
|
||||
}),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,7 +46,9 @@ test.describe('Menu', () => {
|
||||
page,
|
||||
}) => {
|
||||
await expect(
|
||||
page.locator('h1').first().getByText('Hello Desk !'),
|
||||
page.getByRole('button', {
|
||||
name: 'Create a new team',
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
const menu = page.locator('menu').first();
|
||||
@@ -57,11 +59,15 @@ test.describe('Menu', () => {
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if (isDefault) {
|
||||
await expect(
|
||||
page.locator('h1').first().getByText('Hello Desk !'),
|
||||
page.getByRole('button', {
|
||||
name: 'Create a new team',
|
||||
}),
|
||||
).toBeVisible();
|
||||
} else {
|
||||
await expect(
|
||||
page.locator('h1').first().getByText('Hello Desk !'),
|
||||
page.getByRole('button', {
|
||||
name: 'Create a new team',
|
||||
}),
|
||||
).toBeHidden();
|
||||
|
||||
const reg = new RegExp(name.toLowerCase());
|
||||
|
||||
34
src/frontend/apps/e2e/__tests__/app-desk/teams.spec.ts
Normal file
34
src/frontend/apps/e2e/__tests__/app-desk/teams.spec.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
import { keyCloakSignIn } from "./common";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await keyCloakSignIn(page);
|
||||
});
|
||||
|
||||
test.describe("Teams", () => {
|
||||
test("checks all the elements are visible", async ({ page }) => {
|
||||
const panel = page.getByLabel("Teams panel").first();
|
||||
|
||||
await expect(panel.getByText("Recents")).toBeVisible();
|
||||
|
||||
await expect(
|
||||
panel.getByRole("button", {
|
||||
name: "Sort the teams",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
panel.getByRole("button", {
|
||||
name: "Add a team",
|
||||
}),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
panel.getByText(
|
||||
'Create your first team by clicking on the "Create a new team" button.',
|
||||
),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user