Design general languages and advanced

This commit is contained in:
cyril lopez 2017-07-27 16:07:09 +02:00
parent 25f3c91c6c
commit 15c19d7f00
16 changed files with 405 additions and 93 deletions

View File

@ -1,6 +1,6 @@
.contentHeader { /* stylelint-disable */ .contentHeader { /* stylelint-disable */
position: relative; position: relative;
margin: 2.4rem 4rem; margin: 2.4rem 4rem 3.3rem 4rem;
font-family: Lato; font-family: Lato;
} }

View File

@ -2,5 +2,9 @@
margin-top: 1.8rem; margin-top: 1.8rem;
> label { > label {
text-transform: capitalize; text-transform: capitalize;
margin-bottom: .7rem;
}
> select {
color: #333740;
} }
} }

View File

@ -56,6 +56,7 @@ class InputToggle extends React.Component { // eslint-disable-line react/prefer-
const btnClassOff = this.state.isChecked ? 'btn ' : `btn ${styles.gradientOff}`; const btnClassOff = this.state.isChecked ? 'btn ' : `btn ${styles.gradientOff}`;
const btnClassOn = this.state.isChecked ? `btn ${styles.gradientOn}` : 'btn'; const btnClassOn = this.state.isChecked ? `btn ${styles.gradientOn}` : 'btn';
const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4'; const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4';
return ( return (
<div className={`${customBootstrapClass} ${styles.container}`}> <div className={`${customBootstrapClass} ${styles.container}`}>
<div className={styles.toggleLabel}> <div className={styles.toggleLabel}>

View File

@ -7,9 +7,9 @@
* - listButtonLabel: string * - listButtonLabel: string
* - listTitle: string * - listTitle: string
* - noListButtonPopUp: bool * - noListButtonPopUp: bool
* prevent from displaying the List button * prevent from displaying the OldList button
* - renderRow: function * - renderRow: function
* overrides the default rendering of the List tr (we can pass customs components there) * overrides the default rendering of the OldList tr (we can pass customs components there)
* - listItems: array the elements to display * - listItems: array the elements to display
* - handleListPopButtonSave: func * - handleListPopButtonSave: func
* *
@ -18,6 +18,7 @@
import React from 'react'; import React from 'react';
import { map } from 'lodash'; import { map } from 'lodash';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import ButtonPrimaryHotline from 'components/Button'; import ButtonPrimaryHotline from 'components/Button';
import PopUpForm from 'components/PopUpForm'; import PopUpForm from 'components/PopUpForm';
@ -52,9 +53,7 @@ class List extends React.Component { // eslint-disable-line react/prefer-statele
return ( return (
<div className={styles.listContainer}> <div className={styles.listContainer}>
<div className={styles.listComponent}> <div className={styles.listSubContainer}>
<div className="container-fluid">
<div className="row">
<div className={styles.flex}> <div className={styles.flex}>
<div className={styles.titleContainer}> <div className={styles.titleContainer}>
{this.props.listTitle} {this.props.listTitle}
@ -63,47 +62,41 @@ class List extends React.Component { // eslint-disable-line react/prefer-statele
{button} {button}
</div> </div>
</div> </div>
</div> <div className={styles.ulContainer}>
<div className="row"> <ul>
<div className="col-md-12"> {map(this.props.listItems, (listItem, key) => {
<table className={` table ${styles.listNoBorder}`}>
<tbody>
{map(this.props.listItems, (value, key) => {
// handle custom row displaying
if (this.props.renderRow) { if (this.props.renderRow) {
return this.props.renderRow(value, key, styles); return this.props.renderRow(listItem, key, styles);
} }
return ( return (
<tr key={key}> <li key={key}>
<th>{key}</th> <div className={styles.flexLi}>
<td>{value.name}</td> {map(listItem, (item, index) => (
</tr> <div key={index}>{item}</div>
))}
</div>
</li>
); );
})} })}
</tbody> </ul>
</table>
</div> </div>
</div> </div>
</div>
</div>
<div> <div>
<Modal isOpen={this.state.modal} toggle={this.toggle}> <Modal isOpen={this.state.modal} toggle={this.toggle} className={styles.modalPosition}>
<ModalHeader toggle={this.toggle} className={`${styles.noBorder}`}> <ModalHeader toggle={this.toggle} className={`${styles.noBorder} ${styles.padded} ${styles.mHeader}`}>
<FormattedMessage {...{id: this.props.listButtonLabel}} /> <FormattedMessage {...{id: this.props.listButtonLabel}} />
</ModalHeader> </ModalHeader>
<div className={styles.bordered} /> <div className={styles.bordered} />
<ModalBody> <ModalBody className={styles.modalBody}>
<PopUpForm {...this.props} /> <PopUpForm {...this.props} />
</ModalBody> </ModalBody>
<ModalFooter className={`${styles.noBorder} ${styles.flexStart}`}> <ModalFooter className={`${styles.noBorder} ${styles.flexStart} ${styles.modalFooter}`}>
{/* TODO change tthis.toggle => this.props.addLanguage */} {/* TODO change tthis.toggle => this.props.addLanguage */}
<Button onClick={this.handleSubmit} className={styles.primary}>Save</Button>{' '} <Button onClick={this.handleSubmit} className={styles.primary}>Save</Button>{' '}
<Button onClick={this.toggle} className={styles.secondary}>Cancel</Button> <Button onClick={this.toggle} className={styles.secondary}>Cancel</Button>
</ModalFooter> </ModalFooter>
</Modal> </Modal>
</div> </div>
</div> </div>
); );
} }
@ -123,6 +116,6 @@ List.propTypes = {
React.PropTypes.bool, React.PropTypes.bool,
React.PropTypes.func, React.PropTypes.func,
]), ]),
}; }
export default List; export default List;

