mirror of
https://github.com/strapi/strapi.git
synced 2025-08-20 22:59:11 +00:00
Merge pull request #14189 from strapi/relation-input/proptype-fix
[RelationInput] Proptypes update
This commit is contained in:
commit
792ec2f776
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user