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`
height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
@ -26,6 +26,7 @@ const Wrapper = styled.div`
position: relative;
height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
line-height: ${({ withLongerHeight }) => getHeight(withLongerHeight)};
cursor: pointer;
background: ${({ isOverRemove, isSelected }) => {
if (isSelected) {

View File

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

View File

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

View File

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

View File

@ -23,8 +23,8 @@ const Item = ({
const {
goTo,
metadatas,
selectedItemName,
setEditFieldToSelect,
selectedItemName,
} = useLayoutDnd();
const dragRef = 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.
return name !== '_TEMP_';
},
begin() {
setEditFieldToSelect(name, type);
},
collect: monitor => ({
isDragging: monitor.isDragging(),
getItem: monitor.getItem(),
@ -203,12 +200,15 @@ const Item = ({
<DraggedFieldWithPreview
groupUid={groupUid}
isDragging={isDragging}
isSelected={name === selectedItemName}
label={get(metadatas, [name, 'edit', 'label'], '')}
name={name}
onClickEdit={() => setEditFieldToSelect(name, type)}
onClickRemove={() => removeField(rowIndex, itemIndex)}
onClickEdit={setEditFieldToSelect}
onClickRemove={e => {
e.stopPropagation();
removeField(rowIndex, itemIndex);
}}
push={goTo}
selectedItem={selectedItemName}
showLeftCarret={showLeftCarret}
showRightCarret={showRightCarret}
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 { get } from 'lodash';
import {
@ -14,6 +20,7 @@ import getRequestUrl from '../../utils/getRequestUrl';
import FieldsReorder from '../../components/FieldsReorder';
import FormTitle from '../../components/FormTitle';
import LayoutTitle from '../../components/LayoutTitle';
import PopupForm from '../../components/PopupForm';
import SettingsViewWrapper from '../../components/SettingsViewWrapper';
import reducer, { initialState } from './reducer';
@ -27,11 +34,19 @@ const EditSettingsView = ({
},
}) => {
const [reducerState, dispatch] = useReducer(reducer, initialState);
const [isModalFormOpen, setIsModalFormOpen] = useState(false);
const source = getQueryParameters(search, 'source');
const abortController = new AbortController();
const { signal } = abortController;
const params = source === 'content-manager' ? {} : { source };
const { isLoading, initialData, modifiedData } = reducerState.toJS();
const {
fieldNameToEdit,
isLoading,
initialData,
modifiedData,
} = reducerState.toJS();
const getAttributes = useMemo(() => {
return get(modifiedData, ['schema', 'attributes'], {});
@ -119,6 +134,12 @@ const EditSettingsView = ({
});
};
const toggleModalForm = () => {
setIsModalFormOpen(prevState => !prevState);
};
console.log(fieldNameToEdit);
return (
<LayoutDndProvider
attributes={getAttributes}
@ -142,8 +163,14 @@ const EditSettingsView = ({
fieldIndex,
});
}}
setEditFieldToSelect={() => {}}
selectedItemName={''}
setEditFieldToSelect={name => {
dispatch({
type: 'SET_FIELD_TO_EDIT',
name,
});
toggleModalForm();
}}
selectedItemName={fieldNameToEdit}
>
<SettingsViewWrapper
inputs={[
@ -192,6 +219,22 @@ const EditSettingsView = ({
<FieldsReorder />
</div>
</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>
);
};

View File

@ -3,8 +3,8 @@ import { cloneDeep, set } from 'lodash';
import { createLayout, formatLayout, getInputSize } from '../../utils/layout';
const initialState = fromJS({
labelForm: {},
labelToEdit: '',
fieldForm: {},
fieldNameToEdit: '',
initialData: {},
isLoading: true,
modifiedData: {},
@ -140,6 +140,10 @@ const reducer = (state, action) => {
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:
return state;
}

View File

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

View File

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

View File

@ -67,6 +67,7 @@
"containers.ListPage.displayedFields": "Champs affichés",
"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.addRelationalField": "Ajouter un nouveau champ relationnel",