forked from acouzens/open5gs
Initial redux-saga is added
This commit is contained in:
parent
6a5374afa8
commit
c95702c0e6
|
@ -8,6 +8,7 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"add": "^2.0.6",
|
||||
"axios": "^0.16.2",
|
||||
"babel-plugin-polished": "^1.0.3",
|
||||
"babel-plugin-styled-components": "^1.1.4",
|
||||
"babel-preset-stage-0": "^6.24.1",
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
export const CRUD = {
|
||||
FETCH: 'crud/FETCH',
|
||||
FETCH_SUCCESS: 'crud/FETCH_SUCCESS',
|
||||
FETCH_FAILURE: 'crud/FETCH_FAILURE',
|
||||
FETCH_ONE: 'crud/FETCH_ONE',
|
||||
FETCH_ONE_SUCCESS: 'crud/FETCH_ONE_SUCCESS',
|
||||
FETCH_ONE_FAILURE: 'crud/FETCH_ONE_FAILURE',
|
||||
CREATE: 'crud/CREATE',
|
||||
CREATE_SUCCESS: 'crud/CREATE_SUCCESS',
|
||||
CREATE_FAILURE: 'crud/CREATE_FAILURE',
|
||||
UPDATE: 'crud/UPDATE',
|
||||
UPDATE_SUCCESS: 'crud/UPDATE_SUCCESS',
|
||||
UPDATE_FAILURE: 'crud/UPDATE_FAILURE',
|
||||
DELETE: 'crud/DELETE',
|
||||
DELETE_SUCCESS: 'crud/DELETE_SUCCESS',
|
||||
DELETE_FAILURE: 'crud/DELETE_FAILURE',
|
||||
};
|
||||
|
||||
export const fetchCollection = (model, id, url, params) => {
|
||||
return {
|
||||
type: CRUD.FETCH,
|
||||
meta: {
|
||||
success: CRUD.FETCH_SUCCESS,
|
||||
failure: CRUD.FETCH_FAILURE,
|
||||
model,
|
||||
id,
|
||||
params
|
||||
},
|
||||
payload: {
|
||||
method: 'get',
|
||||
url,
|
||||
params
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +1,11 @@
|
|||
import {
|
||||
fetchCollection, fetchRecord, createRecord, updateRecord, deleteRecord
|
||||
} from 'redux-crud-store'
|
||||
fetchCollection
|
||||
} from 'actions/crud'
|
||||
|
||||
const MODEL = 'subscribers'
|
||||
const PATH = '/Subscriber'
|
||||
const MODEL = 'subscribers';
|
||||
const ID = 'imsi';
|
||||
const URL = '/Subscriber';
|
||||
|
||||
export function fetchSubscribers(params = {}) {
|
||||
return fetchCollection(MODEL, PATH, params)
|
||||
}
|
||||
|
||||
export function fetchSubscriber(id, params = {}) {
|
||||
return fetchRecord(MODEL, id, `${PATH}/${id}`, params)
|
||||
}
|
||||
|
||||
export function createSubscriber(data = {}) {
|
||||
return createRecord(MODEL, PATH, data)
|
||||
}
|
||||
|
||||
export function updateSubscriber(id, data = {}) {
|
||||
return updateRecord(MODEL, id, `${PATH}/${id}`, data)
|
||||
}
|
||||
|
||||
export function deleteSubscriber(id) {
|
||||
return deleteRecord(MODEL, id, `${PATH}/${id}`)
|
||||
export const fetchSubscribers = (params = {}) => {
|
||||
return fetchCollection(MODEL, ID, URL, params)
|
||||
}
|
|
@ -1,7 +1,16 @@
|
|||
import { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { fetchSubscribers } from 'actions/subscriber';
|
||||
import { fetchCollection } from 'actions/crud';
|
||||
|
||||
class SubscriberContainer extends Component {
|
||||
componentWillMount() {
|
||||
const { crud, dispatch } = this.props
|
||||
dispatch(fetchSubscribers());
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div>
|
||||
<p>loading...</p>
|
||||
|
@ -9,4 +18,8 @@ class SubscriberContainer extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
export default SubscriberContainer;
|
||||
export default connect(
|
||||
(state) => ({
|
||||
crud: state.crud
|
||||
})
|
||||
)(SubscriberContainer);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { CRUD } from 'actions/crud';
|
||||
import { fromJS } from 'immutable';
|
||||
|
||||
const byIdInitialState = fromJS({});
|
||||
|
||||
export const modelInitialState = fromJS({
|
||||
byId: byIdInitialState
|
||||
});
|
||||
|
||||
const initialState = fromJS({});
|
||||
|
||||
export function byIdReducer(state = byIdInitialState, action) {
|
||||
switch(action.type) {
|
||||
case CRUD.FETCH_SUCCESS:
|
||||
const data = state.toJS();
|
||||
action.payload.forEach((document) => {
|
||||
data[document[action.meta.id]] = {
|
||||
document,
|
||||
error: null
|
||||
}
|
||||
})
|
||||
return fromJS(data);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function crud(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case CRUD.FETCH:
|
||||
case CRUD.FETCH_SUCCESS:
|
||||
case CRUD.FETCH_FAILURE:
|
||||
return state.updateIn([action.meta.model, "byId"],
|
||||
(s) => byIdReducer(s, action));
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default crud;
|
|
@ -1,9 +1,11 @@
|
|||
import { combineReducers } from 'redux';
|
||||
|
||||
import auth from './auth';
|
||||
import crud from './crud';
|
||||
import ui from './ui';
|
||||
|
||||
export default combineReducers({
|
||||
auth,
|
||||
crud,
|
||||
ui
|
||||
});
|
|
@ -1,113 +1,29 @@
|
|||
/* @flow */
|
||||
/* global Generator */
|
||||
|
||||
/*
|
||||
import 'regenerator-runtime/runtime'
|
||||
import { takeEvery, fork, put, call } from 'redux-saga/effects'
|
||||
|
||||
import {
|
||||
FETCH, FETCH_ONE, CREATE, UPDATE, DELETE, API_CALL, GARBAGE_COLLECT
|
||||
} from './actionTypes'
|
||||
|
||||
// TODO: The `Effect` type is not actually defined. Because 'redux-saga' does
|
||||
// not use @flow annotations, flow pretends that this import succeeds.
|
||||
import type { Effect } from 'redux-saga'
|
||||
import type { CrudAction } from './actionTypes'
|
||||
|
||||
// Generator type parameters are: Generator<+Yield,+Return,-Next>
|
||||
|
||||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
function* garbageCollector() {
|
||||
yield call(delay, 10 * 60 * 1000) // initial 10 minute delay
|
||||
for (;;) {
|
||||
yield call(delay, 5 * 60 * 1000) // every 5 minutes thereafter
|
||||
yield put({ type: GARBAGE_COLLECT, meta: { now: Date.now() } })
|
||||
}
|
||||
}
|
||||
|
||||
export const apiGeneric = (apiClient: Object) =>
|
||||
function* _apiGeneric(action: CrudAction<any>): Generator<Effect, void, any> {
|
||||
const { method, path, params, data, fetchConfig } = action.payload
|
||||
const { success, failure } = action.meta
|
||||
const meta = {
|
||||
...action.meta,
|
||||
fetchTime: Date.now()
|
||||
}
|
||||
|
||||
try {
|
||||
const response = yield call(apiClient[method], path, { params, data, fetchConfig })
|
||||
yield put({ meta, type: success, payload: response })
|
||||
} catch (error) {
|
||||
yield put({ meta, type: failure, payload: error, error: true })
|
||||
}
|
||||
}
|
||||
|
||||
const watchFetch = (apiClient) => function* _watchFetch() {
|
||||
yield* takeEvery(FETCH, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
const watchFetchOne = (apiClient) => function* _watchFetchOne() {
|
||||
yield* takeEvery(FETCH_ONE, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
const watchCreate = (apiClient) => function* _watchCreate() {
|
||||
yield* takeEvery(CREATE, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
const watchUpdate = (apiClient) => function* _watchUpdate() {
|
||||
yield* takeEvery(UPDATE, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
const watchDelete = (apiClient) => function* _watchDelete() {
|
||||
yield* takeEvery(DELETE, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
const watchApiCall = (apiClient) => function* _watchApiCall() {
|
||||
yield* takeEvery(API_CALL, apiGeneric(apiClient))
|
||||
}
|
||||
|
||||
export default function crudSaga(apiClient: Object) {
|
||||
return function* _crudSaga(): Generator<Effect, void, any> {
|
||||
yield [
|
||||
fork(watchFetch(apiClient)),
|
||||
fork(watchFetchOne(apiClient)),
|
||||
fork(watchCreate(apiClient)),
|
||||
fork(watchUpdate(apiClient)),
|
||||
fork(watchDelete(apiClient)),
|
||||
fork(watchApiCall(apiClient)),
|
||||
fork(garbageCollector)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
import axios from 'axios';
|
||||
import { all, takeEvery, put, call } from 'redux-saga/effects';
|
||||
import { ApiClient } from 'redux-crud-store';
|
||||
import { crudActions } from 'redux-crud-store';
|
||||
import { CRUD } from 'actions/crud';
|
||||
|
||||
const apiClient = new ApiClient({ basePath: '/api/db' })
|
||||
const crudApi = (method, url, { params, data } = {} ) => {
|
||||
return axios({ baseURL: '/api/db', method, url, params, data })
|
||||
.then(response => response.data);
|
||||
}
|
||||
|
||||
function* apiGeneric(action) {
|
||||
const { method, path, params, data, fetchConfig } = action.payload
|
||||
const { success, failure } = action.meta
|
||||
function* crudEntity(action) {
|
||||
const { method, url, params, data } = action.payload;
|
||||
const { success, failure } = action.meta;
|
||||
const meta = {
|
||||
...action.meta,
|
||||
fetchTime: Date.now()
|
||||
}
|
||||
|
||||
try {
|
||||
const response = yield call(apiClient[method], path, { params, data, fetchConfig })
|
||||
const response = yield call(crudApi, method, url, { params, data })
|
||||
yield put({ meta, type: success, payload: response })
|
||||
} catch (error) {
|
||||
yield put({ meta, type: failure, payload: error, error: true })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function* watchFetch() {
|
||||
yield takeEvery(crudActions.FETCH, apiGeneric)
|
||||
yield takeEvery(CRUD.FETCH, crudEntity)
|
||||
}
|
||||
|
||||
export default function* () {
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { all } from 'redux-saga/effects';
|
||||
import auth from './auth';
|
||||
import crud from './crud';
|
||||
|
||||
export default function* rootSaga() {
|
||||
yield all([
|
||||
auth(),
|
||||
crud()
|
||||
])
|
||||
}
|
|
@ -186,6 +186,13 @@ aws4@^1.2.1:
|
|||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
|
||||
|
||||
axios@^0.16.2:
|
||||
version "0.16.2"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
|
||||
dependencies:
|
||||
follow-redirects "^1.2.3"
|
||||
is-buffer "^1.1.5"
|
||||
|
||||
babel-code-frame@^6.20.0, babel-code-frame@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
|
||||
|
@ -1471,7 +1478,7 @@ debug@2.6.7:
|
|||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@2.6.8, debug@^2.1.1, debug@^2.2.0:
|
||||
debug@2.6.8, debug@^2.1.1, debug@^2.2.0, debug@^2.4.5:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
|
||||
dependencies:
|
||||
|
@ -1844,6 +1851,12 @@ find-up@^2.1.0:
|
|||
dependencies:
|
||||
locate-path "^2.0.0"
|
||||
|
||||
follow-redirects@^1.2.3:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.3.tgz#01abaeca85e3609837d9fcda3167a7e42fdaca21"
|
||||
dependencies:
|
||||
debug "^2.4.5"
|
||||
|
||||
for-in@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
|
Loading…
Reference in New Issue