Apply design guidelines on view list

This commit is contained in:
Aurelsicoko 2017-08-30 17:56:52 +02:00
parent b16b86bb75
commit dd11036d3c
28 changed files with 458 additions and 292 deletions

View File

@ -0,0 +1,33 @@
/**
*
* Button
*
*/
import React from 'react';
import { FormattedMessage } from 'react-intl';
import styles from './styles.scss';
class Button extends React.Component {
// eslint-disable-line react/prefer-stateless-function
render() {
const label = this.props.handlei18n ? <FormattedMessage id={this.props.label} values={this.props.labelValues} /> : this.props.label;
const addShape = this.props.addShape ? <i className="fa fa-plus" /> : '';
return (
<button className={`${styles[this.props.buttonSize]} ${styles[this.props.buttonBackground]} ${styles.button}`} {...this.props}>
{addShape}{label}
</button>
);
}
}
Button.propTypes = {
addShape: React.PropTypes.bool,
buttonBackground: React.PropTypes.string,
buttonSize: React.PropTypes.string,
handlei18n: React.PropTypes.bool,
label: React.PropTypes.string.isRequired,
};
export default Button;

View File

@ -0,0 +1,69 @@
.button {
height: 3rem;
position: relative;
border-radius: 0.3rem;
text-transform: capitalize;
margin-right: 1.8rem;
cursor: pointer;
font-family: Lato;
&:focus {
outline: 0;
}
> i {
margin-right: 1.3rem;
}
&:hover {
&::after {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border-radius: 0.3rem;
content: '';
opacity: 0.1;
background: #FFFFFF;
}
}
}
.buttonLg {
width: 15rem;
}
.buttonMd {
width: 10rem;
}
.primary {
font-weight: 500;
background: linear-gradient(315deg, #0097F6 0%, #005EEA 100%);
-webkit-font-smoothing: antialiased;
color: white;
&:active {
box-shadow: inset 1px 1px 3px rgba(0,0,0,.15);
}
}
.secondary {
// height: 32px !important;
color: #F64D0A;
border: 0.1rem solid #F64D0A;
position: relative;
border-radius: 3px;
overflow: hidden;
&:active {
border: 0.15rem solid #F64D0A;
}
}
.secondaryAddType {
height: 2.6rem;
color: #1C5DE7;
line-height: 1.6rem;
border: 0.1rem solid #1C5DE7;
font-weight: 500;
font-size: 1.3rem;
padding-left: 1.6rem;
padding-right: 1.6rem;
}

View File

@ -9,21 +9,18 @@ import PluginHeaderTitle from 'components/PluginHeaderTitle';
import PluginHeaderActions from 'components/PluginHeaderActions'; import PluginHeaderActions from 'components/PluginHeaderActions';
import styles from './styles.scss'; import styles from './styles.scss';
// const styles = {};
console.log('styles', styles);
class PluginHeader extends React.Component { // eslint-disable-line react/prefer-stateless-function class PluginHeader extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() { render() {
return ( return (
<div className={`${styles.pluginHeader} row`}> <div className={`${styles.pluginHeader} row`}>
<div className="col-lg-6"> <div className="col-lg-8">
<PluginHeaderTitle <PluginHeaderTitle
title={this.props.title} title={this.props.title}
description={this.props.description} description={this.props.description}
/> />
</div> </div>
<div className="col-lg-6"> <div className="col-lg-4 justify-content-end">
<PluginHeaderActions <PluginHeaderActions
actions={this.props.actions} actions={this.props.actions}
/> />

View File

@ -1,3 +1,3 @@
.pluginHeader { .pluginHeader {
margin-bottom: 3.4rem; margin-bottom: 30px;
} }

View File

@ -6,27 +6,24 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import Button from 'components/Button';
import styles from './styles.scss'; import styles from './styles.scss';
class PluginHeaderActions extends React.Component { // eslint-disable-line react/prefer-stateless-function class PluginHeaderActions extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() { render() {
const actions = this.props.actions && this.props.actions.map((action) => ( const actions = this.props.actions && this.props.actions.map((action) => (
<button <Button
{...action}
key={action.label} key={action.label}
className={`btn ${action.class} ${styles.btn}`}
onClick={action.onClick}
disabled={action.disabled}
> >
<FormattedMessage id={action.label} /> <FormattedMessage id={action.label} />
</button> </Button>
)); ));
return ( return (
<div className={styles.pluginHeaderActions}> <div className={styles.pluginHeaderActions}>
<div className="pull-xs-right">
{actions} {actions}
</div>
</div> </div>
); );
} }

View File

@ -1,3 +1,6 @@
.btn { .pluginHeaderActions {
margin-left: 1rem; display: flex;
justify-content: flex-end;
margin-top: 8px;
margin-right: -18px;
} }

View File

@ -11,8 +11,9 @@ import styles from './styles.scss';
class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() { render() {
console.log(this.props.description);
return ( return (
<div className={styles.pluginHeaderTitle}> <div>
<h1 className={styles.pluginHeaderTitleName}> <h1 className={styles.pluginHeaderTitleName}>
<FormattedMessage {...this.props.title} /> <FormattedMessage {...this.props.title} />
</h1> </h1>

View File

@ -1,15 +1,14 @@
.pluginHeaderTitle { /* stylelint-disable */
color: #282A31;
}
.pluginHeaderTitleName { .pluginHeaderTitleName {
font-size: 2.4rem; font-size: 2.4rem;
font-weight: 600;
margin-top: 0.7rem; margin-top: 0.7rem;
margin-bottom: 0.2rem; margin-bottom: 1px;
text-transform: capitalize;
} }
.pluginHeaderTitleDescription { .pluginHeaderTitleDescription {
font-size: 1.3rem; font-size: 1.3rem;
color: #636c72; font-weight: 400;
color: #787E8F;
margin: 0; margin: 0;
} }

View File

@ -6,15 +6,11 @@
import React from 'react'; import React from 'react';
import styles from './styles.scss';
class Container extends React.Component { class Container extends React.Component {
render() { render() {
return ( return (
<div className={styles.container}> <div className={`container`}>
<div className={`row row-eq-height ${styles.containerContent}`}> {this.props.children}
{this.props.children}
</div>
</div> </div>
); );
} }

View File

@ -1,3 +1,2 @@
.container { /* stylelint-disable */ .containerCustom { /* stylelint-disable */
} }

View File

@ -6,10 +6,6 @@
import React from 'react'; import React from 'react';
import _ from 'lodash'; import _ from 'lodash';
import { FormattedMessage } from 'react-intl';
import styles from './styles.scss';
class LimitSelect extends React.Component { class LimitSelect extends React.Component {
componentWillMount() { componentWillMount() {
@ -31,37 +27,39 @@ class LimitSelect extends React.Component {
} }
render() { render() {
// Generate options return <div />;
const options = this.getOptionsValues().map(optionValue => (
<option value={optionValue} key={optionValue}>{optionValue}</option>
));
// Get id in order to link the `label` and the `select` elements // // Generate options
const id = this.state.id; // const options = this.getOptionsValues().map(optionValue => (
// <option value={optionValue} key={optionValue}>{optionValue}</option>
return ( // ));
<form className="form-inline"> //
<div className="form-group"> // // Get id in order to link the `label` and the `select` elements
<label className={styles.label} htmlFor={id}> // const id = this.state.id;
<FormattedMessage id="content-manager.components.LimitSelect.itemsPerPage" />: //
</label> // return (
<div className={styles.selectWrapper}> // <form className="form-inline">
<select // <div className="form-group">
onChange={this.props.onLimitChange} // <label className={styles.label} htmlFor={id}>
className={`form-control ${styles.select}`} // <FormattedMessage id="content-manager.components.LimitSelect.itemsPerPage" />:
id={id} // </label>
> // <div className={styles.selectWrapper}>
{options} // <select
</select> // onChange={this.props.onLimitChange}
</div> // className={`form-control ${styles.select}`}
</div> // id={id}
</form> // >
); // {options}
// </select>
// </div>
// </div>
// </form>
// );
} }
} }
LimitSelect.propTypes = { LimitSelect.propTypes = {
onLimitChange: React.PropTypes.func.isRequired, // onLimitChange: React.PropTypes.func.isRequired,
}; };
export default LimitSelect; export default LimitSelect;

View File

@ -190,7 +190,7 @@ class Pagination extends React.Component {
// Generate links // Generate links
const links = linksOptions.map((linksOption, i) => ( const links = linksOptions.map((linksOption, i) => (
<li <li
className={`${styles.navLi} ${linksOption.isActive && styles.navLiActive}`} className={`${linksOption.isActive && styles.navLiActive}`}
key={i} key={i}
> >
<a href disabled={linksOption.isActive} onClick={linksOption.onClick}> <a href disabled={linksOption.isActive} onClick={linksOption.onClick}>
@ -201,36 +201,35 @@ class Pagination extends React.Component {
return ( return (
<div className={styles.pagination}> <div className={styles.pagination}>
<a <div>
href <a
className={` href
${styles.paginationNavigator} className={`
${styles.paginationNavigatorPrevious} ${styles.paginationNavigator}
${this.isFirstPage() && styles.paginationNavigatorDisabled} ${this.isFirstPage() && styles.paginationNavigatorDisabled}
`} `}
onClick={this.onGoPreviousPageClicked} onClick={this.onGoPreviousPageClicked}
disabled={this.isFirstPage()} disabled={this.isFirstPage()}
> >
<i className="ion ion-chevron-left" /> <i className="fa fa-angle-left" aria-hidden="true"></i>
</a> </a>
<div className={styles.separator} /> <nav className={styles.nav}>
<nav className={styles.nav}> <ul className={styles.navUl}>
<ul className={styles.navUl}> {links}
{links} </ul>
</ul> </nav>
</nav> <a
<a href
href className={`
className={` ${styles.paginationNavigator}
${styles.paginationNavigator} ${this.isLastPage() && styles.paginationNavigatorDisabled}
${styles.paginationNavigatorNext} `}
${this.isLastPage() && styles.paginationNavigatorDisabled} onClick={this.onGoNextPageClicked}
`} disabled={this.isLastPage()}
onClick={this.onGoNextPageClicked} >
disabled={this.isLastPage()} <i className="fa fa-angle-right" aria-hidden="true"></i>
> </a>
<i className="ion ion-chevron-right" /> </div>
</a>
</div> </div>
); );
} }

View File

@ -1,78 +1,126 @@
.pagination { .pagination {
display: inline-flex; width: 100%;
flex-direction: row; display: flex;
border: 1px solid #DADBDC; justify-content: flex-end;
border-radius: 2.4rem;
height: 3.4rem; >div{
display: inline-flex;
flex-direction: row;
min-width: 120px;
height: 32px;
background: #ffffff;
border-radius: 3px;
overflow: hidden;
box-shadow: 0 2px 4px #E3E9F3;
}
} }
.paginationNavigator { .paginationNavigator {
background: #FFFFFF; position: relative;
padding-top: 0.5rem; width: 36px;
padding-left: 2rem; text-align: center;
padding-right: 2rem; line-height: 30px;
border-right: 1px solid #EFF3F6; font-size: 2rem;
}
.paginationNavigatorDisabled { &:first-of-type{
color: #DADBDC; margin-right: 10px;
&:hover, &:after{
&:focus { position: absolute;
color: #DADBDC; content: '';
top: 3px; bottom: 3px; right: 0;
width: 1px;
background: #F1F1F2;
}
} }
}
.paginationNavigatorPrevious { &:last-of-type{
border-radius: 2.4rem 0 0 2.4rem; margin-left: 10px;
border-right: 1px solid #EFF3F6;
}
.paginationNavigatorNext { &:before{
border-radius: 0 2.4rem 2.4rem 0; position: absolute;
border-left: 1px solid #EFF3F6; content: '';
top: 3px; bottom: 3px; left: 0;
width: 1px;
background: #F1F1F2;
}
}
i{
color: #97999E;
}
&[disabled] {
i{
opacity: 0.3;
}
}
} }
.nav { .nav {
background: #FFFFFF; min-width: 48px;
ul{
display: flex;
flex-direction: row;
justify-content: center;
height: 100%;
margin: 0 -5px;
padding: 0;
}
li{
position: relative;
min-width: 15px;
margin: 0 5px;
text-align: center;
line-height: 32px;
color: #333740;
a {
color: #333740;
font-size: 1.3rem;
&:hover{
&:after{
position: absolute;
content: '';
bottom: 0; left: 0;
width: 100%;
height: 2px;
background: #1C5DE7;
}
}
&:hover,
&:visited,
&:focus,
&:active {
text-decoration: none;
color: #333740;
}
}
}
} }
.navUl { .navUl {
margin: 0;
padding: 0;
height: 100%;
padding-left: 1rem;
padding-right: 1rem;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} justify-content: center;
margin: 0;
.navLi { padding: 0;
padding-top: 0.5rem;
padding-left: 0.8rem;
padding-right: 0.8rem;
color: #465373;
border-bottom: 3px solid transparent;
a,
a:visited,
a:focus,
a:active {
text-decoration: none;
color: #465373;;
}
a:hover {
color: #215CEA;
}
} }
.navLiActive { .navLiActive {
border-bottom: 3px solid #215CEA; font-weight: 800;
font-weight: 600;
a, &:after{
a:hover{ position: absolute;
color: #000000 !important; content: '';
bottom: 0; left: 0;
width: 100%;
height: 2px;
background: #1C5DE7;
} }
} }

View File

@ -1,5 +1,19 @@
.table { /* stylelint-disable */ .table { /* stylelint-disable */
border: 1px solid #D4DDE3;
border-radius: 3px; border-radius: 3px;
border-collapse: initial; border-collapse: initial;
overflow: hidden;
box-shadow: 0 2px 4px #E3E9F3;
tr, th, td{
border: none;
padding: 0;
}
th{
padding: 0 25px;
}
td{
padding: 0 25px;
}
} }

View File

@ -15,7 +15,14 @@ class TableFooter extends React.Component {
render() { render() {
return ( return (
<div className={`row ${styles.tableFooter}`}> <div className={`row ${styles.tableFooter}`}>
<div className="col-md-6"> <div className="col-lg-6">
<LimitSelect
className="push-lg-right"
onLimitChange={this.props.onLimitChange}
limit={this.props.limit}
/>
</div>
<div className="col-lg-6">
<Pagination <Pagination
limit={this.props.limit} limit={this.props.limit}
currentPage={this.props.currentPage} currentPage={this.props.currentPage}
@ -23,15 +30,6 @@ class TableFooter extends React.Component {
count={this.props.count} count={this.props.count}
/> />
</div> </div>
<div className="col-md-6">
<div className="pull-xs-right">
<LimitSelect
className="push-lg-right"
onLimitChange={this.props.onLimitChange}
limit={this.props.limit}
/>
</div>
</div>
</div> </div>
); );
} }

View File

@ -40,9 +40,12 @@ class TableHeader extends React.Component {
); );
}); });
// Add empty th for actions column.
headers.push(<th></th>);
return ( return (
<thead className={styles.tableHeader}> <thead className={styles.tableHeader}>
<tr className={styles.tableHeader}> <tr>
{headers} {headers}
</tr> </tr>
</thead> </thead>

View File

@ -1,9 +1,13 @@
.tableHeader { .tableHeader {
background: #EFF3F6; background: #F3F3F4;
border-bottom: 1px solid #D4DDE3; height: 41px;
height: 3.6rem; overflow: hidden;
}
.icon { th{
margin-left: .2rem; height: 41px;
border: none !important;
letter-spacing: 0.03rem;
font-size: 1.3rem;
vertical-align: middle !important;
}
} }

View File

@ -5,7 +5,6 @@
*/ */
import React from 'react'; import React from 'react';
import { Link } from 'react-router';
import _ from 'lodash'; import _ from 'lodash';
import styles from './styles.scss'; import styles from './styles.scss';
@ -13,7 +12,8 @@ import styles from './styles.scss';
class TableRow extends React.Component { class TableRow extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.goEditPage = this.goEditPage.bind(this);
this.handleClick = this.handleClick.bind(this);
} }
/** /**
@ -37,46 +37,32 @@ class TableRow extends React.Component {
} }
} }
/** // Redirect to the edit page
* Redirect to the edit page handleClick() {
*/ this.context.router.history.push(this.props.destination);
goEditPage() {
this.context.router.push(this.props.destination);
} }
render() { render() {
// Generate cells // Generate cells
const cells = this.props.headers.map((header, i) => { const cells = this.props.headers.map((header, i) => (
// Default content <td key={i}>
let content = this.getDisplayedValue( {this.getDisplayedValue(
header.type, header.type,
this.props.record[header.name] this.props.record[header.name]
); )}
</td>
));
// Display a link if the current column is the `id` column // Add actions cell.
if (header.name === this.props.primaryKey) { cells.push(
content = ( <td key='action' className={styles.actions}>
<Link to={this.props.destination} className={styles.idLink}> <i className="fa fa-pencil" aria-hidden="true"></i>
{this.getDisplayedValue( <i className="fa fa-trash" aria-hidden="true"></i>
header.type, </td>
this.props.record[header.name] );
)}
</Link>
);
}
return (
<td key={i} className={styles.tableRowCell}>
{content}
</td>
);
});
return ( return (
<tr // eslint-disable-line jsx-a11y/no-static-element-interactions <tr className={styles.tableRow} onClick={() => this.handleClick(this.props.destination)}>
className={styles.tableRow}
onClick={() => this.goEditPage(this.props.destination)}
>
{cells} {cells}
</tr> </tr>
); );
@ -90,7 +76,6 @@ TableRow.contextTypes = {
TableRow.propTypes = { TableRow.propTypes = {
destination: React.PropTypes.string.isRequired, destination: React.PropTypes.string.isRequired,
headers: React.PropTypes.array.isRequired, headers: React.PropTypes.array.isRequired,
primaryKey: React.PropTypes.string.isRequired,
record: React.PropTypes.object.isRequired, record: React.PropTypes.object.isRequired,
}; };

View File

@ -1,44 +1,33 @@
.tableRow { /* stylelint-disable */ .tableRow { /* stylelint-disable */
height: 54px;
background: #ffffff; background: #ffffff;
border-bottom: 1px solid #D4DDE3;
td:first-child {
border-left: 3px solid transparent;
}
&:hover { &:hover {
background: #F8FAFB;
cursor: pointer; cursor: pointer;
background: #F7F8F8;
td:first-child {
border-left: 3px solid #1C5DE7;
}
} }
}
.tableRowCell { td{
border: none; height: 54px;
font-weight: 400; line-height: 54px;
color: #465373; font-size: 1.3rem;
padding-top: 1.6rem !important; font-weight: 400;
padding-bottom: 1.6rem !important; color: #333740;
border-collapse: collapse;
border-top: 1px solid #F1F1F2 !important;
}
} }
.actions { .actions {
i { text-align: right;
font-size: 1.2rem;
color: #8B96B3;
color: #CDD3E4;
margin-left: 1rem;
&:hover { i {
color: #1C5DE7; margin-left: 15px;
font-size: 1.1rem;
color: #0E1622;
&:first-of-type{
margin-left: 0px;
} }
} }
} }
.idLink {
&:hover {
text-decoration: none;
}
}

View File

@ -6,15 +6,24 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect'; import { createStructuredSelector } from 'reselect';
import _ from 'lodash'; import _ from 'lodash';
import { router } from 'app'; import { router } from 'app';
import Container from 'components/Container';
import EditForm from 'components/EditForm'; import EditForm from 'components/EditForm';
import { makeSelectSchema } from 'containers/App/selectors'; import { makeSelectSchema } from 'containers/App/selectors';
import EditFormRelations from 'components/EditFormRelations'; import EditFormRelations from 'components/EditFormRelations';
import PluginHeader from 'components/PluginHeader';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import reducer from './reducer';
import saga from './sagas';
import styles from './styles.scss';
import { import {
setInitialState, setInitialState,
@ -25,6 +34,7 @@ import {
editRecord, editRecord,
deleteRecord, deleteRecord,
} from './actions'; } from './actions';
import { import {
makeSelectRecord, makeSelectRecord,
makeSelectLoading, makeSelectLoading,
@ -37,21 +47,20 @@ import {
export class Edit extends React.Component { export class Edit extends React.Component {
componentWillMount() { componentWillMount() {
this.props.setInitialState(); this.props.setInitialState();
this.props.setCurrentModelName(this.props.routeParams.slug.toLowerCase()); this.props.setCurrentModelName(this.props.match.params.slug.toLowerCase());
// Detect that the current route is the `create` route or not // Detect that the current route is the `create` route or not
if (this.props.routeParams.id === 'create') { if (this.props.match.params.id === 'create') {
this.props.setIsCreating(); this.props.setIsCreating();
} else { } else {
this.props.loadRecord(this.props.routeParams.id); this.props.loadRecord(this.props.match.params.id);
} }
} }
render() { render() {
const PluginHeader = this.props.exposedComponents.PluginHeader;
let content = <p>Loading...</p>; let content = <p>Loading...</p>;
let relations; let relations;
if (!this.props.loading && this.props.schema && this.props.currentModelName) { if (!this.props.loading && this.props.schema && this.props.currentModelName) {
content = ( content = (
<EditForm <EditForm
@ -77,28 +86,32 @@ export class Edit extends React.Component {
const pluginHeaderActions = [ const pluginHeaderActions = [
{ {
label: 'content-manager.containers.Edit.cancel', label: 'content-manager.containers.Edit.cancel',
class: 'btn-default', handlei18n: true,
buttonBackground: 'secondary',
buttonSize: 'buttonLg',
onClick: () => { onClick: () => {
router.push(`/plugins/content-manager/${this.props.currentModelName}`); router.push(`/plugins/content-manager/${this.props.currentModelName}`);
}, },
}, },
{ {
handlei18n: true,
buttonBackground: 'primary',
buttonSize: 'buttonLg',
label: this.props.editing ? 'content-manager.containers.Edit.editing' : 'content-manager.containers.Edit.submit', label: this.props.editing ? 'content-manager.containers.Edit.editing' : 'content-manager.containers.Edit.submit',
class: 'btn-primary',
onClick: this.props.editRecord, onClick: this.props.editRecord,
disabled: this.props.editing, disabled: this.props.editing,
}, },
]; ];
// Add the `Delete` button only in edit mode // Add the `Delete` button only in edit mode
if (!this.props.isCreating) { // if (!this.props.isCreating) {
pluginHeaderActions.push({ // pluginHeaderActions.push({
label: 'content-manager.containers.Edit.delete', // label: 'content-manager.containers.Edit.delete',
class: 'btn-danger', // class: 'btn-danger',
onClick: this.props.deleteRecord, // onClick: this.props.deleteRecord,
disabled: this.props.deleting, // disabled: this.props.deleting,
}); // });
} // }
// Plugin header config // Plugin header config
const pluginHeaderTitle = _.get(this.props.schema, [this.props.currentModelName, 'label']) || 'Content Manager'; const pluginHeaderTitle = _.get(this.props.schema, [this.props.currentModelName, 'label']) || 'Content Manager';
@ -107,24 +120,26 @@ export class Edit extends React.Component {
: `#${this.props.record && this.props.record.get('id')}`; : `#${this.props.record && this.props.record.get('id')}`;
return ( return (
<div className="col-md-12"> <div>
<div className="container-fluid"> <div className={`container-fluid ${styles.containerFluid}`}>
<PluginHeader <PluginHeader
title={pluginHeaderTitle} title={{
id: pluginHeaderTitle,
}}
description={{ description={{
id: 'plugin-content-manager-description', id: 'plugin-content-manager-description',
defaultMessage: `${pluginHeaderDescription}`, defaultMessage: `${pluginHeaderDescription}`,
}} }}
actions={pluginHeaderActions} actions={pluginHeaderActions}
/> />
<Container> <div className='row'>
<div className="row"> <div className='col-lg-8'>
<div className="col-md-8"> {content}
{content}
{relations}
</div>
</div> </div>
</Container> <div className="col-lg-4">
{relations}
</div>
</div>
</div> </div>
</div> </div>
); );
@ -136,19 +151,23 @@ Edit.propTypes = {
React.PropTypes.bool, React.PropTypes.bool,
React.PropTypes.string, React.PropTypes.string,
]).isRequired, ]).isRequired,
deleteRecord: React.PropTypes.func.isRequired, // deleteRecord: React.PropTypes.func.isRequired,
deleting: React.PropTypes.bool.isRequired, // deleting: React.PropTypes.bool.isRequired,
editing: React.PropTypes.bool.isRequired, editing: React.PropTypes.bool.isRequired,
editRecord: React.PropTypes.func.isRequired, editRecord: React.PropTypes.func.isRequired,
exposedComponents: React.PropTypes.object.isRequired,
isCreating: React.PropTypes.bool.isRequired, isCreating: React.PropTypes.bool.isRequired,
loading: React.PropTypes.bool.isRequired, loading: React.PropTypes.bool.isRequired,
loadRecord: React.PropTypes.func.isRequired, loadRecord: React.PropTypes.func.isRequired,
match: React.PropTypes.shape({
params: React.PropTypes.shape({
id: React.PropTypes.string,
slug: React.PropTypes.string,
}),
}).isRequired,
record: React.PropTypes.oneOfType([ record: React.PropTypes.oneOfType([
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.bool, React.PropTypes.bool,
]).isRequired, ]).isRequired,
routeParams: React.PropTypes.object.isRequired,
schema: React.PropTypes.oneOfType([ schema: React.PropTypes.oneOfType([
React.PropTypes.object, React.PropTypes.object,
React.PropTypes.bool, React.PropTypes.bool,
@ -190,4 +209,13 @@ function mapDispatchToProps(dispatch) {
}; };
} }
export default connect(mapStateToProps, mapDispatchToProps)(Edit); const withConnect = connect(mapStateToProps, mapDispatchToProps);
const withReducer = injectReducer({ key: 'edit', reducer });
const withSaga = injectSaga({ key: 'edit', saga });
export default compose(
withReducer,
withSaga,
withConnect,
)(Edit);

View File

@ -22,7 +22,7 @@ import {
} from './constants'; } from './constants';
const initialState = fromJS({ const initialState = fromJS({
currentModelName: null, currentModelName: '',
loading: false, loading: false,
record: false, record: false,
editing: false, editing: false,

View File

@ -1,6 +1,5 @@
import { takeLatest } from 'redux-saga';
import { LOCATION_CHANGE } from 'react-router-redux'; import { LOCATION_CHANGE } from 'react-router-redux';
import { call, cancel, fork, put, take, select } from 'redux-saga/effects'; import { call, cancel, fork, put, take, select, takeLatest } from 'redux-saga/effects';
import request from 'utils/request'; import request from 'utils/request';
import { router } from 'app'; import { router } from 'app';
@ -110,4 +109,4 @@ export function* defaultSaga() {
} }
// All sagas to be loaded // All sagas to be loaded
export default [defaultSaga]; export default defaultSaga;

View File

@ -1,3 +1,3 @@
.edit { /* stylelint-disable */ .containerFluid { /* stylelint-disable */
padding: 18px 30px;
} }

View File

@ -11,7 +11,6 @@ import { createStructuredSelector } from 'reselect';
import _ from 'lodash'; import _ from 'lodash';
import { makeSelectModels, makeSelectSchema } from 'containers/App/selectors'; import { makeSelectModels, makeSelectSchema } from 'containers/App/selectors';
import Container from 'components/Container';
import Table from 'components/Table'; import Table from 'components/Table';
import TableFooter from 'components/TableFooter'; import TableFooter from 'components/TableFooter';
import PluginHeader from 'components/PluginHeader'; import PluginHeader from 'components/PluginHeader';
@ -116,24 +115,30 @@ export class List extends React.Component {
); );
} }
// Plugin header config
const pluginHeaderTitle = this.props.schema[this.props.currentModelName].label || 'Content Manager';
// Define plugin header actions // Define plugin header actions
const pluginHeaderActions = [ const pluginHeaderActions = [
{ {
label: 'content-manager.containers.List.addAnEntry', label: 'content-manager.containers.List.addAnEntry',
class: 'btn-primary', labelValues: {
onClick: () => this.context.router.push(this.addRoute), entity: pluginHeaderTitle,
},
handlei18n: true,
addShape: true,
buttonBackground: 'primary',
buttonSize: 'buttonLg',
// onClick: () => this.context.router.history.push(this.addRoute),
}, },
]; ];
// Plugin header config
// const pluginHeaderTitle = this.props.schema[this.props.currentModelName].label || 'Content Manager';
return ( return (
<div> <div>
<div className={`container-fluid ${styles.containerFluid}`}> <div className={`container-fluid ${styles.containerFluid}`}>
<PluginHeader <PluginHeader
title={{ title={{
id: 'test', id: pluginHeaderTitle,
}} }}
description={{ description={{
id: 'content-manager.containers.List.pluginHeaderDescription', id: 'content-manager.containers.List.pluginHeaderDescription',
@ -143,17 +148,19 @@ export class List extends React.Component {
}} }}
actions={pluginHeaderActions} actions={pluginHeaderActions}
/> />
<Container> <div className='row'>
{content} <div className='col-lg-12'>
<TableFooter {content}
limit={this.props.limit} <TableFooter
currentPage={this.props.currentPage} limit={this.props.limit}
changePage={this.props.changePage} currentPage={this.props.currentPage}
count={this.props.count} changePage={this.props.changePage}
className="push-lg-right" count={this.props.count}
onLimitChange={this.props.onLimitChange} className="push-lg-right"
/> onLimitChange={this.props.onLimitChange}
</Container> />
</div>
</div>
</div> </div>
</div> </div>
); );

View File

@ -1,3 +1,3 @@
.list { /* stylelint-disable */ .containerFluid { /* stylelint-disable */
padding: 18px 30px;
} }

View File

@ -3,11 +3,11 @@
"containers.Home.pluginHeaderDescription": "Create and update your content types", "containers.Home.pluginHeaderDescription": "Create and update your content types",
"containers.Home.introduction": "A powerful UI to easily manage your data.", "containers.Home.introduction": "A powerful UI to easily manage your data.",
"containers.Home.pluginHeaderDescription": "To edit your content's entries go to the specific link in the left menu.", "containers.Home.pluginHeaderDescription": "To edit your content's entries go to the specific link in the left menu.",
"containers.Edit.submit": "Submit", "containers.Edit.submit": "Save",
"containers.Edit.editing": "Editing...", "containers.Edit.editing": "Editing...",
"containers.Edit.delete": "Delete", "containers.Edit.delete": "Delete",
"containers.Edit.cancel": "Cancel", "containers.Edit.cancel": "Cancel",
"containers.List.addAnEntry": "Add an entry", "containers.List.addAnEntry": "Add New {entity}",
"containers.List.pluginHeaderDescription": "Manage your {label}", "containers.List.pluginHeaderDescription": "Manage your {label}",
"components.LimitSelect.itemsPerPage": "Number of items per page", "components.LimitSelect.itemsPerPage": "Number of items per page",
"containers.List.errorFetchRecords": "Error", "containers.List.errorFetchRecords": "Error",

View File

@ -7,7 +7,7 @@
"containers.Edit.editing": "Édition en cours...", "containers.Edit.editing": "Édition en cours...",
"containers.Edit.delete": "Supprimer", "containers.Edit.delete": "Supprimer",
"containers.Edit.cancel": "Annuler", "containers.Edit.cancel": "Annuler",
"containers.List.addAnEntry": "Ajouter une entrée", "containers.List.addAnEntry": "Ajouter {entity}",
"containers.List.pluginHeaderDescription": "Gérér vos {label}", "containers.List.pluginHeaderDescription": "Gérér vos {label}",
"components.LimitSelect.itemsPerPage": "Nombre d'éléments par page", "components.LimitSelect.itemsPerPage": "Nombre d'éléments par page",
"containers.List.errorFetchRecords": "Erreur" "containers.List.errorFetchRecords": "Erreur"

View File

@ -73,7 +73,7 @@ module.exports = {
update: async ctx => { update: async ctx => {
// Update an entry using `queries` system // Update an entry using `queries` system
const entryUpdated = await queries.update({ const entryUpdated = await queries.update({
id: ctx.params.id id: ctx.params.id,
values: ctx.request.body values: ctx.request.body
}); });