175 lines
5.2 KiB
JavaScript
Raw Normal View History

import React, { useCallback, useState } from 'react';
2019-11-18 18:14:36 +01:00
2019-11-04 09:00:59 +01:00
import { get } from 'lodash';
import PropTypes from 'prop-types';
2019-11-04 10:10:38 +01:00
import { FormattedMessage } from 'react-intl';
import pluginId from '../../pluginId';
2019-11-04 09:00:59 +01:00
import useDataManager from '../../hooks/useDataManager';
2019-11-04 10:10:38 +01:00
import DynamicComponentCard from '../DynamicComponentCard';
2019-11-06 16:29:19 +01:00
import FieldComponent from '../FieldComponent';
2019-11-04 09:00:59 +01:00
import Button from './Button';
2019-11-04 10:10:38 +01:00
import ComponentsPicker from './ComponentsPicker';
2019-11-06 16:29:19 +01:00
import ComponentWrapper from './ComponentWrapper';
import Label from './Label';
import RoundCTA from './RoundCTA';
2019-11-04 09:00:59 +01:00
import Wrapper from './Wrapper';
const DynamicZone = ({ max, min, name }) => {
2019-11-18 18:14:36 +01:00
const [isOpen, setIsOpen] = useState(true);
const {
addComponentToDynamicZone,
formErrors,
layout,
modifiedData,
2019-11-06 16:29:19 +01:00
moveComponentUp,
moveComponentDown,
removeComponentFromDynamicZone,
} = useDataManager();
2019-11-18 18:14:36 +01:00
const getDynamicDisplayedComponents = useCallback(() => {
return get(modifiedData, [name], []).map(data => data.__component);
}, [modifiedData, name]);
const dynamicZoneErrors = Object.keys(formErrors)
.filter(key => {
return key === name;
})
.map(key => formErrors[key]);
2019-11-04 09:00:59 +01:00
const dynamicZoneAvailableComponents = get(
layout,
['schema', 'attributes', name, 'components'],
[]
);
2019-11-18 18:14:36 +01:00
2019-11-06 16:29:19 +01:00
const metas = get(layout, ['metadatas', name, 'edit'], {});
const dynamicDisplayedComponentsLength = getDynamicDisplayedComponents()
.length;
const missingComponentNumber = min - dynamicDisplayedComponentsLength;
const hasError = dynamicZoneErrors.length > 0;
const hasMinError =
dynamicZoneErrors.length > 0 &&
get(dynamicZoneErrors, [0, 'id'], '').includes('min') &&
!isOpen;
2019-11-04 09:00:59 +01:00
return (
<>
2019-11-06 16:29:19 +01:00
{getDynamicDisplayedComponents().length > 0 && (
<Label>
<p>{metas.label}</p>
<p>{metas.description}</p>
</Label>
)}
{getDynamicDisplayedComponents().map((componentUid, index) => {
// TODO when available
// const icon = getDynamicComponentSchemaData(componentUid);
const showDownIcon =
dynamicDisplayedComponentsLength > 0 &&
index < dynamicDisplayedComponentsLength - 1;
const showUpIcon = dynamicDisplayedComponentsLength > 0 && index > 0;
return (
<ComponentWrapper key={index}>
{showDownIcon && (
<RoundCTA
style={{ top: -15, right: 30 }}
onClick={() => moveComponentDown(name, index)}
>
<i className="fa fa-arrow-down" />
</RoundCTA>
)}
{showUpIcon && (
<RoundCTA
style={{ top: -15, right: 45 }}
onClick={() => moveComponentUp(name, index)}
>
<i className="fa fa-arrow-up" />
</RoundCTA>
)}
<RoundCTA
style={{ top: -15, right: 0 }}
onClick={() => removeComponentFromDynamicZone(name, index)}
>
<i className="fa fa-trash" />
</RoundCTA>
<FieldComponent
componentUid={componentUid}
label=""
name={`${name}.${index}`}
isFromDynamicZone
/>
</ComponentWrapper>
);
})}
2019-11-18 18:14:36 +01:00
<Wrapper>
2019-11-04 09:00:59 +01:00
<Button
type="button"
2019-11-18 18:14:36 +01:00
hasError={hasError}
className={isOpen && 'isOpen'}
onClick={() => {
if (dynamicDisplayedComponentsLength < max) {
setIsOpen(prev => !prev);
} else {
strapi.notification.info(
`${pluginId}.components.components.notification.info.maximum-requirement`
);
}
}}
/>
2019-11-04 10:10:38 +01:00
<div className="info">
<FormattedMessage
id={`${pluginId}.components.DynamicZone.add-compo`}
values={{ componentName: name }}
/>
</div>
{hasMinError && <div> {missingComponentNumber} missing components</div>}
2019-11-04 10:10:38 +01:00
<ComponentsPicker isOpen={isOpen}>
2019-11-18 18:14:36 +01:00
<div>
<p className="componentPickerTitle">
<FormattedMessage
id={`${pluginId}.components.DynamicZone.pick-compo`}
/>
2019-11-18 18:14:36 +01:00
</p>
<div className="componentsList">
{dynamicZoneAvailableComponents.map(componentUid => {
return (
<DynamicComponentCard
key={componentUid}
componentUid={componentUid}
icon={''}
onClick={() => {
setIsOpen(false);
const shouldCheckErrors = hasError;
addComponentToDynamicZone(
name,
componentUid,
shouldCheckErrors
);
}}
/>
);
})}
</div>
</div>
2019-11-04 10:10:38 +01:00
</ComponentsPicker>
2019-11-04 09:00:59 +01:00
</Wrapper>
</>
);
};
DynamicZone.defaultProps = {
max: Infinity,
min: -Infinity,
};
DynamicZone.propTypes = {
2019-11-08 16:29:51 +01:00
max: PropTypes.number,
min: PropTypes.number,
name: PropTypes.string.isRequired,
};
export { DynamicZone };
export default DynamicZone;