Merge remote-tracking branch 'origin/features/custom-fields' into custom-fields/attributes-list

This commit is contained in:
Rémi de Juvigny 2022-07-20 10:16:27 +02:00
commit c97ebd192a
5 changed files with 1410 additions and 39 deletions

View File

@ -42,7 +42,10 @@ const AttributeOption = ({ type }) => {
<Flex>
<Typography variant="pi" textColor="neutral600">
{formatMessage({ id: getTrad(`attribute.${type}.description`) })}
{formatMessage({
id: getTrad(`attribute.${type}.description`),
defaultMessage: 'A type for modeling data',
})}
</Typography>
</Flex>
</Box>

View File

@ -12,58 +12,82 @@ import { Divider } from '@strapi/design-system/Divider';
import { Grid, GridItem } from '@strapi/design-system/Grid';
import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable';
import { ModalBody } from '@strapi/design-system/ModalLayout';
import { Flex } from '@strapi/design-system/Flex';
import { Stack } from '@strapi/design-system/Stack';
import { Flex } from '@strapi/design-system/Flex';
import { Typography } from '@strapi/design-system/Typography';
import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs';
import { getTrad } from '../../utils';
import AttributeOption from './AttributeOption';
const AttributeOptions = ({ attributes, forTarget, kind }) => {
const { formatMessage } = useIntl();
const defaultTabId = getTrad('modalForm.tabs.default');
const customTabId = getTrad('modalForm.tabs.custom');
const titleIdSuffix = forTarget.includes('component') ? 'component' : kind;
const titleId = getTrad(`modalForm.sub-header.chooseAttribute.${titleIdSuffix}`);
return (
<ModalBody>
<Flex paddingBottom={4}>
<Typography variant="beta" as="h2">
{formatMessage({ id: titleId, defaultMessage: 'Select a field' })}
</Typography>
</Flex>
<Divider />
<Box paddingTop={6} paddingBottom={4}>
<KeyboardNavigable tagName="button">
<Stack spacing={8}>
{attributes.map((attributeRow, index) => {
const key = index;
<ModalBody padding={6}>
<TabGroup
label={formatMessage({
id: 'modalForm.tab-group.label',
defaultMessage: 'Default and Custom types tabs',
})}
id="attribute-type-tabs"
variant="simple"
>
<Flex justifyContent="space-between">
<Typography variant="beta" as="h2">
{formatMessage({ id: titleId, defaultMessage: 'Select a field' })}
</Typography>
<Tabs>
<Tab>{formatMessage({ id: defaultTabId, defaultMessage: 'Default' })}</Tab>
<Tab>{formatMessage({ id: customTabId, defaultMessage: 'Custom' })}</Tab>
</Tabs>
</Flex>
<Box paddingBottom={6}>
<Divider />
</Box>
<TabPanels>
<TabPanel>
<KeyboardNavigable tagName="button">
<Stack spacing={8}>
{attributes.map((attributeRow, index) => {
const key = index;
return (
<Grid key={key} gap={0}>
{attributeRow.map((attribute, index) => {
const isOdd = index % 2 === 1;
const paddingLeft = isOdd ? 2 : 0;
const paddingRight = isOdd ? 0 : 2;
return (
<Grid key={key} gap={0}>
{attributeRow.map((attribute, index) => {
const isOdd = index % 2 === 1;
const paddingLeft = isOdd ? 2 : 0;
const paddingRight = isOdd ? 0 : 2;
return (
<GridItem key={attribute} col={6} style={{ height: '100%' }}>
<Box
paddingLeft={paddingLeft}
paddingRight={paddingRight}
paddingBottom={1}
style={{ height: '100%' }}
>
<AttributeOption type={attribute} />
</Box>
</GridItem>
);
})}
</Grid>
);
})}
</Stack>
</KeyboardNavigable>
</Box>
return (
<GridItem key={attribute} col={6} style={{ height: '100%' }}>
<Box
paddingLeft={paddingLeft}
paddingRight={paddingRight}
paddingBottom={1}
style={{ height: '100%' }}
>
<AttributeOption type={attribute} />
</Box>
</GridItem>
);
})}
</Grid>
);
})}
</Stack>
</KeyboardNavigable>
</TabPanel>
<TabPanel>
<Typography>Coming soon</Typography>
</TabPanel>
</TabPanels>
</TabGroup>
</ModalBody>
);
};

View File

@ -0,0 +1,77 @@
import React from 'react';
import { render, screen, getByText, fireEvent } from '@testing-library/react';
import { lightTheme, ThemeProvider } from '@strapi/design-system';
import { IntlProvider } from 'react-intl';
import FormModalNavigationProvider from '../../FormModalNavigationProvider';
import AttributeOptions from '../index';
const mockAttributes = [
[
'text',
'email',
'richtext',
'password',
'number',
'enumeration',
'date',
'media',
'boolean',
'json',
'relation',
'uid',
],
['component', 'dynamiczone'],
];
const App = (
<IntlProvider locale="en" messages={{}} textComponent="span">
<ThemeProvider theme={lightTheme}>
<FormModalNavigationProvider>
<AttributeOptions
attributes={mockAttributes}
forTarget="contentType"
kind="collectionType"
/>
</FormModalNavigationProvider>
</ThemeProvider>
</IntlProvider>
);
describe('<AttributeOptions />', () => {
it('renders and matches the snapshot', () => {
const { container } = render(App);
expect(container).toMatchSnapshot();
});
it('shows the simple tabs', () => {
render(App);
const defaultTab = screen.getByRole('tab', { selected: true });
const customTab = screen.getByRole('tab', { selected: false });
expect(defaultTab).toBeVisible();
expect(customTab).toBeVisible();
});
it('defaults to the default tab', () => {
render(App);
const comingSoonText = screen.queryByText('Coming soon');
expect(comingSoonText).toEqual(null);
});
it('switches to the custom tab', () => {
render(App);
const customTab = screen.getByRole('tab', { selected: false });
fireEvent.click(customTab);
const customTabSelected = screen.getByRole('tab', { selected: true });
const customTabText = getByText(customTabSelected, 'Custom');
const comingSoonText = screen.getByText('Coming soon');
expect(customTabText).not.toBe(null);
expect(comingSoonText).toBeVisible();
});
});

View File

@ -155,6 +155,9 @@
"modalForm.sub-header.chooseAttribute.collectionType": "Select a field for your collection type",
"modalForm.sub-header.chooseAttribute.component": "Select a field for your component",
"modalForm.sub-header.chooseAttribute.singleType": "Select a field for your single type",
"modalForm.tabs.custom": "Custom",
"modalForm.tabs.default": "Default",
"modalForm.tabs.label": "Default and Custom types tabs",
"modelPage.attribute.relation-polymorphic": "Relation (polymorphic)",
"modelPage.attribute.relationWith": "Relation with",
"notification.error.dynamiczone-min.validation": "At least one component is required in a dynamic zone to be able to save a content type",