Merge pull request #14189 from strapi/relation-input/proptype-fix

[RelationInput] Proptypes update
This commit is contained in:
Julie Plantey 2022-08-25 12:12:44 +02:00 committed by GitHub
commit 792ec2f776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 85 deletions

View File

@ -36,6 +36,7 @@ export const RelationInput = ({
onSearchNextPage, onSearchNextPage,
onSearch, onSearch,
placeholder, placeholder,
publicationStateTranslations,
searchResults, searchResults,
}) => { }) => {
return ( return (
@ -46,7 +47,7 @@ export const RelationInput = ({
<FieldLabel>{label}</FieldLabel> <FieldLabel>{label}</FieldLabel>
<ReactSelect <ReactSelect
components={{ Option }} components={{ Option }}
options={searchResults} options={searchResults.data.pages.flat()}
isDisabled={disabled} isDisabled={disabled}
error={error} error={error}
inputId={id} inputId={id}
@ -71,9 +72,9 @@ export const RelationInput = ({
> >
<RelationList height={listHeight}> <RelationList height={listHeight}>
{relations.isSuccess && {relations.isSuccess &&
relations.data.pages.flatMap((relation) => { relations.data.pages.flat().map((relation) => {
const { isDraft, href, title, id } = relation; const { publicationState, href, mainField, id } = relation;
const badgeColor = isDraft ? 'secondary' : 'success'; const badgeColor = publicationState === 'draft' ? 'secondary' : 'success';
return ( return (
<RelationItem <RelationItem
@ -92,21 +93,21 @@ export const RelationInput = ({
<Box paddingTop={1} paddingBottom={1}> <Box paddingTop={1} paddingBottom={1}>
{href ? ( {href ? (
<BaseLink disabled={disabled} href={href}> <BaseLink disabled={disabled} href={href}>
{title} {mainField}
</BaseLink> </BaseLink>
) : ( ) : (
title mainField
)} )}
</Box> </Box>
{isDraft !== undefined && ( {publicationState && (
<Badge <Badge
borderSize={1} borderSize={1}
borderColor={`${badgeColor}200`} borderColor={`${badgeColor}200`}
backgroundColor={`${badgeColor}100`} backgroundColor={`${badgeColor}100`}
textColor={`${badgeColor}700`} textColor={`${badgeColor}700`}
> >
{isDraft ? 'Draft' : 'Published'} {publicationStateTranslations[publicationState]}
</Badge> </Badge>
)} )}
</RelationItem> </RelationItem>
@ -125,28 +126,35 @@ export const RelationInput = ({
const ReactQueryRelationResult = PropTypes.shape({ const ReactQueryRelationResult = PropTypes.shape({
data: PropTypes.shape({ data: PropTypes.shape({
pages: PropTypes.arrayOf( pages: PropTypes.arrayOf(
PropTypes.shape({ PropTypes.arrayOf(
id: PropTypes.number.isRequired, PropTypes.shape({
isDraft: PropTypes.bool, href: PropTypes.string,
href: PropTypes.string, id: PropTypes.number.isRequired,
title: PropTypes.string.isRequired, publicationState: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
}) mainField: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
})
)
), ),
}), }),
isLoading: PropTypes.bool.isRequired, isLoading: PropTypes.bool.isRequired,
isSuccess: PropTypes.bool.isRequired, isSuccess: PropTypes.bool.isRequired,
}); });
const ReactQuerySearchResult = PropTypes.arrayOf( const ReactQuerySearchResult = PropTypes.shape({
PropTypes.shape({ data: PropTypes.shape({
label: PropTypes.string, pages: PropTypes.arrayOf(
value: { PropTypes.arrayOf(
id: PropTypes.number, PropTypes.shape({
name: PropTypes.string, id: PropTypes.number.isRequired,
publishedAt: PropTypes.string, mainField: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
}, publicationState: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
}) })
); )
),
}),
isLoading: PropTypes.bool.isRequired,
isSuccess: PropTypes.bool.isRequired,
});
RelationInput.defaultProps = { RelationInput.defaultProps = {
description: undefined, description: undefined,
@ -174,6 +182,10 @@ RelationInput.propTypes = {
onSearch: PropTypes.func.isRequired, onSearch: PropTypes.func.isRequired,
onSearchNextPage: PropTypes.func.isRequired, onSearchNextPage: PropTypes.func.isRequired,
placeholder: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired,
publicationStateTranslations: PropTypes.shape({
draft: PropTypes.string.isRequired,
published: PropTypes.string.isRequired,
}).isRequired,
searchResults: ReactQuerySearchResult, searchResults: ReactQuerySearchResult,
relations: ReactQueryRelationResult, relations: ReactQueryRelationResult,
}; };

View File

@ -21,52 +21,72 @@ WIP
<Story name="base"> <Story name="base">
<Box padding={8}> <Box padding={8}>
<RelationInput <RelationInput
id="relations-1"
label="Relations" label="Relations"
labelLoadMore="Load More" labelLoadMore="Load More"
listHeight="200px" listHeight="200px"
name="options" name="options"
searchResults={[ publicationStateTranslations={{ draft: 'Draft', published: 'Published' }}
{ searchResults={{
label: 'Relation 6', data: {
value: { pages: [
id: 6, [
name: 'Relation 6', {
publishedAt: 'something' id: 6
} mainField: 'Relation 6',
} publicationState: 'draft',
]} },
{
id: 7,
mainField: 'Relation 7',
publicationState: 'published',
},
{
id: 8,
mainField: 'Relation 8',
publicationState: false,
},
],
],
isLoading: false,
isSuccess: true,
},
}}
relations={{ relations={{
data: { data: {
pages: [ pages: [
{ [
id: 1, {
href: '/', id: 1,
title: 'Relation 1', href: '/',
}, mainField: 'Relation 1',
{ publicationState: 'draft',
id: 2, },
href: '', {
title: 'Relation 2', id: 2,
isDraft: true, href: '',
}, mainField: 'Relation 2',
{ publicationState: false,
id: 3, },
href: '', {
title: 'Relation 3', id: 3,
isDraft: false, href: '',
}, mainField: 'Relation 3',
{ publicationState: 'published',
id: 4, },
href: '', {
title: 'Relation 4', id: 4,
isDraft: false, href: '',
}, mainField: 'Relation 4',
{ publicationState: 'draft',
id: 5, },
href: '', {
title: 'Relation 5', id: 5,
isDraft: true, href: '',
}, mainField: 'Relation 5',
publicationState: false,
},
],
], ],
}, },
isLoading: false, isLoading: false,

View File

@ -3,7 +3,6 @@ import styled from 'styled-components';
import { components } from 'react-select'; import { components } from 'react-select';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { get, has, isEmpty } from 'lodash';
import { Flex } from '@strapi/design-system/Flex'; import { Flex } from '@strapi/design-system/Flex';
import { Typography } from '@strapi/design-system/Typography'; import { Typography } from '@strapi/design-system/Typography';
@ -22,10 +21,10 @@ const StyledBullet = styled.div`
export const Option = (props) => { export const Option = (props) => {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const Component = components.Option; const Component = components.Option;
const hasDraftAndPublish = has(get(props, 'data.value'), 'publishedAt'); const { publicationState, mainField } = props.data;
if (hasDraftAndPublish) { if (publicationState) {
const isDraft = isEmpty(get(props, 'data.value.publishedAt')); const isDraft = publicationState === 'draft';
// To fix: use getTrad utils from CM once component is migrated into CM components // To fix: use getTrad utils from CM once component is migrated into CM components
const draftMessage = { const draftMessage = {
id: 'content-manager.components.Select.draft-info-title', id: 'content-manager.components.Select.draft-info-title',
@ -42,29 +41,20 @@ export const Option = (props) => {
<Component {...props}> <Component {...props}>
<Flex> <Flex>
<StyledBullet title={title} isDraft={isDraft} /> <StyledBullet title={title} isDraft={isDraft} />
<Typography ellipsis>{props.label || '-'}</Typography> <Typography ellipsis>{mainField ?? '-'}</Typography>
</Flex> </Flex>
</Component> </Component>
); );
} }
return <Component {...props}>{props.label || '-'}</Component>; return <Component {...props}>{mainField ?? '-'}</Component>;
};
Option.defaultProps = {
label: '',
}; };
Option.propTypes = { Option.propTypes = {
label: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
isFocused: PropTypes.bool.isRequired, isFocused: PropTypes.bool.isRequired,
selectProps: PropTypes.shape({ data: PropTypes.shape({
hasDraftAndPublish: PropTypes.bool, isDraft: PropTypes.bool,
mainField: PropTypes.shape({ mainField: PropTypes.string,
name: PropTypes.string.isRequired, publicationState: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
schema: PropTypes.shape({
type: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
}).isRequired, }).isRequired,
}; };

View File

@ -17,7 +17,7 @@ const setup = (props) =>
describe('RelationInput || Option', () => { describe('RelationInput || Option', () => {
it('should render custom Option with published state title', () => { it('should render custom Option with published state title', () => {
setup({ options: [{ value: { id: 1, publishedAt: 'something' }, label: 'relation 1' }] }); setup({ options: [{ mainField: 'relation 1', publicationState: 'published' }] });
act(() => { act(() => {
fireEvent.mouseDown(screen.getByRole('button')); fireEvent.mouseDown(screen.getByRole('button'));
@ -27,8 +27,8 @@ describe('RelationInput || Option', () => {
expect(screen.getByTitle('State: Published')).toBeInTheDocument(); expect(screen.getByTitle('State: Published')).toBeInTheDocument();
}); });
it('should render custom Option with published state title', () => { it('should render custom Option with draft state title', () => {
setup({ options: [{ value: { id: 1, publishedAt: null }, label: 'relation 1' }] }); setup({ options: [{ mainField: 'relation 1', publicationState: 'draft' }] });
act(() => { act(() => {
fireEvent.mouseDown(screen.getByRole('button')); fireEvent.mouseDown(screen.getByRole('button'));