Created GroupCollapse component

This commit is contained in:
soupette 2019-07-15 13:00:31 +02:00
parent b15b608d07
commit d2896a1a77
11 changed files with 203 additions and 13 deletions

View File

@ -0,0 +1 @@
<svg width="7" height="5" xmlns="http://www.w3.org/2000/svg"><path d="M0 .469c0 .127.043.237.13.33l3.062 3.28a.407.407 0 0 0 .616 0L6.87.8A.467.467 0 0 0 7 .468a.467.467 0 0 0-.13-.33A.407.407 0 0 0 6.563 0H.438A.407.407 0 0 0 .13.14.467.467 0 0 0 0 .468z" fill="#007EFF" fill-rule="nonzero"/></svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@ -0,0 +1 @@
<svg width="6" height="8" xmlns="http://www.w3.org/2000/svg"><g fill="#ABB3C2" fill-rule="evenodd"><path d="M.79 0h2.018v2H.79zM3.816 0h2.017v2H3.816zM.79 3h2.018v2H.79zM3.816 3h2.017v2H3.816zM.79 6h2.018v2H.79zM3.816 6h2.017v2H3.816z"/></g></svg>

After

Width:  |  Height:  |  Size: 247 B

View File

@ -38,8 +38,10 @@ function Input({ type, ...rest }) {
const styles =
type === 'boolean' ? { minWidth: '100px', maxWidth: '200px' } : style;
const wrapperStyle = type == 'boolean' ? { marginRight: '20px' } : {};
return (
<InputWrapperDate type={type || 'text'}>
<InputWrapperDate type={type || 'text'} style={wrapperStyle}>
<Component {...rest} style={styles} />
</InputWrapperDate>
);

View File

@ -1,10 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { get, omit } from 'lodash';
import pluginId from '../../pluginId';
import { Button } from './components';
import GroupCollapse from './GroupCollapse';
import Inputs from './Inputs';
function Group({ isRepeatable, label, layout, name, groupValue, onChange }) {
function Group({
addField,
isRepeatable,
label,
layout,
// min,
max,
name,
groupValue,
onChange,
removeField,
}) {
const fields = get(layout, ['layouts', 'edit'], []);
return (
@ -27,7 +42,8 @@ function Group({ isRepeatable, label, layout, name, groupValue, onChange }) {
marginLeft: '-10px',
marginRight: '-10px',
backgroundColor: '#f5f5f5',
padding: '20px 20px 0px 10px',
padding: '0 20px 10px 10px',
paddingTop: isRepeatable ? '13px' : '20px',
}}
>
{!isRepeatable ? (
@ -95,7 +111,41 @@ function Group({ isRepeatable, label, layout, name, groupValue, onChange }) {
})}
</div>
) : (
<div className="col-12">COMING SOON</div>
<div className="col-12">
<div className="row">
{groupValue.map((field, index) => {
//
return (
<div className="col-12" key={index}>
<GroupCollapse
removeField={() => removeField(`${name}.${index}`)}
groupName={name}
/>
</div>
);
})}
<div className="col-12">
<Button
onClick={() => {
if (groupValue.length < max) {
addField(name);
return;
}
strapi.notification.info(
'You have already reached the maximum'
);
}}
>
<i className="fa fa-plus" />
<FormattedMessage
id={`${pluginId}.containers.EditView.Group.add.new`}
/>
</Button>
</div>
</div>
</div>
)}
</div>
</>
@ -106,15 +156,20 @@ Group.defaultProps = {
groupValue: {},
label: '',
layout: {},
max: Infinity,
onChange: () => {},
};
Group.propTypes = {
addField: PropTypes.func.isRequired,
groupValue: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
isRepeatable: PropTypes.bool.isRequired,
label: PropTypes.string,
layout: PropTypes.object,
max: PropTypes.number,
name: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
removeField: PropTypes.func.isRequired,
};
export default Group;

View File

@ -0,0 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import pluginId from '../../pluginId';
import Grab from '../../assets/images/grab_icon.svg';
import Logo from '../../assets/images/caret_top.svg';
import { Flex, GroupCollapseWrapper, ImgWrapper } from './components';
function GroupCollapse({ isCreating, isOpen, removeField }) {
const id = isCreating
? { id: `${pluginId}.containers.Edit.pluginHeader.title.new` }
: {};
return (
<GroupCollapseWrapper>
<Flex style={{ fontWeight: 500 }}>
<ImgWrapper isOpen={isOpen}>
<img src={Logo} alt="logo" />
</ImgWrapper>
<FormattedMessage {...id} />
</Flex>
<Flex>
<button type="button" style={{ marginRight: 8 }} onClick={removeField}>
<i className="fa fa-trash" />
</button>
<button type="button" style={{ lineHeigth: '32px' }}>
<img src={Grab} alt="grab icon" />
</button>
</Flex>
</GroupCollapseWrapper>
);
}
GroupCollapse.defaultProps = {
isCreating: true,
isOpen: false,
removeField: () => {},
};
GroupCollapse.propTypes = {
isCreating: PropTypes.bool,
isOpen: PropTypes.bool,
removeField: PropTypes.func,
};
export default GroupCollapse;

View File

@ -31,4 +31,63 @@ const LinkWrapper = styled(SubWrapper)`
}
`;
export { LinkWrapper, MainWrapper, SubWrapper };
const Button = styled.div`
width: 100%;
height: 34px;
text-align: center;
background-color: #fafafb;
border-radius: 2px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
color: #333740;
font-size: 12px;
font-weight: 700;
-webkit-font-smoothing: antialiased;
line-height: 35px;
cursor: pointer;
text-transform: uppercase;
> i {
margin-right: 10px;
}
`;
const Flex = styled.div`
display: flex;
`;
const GroupCollapseWrapper = styled(Flex)`
height: 34px;
margin-bottom: 2px;
padding: 0 20px;
justify-content: space-between;
line-height: 34px;
background-color: #ffffff;
font-size: 13px;
button:active {
outline: 0;
}
`;
const ImgWrapper = styled.div`
width: 21px;
height: 21px;
margin: auto;
margin-right: 20px;
border-radius: 50%;
background-color: #e3e9f3;
text-align: center;
line-height: 21px;
${({ isOpen }) => !isOpen && 'transform: rotate(180deg)'}
`;
export {
Button,
Flex,
GroupCollapseWrapper,
ImgWrapper,
LinkWrapper,
MainWrapper,
SubWrapper,
};

View File

@ -292,6 +292,12 @@ function EditView({
<Group
{...group}
{...groupMeta}
addField={keys => {
dispatch({
type: 'ADD_FIELD_TO_GROUP',
keys: keys.split('.'),
});
}}
groupValue={groupValue}
key={key}
isRepeatable={group.repeatable}
@ -304,6 +310,12 @@ function EditView({
});
}}
layout={get(groupLayoutsData, name, {})}
removeField={keys => {
dispatch({
type: 'ON_REMOVE_FIELD',
keys: keys.split('.'),
});
}}
/>
);
}
@ -380,7 +392,9 @@ function EditView({
<SubWrapper
style={{ padding: '0 20px 1px', marginBottom: '28px' }}
>
<div style={{ paddingTop: '19px' }}>Relations</div>
<div style={{ paddingTop: '19px' }}>
RELATIONS COMING SOON
</div>
</SubWrapper>
)}
<LinkWrapper>