View File

@ -1,13 +1,14 @@
.listComponent { /* stylelint-disable */ .listContainer { /* stylelint-disable */
margin: 0 3.3rem; margin-right: 15px;
padding: 2rem 2.8rem 5.8rem 2.8rem;
border-radius: 0.2rem;
background-color: #FFFFFF;
box-shadow: 0 0.2rem 0.4rem 0 #E3E9F3;
} }
.listContainer { .listSubContainer {
margin-right: 15px; margin: 0 3.3rem;
padding: 1rem 3rem 5.8rem 3rem;
border-radius: 0.2rem;
background-color: #FFFFFF;
// background-color: red;
box-shadow: 0 0.2rem 0.4rem 0 #E3E9F3;
} }
.flex { .flex {
@ -23,22 +24,59 @@
font-size: 1.8rem; font-size: 1.8rem;
font-weight: bold; font-weight: bold;
line-height: 2.2rem; line-height: 2.2rem;
align-items: flex-start;
} }
.listNoBorder { .ulContainer {
> tbody { padding-top: .5rem;
tr { > ul {
height: 5.4rem; list-style: none;
font-size: 1.3rem; padding: 0 2.7rem 0 1rem;
line-height: 1.6rem; > li {
font-family: Lato; margin-bottom: 3.3rem;
&:first-of-type {
> td, th {
border-top: none !important;
} }
} }
} }
.flexLi {
display: flex;
justify-content: space-between;
} }
.flexLeft {
display: flex;
align-items: flex-start;
}
.marged {
margin-left: 1rem;
}
.flexed {
display: flex;
}
.label {
width: 20rem;
margin-left: 5.2rem;
color: #333740;
font-weight: 600;
text-transform: capitalize;
}
.centered {
width: 25rem;
text-align: right;
}
.italicText {
color: #49515A;
font-style: italic;
}
.normal {
color: #1C5DE7;
padding-top: 0rem;
} }
.primary { .primary {
@ -86,3 +124,39 @@
font-weight: 600; font-weight: 600;
text-transform: capitalize; text-transform: capitalize;
} }
.modalPosition {
margin-top: 48rem ;
margin-left: 31rem;
width: 50%!important;
max-width: none;
}
.modalBody {
padding: 0;
padding-top: .5rem;
}
.modalFooter {
margin-top: 4.5rem;
margin-bottom: 3.5rem;
padding-left: 3.1rem !important;
> input {
margin-top: 1.3rem!important;
}
}
.padded {
padding-left: 3.1rem;
padding-right: 1.5rem;
}
.mHeader {
> h4 {
font-family: Lato;
font-weight: bold!important;
font-size: 1.8rem!important;
}
}

