Review apply

This commit is contained in:
Virginie Ky 2019-07-08 18:58:29 +02:00
parent 41c2feeacc
commit b6a5ae5644
30 changed files with 205 additions and 153 deletions

View File

@ -6,7 +6,7 @@
display: flex;
flex-direction: row;
overflow: hidden;
margin-top: 4.3rem;
margin-top: 3.8rem;
border-radius: 2px;
box-shadow: 0 2px 4px #e3e9f3;
> a {

View File

@ -10,9 +10,18 @@ const Wrapper = styled.div`
padding: 1.9rem 3rem 1.8rem 3rem;
position: relative;
background-color: white;
div {
p {
width: fit-content;
display: inline-block;
}
}
p {
margin-bottom: 0;
}
button {
position: absolute;
top: 1.7rem;
top: 1.9rem;
right: 1rem;
outline: 0;
}

View File

@ -6,13 +6,23 @@ import SubTitle from './SubTitle';
import Title from './Title';
import Wrapper from './Wrapper';
function ListHeader({ button, subtitle, subtitleValues, title, titleValues }) {
function ListHeader({ button, subtitle, subtitleValues, title }) {
return (
<Wrapper>
{button && <Button {...button} />}
<FormattedMessage id={title} values={titleValues}>
{msg => <Title>{msg}</Title>}
</FormattedMessage>
<div>
{title.map(item => {
return (
<FormattedMessage
key={item.label}
id={item.label}
values={item.values}
>
{msg => <Title>{msg}&nbsp;</Title>}
</FormattedMessage>
);
})}
</div>
<FormattedMessage id={subtitle} values={subtitleValues}>
{msg => <SubTitle>{msg}</SubTitle>}
</FormattedMessage>
@ -24,16 +34,19 @@ ListHeader.defaultProps = {
button: null,
subtitle: 'app.utils.defaultMessage',
subtitleValues: {},
title: 'app.utils.defaultMessage',
titleValues: {},
title: null,
};
ListHeader.propTypes = {
button: PropTypes.object,
subtitle: PropTypes.string,
subtitleValues: PropTypes.object,
title: PropTypes.string,
titleValues: PropTypes.object,
title: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.string,
values: PropTypes.object,
})
),
};
export default ListHeader;

View File

@ -13,7 +13,7 @@ const ListWrapper = styled.div`
overflow-x: scroll;
}
.list-button {
padding: 1rem 3rem 2.5rem 3rem;
padding: 1.3rem 3rem 2.5rem 3rem;
button {
width: 100%;
}

View File

@ -93,7 +93,6 @@ export { default as PopUpWarning } from './components/PopUpWarning';
// Utils
export { default as auth } from './utils/auth';
export { default as attributeIcons } from './utils/attributeIcons';
export { default as cleanData } from './utils/cleanData';
export { darken } from './utils/colors';
export { default as getQueryParameters } from './utils/getQueryParameters';

View File

@ -8,8 +8,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { capitalize } from 'lodash';
import { attributeIcons, IcoContainer } from 'strapi-helper-plugin';
import { IcoContainer } from 'strapi-helper-plugin';
import attributeIcons from '../../utils/attributeIcons';
import pluginId from '../../pluginId';
import styles from './styles.scss';

View File

@ -7,8 +7,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { attributeIcons } from 'strapi-helper-plugin';
import attributeIcons from '../../utils/attributeIcons';
import pluginId from '../../pluginId';
import styles from './styles.scss';

View File

@ -3,12 +3,15 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { attributeIcons, PopUpWarning } from 'strapi-helper-plugin';
import { PopUpWarning } from 'strapi-helper-plugin';
import attributeIcons from '../../utils/attributeIcons';
import pluginId from '../../pluginId';
import StyledListRow from './StyledListRow';
function ListRow({
attributeId,
canOpenModal,
deleteAttribute,
isTemporary,
@ -47,9 +50,14 @@ function ListRow({
)}
</FormattedMessage>
)}
&nbsp; &nbsp; &nbsp;
{isTemporary && (
<FormattedMessage id={`${pluginId}.contentType.temporaryDisplay`} />
<FormattedMessage
id={`${pluginId}.contentType.temporaryDisplay`}
style={{
paddingLeft: '15px',
}}
/>
)}
</p>
</td>
@ -95,7 +103,7 @@ function ListRow({
type="danger"
onConfirm={() => {
setIsOpen(false);
deleteAttribute(name);
deleteAttribute(attributeId);
}}
/>
</>
@ -112,6 +120,7 @@ ListRow.defaultProps = {
};
ListRow.propTypes = {
attributeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
canOpenModal: PropTypes.bool,
deleteAttribute: PropTypes.func,
isTemporary: PropTypes.bool.isRequired,

View File

@ -43,10 +43,6 @@ import {
SUBMIT_CONTENT_TYPE_SUCCEEDED,
SUBMIT_TEMP_CONTENT_TYPE,
SUBMIT_TEMP_CONTENT_TYPE_SUCCEEDED,
SUBMIT_GROUP,
SUBMIT_GROUP_SUCCEEDED,
SUBMIT_TEMP_GROUP,
SUBMIT_TEMP_GROUP_SUCCEEDED,
UPDATE_TEMP_CONTENT_TYPE,
ON_CHANGE_EXISTING_CONTENT_TYPE_MAIN_INFOS,
} from './constants';
@ -438,42 +434,6 @@ export function updateTempContentType() {
};
}
export function submitGroup(oldGroupName, data, context, source) {
const attributes = formatGroupAttributes(data.attributes);
const body = Object.assign(cloneDeep(data), { attributes });
return {
type: SUBMIT_GROUP,
oldGroupName,
body,
source,
context,
};
}
export function submitGroupSucceeded() {
return {
type: SUBMIT_GROUP_SUCCEEDED,
};
}
export function submitTempGroup(data, context) {
const attributes = formatGroupAttributes(data.attributes);
const body = Object.assign(cloneDeep(data), { attributes });
return {
type: SUBMIT_TEMP_GROUP,
body,
context,
};
}
export function submitTempGroupSucceeded() {
return {
type: SUBMIT_TEMP_GROUP_SUCCEEDED,
};
}
// utils
export const buildModelAttributes = attributes => {
const formattedAttributes = attributes.reduce((acc, current) => {

View File

@ -259,27 +259,9 @@ function appReducer(state = initialState, action) {
)
)
.update('newGroupClone', () => state.get('newGroup'));
case DELETE_GROUP_ATTRIBUTE: {
const pathToAttributes = action.keys
.slice()
.reverse()
.splice(1)
.reverse();
const attributes = state.getIn(pathToAttributes);
const attributeName = action.keys.pop();
const attributeToDelete = attributes.findIndex(
attribute => attribute.get('name') === attributeName
);
return state.removeIn([...pathToAttributes, attributeToDelete]);
}
case DELETE_GROUP_ATTRIBUTE:
return state.removeIn(action.keys);
case DELETE_GROUP_SUCCEEDED:
console.log({
st: state
.get('groups')
.findIndex(group => group.get('uid') === action.uid),
action,
});
return state.removeIn([
'groups',
state.get('groups').findIndex(group => group.get('uid') === action.uid),

View File

@ -16,9 +16,9 @@ import {
Button,
EmptyAttributesBlock,
getQueryParameters,
ListWrapper,
ListHeader,
List,
ListHeader,
ListWrapper,
} from 'strapi-helper-plugin';
import { deleteGroupAttribute } from '../App/actions';
@ -132,9 +132,15 @@ export class GroupPage extends React.Component {
const attributes = this.getFeatureAttributes();
const attributesNumber = this.getFeatureAttributesLength();
const listTitle = `${pluginId}.table.attributes.title.${
attributesNumber > 1 ? 'plural' : 'singular'
}`;
const title = [
{
label: `${pluginId}.table.attributes.title.${
attributesNumber > 1 ? 'plural' : 'singular'
}`,
values: { number: attributesNumber },
},
];
const buttonProps = {
kind: 'secondaryHotlineAdd',
@ -153,26 +159,21 @@ export class GroupPage extends React.Component {
>
{attributesNumber === 0 ? (
<EmptyAttributesBlock
description={`${pluginId}.home.emptyAttributes.description.${
this.featureType
}`}
description={`${pluginId}.home.emptyAttributes.description.${this.featureType}`}
id="openAddAttr"
label="content-type-builder.button.attributes.add"
title="content-type-builder.home.emptyAttributes.title"
/>
) : (
<ListWrapper>
<ListHeader
title={listTitle}
titleValues={{ number: attributesNumber }}
button={{ ...buttonProps }}
/>
<ListHeader title={title} button={{ ...buttonProps }} />
<List>
<table>
<tbody>
{attributes.map(attribute => (
{attributes.map((attribute, index) => (
<ListRow
key={attribute.name}
attributeId={index}
{...attribute}
canOpenModal={canOpenModal}
context={this.context}

View File

@ -24,6 +24,9 @@ const Tr = styled.tr`
button {
cursor: pointer;
}
p {
margin-bottom: 0;
}
`;
export default Tr;

View File

@ -106,9 +106,14 @@ class HomePage extends React.Component {
const displayedData = type === 'groups' ? groups : models;
const availableNumber = type === 'groups' ? groups.length : models.length;
const titleType = type === 'groups' ? type : 'contentType';
const title = `${pluginId}.table.${titleType}.title.${
availableNumber > 1 ? 'plural' : 'singular'
}`;
const title = [
{
label: `${pluginId}.table.${titleType}.title.${
availableNumber > 1 ? 'plural' : 'singular'
}`,
values: { number: availableNumber },
},
];
return (
<div className={styles.homePage}>
@ -132,7 +137,6 @@ class HomePage extends React.Component {
<ListWrapper>
<ListHeader
title={title}
titleValues={{ number: availableNumber }}
button={{
kind: 'secondaryHotlineAdd',
label: `${pluginId}.button.${type}.create`,

View File

@ -107,9 +107,12 @@ describe('CTB <HomePage />', () => {
const list = wrapper.find(ListHeader);
expect(list).toHaveLength(1);
expect(list.prop('title')).toBe(
`${pluginId}.table.contentType.title.plural`
);
expect(list.prop('title')).toMatchObject([
{
label: `${pluginId}.table.contentType.title.plural`,
values: { number: 4 },
},
]);
});
it('Should handle the listheader title correctly if there is more than 1 group', () => {
@ -120,7 +123,12 @@ describe('CTB <HomePage />', () => {
const list = wrapper.find(ListHeader);
expect(list).toHaveLength(1);
expect(list.prop('title')).toBe(`${pluginId}.table.groups.title.plural`);
expect(list.prop('title')).toMatchObject([
{
label: `${pluginId}.table.groups.title.plural`,
values: { number: 4 },
},
]);
});
it('Should handle the listheader title correctly if there is less than 2 groups', () => {
@ -140,9 +148,12 @@ describe('CTB <HomePage />', () => {
const list = wrapper.find(ListHeader);
expect(list).toHaveLength(1);
expect(list.prop('title')).toBe(
`${pluginId}.table.groups.title.singular`
);
expect(list.prop('title')).toMatchObject([
{
label: `${pluginId}.table.groups.title.singular`,
values: { number: 1 },
},
]);
});
it('Should handle the listheader title correctly if there is less than 2 models', () => {
@ -161,9 +172,12 @@ describe('CTB <HomePage />', () => {
const list = wrapper.find(ListHeader);
expect(list).toHaveLength(1);
expect(list.prop('title')).toBe(
`${pluginId}.table.contentType.title.singular`
);
expect(list.prop('title')).toMatchObject([
{
label: `${pluginId}.table.contentType.title.singular`,
values: { number: 1 },
},
]);
});
});

View File

@ -84,7 +84,7 @@ const StyledLeftMenu = styled.div`
i {
font-size: 11px;
top: calc(50% - ${sizes.margin * 0.5}px);
color: ${colors.grey};
color: ${colors.leftMenu.grey};
}
&.active {
background-color: ${colors.leftMenu.lightGrey};

View File

@ -17,6 +17,9 @@ import {
BackHeader,
Button,
EmptyAttributesBlock,
List,
ListHeader,
ListWrapper,
PopUpWarning,
routerPropTypes,
getQueryParameters,
@ -539,6 +542,34 @@ export class ModelPage extends React.Component {
const attributeType = this.getAttributeType();
const actionType = this.getActionType();
// const attributes = this.getModelAttributes();
const attributesNumber = this.getModelAttributesLength();
const relationsNumber = this.getModelRelationShipsLength();
let title = [
{
label: `${pluginId}.table.attributes.title.${
attributesNumber > 1 ? 'plural' : 'singular'
}`,
values: { number: attributesNumber },
},
];
if (relationsNumber > 0) {
title.push({
label: `${pluginId}.table.relations.title.${
attributesNumber > 1 ? 'plural' : 'singular'
}`,
values: { number: relationsNumber },
});
}
const buttonProps = {
kind: 'secondaryHotlineAdd',
label: `${pluginId}.button.attributes.add`,
onClick: () => this.handleClickOpenModalChooseAttributes(),
};
return (
<div className={styles.modelpage}>
<BackHeader onClick={this.handleGoBack} />
@ -559,7 +590,7 @@ export class ModelPage extends React.Component {
pluginHeaderActions={this.getPluginHeaderActions()}
onClickIcon={this.handleClickEditModelMainInfos}
>
{this.getModelAttributesLength() === 0 ? (
{attributesNumber === 0 ? (
<EmptyAttributesBlock
description="content-type-builder.home.emptyAttributes.description"
id="openAddAttr"
@ -568,51 +599,75 @@ export class ModelPage extends React.Component {
title="content-type-builder.home.emptyAttributes.title"
/>
) : (
<Block>
<Flex>
<ListTitle>
{this.getModelAttributesLength()}
&nbsp;
<FormattedMessage
id={`${listTitleMessageIdBasePrefix}.${
this.getModelAttributesLength() > 1
? 'plural'
: 'singular'
}`}
/>
{this.getModelRelationShipsLength() > 0 && (
<React.Fragment>
&nbsp;
<FormattedMessage
id={`${listTitleMessageIdBasePrefix}.including`}
<ListWrapper>
<ListHeader title={title} button={{ ...buttonProps }} />
{/* <List>
<table>
<tbody>
{attributes.map(attribute => (
<ListRow
key={attribute.name}
{...attribute}
canOpenModal={canOpenModal}
context={this.context}
deleteAttribute={this.handleDeleteGroupAttribute}
isTemporary={false}
type={attribute.type}
/>
&nbsp;
{this.getModelRelationShipsLength()}
&nbsp;
<FormattedMessage
id={`${pluginId}.modelPage.contentType.list.relationShipTitle.${
this.getModelRelationShipsLength() > 1
? 'plural'
: 'singular'
}`}
/>
</React.Fragment>
)}
</ListTitle>
<div>
<Button
label={`${pluginId}.button.attributes.add`}
onClick={this.handleClickOpenModalChooseAttributes}
secondaryHotlineAdd
/>
</div>
</Flex>
<div>
<Ul id="attributesList">
{Object.keys(this.getModelAttributes()).map(this.renderLi)}
</Ul>
))}
</tbody>
</table>
</List> */}
<div className="list-button">
<Button {...buttonProps} />
</div>
</Block>
<Block>
<Flex>
<ListTitle>
{this.getModelAttributesLength()}
&nbsp;
<FormattedMessage
id={`${listTitleMessageIdBasePrefix}.${
this.getModelAttributesLength() > 1
? 'plural'
: 'singular'
}`}
/>
{this.getModelRelationShipsLength() > 0 && (
<React.Fragment>
&nbsp;
<FormattedMessage
id={`${listTitleMessageIdBasePrefix}.including`}
/>
&nbsp;
{this.getModelRelationShipsLength()}
&nbsp;
<FormattedMessage
id={`${pluginId}.modelPage.contentType.list.relationShipTitle.${
this.getModelRelationShipsLength() > 1
? 'plural'
: 'singular'
}`}
/>
</React.Fragment>
)}
</ListTitle>
<div>
<Button
label={`${pluginId}.button.attributes.add`}
onClick={this.handleClickOpenModalChooseAttributes}
secondaryHotlineAdd
/>
</div>
</Flex>
<div>
<Ul id="attributesList">
{Object.keys(this.getModelAttributes()).map(this.renderLi)}
</Ul>
</div>
</Block>
</ListWrapper>
)}
</ViewContainer>

View File

@ -193,5 +193,7 @@
"table.groups.title.singular": "{number} Group is available",
"table.attributes.title.plural": "{number} fields",
"table.attributes.title.singular": "{number} field",
"table.relations.title.plural": "including {number} relationships",
"table.relations.title.singular": "including {number} relationship",
"prompt.content.unsaved": "Are you sure you want to leave this content type? All your modifications will be lost."
}

View File

@ -25,7 +25,7 @@ module.exports = {
model: 'file',
via: 'related',
plugin: 'upload',
type: 'media',
type: 'relation',
},
},
},
@ -51,7 +51,7 @@ module.exports = {
model: 'file',
via: 'related',
plugin: 'upload',
type: 'media',
type: 'relation',
},
},
},