init rep component

This commit is contained in:
ronronscelestes 2021-10-29 10:50:03 +02:00
parent ac8a8086ba
commit 0800d65e6b
2 changed files with 329 additions and 195 deletions

View File

@ -13,7 +13,7 @@ import { IconButton } from '@strapi/design-system/IconButton';
import { Grid, GridItem } from '@strapi/design-system/Grid';
import { Stack } from '@strapi/design-system/Stack';
import Trash from '@strapi/icons/Trash';
import DragHandle from '@strapi/icons/Drag';
import Drag from '@strapi/icons/Drag';
import ItemTypes from '../../../utils/ItemTypes';
import getTrad from '../../../utils/getTrad';
import Inputs from '../../Inputs';
@ -31,6 +31,24 @@ const StyledBox = styled(Box)`
}
`;
const CustomIconButton = styled(IconButton)`
background-color: transparent;
svg {
path {
fill: ${({ theme, expanded }) => expanded ? theme.colors.primary600 : theme.colors.neutral600}
}
}
&:hover {
svg {
path {
fill: ${({ theme }) => theme.colors.primary600}
}
}
}
`;
/* eslint-disable react/no-array-index-key */
// Issues:
@ -58,199 +76,236 @@ const DraggedItem = ({
// checkFormErrors,
displayedValue,
}) => {
const dragRef = useRef(null);
const dropRef = useRef(null);
const { formatMessage } = useIntl();
// const dragRef = useRef(null);
// const dropRef = useRef(null);
// const { formatMessage } = useIntl();
const fields = schema.layouts.edit;
// const fields = schema.layouts.edit;
const [, drop] = useDrop({
accept: ItemTypes.COMPONENT,
canDrop() {
return false;
},
hover(item, monitor) {
if (!dropRef.current) {
return;
}
// const [, drop] = useDrop({
// accept: ItemTypes.COMPONENT,
// canDrop() {
// return false;
// },
// hover(item, monitor) {
// if (!dropRef.current) {
// return;
// }
const dragPath = item.originalPath;
const hoverPath = componentFieldName;
const fullPathToComponentArray = dragPath.split('.');
const dragIndexString = fullPathToComponentArray
.slice()
.splice(-1)
.join('');
const hoverIndexString = hoverPath
.split('.')
.splice(-1)
.join('');
const pathToComponentArray = fullPathToComponentArray.slice(
0,
fullPathToComponentArray.length - 1
);
const dragIndex = parseInt(dragIndexString, 10);
const hoverIndex = parseInt(hoverIndexString, 10);
// const dragPath = item.originalPath;
// const hoverPath = componentFieldName;
// const fullPathToComponentArray = dragPath.split('.');
// const dragIndexString = fullPathToComponentArray
// .slice()
// .splice(-1)
// .join('');
// const hoverIndexString = hoverPath
// .split('.')
// .splice(-1)
// .join('');
// const pathToComponentArray = fullPathToComponentArray.slice(
// 0,
// fullPathToComponentArray.length - 1
// );
// const dragIndex = parseInt(dragIndexString, 10);
// const hoverIndex = parseInt(hoverIndexString, 10);
// Don't replace items with themselves
if (dragIndex === hoverIndex) {
return;
}
// // Don't replace items with themselves
// if (dragIndex === hoverIndex) {
// return;
// }
// Determine rectangle on screen
const hoverBoundingRect = dropRef.current.getBoundingClientRect();
// Get vertical middle
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// Determine mouse position
const clientOffset = monitor.getClientOffset();
// Get pixels to the top
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// // Determine rectangle on screen
// const hoverBoundingRect = dropRef.current.getBoundingClientRect();
// // Get vertical middle
// const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
// // Determine mouse position
// const clientOffset = monitor.getClientOffset();
// // Get pixels to the top
// const hoverClientY = clientOffset.y - hoverBoundingRect.top;
// Only perform the move when the mouse has crossed half of the items height
// When dragging downwards, only move when the cursor is below 50%
// When dragging upwards, only move when the cursor is above 50%
// Dragging downwards
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
return;
}
// Dragging upwards
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
return;
}
// Time to actually perform the action in the data
moveComponentField(pathToComponentArray, dragIndex, hoverIndex);
// // Only perform the move when the mouse has crossed half of the items height
// // When dragging downwards, only move when the cursor is below 50%
// // When dragging upwards, only move when the cursor is above 50%
// // Dragging downwards
// if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
// return;
// }
// // Dragging upwards
// if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
// return;
// }
// // Time to actually perform the action in the data
// moveComponentField(pathToComponentArray, dragIndex, hoverIndex);
item.originalPath = hoverPath;
},
});
const [{ isDragging }, drag, preview] = useDrag({
type: ItemTypes.COMPONENT,
item: () => {
// Close all collapses
toggleCollapses(-1);
// item.originalPath = hoverPath;
// },
// });
// const [{ isDragging }, drag, preview] = useDrag({
// type: ItemTypes.COMPONENT,
// item: () => {
// // Close all collapses
// toggleCollapses(-1);
return {
displayedValue,
originalPath: componentFieldName,
};
},
end: () => {
// Update the errors
triggerFormValidation();
},
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
});
// return {
// displayedValue,
// originalPath: componentFieldName,
// };
// },
// end: () => {
// // Update the errors
// triggerFormValidation();
// },
// collect: monitor => ({
// isDragging: monitor.isDragging(),
// }),
// });
useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: false });
}, [preview]);
// useEffect(() => {
// preview(getEmptyImage(), { captureDraggingState: false });
// }, [preview]);
// Create the refs
// We need 1 for the drop target
// 1 for the drag target
const refs = {
dragRef: drag(dragRef),
dropRef: drop(dropRef),
};
// const refs = {
// dragRef: drag(dragRef),
// dropRef: drop(dropRef),
// };
return (
<StyledBox ref={refs ? refs.dropRef : null}>
{isDragging && <Preview />}
{!isDragging && (
<Accordion expanded={isOpen} toggle={onClickToggle} id={componentFieldName}>
<AccordionToggle
variant={isOdd ? 'primary' : 'secondary'}
title={toString(displayedValue)}
togglePosition="left"
action={
isReadOnly ? null : (
<Flex>
<IconButton
onClick={() => {
removeRepeatableField(componentFieldName);
toggleCollapses();
}}
label={formatMessage({
id: getTrad('containers.Edit.delete'),
defaultMessage: 'Edit',
})}
icon={<Trash />}
/>
<Box paddingLeft={2}>
<DragHandleWrapper
ref={refs.dragRef}
label={formatMessage({
id: getTrad('components.DragHandle-label'),
defaultMessage: 'Drag',
})}
icon={<DragHandle />}
/>
</Box>
</Flex>
)
}
/>
<AccordionContent>
<Box
background="neutral100"
paddingLeft={6}
paddingRight={6}
paddingTop={6}
paddingBottom={6}
>
<Stack size={6}>
{fields.map((fieldRow, key) => {
return (
<Grid gap={4} key={key}>
{fieldRow.map(({ name, fieldSchema, metadatas, queryInfos, size }) => {
const isComponent = fieldSchema.type === 'component';
const keys = `${componentFieldName}.${name}`;
<Accordion
disabled={false}
expanded={false}
toggle={() => {}}
id=''
size="S"
>
<AccordionToggle
action={
<Stack horizontal size={0}>
<CustomIconButton
expanded={false}
noBorder
onClick={() => console.log('delete')}
label="Delete"
icon={<Trash />}
disabled={false}
/>
<CustomIconButton
expanded={false}
noBorder
onClick={() => console.log('drag')}
label="Drag"
icon={<Drag />}
disabled={false}
/>
</Stack>
}
title={toString(displayedValue)}
togglePosition="left"
/>
<AccordionContent>
<Stack background='neutral100' paddingTop={5} paddingBottom={5} paddingLeft={7} paddingRight={7} size={3}>
kikou
</Stack>
</AccordionContent>
</Accordion>
// <StyledBox ref={refs ? refs.dropRef : null}>
// {isDragging && <Preview />}
// {!isDragging && (
// <Accordion expanded={isOpen} toggle={onClickToggle} id={componentFieldName}>
// <AccordionToggle
// variant={isOdd ? 'primary' : 'secondary'}
// title={toString(displayedValue)}
// togglePosition="left"
// action={
// isReadOnly ? null : (
// <Flex>
// <IconButton
// onClick={() => {
// removeRepeatableField(componentFieldName);
// toggleCollapses();
// }}
// label={formatMessage({
// id: getTrad('containers.Edit.delete'),
// defaultMessage: 'Edit',
// })}
// icon={<Trash />}
// />
// <Box paddingLeft={2}>
// <DragHandleWrapper
// ref={refs.dragRef}
// label={formatMessage({
// id: getTrad('components.DragHandle-label'),
// defaultMessage: 'Drag',
// })}
// icon={<DragHandle />}
// />
// </Box>
// </Flex>
// )
// }
// />
// <AccordionContent>
// <Box
// background="neutral100"
// paddingLeft={6}
// paddingRight={6}
// paddingTop={6}
// paddingBottom={6}
// >
// <Stack size={6}>
// {fields.map((fieldRow, key) => {
// return (
// <Grid gap={4} key={key}>
// {fieldRow.map(({ name, fieldSchema, metadatas, queryInfos, size }) => {
// const isComponent = fieldSchema.type === 'component';
// const keys = `${componentFieldName}.${name}`;
if (isComponent) {
const componentUid = fieldSchema.component;
// if (isComponent) {
// const componentUid = fieldSchema.component;
return (
<GridItem col={size} s={12} xs={12} key={name}>
<FieldComponent
componentUid={componentUid}
intlLabel={{
id: metadatas.label,
defaultMessage: metadatas.label,
}}
isRepeatable={fieldSchema.repeatable}
isNested
name={keys}
max={fieldSchema.max}
min={fieldSchema.min}
required={fieldSchema.required}
/>
</GridItem>
);
}
// return (
// <GridItem col={size} s={12} xs={12} key={name}>
// <FieldComponent
// componentUid={componentUid}
// intlLabel={{
// id: metadatas.label,
// defaultMessage: metadatas.label,
// }}
// isRepeatable={fieldSchema.repeatable}
// isNested
// name={keys}
// max={fieldSchema.max}
// min={fieldSchema.min}
// required={fieldSchema.required}
// />
// </GridItem>
// );
// }
return (
<GridItem key={keys} col={size} s={12} xs={12}>
<Inputs
fieldSchema={fieldSchema}
keys={keys}
metadatas={metadatas}
// onBlur={hasErrors ? checkFormErrors : null}
queryInfos={queryInfos}
/>
</GridItem>
);
})}
</Grid>
);
})}
</Stack>
</Box>
</AccordionContent>
</Accordion>
)}
</StyledBox>
// return (
// <GridItem key={keys} col={size} s={12} xs={12}>
// <Inputs
// fieldSchema={fieldSchema}
// keys={keys}
// metadatas={metadatas}
// // onBlur={hasErrors ? checkFormErrors : null}
// queryInfos={queryInfos}
// />
// </GridItem>
// );
// })}
// </Grid>
// );
// })}
// </Stack>
// </Box>
// </AccordionContent>
// </Accordion>
// )}
// </StyledBox>
);
};