View File

@ -0,0 +1,128 @@
/**
*
* OldList
* params:
* -handlei18n: bool
* used for the buttonComponent to render label with FormattedMessage
* - listButtonLabel: string
* - listTitle: string
* - noListButtonPopUp: bool
* prevent from displaying the OldList button
* - renderRow: function
* overrides the default rendering of the OldList tr (we can pass customs components there)
* - listItems: array the elements to display
* - handleListPopButtonSave: func
*
*/
import React from 'react';
import { map } from 'lodash';
import { FormattedMessage } from 'react-intl';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import ButtonPrimaryHotline from 'components/Button';
import PopUpForm from 'components/PopUpForm';
import styles from './styles.scss';
class OldList extends React.Component { // eslint-disable-line react/prefer-stateless-function
constructor(props) {
super(props);
this.state = {
modal: false,
};
}
toggle = () => {
this.setState({ modal: !this.state.modal });
}
handleSubmit = () => {
this.setState({ modal: !this.state.modal });
this.props.handleListPopUpSubmit();
}
render() {
const button = this.props.noListButtonPopUp ? '' :
<ButtonPrimaryHotline
buttonBackground={'secondaryAddType'}
label={this.props.listButtonLabel}
handlei18n={this.props.handlei18n}
addShape
onClick={this.toggle}
/>;
return (
<div className={styles.listContainer}>
<div className={styles.listComponent}>
<div className="container-fluid">
<div className="row">
<div className={styles.flex}>
<div className={styles.titleContainer}>
{this.props.listTitle}
</div>
<div>
{button}
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<table className={` table ${styles.listNoBorder}`}>
<tbody>
{map(this.props.listItems, (value, key) => {
// handle custom row displaying
if (this.props.renderRow) {
return this.props.renderRow(value, key, styles);
}
return (
<tr key={key}>
<th>{key}</th>
<td>{value.name}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
</div>
</div>
<div>
<Modal isOpen={this.state.modal} toggle={this.toggle}>
<ModalHeader toggle={this.toggle} className={`${styles.noBorder}`}>
<FormattedMessage {...{id: this.props.listButtonLabel}} />
</ModalHeader>
<div className={styles.bordered} />
<ModalBody>
<PopUpForm {...this.props} />
</ModalBody>
<ModalFooter className={`${styles.noBorder} ${styles.flexStart}`}>
{/* TODO change tthis.toggle => this.props.addLanguage */}
<Button onClick={this.handleSubmit} className={styles.primary}>Save</Button>{' '}
<Button onClick={this.toggle} className={styles.secondary}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
</div>
);
}
}
OldList.propTypes = {
handlei18n: React.PropTypes.bool,
handleListPopUpSubmit: React.PropTypes.func,
listButtonLabel: React.PropTypes.string,
listItems: React.PropTypes.array,
listTitle: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.object,
]),
noListButtonPopUp: React.PropTypes.bool,
renderRow: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.func,
]),
};
export default OldList;

View File

