FETCH_ONE modules(redux, saga, selector) is added

This commit is contained in:
Sukchan Lee 2017-06-29 00:12:37 +09:00
parent 32e521b332
commit b8a34c11e5
8 changed files with 148 additions and 67 deletions

View File

@ -218,7 +218,7 @@ class Form extends Component {
transformErrors={transformErrors}
autocomplete="off"
onChange={handleChange}
onSubmit={onSubmit}
onSubmit={() => onSubmit(this.state.formData)}
onError={log("errors")}>
<div>
<button type="submit" ref={(el => this.submitButton = el)}/>

View File

@ -189,34 +189,40 @@ class Edit extends Component {
const { subscribers } = this.props;
const { imsi } = formData;
if (subscribers.filter(subscriber => subscriber.imsi === imsi).length > 0) {
if (subscribers && subscribers.filter(subscriber => subscriber.imsi === imsi).length > 0) {
errors.imsi.addError(`'${imsi}' is duplicated`);
}
return errors;
}
handleSubmit = (formData) => {
console.log(formData);
}
render() {
const {
validate,
handleSubmit
} = this;
const {
visible,
title,
onHide,
onSubmit,
formData
} = this.props;
return (
<Form
visible={visible}
title="Create Subscriber"
title={title}
schema={this.state.schema}
uiSchema={this.state.uiSchema}
formData={formData}
validate={validate}
onHide={onHide}
onSubmit={onSubmit}>
</Form>
onSubmit={handleSubmit} />
)
}
}

View File

@ -5,10 +5,6 @@ import { connect } from 'react-redux';
import { fetchSubscribers } from 'modules/crud/subscriber';
import { select } from 'modules/crud/selectors';
import styled from 'styled-components';
import oc from 'open-color';
import { media } from 'helpers/style-utils';
import {
Layout,
Subscriber,
@ -18,10 +14,13 @@ import {
Dimmed
} from 'components';
import Document from './Document';
class Collection extends Component {
state = {
search: '',
form: {
document: {
action: '',
visible: false,
dimmed: false
}
@ -55,59 +54,58 @@ class Collection extends Component {
});
}
formHandler = {
show: () => {
documentHandler = {
show: (action, payload) => {
this.setState({
form: {
document: {
action,
visible: true,
dimmed: true
dimmed: true,
...payload
}
})
},
hide: () => {
this.setState({
form: {
document: {
...this.state.document,
visible: false,
dimmed: false
}
})
},
submit: async () => {
this.setState({
form: {
visible: false,
dimmed: false
}
})
actions: {
add: () => {
console.log('add')
this.documentHandler.show('add');
},
browser: (imsi) => {
console.log('brower' + imsi)
},
change: (imsi) => {
console.log('change' + imsi)
this.documentHandler.show('change', { imsi });
},
delete: (imsi) => {
console.log('delete')
}
}
}
handleShow = (imsi) => {
}
handleEdit = (imsi) => {
}
handleDelete = (imsi) => {
}
render() {
const {
handleSearchChange,
handleSearchClear,
formHandler,
handleShow,
handleEdit,
handleDelete
documentHandler
} = this;
const {
search,
form
document
} = this.state;
const {
subscribers
subscribers
} = this.props
const {
@ -115,37 +113,31 @@ class Collection extends Component {
data
} = subscribers;
const {
length
} = data;
return (
<Layout.Content>
{length !== 0 && <Subscriber.Search
{data.length !== 0 && <Subscriber.Search
onChange={handleSearchChange}
value={search}
onClear={handleSearchClear} />}
<Subscriber.List
subscribers={subscribers.data}
onShow={handleShow}
onEdit={handleEdit}
onDelete={handleDelete}
subscribers={data}
onShow={documentHandler.actions.browser}
onEdit={documentHandler.actions.change}
onDelete={documentHandler.actions.delete}
search={search}
/>
{isLoading && <Spinner md />}
<Blank
visible={!isLoading && !length}
visible={!isLoading && !data.length}
title="ADD A SUBSCRIBER"
body="You have no subscribers... yet!"
onTitle={formHandler.show}
onTitle={documentHandler.actions.add}
/>
<FloatingButton onClick={formHandler.show}/>
<Subscriber.Edit
subscribers={subscribers.data}
visible={form.visible}
onHide={formHandler.hide}
onSubmit={formHandler.submit} />
<Dimmed visible={form.dimmed} />
<FloatingButton onClick={documentHandler.actions.add}/>
<Document
{ ...document }
onHide={documentHandler.hide} />
<Dimmed visible={document.dimmed} />
</Layout.Content>
)
}

View File

@ -0,0 +1,79 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { fetchSubscriber, fetchSubscribers } from 'modules/crud/subscriber';
import { select } from 'modules/crud/selectors';
import {
Subscriber,
Spinner
} from 'components';
class Document extends Component {
componentWillMount() {
const { subscriber, dispatch } = this.props
if (subscriber.needsFetch) {
dispatch(subscriber.fetch)
}
}
componentWillReceiveProps(nextProps) {
const { subscriber } = nextProps
const { dispatch } = this.props
if (subscriber.needsFetch) {
dispatch(subscriber.fetch)
}
}
handleSubmit = () => {
}
render() {
const {
handleSubmit
} = this;
const {
visible,
action,
subscribers,
subscriber,
onHide
} = this.props
const {
isLoading,
data
} = subscriber;
const title = (action === 'change') ? 'Edit Subscriber' : 'Create Subscriber';
return (
<div>
{isLoading && <Spinner md/>}
<Subscriber.Edit
formData={data}
title={title}
visible={visible}
onHide={onHide}
onSubmit={handleSubmit} />
</div>
)
}
}
function mapStateToProps(state, ownProps) {
let subscriber = {};
if (ownProps.imsi) {
subscriber = select(fetchSubscriber(ownProps.imsi), state.crud);
}
return {
subscriber: subscriber
}
}
export default connect(mapStateToProps)(Document)

View File

@ -1,5 +1,7 @@
import Collection from './Collection';
import Document from './Document';
export {
Collection
Collection,
Document
};

View File

@ -35,15 +35,14 @@ function byIdReducer(state = byIdInitialState, action) {
})
return fromJS(data);
case CRUD.FETCH_ONE:
return state.setIn([id, 'fetchTime'], 0)
return state.setIn([id, 'fetchedAt'], 0)
.setIn([id, 'error'], null)
.setIn([id, 'document'], null)
case CRUD.FETCH_ONE_SUCCESS:
return state.setIn([id, 'fetchTime'], action.meta.fetchedAt)
return state.setIn([id, 'fetchedAt'], action.meta.fetchedAt)
.setIn([id, 'error'], null)
.setIn([id, 'document'], fromJS(action.payload.data))
case CRUD.FETCH_ONE_FAILURE:
return state.setIn([id, 'fetchTime'], action.meta.fetchedAt)
return state.setIn([id, 'fetchedAt'], action.meta.fetchedAt)
.setIn([id, 'error'], action.payload)
.setIn([id, 'document'], null)
default:

View File

@ -61,7 +61,7 @@ export function selectCollection(modelName, crud, params) {
}
export function selectDocument(modelName, id, crud, params) {
const model = crud.getIn([modelName], Map());
const model = crud.getIn([modelName, 'byId', id]);
if (model && model.get('fetchedAt') === 0) {
return {
@ -98,6 +98,7 @@ export function select(action, crud) {
const model = action.meta.model;
const params = action.meta.params;
let id;
let selection;
switch (action.type) {
case CRUD.FETCH:
@ -105,10 +106,11 @@ export function select(action, crud) {
break;
case CRUD.FETCH_ONE:
id = action.meta.id;
if (id == null) {
if (id === null) {
throw new Error('Selecting a record, but no ID was given');
}
selection = selectDocument(model, id, crud, params);
break;
default:
throw new Error(`Action type '${action.type}' is not a fetch action.`);
}

View File

@ -1,14 +1,15 @@
import {
fetchCollection
fetchCollection,
fetchDocument
} from './actions'
const MODEL = 'subscribers';
const URL = '/Subscriber';
export const fetchSubscribers = (params = {}) => {
return fetchCollection(MODEL, URL, params);
return fetchCollection(MODEL, URL, params, { idProperty: 'imsi' });
}
export const fetchSubscriber = (id, params = {}) => {
return fetchDocument(MODEL, id, `${URL}/${id}`, params, { idProperty: 'imsi' });
export const fetchSubscriber = (imsi, params = {}) => {
return fetchDocument(MODEL, imsi, `${URL}/${imsi}`, params, { idProperty: 'imsi' });
}