Init meta form

This commit is contained in:
soupette 2019-07-24 18:24:23 +02:00
parent 8a5361813a
commit 5dd3c9ed81
15 changed files with 187 additions and 37 deletions

View File

@ -6,14 +6,22 @@
import React, { memo } from 'react';
import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import styles from './styles.scss';
import styled from 'styled-components';
const Wrapper = styled.div`
position: absolute;
top: 0;
right: 40px;
color: #b4b6ba;
font-style: italic;
`;
function ClickOverHint({ show }) {
if (show) {
return (
<div className={styles.clickOverHint}>
<Wrapper>
<FormattedMessage id="content-manager.components.DraggableAttr.edit" />
</div>
</Wrapper>
);
}

View File

@ -1,7 +0,0 @@
.clickOverHint {
position: absolute;
top: 0;
right: 40px;
color: #B4B6BA;
font-style: italic;
}

View File

@ -0,0 +1,38 @@
import styled, { css } from 'styled-components';
import BlueIcon from '../../assets/images/icon-edit-blue.svg';
const FieldEditIcon = styled.span`
width: 30px;
float: right;
background: #aed4fb;
text-align: center;
cursor: pointer;
&:after {
display: inline-block;
content: '';
width: 10px;
height: 10px;
margin: auto;
background-image: url(${BlueIcon});
}
${({ withLongerHeight }) => {
if (withLongerHeight) {
return css`
height: 82px;
line-height: 82px;
`;
}
return css`
height: 28px;
&:after {
margin-top: -3px;
}
`;
}}
`;
export default FieldEditIcon;

View File

@ -77,8 +77,8 @@ const NameWrapper = styled.div`
`;
}
}}
${({ isEditing }) => {
if (isEditing) {
${({ isEditing, isSelected }) => {
if (isEditing || isSelected) {
return css`
background: #e6f0fb;
border: 1px solid #aed4fb;

View File

@ -1,9 +1,11 @@
import React, { forwardRef } from 'react';
import React, { forwardRef, useState } from 'react';
import PropTypes from 'prop-types';
// import EditIcon from '../VariableEditIcon';
import GrabIconBlue from '../../assets/images/icon_grab_blue.svg';
import GrabIcon from '../../assets/images/icon_grab.svg';
import ClickOverHint from '../ClickOverHint';
import EditIcon from '../FieldEditIcon';
import RemoveIcon from '../DraggedRemovedIcon';
import { Carret, FullWidthCarret, NameWrapper, Wrapper } from './components';
@ -12,7 +14,9 @@ const FieldItem = forwardRef(
{
isDragging,
isEditing,
isSelected,
name,
onClickEdit,
onClickRemove,
showLeftCarret,
showRightCarret,
@ -22,6 +26,7 @@ const FieldItem = forwardRef(
},
ref
) => {
const [isOver, setIsOver] = useState(false);
const isHidden = name === '_TEMP_';
const withLongerHeight = [
'json',
@ -31,9 +36,31 @@ const FieldItem = forwardRef(
'WYSIWYG',
].includes(type);
const carretStyle = withLongerHeight ? { height: '84px' } : {};
const renderIcon = () => {
if (isHidden) {
return null;
}
return (isSelected || isEditing) && !isOver ? (
<EditIcon withLongerHeight={withLongerHeight} />
) : (
<RemoveIcon
onClick={onClickRemove}
withLongerHeight={withLongerHeight}
isDragging={isOver && isSelected}
/>
);
};
const opacity = isDragging ? 0 : 1;
return (
<div style={{ width: `${(1 / 12) * size * 100}%`, ...style }} ref={ref}>
<div
onClick={onClickEdit}
onMouseEnter={() => setIsOver(true)}
onMouseLeave={() => setIsOver(false)}
style={{ width: `${(1 / 12) * size * 100}%`, ...style }}
ref={ref}
>
<Wrapper>
{isDragging && size === 12 ? (
<FullWidthCarret>
@ -42,29 +69,27 @@ const FieldItem = forwardRef(
) : (
<>
{showLeftCarret && <Carret style={carretStyle} />}
<div className="sub_wrapper">
<div className="sub_wrapper" style={{ opacity }}>
<NameWrapper
style={carretStyle}
isEditing={isEditing}
isHidden={isHidden}
isSelected={isSelected}
>
<div>
{!isHidden && (
<img
src={isEditing ? GrabIconBlue : GrabIcon}
src={isEditing || isSelected ? GrabIconBlue : GrabIcon}
alt="Grab Icon"
style={{ marginRight: 10 }}
/>
)}
<span className="name">{!isHidden && name}</span>
{!isHidden && (
<ClickOverHint show={isOver && !isSelected} />
)}
</div>
{!isHidden && (
<RemoveIcon
onClick={onClickRemove}
withLongerHeight={withLongerHeight}
isDragging={isEditing}
/>
)}
{renderIcon()}
</NameWrapper>
</div>
{showRightCarret && <Carret right style={carretStyle} />}
@ -79,6 +104,8 @@ const FieldItem = forwardRef(
FieldItem.defaultProps = {
isDragging: false,
isEditing: false,
isSelected: false,
onClickEdit: () => {},
onClickRemove: () => {},
showLeftCarret: false,
showRightCarret: false,
@ -89,7 +116,9 @@ FieldItem.defaultProps = {
FieldItem.propTypes = {
isDragging: PropTypes.bool,
isEditing: PropTypes.bool,
isSelected: PropTypes.bool,
name: PropTypes.string.isRequired,
onClickEdit: PropTypes.func,
onClickRemove: PropTypes.func,
showLeftCarret: PropTypes.bool,
showRightCarret: PropTypes.bool,

View File

@ -3,6 +3,7 @@ import { useDrag, useDrop } from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';
import PropTypes from 'prop-types';
import { useLayoutDnd } from '../../contexts/LayoutDnd';
import FieldItem from '../FieldItem';
import ItemTypes from '../../utils/itemsTypes';
@ -17,7 +18,7 @@ const Item = ({
size,
type,
}) => {
// console.log({ rowIndex });
const { selectedItemName, setEditFieldToSelect } = useLayoutDnd();
const ref = useRef(null);
const [{ clientOffset, isOver }, drop] = useDrop({
accept: ItemTypes.EDIT_FIELD,
@ -143,6 +144,9 @@ const Item = ({
canDrag() {
return name !== '_TEMP_';
},
begin() {
setEditFieldToSelect(name, type);
},
collect: monitor => ({
isDragging: monitor.isDragging(),
getItem: monitor.getItem(),
@ -184,7 +188,9 @@ const Item = ({
return (
<FieldItem
isDragging={isDragging}
isSelected={name === selectedItemName}
name={name}
onClickEdit={() => setEditFieldToSelect(name, type)}
onClickRemove={() => removeField(rowIndex, itemIndex)}
showLeftCarret={showLeftCarret}
showRightCarret={showRightCarret}

View File

@ -2,12 +2,14 @@ import React, { useEffect, useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import PropTypes from 'prop-types';
import { getEmptyImage } from 'react-dnd-html5-backend';
import { useLayoutDnd } from '../../contexts/LayoutDnd';
import FieldItem from '../FieldItem';
import ItemTypes from '../../utils/itemsTypes';
const Item = ({ index, move, name, removeItem }) => {
const { selectedItemName, setEditFieldToSelect } = useLayoutDnd();
const ref = useRef(null);
// from: https://codesandbox.io/s/github/react-dnd/react-dnd/tree/gh-pages/examples_hooks_js/04-sortable/simple?from-embed
@ -53,6 +55,9 @@ const Item = ({ index, move, name, removeItem }) => {
},
});
const [{ isDragging }, drag, preview] = useDrag({
begin() {
setEditFieldToSelect(name, 'relation');
},
item: { type: ItemTypes.EDIT_RELATION, id: name, name, index },
collect: monitor => ({
isDragging: monitor.isDragging(),
@ -67,11 +72,13 @@ const Item = ({ index, move, name, removeItem }) => {
return (
<FieldItem
isDragging={isDragging}
isSelected={name === selectedItemName}
name={name}
onClickEdit={() => setEditFieldToSelect(name, 'relation')}
onClickRemove={() => removeItem(index)}
ref={ref}
size={12}
isDragging={isDragging}
name={name}
onClickRemove={() => removeItem(index)}
style={{ marginBottom: 6 }}
/>
);

View File

@ -101,10 +101,11 @@ function EditView({
);
const groupLayouts = data.reduce((acc, current) => {
acc[current.data.uid] = current.layout;
acc[current.data.uid] = current.data;
return acc;
}, {});
// console.log()
// Retrieve all the default values for the repeatables and init the form
const defaultGroupValues = groups.reduce((acc, current) => {
const defaultForm = setDefaultForm(
@ -141,7 +142,6 @@ function EditView({
});
} catch (err) {
// TODO ADD A TRAD
console.log({ err });
if (err.code !== 20) {
strapi.notification.error('notification.error');
@ -379,7 +379,7 @@ function EditView({
title={pluginHeaderTitle}
/>
<div className="row">
<div className="coel-md-12 col-lg-9">
<div className="col-md-12 col-lg-9">
<MainWrapper>
{fields.map((fieldsRow, key) => {
const [{ name }] = fieldsRow;

View File

@ -6,7 +6,7 @@ import GrabIcon from '../../assets/images/icon_grab.svg';
import GrabIconBlue from '../../assets/images/icon_grab_blue.svg';
import ClickOverHint from '../../components/ClickOverHint';
import RemoveIcon from '../../components/DraggedRemovedIcon';
import EditIcon from '../../components/VariableEditIcon';
import EditIcon from '../../components/FieldEditIcon';
import { Field, InfoLabel, FullWidthCarret } from './components';
import ItemTypes from '../../utils/itemsTypes';

View File

@ -18,6 +18,7 @@ import {
REORDER_DIFF_ROW,
REORDER_ROW,
RESET_PROPS,
SET_EDIT_FIELD_TO_SELECT,
SET_LIST_FIELD_TO_EDIT_INDEX,
SUBMIT_SUCCEEDED,
} from './constants';
@ -51,7 +52,7 @@ export function getData(uid, source) {
};
}
export function getDataSucceeded(layout) {
export function getDataSucceeded(layout, itemNameToSelect, itemFormType) {
set(
layout,
['layouts', 'edit'],
@ -60,6 +61,8 @@ export function getDataSucceeded(layout) {
return {
type: GET_DATA_SUCCEEDED,
layout,
itemFormType,
itemNameToSelect,
};
}
@ -167,6 +170,14 @@ export function resetProps() {
};
}
export function setEditFieldToSelect(name, fieldType) {
return {
type: SET_EDIT_FIELD_TO_SELECT,
name,
fieldType,
};
}
export function setListFieldToEditIndex(index) {
return {
type: SET_LIST_FIELD_TO_EDIT_INDEX,

View File

@ -22,6 +22,8 @@ export const REORDER_ROW = 'ContentManager/SettingViewModel/REORDER_ROW';
export const REORDER_DIFF_ROW =
'ContentManager/SettingViewModel/REORDER_DIFF_ROW';
export const RESET_PROPS = 'ContentManager/SettingViewModel/RESET_PROPS';
export const SET_EDIT_FIELD_TO_SELECT =
'ContentManager/SettingViewModel/SET_EDIT_FIELD_TO_SELECT';
export const SET_LIST_FIELD_TO_EDIT_INDEX =
'ContentManager/SettingViewModel/SET_LIST_FIELD_TO_EDIT_INDEX';
export const SUBMIT_SUCCEEDED =

View File

@ -46,6 +46,7 @@ import {
reorderDiffRow,
reorderRow,
resetProps,
setEditFieldToSelect,
setListFieldToEditIndex,
} from './actions';
import reducer from './reducer';
@ -53,6 +54,7 @@ import saga from './saga';
import makeSelectSettingViewModel from './selectors';
import forms from './forms.json';
import SettingFormWrapper from '../../components/SettingFormWrapper';
const getUrl = (name, to, source) =>
`/plugins/${pluginId}/ctm-configurations/models/${name}/${to}${
@ -69,6 +71,8 @@ function SettingViewModel({
history: { goBack },
initialData,
isLoading,
itemFormType,
itemNameToSelect,
listFieldToEditIndex,
location: { search },
match: {
@ -88,6 +92,7 @@ function SettingViewModel({
reorderDiffRow,
reorderRow,
resetProps,
setEditFieldToSelect,
setListFieldToEditIndex,
shouldToggleModalSubmit,
}) {
@ -247,6 +252,8 @@ function SettingViewModel({
onAddData={onAddData}
relationsLayout={getRelationsLayout()}
removeField={removeField}
setEditFieldToSelect={setEditFieldToSelect}
selectedItemName={itemNameToSelect}
>
<BackHeader onClick={() => goBack()} />
<Container className="container-fluid">
@ -354,6 +361,11 @@ function SettingViewModel({
removeItem={removeRelation}
/>
)}
{settingType === 'edit-settings' && (
<div className="col-8">
<SettingFormWrapper>{itemFormType}</SettingFormWrapper>
</div>
)}
</div>
</Block>
</div>
@ -402,6 +414,8 @@ SettingViewModel.propTypes = {
}).isRequired,
initialData: PropTypes.object.isRequired,
isLoading: PropTypes.bool.isRequired,
itemFormType: PropTypes.string.isRequired,
itemNameToSelect: PropTypes.string.isRequired,
listFieldToEditIndex: PropTypes.number.isRequired,
location: PropTypes.shape({
search: PropTypes.string,
@ -426,6 +440,7 @@ SettingViewModel.propTypes = {
reorderDiffRow: PropTypes.func.isRequired,
reorderRow: PropTypes.func.isRequired,
resetProps: PropTypes.func.isRequired,
setEditFieldToSelect: PropTypes.func.isRequired,
setListFieldToEditIndex: PropTypes.func.isRequired,
shouldToggleModalSubmit: PropTypes.bool.isRequired,
};
@ -452,6 +467,7 @@ export function mapDispatchToProps(dispatch) {
reorderDiffRow,
reorderRow,
resetProps,
setEditFieldToSelect,
setListFieldToEditIndex,
},
dispatch

View File

@ -23,15 +23,18 @@ import {
REORDER_DIFF_ROW,
REORDER_ROW,
RESET_PROPS,
SET_EDIT_FIELD_TO_SELECT,
SET_LIST_FIELD_TO_EDIT_INDEX,
SUBMIT_SUCCEEDED,
} from './constants';
export const initialState = fromJS({
didDrop: false,
listFieldToEditIndex: 0,
initialData: fromJS({}),
isLoading: true,
itemFormType: '',
itemNameToSelect: '',
listFieldToEditIndex: 0,
modifiedData: fromJS({}),
shouldToggleModalSubmit: true,
});
@ -75,7 +78,9 @@ function settingViewModelReducer(state = initialState, action) {
return state
.update('initialData', () => fromJS(action.layout || {}))
.update('isLoading', () => false)
.update('modifiedData', () => fromJS(action.layout || {}));
.update('modifiedData', () => fromJS(action.layout || {}))
.update('itemFormType', () => action.itemFormType)
.update('itemNameToSelect', () => action.itemNameToSelect);
case MOVE_FIELD_LIST:
return state
.updateIn(['modifiedData', 'layouts', 'list'], list => {
@ -206,6 +211,10 @@ function settingViewModelReducer(state = initialState, action) {
.update('didDrop', v => !v);
case RESET_PROPS:
return initialState;
case SET_EDIT_FIELD_TO_SELECT:
return state
.update('itemNameToSelect', () => action.name)
.update('itemFormType', () => action.fieldType);
case SET_LIST_FIELD_TO_EDIT_INDEX:
return state.update('listFieldToEditIndex', () => action.index);
case SUBMIT_SUCCEEDED:

View File

@ -1,5 +1,5 @@
import { all, fork, put, call, takeLatest, select } from 'redux-saga/effects';
import { set } from 'lodash';
import { get, set } from 'lodash';
import { request } from 'strapi-helper-plugin';
import pluginId from '../../pluginId';
@ -23,7 +23,29 @@ export function* getData({ source, uid }) {
}
);
yield put(getDataSucceeded(layout));
const firstEditLayoutField = get(
layout,
['layouts', 'edit', 0, 0, 'name'],
''
);
const firstEditLayoutFieldType = get(
layout,
['schema', 'attributes', firstEditLayoutField, 'type'],
null
);
const firstEditLayoutRelation = get(
layout,
['layouts', 'editRelations', 0],
null
);
const formItemToSelectName =
firstEditLayoutField || firstEditLayoutRelation;
const formItemToSelectType = firstEditLayoutFieldType || 'relation';
yield put(
getDataSucceeded(layout, formItemToSelectName, formItemToSelectType)
);
} catch (err) {
strapi.notification.error('notification.error');
}
@ -36,6 +58,7 @@ export function* submit({ emitEvent, uid }) {
set(body, 'layouts.edit', unformatLayout(body.layouts.edit));
delete body.schema;
delete body.uid;
yield call(request, getRequestUrl(`content-types/${uid}`), {
method: 'PUT',

View File

@ -7,12 +7,15 @@ export function LayoutDndProvider({
attributes,
buttonData,
children,
layout,
moveItem,
moveRow,
onAddData,
relationsLayout,
removeField,
selectedItemName,
setEditFieldToSelect,
}) {
return (
<LayoutDndContext.Provider
@ -25,6 +28,8 @@ export function LayoutDndProvider({
onAddData,
relationsLayout,
removeField,
selectedItemName,
setEditFieldToSelect,
}}
>
{children}
@ -42,6 +47,7 @@ LayoutDndProvider.defaultProps = {
layout: [],
onAddData: () => {},
relationsLayout: [],
setEditFieldToSelect: () => {},
};
LayoutDndProvider.propTypes = {
@ -54,4 +60,6 @@ LayoutDndProvider.propTypes = {
onAddData: PropTypes.func,
relationsLayout: PropTypes.array,
removeField: PropTypes.func.isRequired,
selectedItemName: PropTypes.string.isRequired,
setEditFieldToSelect: PropTypes.func,
};