mirror of
https://github.com/strapi/strapi.git
synced 2025-09-24 07:50:33 +00:00
Design TableList component
This commit is contained in:
parent
262f2e9c86
commit
a568c54e5f
@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* Table
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
import ButtonPrimaryHotline from 'components/Button';
|
|
||||||
import styles from './styles.scss';
|
|
||||||
|
|
||||||
class Table extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className={styles.table}>
|
|
||||||
<div className="container-fluid">
|
|
||||||
<div className="row">
|
|
||||||
<div className={styles.headerContainer}>
|
|
||||||
<div className={styles.titleContainer}>
|
|
||||||
{this.props.availableNumber} <FormattedMessage {...{ id: this.props.title }} />
|
|
||||||
</div>
|
|
||||||
<div className={styles.buttonContainer}>
|
|
||||||
<ButtonPrimaryHotline
|
|
||||||
buttonBackground={'secondaryAddType'}
|
|
||||||
label={this.props.buttonLabel}
|
|
||||||
handlei18n
|
|
||||||
addShape
|
|
||||||
onClick={this.props.handleButtonClick}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Table.propTypes = {
|
|
||||||
availableNumber: React.PropTypes.number.isRequired,
|
|
||||||
buttonLabel: React.PropTypes.string.isRequired,
|
|
||||||
handleButtonClick: React.PropTypes.func,
|
|
||||||
title: React.PropTypes.string.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Table;
|
|
@ -1,21 +0,0 @@
|
|||||||
.table { /* stylelint-disable */
|
|
||||||
padding: 2rem 3.2rem 3.2rem 1.8rem;
|
|
||||||
// background: red;
|
|
||||||
background: #FFFFFF;
|
|
||||||
font-family: Lato;
|
|
||||||
}
|
|
||||||
|
|
||||||
.headerContainer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.titleContainer {
|
|
||||||
color: #333740;
|
|
||||||
font-size: 1.8rem;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 2.2rem;
|
|
||||||
}
|
|
@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* TableList
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { map, startCase } from 'lodash';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
import ButtonPrimaryHotline from 'components/Button';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
|
||||||
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
|
class TableList extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||||
|
delete = () => {
|
||||||
|
console.log('will delete');
|
||||||
|
}
|
||||||
|
|
||||||
|
edit = () => {
|
||||||
|
console.log('edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
goTo = (e) => {
|
||||||
|
if (e.target.id !== 'edit' && e.target.id !== 'delete') {
|
||||||
|
console.log('will go to');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={styles.tableListContainer}>
|
||||||
|
<div className="container-fluid">
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className={styles.headerContainer}>
|
||||||
|
<div className={styles.titleContainer}>
|
||||||
|
{this.props.availableNumber} <FormattedMessage {...{ id: this.props.title }} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.buttonContainer}>
|
||||||
|
<ButtonPrimaryHotline
|
||||||
|
buttonBackground={'secondaryAddType'}
|
||||||
|
label={this.props.buttonLabel}
|
||||||
|
handlei18n
|
||||||
|
addShape
|
||||||
|
onClick={this.props.handleButtonClick}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<div className={styles.ulContainer}>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div className={`${styles.liHeaderContainer} row`}>
|
||||||
|
<div className="col-md-1"></div>
|
||||||
|
<div className="col-md-2"><FormattedMessage {...{ id: 'table.contentType.head.name' }} /></div>
|
||||||
|
<div className="col-md-5 text-center"><FormattedMessage {...{ id: 'table.contentType.head.description' }} /></div>
|
||||||
|
<div className="col-md-3 text-center"><FormattedMessage {...{ id: 'table.contentType.head.fields' }} /></div>
|
||||||
|
<div className="col-md-1"></div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{map(this.props.rowItems, (rowItem, key) => (
|
||||||
|
<li key={key} onClick={this.goTo}>
|
||||||
|
<div className={styles.hovered} />
|
||||||
|
<div className={`${styles.liInnerContainer} row`}>
|
||||||
|
<div className="col-md-1"><i className={`fa ${rowItem.icon}`} /></div>
|
||||||
|
<div className="col-md-2">{startCase(rowItem.name)}</div>
|
||||||
|
<div className="col-md-5 text-center">{rowItem.description}</div>
|
||||||
|
<div className="col-md-3 text-center">{rowItem.fields}</div>
|
||||||
|
<div className="col-md-1">
|
||||||
|
<div className={styles.icoContainer}>
|
||||||
|
<div>
|
||||||
|
<i className="fa fa-pencil" id="edit" onClick={this.edit} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i className="fa fa-trash" id="delete" onClick={this.delete} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TableList.propTypes = {
|
||||||
|
availableNumber: React.PropTypes.number.isRequired,
|
||||||
|
buttonLabel: React.PropTypes.string.isRequired,
|
||||||
|
handleButtonClick: React.PropTypes.func,
|
||||||
|
rowItems: React.PropTypes.array.isRequired,
|
||||||
|
title: React.PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TableList;
|
@ -0,0 +1,122 @@
|
|||||||
|
.tableListContainer { /* stylelint-disable */
|
||||||
|
padding: 2rem 0 0rem 0;
|
||||||
|
background: #FFFFFF;
|
||||||
|
font-family: Lato;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headerContainer {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 1.8rem 0 1.8rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleContainer {
|
||||||
|
color: #333740;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 2.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ulContainer {
|
||||||
|
margin-top: 1.6rem;
|
||||||
|
width: 100%;
|
||||||
|
> ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
> li:first-child {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
border-radius: 2px 2px 0 0;
|
||||||
|
background-color: #F3F3F4;
|
||||||
|
// background-color: rgba(16,22,34,0.04);
|
||||||
|
}
|
||||||
|
> li:not(:first-child) {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: .2rem;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
.hovered {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 5.4rem;
|
||||||
|
top: -.2rem;
|
||||||
|
|
||||||
|
background-color: #F7F8F8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> li:nth-child(2) {
|
||||||
|
&:hover {
|
||||||
|
.hovered {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 5.6rem;
|
||||||
|
top: -.5rem;
|
||||||
|
background-color: #F7F8F8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> li:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
.liInnerContainer {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.liHeaderContainer {
|
||||||
|
height: 3rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 4.6rem 0 1.9rem;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
line-height: 1.6rem;
|
||||||
|
font-weight: 600;
|
||||||
|
> div {
|
||||||
|
padding: 0;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
> div:last-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.liInnerContainer {
|
||||||
|
height: 5.2rem;
|
||||||
|
margin: 0 3.2rem 0 1.9rem ;
|
||||||
|
padding: 0 1.4rem 0 0rem;
|
||||||
|
border-bottom: 1px solid rgba(14,22,34,0.04);
|
||||||
|
color: #333740;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
> div {
|
||||||
|
padding: 0;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
> div:first-child{
|
||||||
|
padding-left: 1.4rem;
|
||||||
|
}
|
||||||
|
> div:last-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
> div:nth-child(2) {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.icoContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
> div {
|
||||||
|
color: #0E1622;
|
||||||
|
> i {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> div:last-child {
|
||||||
|
margin-left: 1.3rem;
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
// import Table from '../index';
|
// import TableList from '../index';
|
||||||
|
|
||||||
import expect from 'expect';
|
import expect from 'expect';
|
||||||
// import { shallow } from 'enzyme';
|
// import { shallow } from 'enzyme';
|
||||||
// import React from 'react';
|
// import React from 'react';
|
||||||
|
|
||||||
describe('<Table />', () => {
|
describe('<TableList />', () => {
|
||||||
it('Expect to have unit tests specified', () => {
|
it('Expect to have unit tests specified', () => {
|
||||||
expect(true).toEqual(false);
|
expect(true).toEqual(false);
|
||||||
});
|
});
|
@ -7,14 +7,12 @@
|
|||||||
import { MODELS_FETCH, MODELS_FETCH_SUCCEEDED } from './constants';
|
import { MODELS_FETCH, MODELS_FETCH_SUCCEEDED } from './constants';
|
||||||
|
|
||||||
export function modelsFetch() {
|
export function modelsFetch() {
|
||||||
console.log('fetching models');
|
|
||||||
return {
|
return {
|
||||||
type: MODELS_FETCH,
|
type: MODELS_FETCH,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function modelsFetchSucceeded(models) {
|
export function modelsFetchSucceeded(models) {
|
||||||
console.log('succeeded');
|
|
||||||
return {
|
return {
|
||||||
type: MODELS_FETCH_SUCCEEDED,
|
type: MODELS_FETCH_SUCCEEDED,
|
||||||
models,
|
models,
|
||||||
|
@ -24,7 +24,6 @@ define(map(messages, (message, id) => ({
|
|||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
console.log('did mount');
|
|
||||||
this.props.modelsFetch();
|
this.props.modelsFetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ function appReducer(state = initialState, action) {
|
|||||||
case MODELS_FETCH:
|
case MODELS_FETCH:
|
||||||
return state.set('loading', true);
|
return state.set('loading', true);
|
||||||
case MODELS_FETCH_SUCCEEDED:
|
case MODELS_FETCH_SUCCEEDED:
|
||||||
console.log('ok');
|
|
||||||
return state
|
return state
|
||||||
.set('loading', false)
|
.set('loading', false)
|
||||||
.set('models', List(action.models.models));
|
.set('models', List(action.models.models));
|
||||||
|
@ -9,10 +9,10 @@ export function* fetchModels() {
|
|||||||
|
|
||||||
const requestUrl = '/content-type-builder/models';
|
const requestUrl = '/content-type-builder/models';
|
||||||
const data = yield call(request, requestUrl, { method: 'GET' });
|
const data = yield call(request, requestUrl, { method: 'GET' });
|
||||||
console.log('data', data);
|
|
||||||
yield put(modelsFetchSucceeded(data));
|
yield put(modelsFetchSucceeded(data));
|
||||||
|
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
|
// TODO handle i18n
|
||||||
window.Strapi.notification.error('notification.error.message')
|
window.Strapi.notification.error('notification.error.message')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import { makeSelectLoading, makeSelectModels } from 'containers/App/selectors';
|
|||||||
// Design
|
// Design
|
||||||
import ContentHeader from 'components/ContentHeader';
|
import ContentHeader from 'components/ContentHeader';
|
||||||
import EmptyContentTypeView from 'components/EmptyContentTypeView';
|
import EmptyContentTypeView from 'components/EmptyContentTypeView';
|
||||||
import Table from 'components/Table';
|
import TableList from 'components/TableList';
|
||||||
|
|
||||||
import selectHomePage from './selectors';
|
import selectHomePage from './selectors';
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
@ -26,16 +26,17 @@ export class HomePage extends React.Component { // eslint-disable-line react/pre
|
|||||||
console.log('ici', this.props.homePage);
|
console.log('ici', this.props.homePage);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableComponent = () => {
|
renderTableListComponent = () => {
|
||||||
const availableNumber = size(this.props.models);
|
const availableNumber = size(this.props.models);
|
||||||
const title = availableNumber > 1 ? 'table.contentType.title.plural'
|
const title = availableNumber > 1 ? 'table.contentType.title.plural'
|
||||||
: 'table.contentType.title.singular';
|
: 'table.contentType.title.singular';
|
||||||
return (
|
return (
|
||||||
<Table
|
<TableList
|
||||||
availableNumber={availableNumber}
|
availableNumber={availableNumber}
|
||||||
title={title}
|
title={title}
|
||||||
buttonLabel={'button.contentType.add'}
|
buttonLabel={'button.contentType.add'}
|
||||||
handleButtonClick={this.handleClick}
|
handleButtonClick={this.handleClick}
|
||||||
|
rowItems={this.props.models}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ export class HomePage extends React.Component { // eslint-disable-line react/pre
|
|||||||
|
|
||||||
const component = size(this.props.models) === 0 ?
|
const component = size(this.props.models) === 0 ?
|
||||||
<EmptyContentTypeView handleClick={this.handleClick} />
|
<EmptyContentTypeView handleClick={this.handleClick} />
|
||||||
: this.renderTableComponent();
|
: this.renderTableListComponent();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.homePage}>
|
<div className={styles.homePage}>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"home.contentTypeBuilder.name": "Content Types",
|
"home.contentTypeBuilder.name": "Content Types",
|
||||||
"home.contentTypeBuilder.description": "Create, update you own content types.",
|
"home.contentTypeBuilder.description": "Create, update your own content types.",
|
||||||
"home.emptyContentType.title": "There is no Content Type Available",
|
"home.emptyContentType.title": "There is no Content Type Available",
|
||||||
"home.emptyContentType.description": "Create your first Content Type to be able to retrieve data from your API.",
|
"home.emptyContentType.description": "Create your first Content Type to be able to retrieve data from your API.",
|
||||||
|
|
||||||
@ -10,6 +10,9 @@
|
|||||||
"notification.error.message": "An error occured",
|
"notification.error.message": "An error occured",
|
||||||
|
|
||||||
"table.contentType.title.plural": "Content Types are available",
|
"table.contentType.title.plural": "Content Types are available",
|
||||||
"table.contentType.title.singular": "Content Type is available"
|
"table.contentType.title.singular": "Content Type is available",
|
||||||
|
"table.contentType.head.name": "Name",
|
||||||
|
"table.contentType.head.description": "Description",
|
||||||
|
"table.contentType.head.fields": "Fields"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
"notification.error.message": "Une erreur est survenue",
|
"notification.error.message": "Une erreur est survenue",
|
||||||
|
|
||||||
"table.contentType.title.plural": "Modèles sont disponibles",
|
"table.contentType.title.plural": "Modèles sont disponibles",
|
||||||
"table.contentType.title.singular": "Modèle est disponible"
|
"table.contentType.title.singular": "Modèle est disponible",
|
||||||
|
"table.contentType.head.name": "Nom",
|
||||||
|
"table.contentType.head.description": "Description",
|
||||||
|
"table.contentType.head.fields": "Champs"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user