Add form logic

This commit is contained in:
soupette 2019-10-22 17:24:11 +02:00 committed by Alexandre Bodin
parent 4856f7b342
commit 7e47239da1
11 changed files with 140 additions and 30 deletions

View File

@ -0,0 +1,18 @@
import styled from 'styled-components';
const Link = styled.div`
position: absolute;
bottom: 4px;
left: 38px;
font-weight: 400;
color: #007eff;
cursor: pointer;
&:before {
content: '\f013';
margin-right: 7px;
font-family: 'FontAwesome';
font-size: 12px;
}
`;
export default Link;

View File

@ -11,7 +11,7 @@ const getColor = (isOverRemove, isSelected) => {
} }
}; };
const getHeight = withLongerHeight => (withLongerHeight ? '84px' : '30px'); const getHeight = withLongerHeight => (withLongerHeight ? '102px' : '30px');
const Wrapper = styled.div` const Wrapper = styled.div`
height: ${({ withLongerHeight }) => getHeight(withLongerHeight)}; height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
@ -26,6 +26,7 @@ const Wrapper = styled.div`
position: relative; position: relative;
height: ${({ withLongerHeight }) => getHeight(withLongerHeight)}; height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
line-height: ${({ withLongerHeight }) => getHeight(withLongerHeight)}; line-height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
cursor: pointer;
background: ${({ isOverRemove, isSelected }) => { background: ${({ isOverRemove, isSelected }) => {
if (isSelected) { if (isSelected) {

View File

@ -1,14 +1,16 @@
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
import React, { forwardRef, useState } from 'react'; import React, { forwardRef, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { Grab, GrabLarge, Pencil, Remove } from '@buffetjs/icons'; import { Grab, GrabLarge, Pencil, Remove } from '@buffetjs/icons';
import pluginId from '../../pluginId';
import Link from './Link';
import Wrapper from './Wrapper'; import Wrapper from './Wrapper';
const DraggedField = forwardRef( const DraggedField = forwardRef(
( (
{ {
children,
count, count,
isDragging, isDragging,
isHidden, isHidden,
@ -17,6 +19,7 @@ const DraggedField = forwardRef(
onRemove, onRemove,
selectedItem, selectedItem,
style, style,
type,
withLongerHeight, withLongerHeight,
}, },
ref ref
@ -35,17 +38,21 @@ const DraggedField = forwardRef(
withLongerHeight={withLongerHeight} withLongerHeight={withLongerHeight}
> >
{!isHidden && ( {!isHidden && (
<div className="sub_wrapper" style={{ opacity }}> <div
<div className="grab" ref={ref}> className="sub_wrapper"
style={{ opacity }}
onClick={() => {
onClick(name);
}}
>
<div className="grab" ref={ref} onClick={e => e.stopPropagation()}>
{withLongerHeight ? ( {withLongerHeight ? (
<GrabLarge style={{ marginRight: 10, cursor: 'move' }} /> <GrabLarge style={{ marginRight: 10, cursor: 'move' }} />
) : ( ) : (
<Grab style={{ marginRight: 10, cursor: 'move' }} /> <Grab style={{ marginRight: 10, cursor: 'move' }} />
)} )}
</div> </div>
<div className="name" onClick={() => onClick(name)}> <div className="name">{children ? children : name}</div>
{name}
</div>
<div <div
className="remove" className="remove"
onClick={onRemove} onClick={onRemove}
@ -56,12 +63,31 @@ const DraggedField = forwardRef(
</div> </div>
</div> </div>
)} )}
{type === 'group' && (
<FormattedMessage
id={`${pluginId}.components.FieldItem.linkToGroupLayout`}
>
{msg => (
<Link
onClick={e => {
e.stopPropagation();
// push(
// `/plugins/${pluginId}/ctm-configurations/groups/${groupUid}`
// )
}}
>
{msg}
</Link>
)}
</FormattedMessage>
)}
</Wrapper> </Wrapper>
); );
} }
); );
DraggedField.defaultProps = { DraggedField.defaultProps = {
children: null,
count: 1, count: 1,
isDragging: false, isDragging: false,
isHidden: false, isHidden: false,
@ -73,6 +99,7 @@ DraggedField.defaultProps = {
}; };
DraggedField.propTypes = { DraggedField.propTypes = {
children: PropTypes.node,
count: PropTypes.number, count: PropTypes.number,
isDragging: PropTypes.bool, isDragging: PropTypes.bool,
isHidden: PropTypes.bool, isHidden: PropTypes.bool,
@ -81,6 +108,7 @@ DraggedField.propTypes = {
onRemove: PropTypes.func, onRemove: PropTypes.func,
selectedItem: PropTypes.string, selectedItem: PropTypes.string,
style: PropTypes.object, style: PropTypes.object,
type: PropTypes.string,
withLongerHeight: PropTypes.bool, withLongerHeight: PropTypes.bool,
}; };

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
const Wrapper = styled.div` const Wrapper = styled.div`
display: flex; display: flex;
position: relative; position: relative;
height: ${({ withLongerHeight }) => (withLongerHeight ? '84px' : '30px')}; height: ${({ withLongerHeight }) => (withLongerHeight ? '102px' : '30px')};
.sub { .sub {
width: 100%; width: 100%;

View File

@ -1,9 +1,5 @@
import React, { forwardRef, useState } from 'react'; import React, { forwardRef, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
// import { FormattedMessage } from 'react-intl';
// import { Grab, Pencil, Remove } from '@buffetjs/icons';
// import pluginId from '../../pluginId';
import Carret from './Carret'; import Carret from './Carret';
import DraggedField from '../DraggedField'; import DraggedField from '../DraggedField';
import PreviewCarret from '../PreviewCarret'; import PreviewCarret from '../PreviewCarret';
@ -12,7 +8,16 @@ import Wrapper from './Wrapper';
// eslint-disable-next-line react/display-name // eslint-disable-next-line react/display-name
const DraggedFieldWithPreview = forwardRef( const DraggedFieldWithPreview = forwardRef(
( (
{ name, onClickRemove, showLeftCarret, showRightCarret, size, type }, {
name,
onClickEdit,
onClickRemove,
selectedItem,
showLeftCarret,
showRightCarret,
size,
type,
},
refs refs
) => { ) => {
const isHidden = name === '_TEMP_'; const isHidden = name === '_TEMP_';
@ -23,7 +28,7 @@ const DraggedFieldWithPreview = forwardRef(
const withLongerHeight = const withLongerHeight =
['json', 'text', 'file', 'media', 'group', 'richtext'].includes(type) && ['json', 'text', 'file', 'media', 'group', 'richtext'].includes(type) &&
!dragStart; !dragStart;
const carretStyle = withLongerHeight ? { height: '84px' } : {}; const carretStyle = withLongerHeight ? { height: '102px' } : {};
return ( return (
<div <div
@ -51,10 +56,13 @@ const DraggedFieldWithPreview = forwardRef(
ref={refs.dragRef} ref={refs.dragRef}
isHidden={isHidden} isHidden={isHidden}
name={name} name={name}
onClick={onClickEdit}
onRemove={onClickRemove} onRemove={onClickRemove}
selectedItem={selectedItem}
style={{ padding: 0, margin: 0, display }} style={{ padding: 0, margin: 0, display }}
type={type}
withLongerHeight={withLongerHeight} withLongerHeight={withLongerHeight}
/> ></DraggedField>
</div> </div>
{showRightCarret && <Carret right style={carretStyle} />} {showRightCarret && <Carret right style={carretStyle} />}
</> </>
@ -65,7 +73,9 @@ const DraggedFieldWithPreview = forwardRef(
); );
DraggedFieldWithPreview.defaultProps = { DraggedFieldWithPreview.defaultProps = {
onClickEdit: () => {},
onClickRemove: () => {}, onClickRemove: () => {},
selectedItem: '',
showLeftCarret: false, showLeftCarret: false,
showRightCarret: false, showRightCarret: false,
size: 1, size: 1,
@ -74,7 +84,9 @@ DraggedFieldWithPreview.defaultProps = {
DraggedFieldWithPreview.propTypes = { DraggedFieldWithPreview.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
onClickEdit: PropTypes.func,
onClickRemove: PropTypes.func, onClickRemove: PropTypes.func,
selectedItem: PropTypes.string,
showLeftCarret: PropTypes.bool, showLeftCarret: PropTypes.bool,
showRightCarret: PropTypes.bool, showRightCarret: PropTypes.bool,
size: PropTypes.number, size: PropTypes.number,

View File

@ -23,8 +23,8 @@ const Item = ({
const { const {
goTo, goTo,
metadatas, metadatas,
selectedItemName,
setEditFieldToSelect, setEditFieldToSelect,
selectedItemName,
} = useLayoutDnd(); } = useLayoutDnd();
const dragRef = useRef(null); const dragRef = useRef(null);
const dropRef = useRef(null); const dropRef = useRef(null);
@ -153,9 +153,6 @@ const Item = ({
// We will need to add a 12 size _TEMP_ div to offer a drop target between each existing row. // We will need to add a 12 size _TEMP_ div to offer a drop target between each existing row.
return name !== '_TEMP_'; return name !== '_TEMP_';
}, },
begin() {
setEditFieldToSelect(name, type);
},
collect: monitor => ({ collect: monitor => ({
isDragging: monitor.isDragging(), isDragging: monitor.isDragging(),
getItem: monitor.getItem(), getItem: monitor.getItem(),
@ -203,12 +200,15 @@ const Item = ({
<DraggedFieldWithPreview <DraggedFieldWithPreview
groupUid={groupUid} groupUid={groupUid}
isDragging={isDragging} isDragging={isDragging}
isSelected={name === selectedItemName}
label={get(metadatas, [name, 'edit', 'label'], '')} label={get(metadatas, [name, 'edit', 'label'], '')}
name={name} name={name}
onClickEdit={() => setEditFieldToSelect(name, type)} onClickEdit={setEditFieldToSelect}
onClickRemove={() => removeField(rowIndex, itemIndex)} onClickRemove={e => {
e.stopPropagation();
removeField(rowIndex, itemIndex);
}}
push={goTo} push={goTo}
selectedItem={selectedItemName}
showLeftCarret={showLeftCarret} showLeftCarret={showLeftCarret}
showRightCarret={showRightCarret} showRightCarret={showRightCarret}
size={size} size={size}

View File

@ -1,4 +1,10 @@
import React, { useCallback, useEffect, useMemo, useReducer } from 'react'; import React, {
useCallback,
useEffect,
useMemo,
useReducer,
useState,
} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { get } from 'lodash'; import { get } from 'lodash';
import { import {
@ -14,6 +20,7 @@ import getRequestUrl from '../../utils/getRequestUrl';
import FieldsReorder from '../../components/FieldsReorder'; import FieldsReorder from '../../components/FieldsReorder';
import FormTitle from '../../components/FormTitle'; import FormTitle from '../../components/FormTitle';
import LayoutTitle from '../../components/LayoutTitle'; import LayoutTitle from '../../components/LayoutTitle';
import PopupForm from '../../components/PopupForm';
import SettingsViewWrapper from '../../components/SettingsViewWrapper'; import SettingsViewWrapper from '../../components/SettingsViewWrapper';
import reducer, { initialState } from './reducer'; import reducer, { initialState } from './reducer';
@ -27,11 +34,19 @@ const EditSettingsView = ({
}, },
}) => { }) => {
const [reducerState, dispatch] = useReducer(reducer, initialState); const [reducerState, dispatch] = useReducer(reducer, initialState);
const [isModalFormOpen, setIsModalFormOpen] = useState(false);
const source = getQueryParameters(search, 'source'); const source = getQueryParameters(search, 'source');
const abortController = new AbortController(); const abortController = new AbortController();
const { signal } = abortController; const { signal } = abortController;
const params = source === 'content-manager' ? {} : { source }; const params = source === 'content-manager' ? {} : { source };
const { isLoading, initialData, modifiedData } = reducerState.toJS();
const {
fieldNameToEdit,
isLoading,
initialData,
modifiedData,
} = reducerState.toJS();
const getAttributes = useMemo(() => { const getAttributes = useMemo(() => {
return get(modifiedData, ['schema', 'attributes'], {}); return get(modifiedData, ['schema', 'attributes'], {});
@ -119,6 +134,12 @@ const EditSettingsView = ({
}); });
}; };
const toggleModalForm = () => {
setIsModalFormOpen(prevState => !prevState);
};
console.log(fieldNameToEdit);
return ( return (
<LayoutDndProvider <LayoutDndProvider
attributes={getAttributes} attributes={getAttributes}
@ -142,8 +163,14 @@ const EditSettingsView = ({
fieldIndex, fieldIndex,
}); });
}} }}
setEditFieldToSelect={() => {}} setEditFieldToSelect={name => {
selectedItemName={''} dispatch({
type: 'SET_FIELD_TO_EDIT',
name,
});
toggleModalForm();
}}
selectedItemName={fieldNameToEdit}
> >
<SettingsViewWrapper <SettingsViewWrapper
inputs={[ inputs={[
@ -192,6 +219,22 @@ const EditSettingsView = ({
<FieldsReorder /> <FieldsReorder />
</div> </div>
</SettingsViewWrapper> </SettingsViewWrapper>
<PopupForm
headerId={`${pluginId}.containers.EditSettingsView.modal-form.edit-field`}
isOpen={isModalFormOpen}
onClosed={() => {
dispatch({
type: 'UNSET_FIELD_TO_EDIT',
});
}}
onSubmit={e => {
e.preventDefault();
toggleModalForm();
}}
onToggle={toggleModalForm}
renderForm={() => {}}
subHeaderContent={fieldNameToEdit}
/>
</LayoutDndProvider> </LayoutDndProvider>
); );
}; };

View File

@ -3,8 +3,8 @@ import { cloneDeep, set } from 'lodash';
import { createLayout, formatLayout, getInputSize } from '../../utils/layout'; import { createLayout, formatLayout, getInputSize } from '../../utils/layout';
const initialState = fromJS({ const initialState = fromJS({
labelForm: {}, fieldForm: {},
labelToEdit: '', fieldNameToEdit: '',
initialData: {}, initialData: {},
isLoading: true, isLoading: true,
modifiedData: {}, modifiedData: {},
@ -140,6 +140,10 @@ const reducer = (state, action) => {
return state.updateIn(layoutPathEdit, () => fromJS(updatedList)); return state.updateIn(layoutPathEdit, () => fromJS(updatedList));
} }
case 'SET_FIELD_TO_EDIT':
return state.update('fieldNameToEdit', () => action.name);
case 'UNSET_FIELD_TO_EDIT':
return state.update('fieldNameToEdit', () => '');
default: default:
return state; return state;
} }

View File

@ -247,7 +247,9 @@ const ListSettingsView = ({
move={move} move={move}
name={item} name={item}
onClick={handleClickEditLabel} onClick={handleClickEditLabel}
onRemove={() => { onRemove={e => {
e.stopPropagation();
if (getListDisplayedFields().length === 1) { if (getListDisplayedFields().length === 1) {
strapi.notification.info( strapi.notification.info(
`${pluginId}.notification.info.minimumFields` `${pluginId}.notification.info.minimumFields`

View File

@ -68,6 +68,7 @@
"containers.ListPage.displayedFields": "Displayed Fields", "containers.ListPage.displayedFields": "Displayed Fields",
"containers.ListSettingsView.modal-form.edit-label": "Edit label", "containers.ListSettingsView.modal-form.edit-label": "Edit label",
"containers.EditSettingsView.modal-form.edit-field": "Edit field",
"containers.SettingPage.addField": "Add new field", "containers.SettingPage.addField": "Add new field",
"containers.SettingPage.addRelationalField": "Add new relational field", "containers.SettingPage.addRelationalField": "Add new relational field",

View File

@ -67,6 +67,7 @@
"containers.ListPage.displayedFields": "Champs affichés", "containers.ListPage.displayedFields": "Champs affichés",
"containers.ListSettingsView.modal-form.edit-label": "Editer le label", "containers.ListSettingsView.modal-form.edit-label": "Editer le label",
"containers.EditSettingsView.modal-form.edit-field": "Editer le champ",
"containers.SettingPage.addField": "Ajouter un nouveau champ", "containers.SettingPage.addField": "Ajouter un nouveau champ",
"containers.SettingPage.addRelationalField": "Ajouter un nouveau champ relationnel", "containers.SettingPage.addRelationalField": "Ajouter un nouveau champ relationnel",