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 */
position: relative;
margin: 2.4rem 4rem;
margin: 2.4rem 4rem 3.3rem 4rem;
font-family: Lato;
}

View File

@ -2,5 +2,9 @@
margin-top: 1.8rem;
> label {
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 btnClassOn = this.state.isChecked ? `btn ${styles.gradientOn}` : 'btn';
const customBootstrapClass = this.props.customBootstrapClass ? this.props.customBootstrapClass : 'col-md-4';
return (
<div className={`${customBootstrapClass} ${styles.container}`}>
<div className={styles.toggleLabel}>

View File

@ -7,9 +7,9 @@
* - listButtonLabel: string
* - listTitle: string
* - noListButtonPopUp: bool
* prevent from displaying the List button
* prevent from displaying the OldList button
* - 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
* - handleListPopButtonSave: func
*
@ -18,6 +18,7 @@
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';
@ -52,9 +53,7 @@ class List extends React.Component { // eslint-disable-line react/prefer-statele
return (
<div className={styles.listContainer}>
<div className={styles.listComponent}>
<div className="container-fluid">
<div className="row">
<div className={styles.listSubContainer}>
<div className={styles.flex}>
<div className={styles.titleContainer}>
{this.props.listTitle}
@ -63,47 +62,41 @@ class List extends React.Component { // eslint-disable-line react/prefer-statele
{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
<div className={styles.ulContainer}>
<ul>
{map(this.props.listItems, (listItem, key) => {
if (this.props.renderRow) {
return this.props.renderRow(value, key, styles);
return this.props.renderRow(listItem, key, styles);
}
return (
<tr key={key}>
<th>{key}</th>
<td>{value.name}</td>
</tr>
<li key={key}>
<div className={styles.flexLi}>
{map(listItem, (item, index) => (
<div key={index}>{item}</div>
))}
</div>
</li>
);
})}
</tbody>
</table>
</ul>
</div>
</div>
</div>
</div>
<div>
<Modal isOpen={this.state.modal} toggle={this.toggle}>
<ModalHeader toggle={this.toggle} className={`${styles.noBorder}`}>
<Modal isOpen={this.state.modal} toggle={this.toggle} className={styles.modalPosition}>
<ModalHeader toggle={this.toggle} className={`${styles.noBorder} ${styles.padded} ${styles.mHeader}`}>
<FormattedMessage {...{id: this.props.listButtonLabel}} />
</ModalHeader>
<div className={styles.bordered} />
<ModalBody>
<ModalBody className={styles.modalBody}>
<PopUpForm {...this.props} />
</ModalBody>
<ModalFooter className={`${styles.noBorder} ${styles.flexStart}`}>
<ModalFooter className={`${styles.noBorder} ${styles.flexStart} ${styles.modalFooter}`}>
{/* 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>
);
}
@ -123,6 +116,6 @@ List.propTypes = {
React.PropTypes.bool,
React.PropTypes.func,
]),
};
}
export default List;

View File

@ -1,13 +1,14 @@
.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 { /* stylelint-disable */
margin-right: 15px;
}
.listContainer {
margin-right: 15px;
.listSubContainer {
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 {
@ -23,24 +24,61 @@
font-size: 1.8rem;
font-weight: bold;
line-height: 2.2rem;
align-items: flex-start;
}
.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;
}
}
.ulContainer {
padding-top: .5rem;
> ul {
list-style: none;
padding: 0 2.7rem 0 1rem;
> li {
margin-bottom: 3.3rem;
}
}
}
.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 {
background: linear-gradient(315deg, #0097F6 0%, #005EEA 100%);
color: white;
@ -86,3 +124,39 @@
font-weight: 600;
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-right: 2rem;
padding-top: 1rem;
padding-left: 1rem;
padding-left: .6rem;
min-height: 3.4rem;
border-left: 0.4rem solid transparent;
color: #2C3138 !important;
@ -25,6 +25,7 @@ li:not(:first-child) {
}
.linkActive {
height: 3.4rem;
border-radius: 0.2rem;
background-color: #E9EAEB;;
font-weight: bold;

View File

@ -18,6 +18,7 @@ import styles from './styles.scss';
const WithFormSection = (InnerComponent) => class extends React.Component {
static propTypes = {
checkForNestedForm: React.PropTypes.bool,
handleChange: React.PropTypes.func.isRequired,
section: React.PropTypes.object,
values: React.PropTypes.object,
@ -46,6 +47,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
componentDidMount() {
// 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(items, (item) => {
forEach(item, (input) => {
@ -63,6 +65,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
});
});
}
}
renderInput = (props, key) => {
const inputs = {
@ -86,7 +89,6 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
// custom handle change props for nested input form
const handleChange = this.state.hasNestedInput ? this.handleChange : this.props.handleChange;
return (
<Input
customBootstrapClass={customBootstrapClass}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"customComponents": {
"editForm": ["general"],
"editForm": ["general", "advanced"],
"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
renderRowLanguage = (props, key, rowStyles) => {
renderRowLanguage = (props, key, liStyles) => {
// 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
// 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 languageLabel = props.active ?
<span className={rowStyles.italicText}>
<span className={liStyles.italicText}>
<FormattedMessage {...{id: 'list.languages.default.languages'}} />
</span> :
// set the span's id with the language name to retrieve it
<FormattedMessage {...{id: 'list.languages.set.languages'}}>
{(message) => (
<button className={rowStyles.normal} onClick={this.changeDefaultLanguage} id={props.name}>
<button className={liStyles.normal} onClick={this.changeDefaultLanguage} id={props.name}>
{message}
</button>
)}
</FormattedMessage>;
return (
<tr key={key}>
<th>{key}</th>
<td className={rowStyles.label}>{languageDisplay}</td>
<td className={rowStyles.lighter}>{props.name}</td>
<td>{languageLabel}</td>
<td>{deleteIcon}</td>
</tr>
);
<li key={key}>
<div className={liStyles.flexLi}>
<div className={liStyles.flexed}>
<div>{key}</div>
<div className={liStyles.label}>{languageDisplay}</div>
</div>
<div>{props.name}</div>
<div className={liStyles.centered}>{languageLabel}</div>
<div>{deleteIcon}</div>
</div>
</li>
)
}
renderListTitle = () => {
@ -232,6 +236,9 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
// custom rendering for PopUpForm
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 (
<Component
sections={sections}
@ -250,6 +257,7 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
handleListPopUpSubmit={this.addLanguage}
selectOptions={selectOptions}
renderPopUpForm={renderPopUpForm}
checkForNestedForm={checkForNestedForm}
/>
);
}

View File

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