Display records list (fake data)

This commit is contained in:
Aurélien Georget 2017-01-23 20:04:12 +01:00
parent 9aa2cedf85
commit 6b57603a37
6 changed files with 125 additions and 16 deletions

View File

@ -5,11 +5,20 @@
*/ */
import { import {
DEFAULT_ACTION, LOAD_RECORDS,
LOADED_RECORDS
} from './constants'; } from './constants';
export function defaultAction() { export function loadRecords(model) {
return { return {
type: DEFAULT_ACTION, type: LOAD_RECORDS,
model
};
}
export function loadedRecord(records) {
return {
type: LOADED_RECORDS,
records
}; };
} }

View File

@ -4,4 +4,5 @@
* *
*/ */
export const DEFAULT_ACTION = 'app/List/DEFAULT_ACTION'; export const LOAD_RECORDS = 'app/List/LOAD_RECORDS';
export const LOADED_RECORDS = 'app/List/LOADED_RECORDS';

View File

@ -8,27 +8,81 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect'; import { createStructuredSelector } from 'reselect';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import Container from 'components/Container';
import styles from './styles.scss'; import styles from './styles.scss';
import { loadRecords } from './actions';
import {
makeSelectModelRecords,
makeSelectLoading
} from './selectors';
export class List extends React.Component { // eslint-disable-line react/prefer-stateless-function export class List extends React.Component { // eslint-disable-line react/prefer-stateless-function
componentWillMount() {
this.props.loadRecords(this.props.routeParams.slug.toLowerCase());
}
render() { render() {
if (this.props.loading) {
return ( return (
<div> <div>
<div className={styles.list}> <p>Loading...</p>
List View for {this.props.routeParams.slug} </div>
);
}
const Plugin = this.props.plugin;
const ListItems = this.props.records.map((record, key) => {
return (
<li key={key}>
<h4>{record.title}</h4>
<p>{record.message}</p>
</li>
);
});
return (
<div>
<div className={`container-fluid ${styles.containerFluid}`}>
<Plugin title={{
id: 'plugin-content-manager-title',
defaultMessage: `Content Manager > ${this.props.routeParams.slug}`
}} description={{
id: 'plugin-content-manager-description',
defaultMessage: `Manage your ${this.props.routeParams.slug}`
}} noActions={false}>
</Plugin>
<Container>
<p></p>
<ul>
{ListItems}
</ul>
</Container>
</div> </div>
</div> </div>
); );
} }
} }
List.propTypes = {
records: React.PropTypes.array,
loadRecords: React.PropTypes.func,
loading: React.PropTypes.bool
};
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {
return { return {
loadRecords: (model) => dispatch(loadRecords(model)),
dispatch, dispatch,
}; };
} }
const mapStateToProps = createStructuredSelector({}); const mapStateToProps = createStructuredSelector({
records: makeSelectModelRecords(),
loading: makeSelectLoading()
});
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(List)); export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(List));

View File

@ -6,15 +6,26 @@
import { fromJS } from 'immutable'; import { fromJS } from 'immutable';
import { import {
DEFAULT_ACTION, LOAD_RECORDS,
LOADED_RECORDS
} from './constants'; } from './constants';
const initialState = fromJS({}); const initialState = fromJS({
loading: true,
currentModel: null,
models: {}
});
function listReducer(state = initialState, action) { function listReducer(state = initialState, action) {
switch (action.type) { switch (action.type) {
case DEFAULT_ACTION: case LOAD_RECORDS:
return state; return state
.set('loading', true)
.set('currentModel', action.model);
case LOADED_RECORDS:
return state
.set('loading', false)
.setIn(['models', state.get('currentModel')], action.records);
default: default:
return state; return state;
} }

View File

@ -1,8 +1,33 @@
// import { take, call, put, select } from 'redux-saga/effects'; import { takeLatest } from 'redux-saga';
import { put } from 'redux-saga/effects';
import {
loadedRecord,
} from './actions';
import {
LOAD_RECORDS,
} from './constants';
export function* getRecords() {
const fakeData = [{
title: 'Roger Federer has won the first set.',
message: 'Try to do better than that man and you will be a winner.'
}, {
title: 'Lewis Hamilton is on fire.',
message: 'Did you ever seen someone like that guy?'
}, {
title: 'Elon Musk is awesome!',
message: 'Space X, Paypal, Tesla, & cie.'
}];
yield put(loadedRecord(fakeData));
}
// Individual exports for testing // Individual exports for testing
export function* defaultSaga() { export function* defaultSaga() {
return yield new Promise(resolve => resolve()); yield takeLatest(LOAD_RECORDS, getRecords);
} }
// All sagas to be loaded // All sagas to be loaded

View File

@ -14,12 +14,21 @@ const selectListDomain = () => state => state.get('list');
* Default selector used by List * Default selector used by List
*/ */
const selectList = () => createSelector( const makeSelectModelRecords = () => createSelector(
selectListDomain(), selectListDomain(),
(substate) => substate.toJS() (substate) => {
const model = substate.get('currentModel');
return substate.getIn(['models', model]);
}
);
const makeSelectLoading = () => createSelector(
selectListDomain(),
(substate) => substate.get('loading')
); );
export default selectList;
export { export {
selectListDomain, selectListDomain,
makeSelectLoading,
makeSelectModelRecords
}; };