mirror of
https://github.com/strapi/strapi.git
synced 2025-09-26 00:39:49 +00:00
Merge pull request #11545 from strapi/accordion-error-state
CM/ Accordion Error state
This commit is contained in:
commit
baae2f0252
@ -23,45 +23,64 @@ const IconWrapper = styled.span`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ComponentInitializer = ({ isReadOnly, onClick }) => {
|
const ComponentInitializer = ({ error, isReadOnly, onClick }) => {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<>
|
||||||
as="button"
|
<Box
|
||||||
background="neutral100"
|
as="button"
|
||||||
borderColor="neutral200"
|
background="neutral100"
|
||||||
disabled={isReadOnly}
|
borderColor={error ? 'danger600' : 'neutral200'}
|
||||||
hasRadius
|
disabled={isReadOnly}
|
||||||
onClick={onClick}
|
hasRadius
|
||||||
paddingTop={9}
|
onClick={onClick}
|
||||||
paddingBottom={9}
|
paddingTop={9}
|
||||||
type="button"
|
paddingBottom={9}
|
||||||
>
|
type="button"
|
||||||
<Stack size={2}>
|
>
|
||||||
<Flex justifyContent="center" style={{ cursor: isReadOnly ? 'not-allowed' : 'inherit' }}>
|
<Stack size={2}>
|
||||||
<IconWrapper>
|
<Flex justifyContent="center" style={{ cursor: isReadOnly ? 'not-allowed' : 'inherit' }}>
|
||||||
<PlusCircle />
|
<IconWrapper>
|
||||||
</IconWrapper>
|
<PlusCircle />
|
||||||
</Flex>
|
</IconWrapper>
|
||||||
<Flex justifyContent="center">
|
</Flex>
|
||||||
<Text textColor="primary600" small bold>
|
<Flex justifyContent="center">
|
||||||
{formatMessage({
|
<Text textColor="primary600" small bold>
|
||||||
id: getTrad('components.empty-repeatable'),
|
{formatMessage({
|
||||||
defaultMessage: 'No entry yet. Click on the button below to add one.',
|
id: getTrad('components.empty-repeatable'),
|
||||||
})}
|
defaultMessage: 'No entry yet. Click on the button below to add one.',
|
||||||
</Text>
|
})}
|
||||||
</Flex>
|
</Text>
|
||||||
</Stack>
|
</Flex>
|
||||||
</Box>
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
{error?.id && (
|
||||||
|
<Text textColor="danger600" small>
|
||||||
|
{formatMessage(
|
||||||
|
{
|
||||||
|
id: error.id,
|
||||||
|
defaultMessage: error.defaultMessage,
|
||||||
|
},
|
||||||
|
error.values
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
ComponentInitializer.defaultProps = {
|
ComponentInitializer.defaultProps = {
|
||||||
|
error: undefined,
|
||||||
isReadOnly: false,
|
isReadOnly: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
ComponentInitializer.propTypes = {
|
ComponentInitializer.propTypes = {
|
||||||
|
error: PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
defaultMessage: PropTypes.string.isRequired,
|
||||||
|
values: PropTypes.object,
|
||||||
|
}),
|
||||||
isReadOnly: PropTypes.bool,
|
isReadOnly: PropTypes.bool,
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
@ -22,15 +22,18 @@ const IconButtonCustom = styled(IconButton)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledBox = styled(Box)`
|
const StyledBox = styled(Box)`
|
||||||
> div {
|
> div:first-child {
|
||||||
> div:not(:first-of-type) {
|
box-shadow: ${({ theme }) => theme.shadows.tableShadow};
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const AccordionContentRadius = styled(Box)`
|
||||||
|
border-radius: 0 0 ${({ theme }) => theme.spaces[1]} ${({ theme }) => theme.spaces[1]};
|
||||||
|
`;
|
||||||
|
|
||||||
const Component = ({
|
const Component = ({
|
||||||
componentUid,
|
componentUid,
|
||||||
|
formErrors,
|
||||||
index,
|
index,
|
||||||
isOpen,
|
isOpen,
|
||||||
isFieldAllowed,
|
isFieldAllowed,
|
||||||
@ -74,11 +77,32 @@ const Component = ({
|
|||||||
{ name: friendlyName }
|
{ name: friendlyName }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const formErrorsKeys = Object.keys(formErrors);
|
||||||
|
|
||||||
|
const fieldsErrors = formErrorsKeys.filter(errorKey => {
|
||||||
|
const errorKeysArray = errorKey.split('.');
|
||||||
|
|
||||||
|
if (`${errorKeysArray[0]}.${errorKeysArray[1]}` === `${name}.${index}`) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
let errorMessage;
|
||||||
|
|
||||||
|
if (fieldsErrors.length > 0) {
|
||||||
|
errorMessage = formatMessage({
|
||||||
|
id: getTrad('components.DynamicZone.error-message'),
|
||||||
|
defaultMessage: 'The component contains error(s)',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Rectangle />
|
<Rectangle />
|
||||||
<StyledBox shadow="tableShadow" hasRadius>
|
<StyledBox hasRadius>
|
||||||
<Accordion expanded={isOpen} toggle={() => onToggle(index)} size="S">
|
<Accordion expanded={isOpen} toggle={() => onToggle(index)} size="S" error={errorMessage}>
|
||||||
<AccordionToggle
|
<AccordionToggle
|
||||||
startIcon={<FontAwesomeIcon icon={icon} />}
|
startIcon={<FontAwesomeIcon icon={icon} />}
|
||||||
action={
|
action={
|
||||||
@ -113,14 +137,16 @@ const Component = ({
|
|||||||
togglePosition="left"
|
togglePosition="left"
|
||||||
/>
|
/>
|
||||||
<AccordionContent>
|
<AccordionContent>
|
||||||
<FocusTrap onEscape={() => onToggle(index)}>
|
<AccordionContentRadius background="neutral0">
|
||||||
<FieldComponent
|
<FocusTrap onEscape={() => onToggle(index)}>
|
||||||
componentUid={componentUid}
|
<FieldComponent
|
||||||
icon={icon}
|
componentUid={componentUid}
|
||||||
name={`${name}.${index}`}
|
icon={icon}
|
||||||
isFromDynamicZone
|
name={`${name}.${index}`}
|
||||||
/>
|
isFromDynamicZone
|
||||||
</FocusTrap>
|
/>
|
||||||
|
</FocusTrap>
|
||||||
|
</AccordionContentRadius>
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
</StyledBox>
|
</StyledBox>
|
||||||
@ -130,6 +156,7 @@ const Component = ({
|
|||||||
|
|
||||||
Component.propTypes = {
|
Component.propTypes = {
|
||||||
componentUid: PropTypes.string.isRequired,
|
componentUid: PropTypes.string.isRequired,
|
||||||
|
formErrors: PropTypes.object.isRequired,
|
||||||
index: PropTypes.number.isRequired,
|
index: PropTypes.number.isRequired,
|
||||||
isFieldAllowed: PropTypes.bool.isRequired,
|
isFieldAllowed: PropTypes.bool.isRequired,
|
||||||
isOpen: PropTypes.bool.isRequired,
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
@ -188,6 +188,7 @@ const DynamicZone = ({
|
|||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
componentUid={componentUid}
|
componentUid={componentUid}
|
||||||
|
formErrors={formErrors}
|
||||||
key={index}
|
key={index}
|
||||||
index={index}
|
index={index}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
@ -300,8 +300,8 @@ const EditViewDataManagerProvider = ({
|
|||||||
onPut(formData, trackerProperty);
|
onPut(formData, trackerProperty);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('ValidationError');
|
console.log('ValidationError');
|
||||||
console.error(err);
|
console.log(err);
|
||||||
|
|
||||||
errors = getYupInnerErrors(err);
|
errors = getYupInnerErrors(err);
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
background={isFromDynamicZone ? 'neutral0' : 'neutral100'}
|
background={isFromDynamicZone ? '' : 'neutral100'}
|
||||||
paddingLeft={6}
|
paddingLeft={6}
|
||||||
paddingRight={6}
|
paddingRight={6}
|
||||||
paddingTop={6}
|
paddingTop={6}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import React from 'react';
|
import React, { Children, cloneElement } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useIntl } from 'react-intl';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Box } from '@strapi/design-system/Box';
|
import { Box } from '@strapi/design-system/Box';
|
||||||
import { Text } from '@strapi/design-system/Text';
|
import { Text } from '@strapi/design-system/Text';
|
||||||
|
import { Typography } from '@strapi/design-system/Typography';
|
||||||
import { Flex } from '@strapi/design-system/Flex';
|
import { Flex } from '@strapi/design-system/Flex';
|
||||||
import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable';
|
import { KeyboardNavigable } from '@strapi/design-system/KeyboardNavigable';
|
||||||
|
|
||||||
@ -61,7 +63,12 @@ const LabelAction = styled(Box)`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AccordionGroupCustom = ({ children, footer, label, labelAction }) => {
|
const AccordionGroupCustom = ({ children, footer, label, labelAction, error }) => {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const childrenArray = Children.toArray(children).map(child => {
|
||||||
|
return cloneElement(child, { hasErrorMessage: false });
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardNavigable attributeName="data-strapi-accordion-toggle">
|
<KeyboardNavigable attributeName="data-strapi-accordion-toggle">
|
||||||
{label && (
|
{label && (
|
||||||
@ -72,13 +79,21 @@ const AccordionGroupCustom = ({ children, footer, label, labelAction }) => {
|
|||||||
{labelAction && <LabelAction paddingLeft={1}>{labelAction}</LabelAction>}
|
{labelAction && <LabelAction paddingLeft={1}>{labelAction}</LabelAction>}
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
<EnhancedGroup footer={footer}>{children}</EnhancedGroup>
|
<EnhancedGroup footer={footer}>{childrenArray}</EnhancedGroup>
|
||||||
{footer && <AccordionFooter>{footer}</AccordionFooter>}
|
{footer && <AccordionFooter>{footer}</AccordionFooter>}
|
||||||
|
{error && (
|
||||||
|
<Box paddingTop={1}>
|
||||||
|
<Typography variant="pi" textColor="danger600">
|
||||||
|
{formatMessage({ id: error.id, defaultMessage: error.defaultMessage }, error.values)}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</KeyboardNavigable>
|
</KeyboardNavigable>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
AccordionGroupCustom.defaultProps = {
|
AccordionGroupCustom.defaultProps = {
|
||||||
|
error: undefined,
|
||||||
footer: null,
|
footer: null,
|
||||||
label: null,
|
label: null,
|
||||||
labelAction: undefined,
|
labelAction: undefined,
|
||||||
@ -86,6 +101,11 @@ AccordionGroupCustom.defaultProps = {
|
|||||||
|
|
||||||
AccordionGroupCustom.propTypes = {
|
AccordionGroupCustom.propTypes = {
|
||||||
children: PropTypes.node.isRequired,
|
children: PropTypes.node.isRequired,
|
||||||
|
error: PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
defaultMessage: PropTypes.string.isRequired,
|
||||||
|
values: PropTypes.object,
|
||||||
|
}),
|
||||||
footer: PropTypes.node,
|
footer: PropTypes.node,
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
labelAction: PropTypes.node,
|
labelAction: PropTypes.node,
|
||||||
|
@ -5,7 +5,6 @@ import { useDrag, useDrop } from 'react-dnd';
|
|||||||
import { getEmptyImage } from 'react-dnd-html5-backend';
|
import { getEmptyImage } from 'react-dnd-html5-backend';
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import toString from 'lodash/toString';
|
import toString from 'lodash/toString';
|
||||||
import styled from 'styled-components';
|
|
||||||
import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
|
import { Accordion, AccordionToggle, AccordionContent } from '@strapi/design-system/Accordion';
|
||||||
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
||||||
import { Stack } from '@strapi/design-system/Stack';
|
import { Stack } from '@strapi/design-system/Stack';
|
||||||
@ -21,14 +20,6 @@ import DraggingSibling from './DraggingSibling';
|
|||||||
import { CustomIconButton, DragHandleWrapper } from './IconButtonCustoms';
|
import { CustomIconButton, DragHandleWrapper } from './IconButtonCustoms';
|
||||||
import { connect, select } from './utils';
|
import { connect, select } from './utils';
|
||||||
|
|
||||||
const StyledBox = styled(Box)`
|
|
||||||
> div {
|
|
||||||
> div:not(:first-of-type) {
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/* eslint-disable react/no-array-index-key */
|
/* eslint-disable react/no-array-index-key */
|
||||||
|
|
||||||
// Issues:
|
// Issues:
|
||||||
@ -37,11 +28,9 @@ const StyledBox = styled(Box)`
|
|||||||
|
|
||||||
const DraggedItem = ({
|
const DraggedItem = ({
|
||||||
componentFieldName,
|
componentFieldName,
|
||||||
// FIXME: errors
|
// Errors are retrieved from the AccordionGroupCustom cloneElement
|
||||||
// doesPreviousFieldContainErrorsAndIsOpen,
|
hasErrorMessage,
|
||||||
// hasErrors,
|
hasErrors,
|
||||||
// hasMinError,
|
|
||||||
// isFirst,
|
|
||||||
isDraggingSibling,
|
isDraggingSibling,
|
||||||
isOpen,
|
isOpen,
|
||||||
isReadOnly,
|
isReadOnly,
|
||||||
@ -171,16 +160,24 @@ const DraggedItem = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const accordionTitle = toString(displayedValue);
|
const accordionTitle = toString(displayedValue);
|
||||||
|
const accordionHasError = hasErrors ? 'error' : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledBox ref={refs ? refs.dropRef : null}>
|
<Box ref={refs ? refs.dropRef : null}>
|
||||||
{isDragging && <Preview />}
|
{isDragging && <Preview />}
|
||||||
{!isDragging && isDraggingSibling && (
|
{!isDragging && isDraggingSibling && (
|
||||||
<DraggingSibling displayedValue={accordionTitle} componentFieldName={componentFieldName} />
|
<DraggingSibling displayedValue={accordionTitle} componentFieldName={componentFieldName} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!isDragging && !isDraggingSibling && (
|
{!isDragging && !isDraggingSibling && (
|
||||||
<Accordion expanded={isOpen} toggle={onClickToggle} id={componentFieldName} size="S">
|
<Accordion
|
||||||
|
error={accordionHasError}
|
||||||
|
hasErrorMessage={hasErrorMessage}
|
||||||
|
expanded={isOpen}
|
||||||
|
toggle={onClickToggle}
|
||||||
|
id={componentFieldName}
|
||||||
|
size="S"
|
||||||
|
>
|
||||||
<AccordionToggle
|
<AccordionToggle
|
||||||
action={
|
action={
|
||||||
isReadOnly ? null : (
|
isReadOnly ? null : (
|
||||||
@ -264,15 +261,11 @@ const DraggedItem = ({
|
|||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
)}
|
)}
|
||||||
</StyledBox>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
DraggedItem.defaultProps = {
|
DraggedItem.defaultProps = {
|
||||||
// doesPreviousFieldContainErrorsAndIsOpen: false,
|
|
||||||
// hasErrors: false,
|
|
||||||
// hasMinError: false,
|
|
||||||
// isFirst: false,
|
|
||||||
isDraggingSibling: false,
|
isDraggingSibling: false,
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
setIsDraggingSiblig: () => {},
|
setIsDraggingSiblig: () => {},
|
||||||
@ -281,10 +274,8 @@ DraggedItem.defaultProps = {
|
|||||||
|
|
||||||
DraggedItem.propTypes = {
|
DraggedItem.propTypes = {
|
||||||
componentFieldName: PropTypes.string.isRequired,
|
componentFieldName: PropTypes.string.isRequired,
|
||||||
// doesPreviousFieldContainErrorsAndIsOpen: PropTypes.bool,
|
hasErrorMessage: PropTypes.bool.isRequired,
|
||||||
// hasErrors: PropTypes.bool,
|
hasErrors: PropTypes.bool.isRequired,
|
||||||
// hasMinError: PropTypes.bool,
|
|
||||||
// isFirst: PropTypes.bool,
|
|
||||||
isDraggingSibling: PropTypes.bool,
|
isDraggingSibling: PropTypes.bool,
|
||||||
isOpen: PropTypes.bool,
|
isOpen: PropTypes.bool,
|
||||||
isReadOnly: PropTypes.bool.isRequired,
|
isReadOnly: PropTypes.bool.isRequired,
|
||||||
|
@ -43,7 +43,7 @@ const RepeatableComponent = ({
|
|||||||
isNested,
|
isNested,
|
||||||
isReadOnly,
|
isReadOnly,
|
||||||
max,
|
max,
|
||||||
// min,
|
min,
|
||||||
name,
|
name,
|
||||||
}) => {
|
}) => {
|
||||||
const toggleNotification = useNotification();
|
const toggleNotification = useNotification();
|
||||||
@ -75,11 +75,10 @@ const RepeatableComponent = ({
|
|||||||
const toggleCollapses = () => {
|
const toggleCollapses = () => {
|
||||||
setCollapseToOpen('');
|
setCollapseToOpen('');
|
||||||
};
|
};
|
||||||
// TODO
|
|
||||||
// const missingComponentsValue = min - componentValueLength;
|
|
||||||
const errorsArray = componentErrorKeys.map(key => get(formErrors, [key, 'id'], ''));
|
|
||||||
|
|
||||||
const hasMinError = get(errorsArray, [0], '').includes('min');
|
const missingComponentsValue = min - componentValueLength;
|
||||||
|
|
||||||
|
const hasMinError = get(formErrors, name, { id: '' }).id.includes('min');
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
if (!isReadOnly) {
|
if (!isReadOnly) {
|
||||||
@ -108,13 +107,38 @@ const RepeatableComponent = ({
|
|||||||
toggleNotification,
|
toggleNotification,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let errorMessage = formErrors[name];
|
||||||
|
|
||||||
|
if (hasMinError) {
|
||||||
|
errorMessage = {
|
||||||
|
id: getTrad('components.DynamicZone.missing-components'),
|
||||||
|
defaultMessage:
|
||||||
|
'There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}',
|
||||||
|
values: { number: missingComponentsValue },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (componentValueLength === 0) {
|
if (componentValueLength === 0) {
|
||||||
return <ComponentInitializer isReadOnly={isReadOnly} onClick={handleClick} />;
|
return (
|
||||||
|
<ComponentInitializer error={errorMessage} isReadOnly={isReadOnly} onClick={handleClick} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const doesRepComponentHasChildError = componentErrorKeys.some(
|
||||||
|
error => error.split('.').length > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (doesRepComponentHasChildError && !hasMinError) {
|
||||||
|
errorMessage = {
|
||||||
|
id: getTrad('components.RepeatableComponent.error-message'),
|
||||||
|
defaultMessage: 'The component(s) contain error(s)',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box hasRadius background="neutral0" shadow="tableShadow" ref={drop}>
|
<Box hasRadius ref={drop}>
|
||||||
<AccordionGroupCustom
|
<AccordionGroupCustom
|
||||||
|
error={errorMessage}
|
||||||
footer={
|
footer={
|
||||||
<Flex justifyContent="center" height="48px" background="neutral0" hasRadius>
|
<Flex justifyContent="center" height="48px" background="neutral0" hasRadius>
|
||||||
<TextButtonCustom disabled={isReadOnly} onClick={handleClick} startIcon={<Plus />}>
|
<TextButtonCustom disabled={isReadOnly} onClick={handleClick} startIcon={<Plus />}>
|
||||||
@ -130,24 +154,15 @@ const RepeatableComponent = ({
|
|||||||
const key = data.__temp_key__;
|
const key = data.__temp_key__;
|
||||||
const isOpen = collapseToOpen === key;
|
const isOpen = collapseToOpen === key;
|
||||||
const componentFieldName = `${name}.${index}`;
|
const componentFieldName = `${name}.${index}`;
|
||||||
const previousComponentTempKey = get(componentValue, [index - 1, '__temp_key__']);
|
|
||||||
const doesPreviousFieldContainErrorsAndIsOpen =
|
|
||||||
componentErrorKeys.includes(`${name}.${index - 1}`) &&
|
|
||||||
index !== 0 &&
|
|
||||||
collapseToOpen === previousComponentTempKey;
|
|
||||||
|
|
||||||
const hasErrors = componentErrorKeys.includes(componentFieldName);
|
const hasErrors = componentErrorKeys.includes(componentFieldName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DraggedItem
|
<DraggedItem
|
||||||
componentFieldName={componentFieldName}
|
componentFieldName={componentFieldName}
|
||||||
componentUid={componentUid}
|
componentUid={componentUid}
|
||||||
// TODO
|
|
||||||
doesPreviousFieldContainErrorsAndIsOpen={doesPreviousFieldContainErrorsAndIsOpen}
|
|
||||||
hasErrors={hasErrors}
|
hasErrors={hasErrors}
|
||||||
hasMinError={hasMinError}
|
hasMinError={hasMinError}
|
||||||
isDraggingSibling={isDraggingSibling}
|
isDraggingSibling={isDraggingSibling}
|
||||||
isFirst={index === 0}
|
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
key={key}
|
key={key}
|
||||||
@ -167,139 +182,7 @@ const RepeatableComponent = ({
|
|||||||
})}
|
})}
|
||||||
</AccordionGroupCustom>
|
</AccordionGroupCustom>
|
||||||
</Box>
|
</Box>
|
||||||
// <Box hasRadius borderColor="neutral200">
|
|
||||||
// <Box ref={drop}>
|
|
||||||
// {componentValue.map((data, index) => {
|
|
||||||
// const key = data.__temp_key__;
|
|
||||||
// const isOpen = collapseToOpen === key;
|
|
||||||
// const componentFieldName = `${name}.${index}`;
|
|
||||||
// const previousComponentTempKey = get(componentValue, [index - 1, '__temp_key__']);
|
|
||||||
// const doesPreviousFieldContainErrorsAndIsOpen =
|
|
||||||
// componentErrorKeys.includes(`${name}.${index - 1}`) &&
|
|
||||||
// index !== 0 &&
|
|
||||||
// collapseToOpen === previousComponentTempKey;
|
|
||||||
|
|
||||||
// const hasErrors = componentErrorKeys.includes(componentFieldName);
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <DraggedItem
|
|
||||||
// componentFieldName={componentFieldName}
|
|
||||||
// componentUid={componentUid}
|
|
||||||
// // TODO
|
|
||||||
// doesPreviousFieldContainErrorsAndIsOpen={doesPreviousFieldContainErrorsAndIsOpen}
|
|
||||||
// hasErrors={hasErrors}
|
|
||||||
// hasMinError={hasMinError}
|
|
||||||
// isFirst={index === 0}
|
|
||||||
// isOdd={index % 2 === 1}
|
|
||||||
// isOpen={isOpen}
|
|
||||||
// isReadOnly={isReadOnly}
|
|
||||||
// key={key}
|
|
||||||
// onClickToggle={() => {
|
|
||||||
// if (isOpen) {
|
|
||||||
// setCollapseToOpen('');
|
|
||||||
// } else {
|
|
||||||
// setCollapseToOpen(key);
|
|
||||||
// }
|
|
||||||
// }}
|
|
||||||
// parentName={name}
|
|
||||||
// schema={componentLayoutData}
|
|
||||||
// toggleCollapses={toggleCollapses}
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
// })}
|
|
||||||
// </Box>
|
|
||||||
// <Button
|
|
||||||
// // TODO
|
|
||||||
// // hasMinError={hasMinError}
|
|
||||||
// disabled={isReadOnly}
|
|
||||||
// // TODO
|
|
||||||
// // doesPreviousFieldContainErrorsAndIsClosed={
|
|
||||||
// // componentValueLength > 0 &&
|
|
||||||
// // componentErrorKeys.includes(`${name}.${componentValueLength - 1}`) &&
|
|
||||||
// // componentValue[componentValueLength - 1].__temp_key__ !== collapseToOpen
|
|
||||||
// // }
|
|
||||||
// onClick={handleClick}
|
|
||||||
// />
|
|
||||||
// </Box>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// return (
|
|
||||||
// <div>
|
|
||||||
// {componentValueLength === 0 && (
|
|
||||||
// <EmptyComponent hasMinError={hasMinError}>
|
|
||||||
// <FormattedMessage id={getTrad('components.empty-repeatable')}>
|
|
||||||
// {msg => <p>{msg}</p>}
|
|
||||||
// </FormattedMessage>
|
|
||||||
// </EmptyComponent>
|
|
||||||
// )}
|
|
||||||
// <div ref={drop}>
|
|
||||||
// {componentValueLength > 0 &&
|
|
||||||
// componentValue.map((data, index) => {
|
|
||||||
// const key = data.__temp_key__;
|
|
||||||
// const isOpen = collapseToOpen === key;
|
|
||||||
// const componentFieldName = `${name}.${index}`;
|
|
||||||
// const previousComponentTempKey = get(componentValue, [index - 1, '__temp_key__']);
|
|
||||||
// const doesPreviousFieldContainErrorsAndIsOpen =
|
|
||||||
// componentErrorKeys.includes(`${name}.${index - 1}`) &&
|
|
||||||
// index !== 0 &&
|
|
||||||
// collapseToOpen === previousComponentTempKey;
|
|
||||||
|
|
||||||
// const hasErrors = componentErrorKeys.includes(componentFieldName);
|
|
||||||
|
|
||||||
// return (
|
|
||||||
// <DraggedItem
|
|
||||||
// componentFieldName={componentFieldName}
|
|
||||||
// componentUid={componentUid}
|
|
||||||
// doesPreviousFieldContainErrorsAndIsOpen={doesPreviousFieldContainErrorsAndIsOpen}
|
|
||||||
// hasErrors={hasErrors}
|
|
||||||
// hasMinError={hasMinError}
|
|
||||||
// isFirst={index === 0}
|
|
||||||
// isReadOnly={isReadOnly}
|
|
||||||
// isOpen={isOpen}
|
|
||||||
// key={key}
|
|
||||||
// onClickToggle={() => {
|
|
||||||
// if (isOpen) {
|
|
||||||
// setCollapseToOpen('');
|
|
||||||
// } else {
|
|
||||||
// setCollapseToOpen(key);
|
|
||||||
// }
|
|
||||||
// }}
|
|
||||||
// parentName={name}
|
|
||||||
// schema={componentLayoutData}
|
|
||||||
// toggleCollapses={toggleCollapses}
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
// })}
|
|
||||||
// </div>
|
|
||||||
// <Button
|
|
||||||
// hasMinError={hasMinError}
|
|
||||||
// disabled={isReadOnly}
|
|
||||||
// withBorderRadius={false}
|
|
||||||
// doesPreviousFieldContainErrorsAndIsClosed={
|
|
||||||
// componentValueLength > 0 &&
|
|
||||||
// componentErrorKeys.includes(`${name}.${componentValueLength - 1}`) &&
|
|
||||||
// componentValue[componentValueLength - 1].__temp_key__ !== collapseToOpen
|
|
||||||
// }
|
|
||||||
// type="button"
|
|
||||||
// onClick={handleClick}
|
|
||||||
// >
|
|
||||||
// <i className="fa fa-plus" />
|
|
||||||
// <FormattedMessage id={getTrad('containers.EditView.add.new')} />
|
|
||||||
// </Button>
|
|
||||||
// {hasMinError && (
|
|
||||||
// <ErrorMessage>
|
|
||||||
// <FormattedMessage
|
|
||||||
// id={getTrad(
|
|
||||||
// `components.DynamicZone.missing${
|
|
||||||
// missingComponentsValue > 1 ? '.plural' : '.singular'
|
|
||||||
// }`
|
|
||||||
// )}
|
|
||||||
// values={{ count: missingComponentsValue }}
|
|
||||||
// />
|
|
||||||
// </ErrorMessage>
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RepeatableComponent.defaultProps = {
|
RepeatableComponent.defaultProps = {
|
||||||
@ -308,7 +191,7 @@ RepeatableComponent.defaultProps = {
|
|||||||
formErrors: {},
|
formErrors: {},
|
||||||
isNested: false,
|
isNested: false,
|
||||||
max: Infinity,
|
max: Infinity,
|
||||||
// min: -Infinity,
|
min: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
RepeatableComponent.propTypes = {
|
RepeatableComponent.propTypes = {
|
||||||
@ -320,7 +203,7 @@ RepeatableComponent.propTypes = {
|
|||||||
isNested: PropTypes.bool,
|
isNested: PropTypes.bool,
|
||||||
isReadOnly: PropTypes.bool.isRequired,
|
isReadOnly: PropTypes.bool.isRequired,
|
||||||
max: PropTypes.number,
|
max: PropTypes.number,
|
||||||
// min: PropTypes.number,
|
min: PropTypes.number,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -461,6 +461,7 @@
|
|||||||
"content-manager.components.DynamicZone.ComponentPicker-label": "Pick one component",
|
"content-manager.components.DynamicZone.ComponentPicker-label": "Pick one component",
|
||||||
"content-manager.components.DynamicZone.add-component": "Add a component to {componentName}",
|
"content-manager.components.DynamicZone.add-component": "Add a component to {componentName}",
|
||||||
"content-manager.components.DynamicZone.delete-label": "Delete {name}",
|
"content-manager.components.DynamicZone.delete-label": "Delete {name}",
|
||||||
|
"content-manager.components.DynamicZone.error-message": "The component contains error(s)",
|
||||||
"content-manager.components.DynamicZone.missing-components": "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}",
|
"content-manager.components.DynamicZone.missing-components": "There {number, plural, =0 {are # missing components} one {is # missing component} other {are # missing components}}",
|
||||||
"content-manager.components.DynamicZone.move-down-label": "Move component down",
|
"content-manager.components.DynamicZone.move-down-label": "Move component down",
|
||||||
"content-manager.components.DynamicZone.move-up-label": "Move component up",
|
"content-manager.components.DynamicZone.move-up-label": "Move component up",
|
||||||
@ -481,6 +482,7 @@
|
|||||||
"content-manager.components.LeftMenu.single-types": "{number, plural, =0 {Single Types} one {Single Type } other {Single Types}}",
|
"content-manager.components.LeftMenu.single-types": "{number, plural, =0 {Single Types} one {Single Type } other {Single Types}}",
|
||||||
"content-manager.components.LimitSelect.itemsPerPage": "Items per page",
|
"content-manager.components.LimitSelect.itemsPerPage": "Items per page",
|
||||||
"content-manager.components.NotAllowedInput.text": "No permissions to see this field",
|
"content-manager.components.NotAllowedInput.text": "No permissions to see this field",
|
||||||
|
"content-manager.components.RepeatableComponent.error-message": "The component(s) contain error(s)",
|
||||||
"content-manager.components.Search.placeholder": "Search for an entry...",
|
"content-manager.components.Search.placeholder": "Search for an entry...",
|
||||||
"content-manager.components.Select.draft-info-title": "State: Draft",
|
"content-manager.components.Select.draft-info-title": "State: Draft",
|
||||||
"content-manager.components.Select.publish-info-title": "State: Published",
|
"content-manager.components.Select.publish-info-title": "State: Published",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user