mirror of
https://github.com/strapi/strapi.git
synced 2025-12-11 15:04:33 +00:00
Apply design guidelines on view list
This commit is contained in:
parent
b16b86bb75
commit
dd11036d3c
33
packages/strapi-helper-plugin/lib/src/components/Button/index.js
Executable file
33
packages/strapi-helper-plugin/lib/src/components/Button/index.js
Executable 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;
|
||||
69
packages/strapi-helper-plugin/lib/src/components/Button/styles.scss
Executable file
69
packages/strapi-helper-plugin/lib/src/components/Button/styles.scss
Executable 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;
|
||||
}
|
||||
@ -9,21 +9,18 @@ import PluginHeaderTitle from 'components/PluginHeaderTitle';
|
||||
import PluginHeaderActions from 'components/PluginHeaderActions';
|
||||
|
||||
import styles from './styles.scss';
|
||||
// const styles = {};
|
||||
console.log('styles', styles);
|
||||
|
||||
|
||||
class PluginHeader extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
return (
|
||||
<div className={`${styles.pluginHeader} row`}>
|
||||
<div className="col-lg-6">
|
||||
<div className="col-lg-8">
|
||||
<PluginHeaderTitle
|
||||
title={this.props.title}
|
||||
description={this.props.description}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-lg-6">
|
||||
<div className="col-lg-4 justify-content-end">
|
||||
<PluginHeaderActions
|
||||
actions={this.props.actions}
|
||||
/>
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
.pluginHeader {
|
||||
margin-bottom: 3.4rem;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
@ -6,27 +6,24 @@
|
||||
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Button from 'components/Button';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class PluginHeaderActions extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
const actions = this.props.actions && this.props.actions.map((action) => (
|
||||
<button
|
||||
<Button
|
||||
{...action}
|
||||
key={action.label}
|
||||
className={`btn ${action.class} ${styles.btn}`}
|
||||
onClick={action.onClick}
|
||||
disabled={action.disabled}
|
||||
>
|
||||
<FormattedMessage id={action.label} />
|
||||
</button>
|
||||
</Button>
|
||||
));
|
||||
|
||||
return (
|
||||
<div className={styles.pluginHeaderActions}>
|
||||
<div className="pull-xs-right">
|
||||
{actions}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
.btn {
|
||||
margin-left: 1rem;
|
||||
.pluginHeaderActions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 8px;
|
||||
margin-right: -18px;
|
||||
}
|
||||
|
||||
@ -11,8 +11,9 @@ import styles from './styles.scss';
|
||||
|
||||
class PluginHeaderTitle extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
console.log(this.props.description);
|
||||
return (
|
||||
<div className={styles.pluginHeaderTitle}>
|
||||
<div>
|
||||
<h1 className={styles.pluginHeaderTitleName}>
|
||||
<FormattedMessage {...this.props.title} />
|
||||
</h1>
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
.pluginHeaderTitle { /* stylelint-disable */
|
||||
color: #282A31;
|
||||
}
|
||||
|
||||
.pluginHeaderTitleName {
|
||||
font-size: 2.4rem;
|
||||
font-weight: 600;
|
||||
margin-top: 0.7rem;
|
||||
margin-bottom: 0.2rem;
|
||||
margin-bottom: 1px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.pluginHeaderTitleDescription {
|
||||
font-size: 1.3rem;
|
||||
color: #636c72;
|
||||
font-weight: 400;
|
||||
color: #787E8F;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -6,15 +6,11 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
class Container extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={`row row-eq-height ${styles.containerContent}`}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
<div className={`container`}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
.container { /* stylelint-disable */
|
||||
|
||||
.containerCustom { /* stylelint-disable */
|
||||
}
|
||||
|
||||
@ -6,10 +6,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import styles from './styles.scss';
|
||||
|
||||
|
||||
class LimitSelect extends React.Component {
|
||||
componentWillMount() {
|
||||
@ -31,37 +27,39 @@ class LimitSelect extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
// Generate options
|
||||
const options = this.getOptionsValues().map(optionValue => (
|
||||
<option value={optionValue} key={optionValue}>{optionValue}</option>
|
||||
));
|
||||
return <div />;
|
||||
|
||||
// Get id in order to link the `label` and the `select` elements
|
||||
const id = this.state.id;
|
||||
|
||||
return (
|
||||
<form className="form-inline">
|
||||
<div className="form-group">
|
||||
<label className={styles.label} htmlFor={id}>
|
||||
<FormattedMessage id="content-manager.components.LimitSelect.itemsPerPage" />:
|
||||
</label>
|
||||
<div className={styles.selectWrapper}>
|
||||
<select
|
||||
onChange={this.props.onLimitChange}
|
||||
className={`form-control ${styles.select}`}
|
||||
id={id}
|
||||
>
|
||||
{options}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
// // Generate options
|
||||
// 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
|
||||
// const id = this.state.id;
|
||||
//
|
||||
// return (
|
||||
// <form className="form-inline">
|
||||
// <div className="form-group">
|
||||
// <label className={styles.label} htmlFor={id}>
|
||||
// <FormattedMessage id="content-manager.components.LimitSelect.itemsPerPage" />:
|
||||
// </label>
|
||||
// <div className={styles.selectWrapper}>
|
||||
// <select
|
||||
// onChange={this.props.onLimitChange}
|
||||
// className={`form-control ${styles.select}`}
|
||||
// id={id}
|
||||
// >
|
||||
// {options}
|
||||
// </select>
|
||||
// </div>
|
||||
// </div>
|
||||
// </form>
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
LimitSelect.propTypes = {
|
||||
onLimitChange: React.PropTypes.func.isRequired,
|
||||
// onLimitChange: React.PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default LimitSelect;
|
||||
|
||||
@ -190,7 +190,7 @@ class Pagination extends React.Component {
|
||||
// Generate links
|
||||
const links = linksOptions.map((linksOption, i) => (
|
||||
<li
|
||||
className={`${styles.navLi} ${linksOption.isActive && styles.navLiActive}`}
|
||||
className={`${linksOption.isActive && styles.navLiActive}`}
|
||||
key={i}
|
||||
>
|
||||
<a href disabled={linksOption.isActive} onClick={linksOption.onClick}>
|
||||
@ -201,36 +201,35 @@ class Pagination extends React.Component {
|
||||
|
||||
return (
|
||||
<div className={styles.pagination}>
|
||||
<a
|
||||
href
|
||||
className={`
|
||||
${styles.paginationNavigator}
|
||||
${styles.paginationNavigatorPrevious}
|
||||
${this.isFirstPage() && styles.paginationNavigatorDisabled}
|
||||
`}
|
||||
onClick={this.onGoPreviousPageClicked}
|
||||
disabled={this.isFirstPage()}
|
||||
>
|
||||
<i className="ion ion-chevron-left" />
|
||||
</a>
|
||||
<div className={styles.separator} />
|
||||
<nav className={styles.nav}>
|
||||
<ul className={styles.navUl}>
|
||||
{links}
|
||||
</ul>
|
||||
</nav>
|
||||
<a
|
||||
href
|
||||
className={`
|
||||
${styles.paginationNavigator}
|
||||
${styles.paginationNavigatorNext}
|
||||
${this.isLastPage() && styles.paginationNavigatorDisabled}
|
||||
`}
|
||||
onClick={this.onGoNextPageClicked}
|
||||
disabled={this.isLastPage()}
|
||||
>
|
||||
<i className="ion ion-chevron-right" />
|
||||
</a>
|
||||
<div>
|
||||
<a
|
||||
href
|
||||
className={`
|
||||
${styles.paginationNavigator}
|
||||
${this.isFirstPage() && styles.paginationNavigatorDisabled}
|
||||
`}
|
||||
onClick={this.onGoPreviousPageClicked}
|
||||
disabled={this.isFirstPage()}
|
||||
>
|
||||
<i className="fa fa-angle-left" aria-hidden="true"></i>
|
||||
</a>
|
||||
<nav className={styles.nav}>
|
||||
<ul className={styles.navUl}>
|
||||
{links}
|
||||
</ul>
|
||||
</nav>
|
||||
<a
|
||||
href
|
||||
className={`
|
||||
${styles.paginationNavigator}
|
||||
${this.isLastPage() && styles.paginationNavigatorDisabled}
|
||||
`}
|
||||
onClick={this.onGoNextPageClicked}
|
||||
disabled={this.isLastPage()}
|
||||
>
|
||||
<i className="fa fa-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,78 +1,126 @@
|
||||
.pagination {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #DADBDC;
|
||||
border-radius: 2.4rem;
|
||||
height: 3.4rem;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
>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 {
|
||||
background: #FFFFFF;
|
||||
padding-top: 0.5rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
border-right: 1px solid #EFF3F6;
|
||||
}
|
||||
position: relative;
|
||||
width: 36px;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
font-size: 2rem;
|
||||
|
||||
.paginationNavigatorDisabled {
|
||||
color: #DADBDC;
|
||||
&:first-of-type{
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #DADBDC;
|
||||
&:after{
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 3px; bottom: 3px; right: 0;
|
||||
width: 1px;
|
||||
background: #F1F1F2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.paginationNavigatorPrevious {
|
||||
border-radius: 2.4rem 0 0 2.4rem;
|
||||
border-right: 1px solid #EFF3F6;
|
||||
}
|
||||
&:last-of-type{
|
||||
margin-left: 10px;
|
||||
|
||||
.paginationNavigatorNext {
|
||||
border-radius: 0 2.4rem 2.4rem 0;
|
||||
border-left: 1px solid #EFF3F6;
|
||||
&:before{
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 3px; bottom: 3px; left: 0;
|
||||
width: 1px;
|
||||
background: #F1F1F2;
|
||||
}
|
||||
}
|
||||
|
||||
i{
|
||||
color: #97999E;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
i{
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.navLi {
|
||||
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;
|
||||
}
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.navLiActive {
|
||||
border-bottom: 3px solid #215CEA;
|
||||
font-weight: 600;
|
||||
font-weight: 800;
|
||||
|
||||
a,
|
||||
a:hover{
|
||||
color: #000000 !important;
|
||||
&:after{
|
||||
position: absolute;
|
||||
content: '';
|
||||
bottom: 0; left: 0;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background: #1C5DE7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
.table { /* stylelint-disable */
|
||||
border: 1px solid #D4DDE3;
|
||||
border-radius: 3px;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,14 @@ class TableFooter extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<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
|
||||
limit={this.props.limit}
|
||||
currentPage={this.props.currentPage}
|
||||
@ -23,15 +30,6 @@ class TableFooter extends React.Component {
|
||||
count={this.props.count}
|
||||
/>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -40,9 +40,12 @@ class TableHeader extends React.Component {
|
||||
);
|
||||
});
|
||||
|
||||
// Add empty th for actions column.
|
||||
headers.push(<th></th>);
|
||||
|
||||
return (
|
||||
<thead className={styles.tableHeader}>
|
||||
<tr className={styles.tableHeader}>
|
||||
<tr>
|
||||
{headers}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
.tableHeader {
|
||||
background: #EFF3F6;
|
||||
border-bottom: 1px solid #D4DDE3;
|
||||
height: 3.6rem;
|
||||
}
|
||||
background: #F3F3F4;
|
||||
height: 41px;
|
||||
overflow: hidden;
|
||||
|
||||
.icon {
|
||||
margin-left: .2rem;
|
||||
th{
|
||||
height: 41px;
|
||||
border: none !important;
|
||||
letter-spacing: 0.03rem;
|
||||
font-size: 1.3rem;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import _ from 'lodash';
|
||||
|
||||
import styles from './styles.scss';
|
||||
@ -13,7 +12,8 @@ import styles from './styles.scss';
|
||||
class TableRow extends React.Component {
|
||||
constructor(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
|
||||
*/
|
||||
goEditPage() {
|
||||
this.context.router.push(this.props.destination);
|
||||
// Redirect to the edit page
|
||||
handleClick() {
|
||||
this.context.router.history.push(this.props.destination);
|
||||
}
|
||||
|
||||
render() {
|
||||
// Generate cells
|
||||
const cells = this.props.headers.map((header, i) => {
|
||||
// Default content
|
||||
let content = this.getDisplayedValue(
|
||||
header.type,
|
||||
this.props.record[header.name]
|
||||
);
|
||||
const cells = this.props.headers.map((header, i) => (
|
||||
<td key={i}>
|
||||
{this.getDisplayedValue(
|
||||
header.type,
|
||||
this.props.record[header.name]
|
||||
)}
|
||||
</td>
|
||||
));
|
||||
|
||||
// Display a link if the current column is the `id` column
|
||||
if (header.name === this.props.primaryKey) {
|
||||
content = (
|
||||
<Link to={this.props.destination} className={styles.idLink}>
|
||||
{this.getDisplayedValue(
|
||||
header.type,
|
||||
this.props.record[header.name]
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<td key={i} className={styles.tableRowCell}>
|
||||
{content}
|
||||
</td>
|
||||
);
|
||||
});
|
||||
// Add actions cell.
|
||||
cells.push(
|
||||
<td key='action' className={styles.actions}>
|
||||
<i className="fa fa-pencil" aria-hidden="true"></i>
|
||||
<i className="fa fa-trash" aria-hidden="true"></i>
|
||||
</td>
|
||||
);
|
||||
|
||||
return (
|
||||
<tr // eslint-disable-line jsx-a11y/no-static-element-interactions
|
||||
className={styles.tableRow}
|
||||
onClick={() => this.goEditPage(this.props.destination)}
|
||||
>
|
||||
<tr className={styles.tableRow} onClick={() => this.handleClick(this.props.destination)}>
|
||||
{cells}
|
||||
</tr>
|
||||
);
|
||||
@ -90,7 +76,6 @@ TableRow.contextTypes = {
|
||||
TableRow.propTypes = {
|
||||
destination: React.PropTypes.string.isRequired,
|
||||
headers: React.PropTypes.array.isRequired,
|
||||
primaryKey: React.PropTypes.string.isRequired,
|
||||
record: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -1,44 +1,33 @@
|
||||
.tableRow { /* stylelint-disable */
|
||||
height: 54px;
|
||||
background: #ffffff;
|
||||
border-bottom: 1px solid #D4DDE3;
|
||||
|
||||
td:first-child {
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #F8FAFB;
|
||||
cursor: pointer;
|
||||
|
||||
td:first-child {
|
||||
border-left: 3px solid #1C5DE7;
|
||||
}
|
||||
background: #F7F8F8;
|
||||
}
|
||||
}
|
||||
|
||||
.tableRowCell {
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
color: #465373;
|
||||
padding-top: 1.6rem !important;
|
||||
padding-bottom: 1.6rem !important;
|
||||
td{
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 400;
|
||||
color: #333740;
|
||||
border-collapse: collapse;
|
||||
border-top: 1px solid #F1F1F2 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
i {
|
||||
font-size: 1.2rem;
|
||||
color: #8B96B3;
|
||||
color: #CDD3E4;
|
||||
margin-left: 1rem;
|
||||
text-align: right;
|
||||
|
||||
&:hover {
|
||||
color: #1C5DE7;
|
||||
i {
|
||||
margin-left: 15px;
|
||||
font-size: 1.1rem;
|
||||
color: #0E1622;
|
||||
|
||||
&:first-of-type{
|
||||
margin-left: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.idLink {
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,15 +6,24 @@
|
||||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { compose } from 'redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { router } from 'app';
|
||||
|
||||
import Container from 'components/Container';
|
||||
import EditForm from 'components/EditForm';
|
||||
import { makeSelectSchema } from 'containers/App/selectors';
|
||||
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 {
|
||||
setInitialState,
|
||||
@ -25,6 +34,7 @@ import {
|
||||
editRecord,
|
||||
deleteRecord,
|
||||
} from './actions';
|
||||
|
||||
import {
|
||||
makeSelectRecord,
|
||||
makeSelectLoading,
|
||||
@ -37,21 +47,20 @@ import {
|
||||
export class Edit extends React.Component {
|
||||
componentWillMount() {
|
||||
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
|
||||
if (this.props.routeParams.id === 'create') {
|
||||
if (this.props.match.params.id === 'create') {
|
||||
this.props.setIsCreating();
|
||||
} else {
|
||||
this.props.loadRecord(this.props.routeParams.id);
|
||||
this.props.loadRecord(this.props.match.params.id);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const PluginHeader = this.props.exposedComponents.PluginHeader;
|
||||
|
||||
let content = <p>Loading...</p>;
|
||||
let relations;
|
||||
|
||||
if (!this.props.loading && this.props.schema && this.props.currentModelName) {
|
||||
content = (
|
||||
<EditForm
|
||||
@ -77,28 +86,32 @@ export class Edit extends React.Component {
|
||||
const pluginHeaderActions = [
|
||||
{
|
||||
label: 'content-manager.containers.Edit.cancel',
|
||||
class: 'btn-default',
|
||||
handlei18n: true,
|
||||
buttonBackground: 'secondary',
|
||||
buttonSize: 'buttonLg',
|
||||
onClick: () => {
|
||||
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',
|
||||
class: 'btn-primary',
|
||||
onClick: this.props.editRecord,
|
||||
disabled: this.props.editing,
|
||||
},
|
||||
];
|
||||
|
||||
// Add the `Delete` button only in edit mode
|
||||
if (!this.props.isCreating) {
|
||||
pluginHeaderActions.push({
|
||||
label: 'content-manager.containers.Edit.delete',
|
||||
class: 'btn-danger',
|
||||
onClick: this.props.deleteRecord,
|
||||
disabled: this.props.deleting,
|
||||
});
|
||||
}
|
||||
// if (!this.props.isCreating) {
|
||||
// pluginHeaderActions.push({
|
||||
// label: 'content-manager.containers.Edit.delete',
|
||||
// class: 'btn-danger',
|
||||
// onClick: this.props.deleteRecord,
|
||||
// disabled: this.props.deleting,
|
||||
// });
|
||||
// }
|
||||
|
||||
// Plugin header config
|
||||
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')}`;
|
||||
|
||||
return (
|
||||
<div className="col-md-12">
|
||||
<div className="container-fluid">
|
||||
<div>
|
||||
<div className={`container-fluid ${styles.containerFluid}`}>
|
||||
<PluginHeader
|
||||
title={pluginHeaderTitle}
|
||||
title={{
|
||||
id: pluginHeaderTitle,
|
||||
}}
|
||||
description={{
|
||||
id: 'plugin-content-manager-description',
|
||||
defaultMessage: `${pluginHeaderDescription}`,
|
||||
}}
|
||||
actions={pluginHeaderActions}
|
||||
/>
|
||||
<Container>
|
||||
<div className="row">
|
||||
<div className="col-md-8">
|
||||
{content}
|
||||
{relations}
|
||||
</div>
|
||||
<div className='row'>
|
||||
<div className='col-lg-8'>
|
||||
{content}
|
||||
</div>
|
||||
</Container>
|
||||
<div className="col-lg-4">
|
||||
{relations}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -136,19 +151,23 @@ Edit.propTypes = {
|
||||
React.PropTypes.bool,
|
||||
React.PropTypes.string,
|
||||
]).isRequired,
|
||||
deleteRecord: React.PropTypes.func.isRequired,
|
||||
deleting: React.PropTypes.bool.isRequired,
|
||||
// deleteRecord: React.PropTypes.func.isRequired,
|
||||
// deleting: React.PropTypes.bool.isRequired,
|
||||
editing: React.PropTypes.bool.isRequired,
|
||||
editRecord: React.PropTypes.func.isRequired,
|
||||
exposedComponents: React.PropTypes.object.isRequired,
|
||||
isCreating: React.PropTypes.bool.isRequired,
|
||||
loading: React.PropTypes.bool.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([
|
||||
React.PropTypes.object,
|
||||
React.PropTypes.bool,
|
||||
]).isRequired,
|
||||
routeParams: React.PropTypes.object.isRequired,
|
||||
schema: React.PropTypes.oneOfType([
|
||||
React.PropTypes.object,
|
||||
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);
|
||||
|
||||
@ -22,7 +22,7 @@ import {
|
||||
} from './constants';
|
||||
|
||||
const initialState = fromJS({
|
||||
currentModelName: null,
|
||||
currentModelName: '',
|
||||
loading: false,
|
||||
record: false,
|
||||
editing: false,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { takeLatest } from 'redux-saga';
|
||||
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 { router } from 'app';
|
||||
@ -110,4 +109,4 @@ export function* defaultSaga() {
|
||||
}
|
||||
|
||||
// All sagas to be loaded
|
||||
export default [defaultSaga];
|
||||
export default defaultSaga;
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
.edit { /* stylelint-disable */
|
||||
|
||||
.containerFluid { /* stylelint-disable */
|
||||
padding: 18px 30px;
|
||||
}
|
||||
|
||||
@ -11,7 +11,6 @@ import { createStructuredSelector } from 'reselect';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { makeSelectModels, makeSelectSchema } from 'containers/App/selectors';
|
||||
import Container from 'components/Container';
|
||||
import Table from 'components/Table';
|
||||
import TableFooter from 'components/TableFooter';
|
||||
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
|
||||
const pluginHeaderActions = [
|
||||
{
|
||||
label: 'content-manager.containers.List.addAnEntry',
|
||||
class: 'btn-primary',
|
||||
onClick: () => this.context.router.push(this.addRoute),
|
||||
labelValues: {
|
||||
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 (
|
||||
<div>
|
||||
<div className={`container-fluid ${styles.containerFluid}`}>
|
||||
<PluginHeader
|
||||
title={{
|
||||
id: 'test',
|
||||
id: pluginHeaderTitle,
|
||||
}}
|
||||
description={{
|
||||
id: 'content-manager.containers.List.pluginHeaderDescription',
|
||||
@ -143,17 +148,19 @@ export class List extends React.Component {
|
||||
}}
|
||||
actions={pluginHeaderActions}
|
||||
/>
|
||||
<Container>
|
||||
{content}
|
||||
<TableFooter
|
||||
limit={this.props.limit}
|
||||
currentPage={this.props.currentPage}
|
||||
changePage={this.props.changePage}
|
||||
count={this.props.count}
|
||||
className="push-lg-right"
|
||||
onLimitChange={this.props.onLimitChange}
|
||||
/>
|
||||
</Container>
|
||||
<div className='row'>
|
||||
<div className='col-lg-12'>
|
||||
{content}
|
||||
<TableFooter
|
||||
limit={this.props.limit}
|
||||
currentPage={this.props.currentPage}
|
||||
changePage={this.props.changePage}
|
||||
count={this.props.count}
|
||||
className="push-lg-right"
|
||||
onLimitChange={this.props.onLimitChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
.list { /* stylelint-disable */
|
||||
|
||||
.containerFluid { /* stylelint-disable */
|
||||
padding: 18px 30px;
|
||||
}
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
"containers.Home.pluginHeaderDescription": "Create and update your content types",
|
||||
"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.Edit.submit": "Submit",
|
||||
"containers.Edit.submit": "Save",
|
||||
"containers.Edit.editing": "Editing...",
|
||||
"containers.Edit.delete": "Delete",
|
||||
"containers.Edit.cancel": "Cancel",
|
||||
"containers.List.addAnEntry": "Add an entry",
|
||||
"containers.List.addAnEntry": "Add New {entity}",
|
||||
"containers.List.pluginHeaderDescription": "Manage your {label}",
|
||||
"components.LimitSelect.itemsPerPage": "Number of items per page",
|
||||
"containers.List.errorFetchRecords": "Error",
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
"containers.Edit.editing": "Édition en cours...",
|
||||
"containers.Edit.delete": "Supprimer",
|
||||
"containers.Edit.cancel": "Annuler",
|
||||
"containers.List.addAnEntry": "Ajouter une entrée",
|
||||
"containers.List.addAnEntry": "Ajouter {entity}",
|
||||
"containers.List.pluginHeaderDescription": "Gérér vos {label}",
|
||||
"components.LimitSelect.itemsPerPage": "Nombre d'éléments par page",
|
||||
"containers.List.errorFetchRecords": "Erreur"
|
||||
|
||||
@ -73,7 +73,7 @@ module.exports = {
|
||||
update: async ctx => {
|
||||
// Update an entry using `queries` system
|
||||
const entryUpdated = await queries.update({
|
||||
id: ctx.params.id
|
||||
id: ctx.params.id,
|
||||
values: ctx.request.body
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user