From 32e521b3324226bd04ac69a66c8d4feb629f8687 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 28 Jun 2017 14:29:53 +0900 Subject: [PATCH] update it --- webui/src/components/Shared/Spinner.js | 6 +-- webui/src/containers/Subscriber/Collection.js | 2 +- webui/src/modules/crud/actions.js | 21 +++++++++- webui/src/modules/crud/reducers.js | 22 +++++++++- webui/src/modules/crud/sagas.js | 10 ++++- webui/src/modules/crud/selectors.js | 40 +++++++++++++++++++ webui/src/modules/crud/subscriber.js | 6 ++- 7 files changed, 98 insertions(+), 9 deletions(-) diff --git a/webui/src/components/Shared/Spinner.js b/webui/src/components/Shared/Spinner.js index 8187c1472..13ef2bd49 100644 --- a/webui/src/components/Shared/Spinner.js +++ b/webui/src/components/Shared/Spinner.js @@ -1,7 +1,7 @@ - import PropTypes from 'prop-types'; -import React from 'react'; + import styled, { keyframes } from 'styled-components'; +import oc from 'open-color'; const circleAnim = keyframes` 0% { transform: rotate(0deg); } @@ -30,7 +30,7 @@ const Circle = styled.div` display: inline-block; box-sizing: border-box; font-size: 0px; - color: ${props => props.color || '#333'}; + color: ${props => props.color || oc.indigo[8]}; `; const CircleInner = styled.div` diff --git a/webui/src/containers/Subscriber/Collection.js b/webui/src/containers/Subscriber/Collection.js index 2f42c3859..22039fb9c 100644 --- a/webui/src/containers/Subscriber/Collection.js +++ b/webui/src/containers/Subscriber/Collection.js @@ -132,7 +132,7 @@ class Collection extends Component { onDelete={handleDelete} search={search} /> - {isLoading && } + {isLoading && } { failure: CRUD.FETCH_FAILURE, model, idProperty, - params, + params }, payload: { method: 'get', @@ -34,3 +34,22 @@ export const fetchCollection = (model, url, params = {}, options = {}) => { } } } + +export const fetchDocument = (model, id, url, params = {}, options = {}) => { + const idProperty = options.idProperty || '_id'; + return { + type: CRUD.FETCH_ONE, + meta: { + success: CRUD.FETCH_ONE_SUCCESS, + failure: CRUD.FETCH_ONE_FAILURE, + model, + idProperty, + id, + }, + payload: { + method: 'get', + url, + params + } + } +} \ No newline at end of file diff --git a/webui/src/modules/crud/reducers.js b/webui/src/modules/crud/reducers.js index f5ea8ef49..60e290ebd 100644 --- a/webui/src/modules/crud/reducers.js +++ b/webui/src/modules/crud/reducers.js @@ -21,9 +21,10 @@ const modelInitialState = fromJS({ const initialState = fromJS({}); function byIdReducer(state = byIdInitialState, action) { + const idProperty = action.meta ? action.meta.idProperty : '_id'; + const id = action.meta ? action.meta.id : undefined; switch(action.type) { case CRUD.FETCH_SUCCESS: - const idProperty = action.meta ? action.meta.idProperty : '_id'; const data = state.toJS(); action.payload.data.forEach((document) => { data[document[idProperty]] = { @@ -33,6 +34,18 @@ function byIdReducer(state = byIdInitialState, action) { } }) return fromJS(data); + case CRUD.FETCH_ONE: + return state.setIn([id, 'fetchTime'], 0) + .setIn([id, 'error'], null) + .setIn([id, 'document'], null) + case CRUD.FETCH_ONE_SUCCESS: + return state.setIn([id, 'fetchTime'], 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) + .setIn([id, 'error'], action.payload) + .setIn([id, 'document'], null) default: return state; } @@ -83,10 +96,15 @@ function crud(state = initialState, action) { case CRUD.FETCH: case CRUD.FETCH_SUCCESS: case CRUD.FETCH_FAILURE: - return state.updateIn([action.meta.model, 'byId'], + return state.updateIn([action.meta.model, 'byId'], (s) => byIdReducer(s, action)) .updateIn([action.meta.model, 'collections'], (s) => collectionsReducer(s, action)); + case CRUD.FETCH_ONE: + case CRUD.FETCH_ONE_SUCCESS: + case CRUD.FETCH_ONE_FAILURE: + return state.updateIn([action.meta.model, 'byId'], + (s) => byIdReducer(s, action)) default: return state; } diff --git a/webui/src/modules/crud/sagas.js b/webui/src/modules/crud/sagas.js index d843851d2..21678ad4f 100644 --- a/webui/src/modules/crud/sagas.js +++ b/webui/src/modules/crud/sagas.js @@ -29,8 +29,16 @@ function* watchFetch() { } } +function* watchFetchOne() { + while(true) { + const action = yield take(CRUD.FETCH_ONE); + yield fork(crudEntity, action); + } +} + export default function* () { yield all([ - fork(watchFetch) + fork(watchFetch), + fork(watchFetchOne) ]) } diff --git a/webui/src/modules/crud/selectors.js b/webui/src/modules/crud/selectors.js index 912eab2a1..1367fd84a 100644 --- a/webui/src/modules/crud/selectors.js +++ b/webui/src/modules/crud/selectors.js @@ -60,6 +60,40 @@ export function selectCollection(modelName, crud, params) { } } +export function selectDocument(modelName, id, crud, params) { + const model = crud.getIn([modelName], Map()); + + if (model && model.get('fetchedAt') === 0) { + return { + isLoading: true, + needsFetch: false, + error: new Error('Loading...') + } + } + + if (id === undefined || model == undefined || !recent(model.get('fetchedAt'))) { + return { + isLoading: true, + needsFetch: true, + error: new Error('Loading...') + } + } + + if (model.get('error') !== null) { + return { + isLoading: false, + needsFetch: false, + error: model.get('error') + } + } + + return { + isLoading: false, + needsFetch: false, + data: model.get('document').toJS() + } +} + export function select(action, crud) { const model = action.meta.model; const params = action.meta.params; @@ -69,6 +103,12 @@ export function select(action, crud) { case CRUD.FETCH: selection = selectCollection(model, crud, params); break; + case CRUD.FETCH_ONE: + id = action.meta.id; + if (id == null) { + throw new Error('Selecting a record, but no ID was given'); + } + selection = selectDocument(model, id, crud, params); default: throw new Error(`Action type '${action.type}' is not a fetch action.`); } diff --git a/webui/src/modules/crud/subscriber.js b/webui/src/modules/crud/subscriber.js index c51f26419..35c2ce6d0 100644 --- a/webui/src/modules/crud/subscriber.js +++ b/webui/src/modules/crud/subscriber.js @@ -6,5 +6,9 @@ const MODEL = 'subscribers'; const URL = '/Subscriber'; export const fetchSubscribers = (params = {}) => { - return fetchCollection(MODEL, URL, params, { idProperty: 'imsi' }); + return fetchCollection(MODEL, URL, params); +} + +export const fetchSubscriber = (id, params = {}) => { + return fetchDocument(MODEL, id, `${URL}/${id}`, params, { idProperty: 'imsi' }); }