View File

@ -11,6 +11,14 @@ const initialState = fromJS({
function reducer(state, action) {
switch (action.type) {
case 'ADD_FIELD_TO_GROUP':
return state.updateIn(['modifiedData', ...action.keys], list => {
if (list) {
return list.push(fromJS({}));
}
return fromJS([{}]);
});
case 'GET_DATA_SUCCEEDED':
return state
.update('initialData', () => fromJS(action.data))
@ -25,6 +33,8 @@ function reducer(state, action) {
['modifiedData', ...action.keys],
() => action.value
);
case 'ON_REMOVE_FIELD':
return state.removeIn(['modifiedData', ...action.keys]);
case 'RESET_FORM':
return state.update('modifiedData', () => state.get('initialData'));
case 'SET_COLLAPSES_COMPONENTS_STATE':

View File

@ -65,7 +65,7 @@
"containers.SettingPage.relations": "Relational fields",
"containers.SettingPage.settings": "Settings",
"containers.SettingPage.layout": "Layout",
"containers.EditView.Group.add.new": "ADD NEW ENTRY",
"containers.SettingViewModel.pluginHeader.title": "Content Manager - {name}",
"containers.SettingsPage.Block.contentType.description": "Configure the specific settings",

View File

@ -39,6 +39,7 @@
"containers.Edit.returnList": "Retourner à la liste",
"containers.Edit.seeDetails": "Détails",
"containers.Edit.submit": "Valider",
"containers.EditView.Group.add.new": "AJOUTER UNE ENTREE",
"containers.Edit.Link.Layout": "Paramétrer la vue",
"containers.Edit.Link.Fields": "Éditer le modèle",
"containers.Home.introduction": "Pour éditer du contenu, choisissez un type de données dans le menu de gauche.",

View File

@ -171,12 +171,12 @@ module.exports = {
size: 12,
},
],
[
{
name: 'ingredient',
size: 12,
},
],
// [
// {
// name: 'ingredient',
// size: 12,
// },
// ],
],
},
},