@ -0,0 +1,88 @@
.listComponent { /* stylelint-disable */
margin: 0 3.3rem;
padding: 2rem 2.8rem 5.8rem 2.8rem;
border-radius: 0.2rem;
background-color: #FFFFFF;
box-shadow: 0 0.2rem 0.4rem 0 #E3E9F3;
}
.listContainer {
margin-right: 15px;
}
.flex {
display: flex;
justify-content: space-between;
margin-top: 0.8rem;
margin-bottom: 2.5rem;
}
.titleContainer {
color: #333740;
font-family: Lato;
font-size: 1.8rem;
font-weight: bold;
line-height: 2.2rem;
}
.listNoBorder {
> tbody {
tr {
height: 5.4rem;
font-size: 1.3rem;
line-height: 1.6rem;
font-family: Lato;
&:first-of-type {
> td, th {
border-top: none !important;
}
}
}
}
}
.primary {
background: linear-gradient(315deg, #0097F6 0%, #005EEA 100%);
color: white;
width: 15rem;
}
.secondary {
color: #F64D0A;
border: 0.1rem solid #F64D0A;
margin-left: 1.9rem!important;
}
.bordered {
margin-left: 3rem;
margin-right: 3rem;
border: 1px solid #F6F6F6;
}
.noBorder {
border: none!important;
}
.flexStart {
justify-content: flex-start!important;
}
.italicText {
color: #49515A;
font-style: italic;
}
.normal {
color: #1C5DE7;
padding-top: 0rem;
}
.lighter {
color: #333740;
}
.label {
color: #333740;
font-weight: 600;
text-transform: capitalize;
}

View File

@ -0,0 +1,11 @@
// import OldList from '../index';
import expect from 'expect';
// import { shallow } from 'enzyme';
// import React from 'react';
describe('<OldList />', () => {
it('Expect to have unit tests specified', () => {
expect(true).toEqual(false);
});
});

View File

@ -12,7 +12,7 @@ li:not(:first-child) {
margin-left: 2rem; margin-left: 2rem;
margin-right: 2rem; margin-right: 2rem;
padding-top: 1rem; padding-top: 1rem;
padding-left: 1rem; padding-left: .6rem;
min-height: 3.4rem; min-height: 3.4rem;
border-left: 0.4rem solid transparent; border-left: 0.4rem solid transparent;
color: #2C3138 !important; color: #2C3138 !important;
@ -25,6 +25,7 @@ li:not(:first-child) {
} }
.linkActive { .linkActive {
height: 3.4rem;
border-radius: 0.2rem; border-radius: 0.2rem;
background-color: #E9EAEB;; background-color: #E9EAEB;;
font-weight: bold; font-weight: bold;

View File

@ -18,6 +18,7 @@ import styles from './styles.scss';
const WithFormSection = (InnerComponent) => class extends React.Component { const WithFormSection = (InnerComponent) => class extends React.Component {
static propTypes = { static propTypes = {
checkForNestedForm: React.PropTypes.bool,
handleChange: React.PropTypes.func.isRequired, handleChange: React.PropTypes.func.isRequired,
section: React.PropTypes.object, section: React.PropTypes.object,
values: React.PropTypes.object, values: React.PropTypes.object,
@ -46,6 +47,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
componentDidMount() { componentDidMount() {
// check if there is inside a section an input that requires nested input to display it on the entire line // check if there is inside a section an input that requires nested input to display it on the entire line
if (this.props.checkForNestedForm) {
forEach(this.props.section.items, (items) => { forEach(this.props.section.items, (items) => {
forEach(items, (item) => { forEach(items, (item) => {
forEach(item, (input) => { forEach(item, (input) => {
@ -63,6 +65,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
}); });
}); });
} }
}
renderInput = (props, key) => { renderInput = (props, key) => {
const inputs = { const inputs = {
@ -86,7 +89,6 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
// custom handle change props for nested input form // custom handle change props for nested input form
const handleChange = this.state.hasNestedInput ? this.handleChange : this.props.handleChange; const handleChange = this.state.hasNestedInput ? this.handleChange : this.props.handleChange;
return ( return (
<Input <Input
customBootstrapClass={customBootstrapClass} customBootstrapClass={customBootstrapClass}

View File

@ -1,6 +1,6 @@
.editFormSection { /* stylelint-disable */ .editFormSection { /* stylelint-disable */
background: #FFFFFF; background: #FFFFFF;
padding-top: .3rem; padding-top: 0rem;
} }
.sectionHeader { .sectionHeader {

View File

@ -1,5 +1,5 @@
.inputNumber { /* stylelint-disable */ .inputNumber { /* stylelint-disable */
margin-top: 1.8rem; margin-top: 1.5rem;
> label { > label {
text-transform: capitalize; text-transform: capitalize;
} }
@ -9,12 +9,13 @@
color: #ABAFBB; color: #ABAFBB;
} }
> input { > input {
margin-bottom: 1.3rem; margin-top: 2px;
margin-bottom: 1.4rem;
} }
} }
.inputText { /* stylelint-disable */ .inputText { /* stylelint-disable */
margin-top: 1.8rem; margin-top: 1.5rem;
> label { > label {
text-transform: capitalize; text-transform: capitalize;
} }
@ -24,6 +25,7 @@
color: #ABAFBB; color: #ABAFBB;
} }
> input { > input {
margin-bottom: 1.3rem; margin-top: 2px;
margin-bottom: 1.4rem;
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"customComponents": { "customComponents": {
"editForm": ["general"], "editForm": ["general", "advanced"],
"list": ["languages"] "list": ["languages"]
} }
} }

View File

@ -164,7 +164,7 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
} }
// custom Row rendering for the component List with params slug === languages // custom Row rendering for the component List with params slug === languages
renderRowLanguage = (props, key, rowStyles) => { renderRowLanguage = (props, key, liStyles) => {
// assign the target id the language name to prepare for delete // assign the target id the language name to prepare for delete
const deleteIcon = props.active ? '' : <i className="fa fa-trash" onClick={this.handleLanguageDelete} id={props.name} />; // eslint-disable-line jsx-a11y/no-static-element-interactions const deleteIcon = props.active ? '' : <i className="fa fa-trash" onClick={this.handleLanguageDelete} id={props.name} />; // eslint-disable-line jsx-a11y/no-static-element-interactions
// retrieve language name from i18n translation // retrieve language name from i18n translation
@ -173,27 +173,31 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
const languageDisplay = isObject(languageObject) ? <FormattedMessage {...{ id: languageObject.name }} /> : ''; const languageDisplay = isObject(languageObject) ? <FormattedMessage {...{ id: languageObject.name }} /> : '';
const languageLabel = props.active ? const languageLabel = props.active ?
<span className={rowStyles.italicText}> <span className={liStyles.italicText}>
<FormattedMessage {...{id: 'list.languages.default.languages'}} /> <FormattedMessage {...{id: 'list.languages.default.languages'}} />
</span> : </span> :
// set the span's id with the language name to retrieve it // set the span's id with the language name to retrieve it
<FormattedMessage {...{id: 'list.languages.set.languages'}}> <FormattedMessage {...{id: 'list.languages.set.languages'}}>
{(message) => ( {(message) => (
<button className={rowStyles.normal} onClick={this.changeDefaultLanguage} id={props.name}> <button className={liStyles.normal} onClick={this.changeDefaultLanguage} id={props.name}>
{message} {message}
</button> </button>
)} )}
</FormattedMessage>; </FormattedMessage>;
return ( return (
<tr key={key}> <li key={key}>
<th>{key}</th> <div className={liStyles.flexLi}>
<td className={rowStyles.label}>{languageDisplay}</td> <div className={liStyles.flexed}>
<td className={rowStyles.lighter}>{props.name}</td> <div>{key}</div>
<td>{languageLabel}</td> <div className={liStyles.label}>{languageDisplay}</div>
<td>{deleteIcon}</td> </div>
</tr> <div>{props.name}</div>
); <div className={liStyles.centered}>{languageLabel}</div>
<div>{deleteIcon}</div>
</div>
</li>
)
} }
renderListTitle = () => { renderListTitle = () => {
@ -232,6 +236,9 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
// custom rendering for PopUpForm // custom rendering for PopUpForm
const renderPopUpForm = this.props.params.slug === 'languages' ? this.renderPopUpFormLanguage : false; const renderPopUpForm = this.props.params.slug === 'languages' ? this.renderPopUpFormLanguage : false;
// TODO remove temporary condition to handle nestedForm rendering
const checkForNestedForm = this.props.params.slug !== 'languages'
return ( return (
<Component <Component
sections={sections} sections={sections}
@ -250,6 +257,7 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
handleListPopUpSubmit={this.addLanguage} handleListPopUpSubmit={this.addLanguage}
selectOptions={selectOptions} selectOptions={selectOptions}
renderPopUpForm={renderPopUpForm} renderPopUpForm={renderPopUpForm}
checkForNestedForm={checkForNestedForm}
/> />
); );
} }

View File

@ -4,7 +4,7 @@
padding: 0; padding: 0;
} }
.baseline { .baseline {
// display: none; display: none;
z-index: 100001; z-index: 100001;
opacity: .2; opacity: .2;
position: absolute; position: absolute;