View File

@ -1,22 +1,39 @@
import React, { memo, useCallback, useMemo, useState } from 'react';
/* eslint-disable import/no-cycle */
import { useDrop } from 'react-dnd';
// import { useDrop } from 'react-dnd';
import { useIntl } from 'react-intl';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import get from 'lodash/get';
import take from 'lodash/take';
// import { FormattedMessage } from 'react-intl';
import { useNotification } from '@strapi/helper-plugin';
import { Box } from '@strapi/design-system/Box';
import { AccordionGroup } from '@strapi/design-system/Accordion';
import { Flex } from '@strapi/design-system/Flex';
import { TextButton } from '@strapi/design-system/TextButton';
import Plus from '@strapi/icons/Plus';
// import { ErrorMessage } from '@buffetjs/styles';
import { getMaxTempKey, getTrad } from '../../utils';
import { useContentTypeLayout } from '../../hooks';
import ItemTypes from '../../utils/ItemTypes';
// import ItemTypes from '../../utils/ItemTypes';
import ComponentInitializer from '../ComponentInitializer';
import connect from './utils/connect';
import select from './utils/select';
import Button from './AddFieldButton';
import DraggedItem from './DraggedItem';
const TextButtonCustom = styled(TextButton)`
height: 100%;
width: 100%;
border-radius: 0 0 4px 4px;
display: flex;
justify-content: center;
span {
font-weight: 600;
font-size: 14px;
}
`;
const RepeatableComponent = ({
addRepeatableComponentToField,
formErrors,
@ -30,8 +47,9 @@ const RepeatableComponent = ({
name,
}) => {
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const [collapseToOpen, setCollapseToOpen] = useState('');
const [, drop] = useDrop({ accept: ItemTypes.COMPONENT });
// const [, drop] = useDrop({ accept: ItemTypes.COMPONENT });
const { getComponentLayout } = useContentTypeLayout();
const componentLayoutData = useMemo(() => getComponentLayout(componentUid), [
componentUid,
@ -94,8 +112,27 @@ const RepeatableComponent = ({
}
return (
<Box hasRadius borderColor="neutral200">
<Box ref={drop}>
<Box
hasRadius
background='neutral0'
shadow='tableShadow'
paddingLeft={7}
paddingRight={7}
paddingBottom={6}
paddingTop={6}
>
<AccordionGroup
footer={
<Flex justifyContent="center" height="48px" background="neutral0" hasRadius>
<TextButtonCustom disabled={isReadOnly} onClick={handleClick} startIcon={<Plus />}>
{formatMessage({
id: getTrad('containers.EditView.add.new-entry'),
defaultMessage: 'Add an entry',
})}
</TextButtonCustom>
</Flex>
}
>
{componentValue.map((data, index) => {
const key = data.__temp_key__;
const isOpen = collapseToOpen === key;
@ -134,20 +171,62 @@ const RepeatableComponent = ({
/>
);
})}
</Box>
<Button
// TODO
// hasMinError={hasMinError}
disabled={isReadOnly}
// TODO
// doesPreviousFieldContainErrorsAndIsClosed={
// componentValueLength > 0 &&
// componentErrorKeys.includes(`${name}.${componentValueLength - 1}`) &&
// componentValue[componentValueLength - 1].__temp_key__ !== collapseToOpen
// }
onClick={handleClick}
/>
</AccordionGroup>
</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 (