src/main/app/src/redux/modules/catalog.js
import { createAction, handleActions } from 'redux-actions';
import { LoadingStates } from '../../utils/common';
import { SubmissionError } from 'redux-form';
import _ from 'lodash';
import fetch from 'isomorphic-fetch';
// import BACKEND_URL from '../../env-config.js';
// region Action constants
export const REQUEST = 'microservice-catalog/microservices/REQUEST';
export const RECEIVE_SUCCESS = 'microservice-catalog/microservices/RECEIVE_SUCCESS';
export const RECEIVE_ERROR = 'microservice-catalog/microservices/RECEIVE_ERROR';
export const INITIALIZE_EDIT_FORM_SUCCESS = 'microservice-catalog/microservices/INITIALIZE_EDIT_FORM_SUCCESS';
export const INITIALIZE_EDIT_FORM_ERROR = 'microservice-catalog/microservices/INITIALIZE_EDIT_FORM_ERROR';
export const CREATE_MICROSERVICE_SUCCESS = '@@redux-form/SET_SUBMIT_SUCCEEDED';
export const FILTER_DATA = 'micorservices-catalog/microservices/FILTER_DATA';
// end region
// region Action creators
export const request = createAction(REQUEST);
/**
* Callback to receive the results of a REQUEST call and update the store.
*/
export const receiveSuccess = createAction(RECEIVE_SUCCESS, (catalogData) => catalogData);
export const receiveError = createAction(RECEIVE_ERROR, () => {});
export const initializeEditFormSuccess = createAction(INITIALIZE_EDIT_FORM_SUCCESS, (catalogData) => catalogData);
export const initializeEditFormError = createAction(INITIALIZE_EDIT_FORM_ERROR, () => {});
export const filterText = createAction(FILTER_DATA, (text)=>text);
// end region
/**
* Convenience function to dispatch REQUEST and RECEIVE to initialize edit form actions in sequence.
*
* @param {function(action: Object)} dispatch - The dispatch function from the Redux store.
*/
export const initializeEditForm = (id) => (dispatch) => {
// return fetch(BACKEND_URL+'/catalog/'+id)
return fetch('/catalog/'+id)
.then(response => response.json())
.then(json => dispatch(initializeEditFormSuccess(json)))
.catch(ex => dispatch(initializeEditFormError()))
}
/**
* Convenience function to dispatch REQUEST and RECEIVE actions in sequence.
*
* @param {function(action: Object)} dispatch - The dispatch function from the Redux store.
*/
export const fetchMicroservices = (dispatch) => {
dispatch(request());
// return fetch(BACKEND_URL+'/catalog')
return fetch('/catalog')
.then(response => response.json())
.then(json => dispatch(receiveSuccess(json)))
.catch(ex => dispatch(receiveError()))
}
export const parseFormErrors = (errors) => _.zipObject(errors.map(e => e.property), errors.map(e => e.message));
export const formatValues = (values) => {
values.url = values.url.split(",");
values.url = values.url.map(function(strURL){
return strURL.trim();
})
return values;
}
/**
* [submitForm description]
* @param {[type]} url [description]
* @param {[type]} method [description]
* @return {[type]} [description]
*/
export const submitForm = (url, method) => (values) => {
values = formatValues(values);
return new Promise((resolve, reject) => {
fetch(url, {
headers: {
'Content-Type': 'application/json'
},
method,
body: JSON.stringify(values)
})
.then(response => response.json()
.then(json => {
if (response.ok) {
resolve(json);
} else if (response.status === 400) {
reject(new SubmissionError(parseFormErrors(json.errors)));
} else {
throw new Error('A system error has occurred. Please try again later.');
}
}))
.catch(error => reject(new SubmissionError({ error: [ error.message ] })));
});
};
/**
* Attempts to POST a new MicroService and handles any errors by formatting them to Redux form to display
*
* @param {string} url - The location where the form should be patched
*
* @return {function(resetForm: function)} - A function which accepts the reset function from Redux forms and returns a function which accepts parameters in the shape of Redux forms' handleSubmit that POSTs a MicroService and handles any errors.
*/
export const postMicroservice = (url='/catalog') => submitForm(url, 'POST');
/**
* Attempts to PATCH the changes to MicroService and handles any errors by formatting them to Redux form to display
*
* @param {string} url - The location where the form should be patched
*
* @return {function(resetForm: function)} - A function which accepts the reset function from Redux forms and returns a function which accepts parameters in the shape of Redux forms' handleSubmit that POSTs a MicroService and handles any errors.
*/
export const patchMicroservice = (url) => submitForm('/catalog'+url, 'PATCH');
//region Action Handlers
export const receiveHandler = (state, action) => {
return {
...state,
loading: LoadingStates.LOADED,
errorfetching: false,
catalogData:action.payload._embedded.catalog.map(function(obj){
return {
id: obj._links.self.href.substring(obj._links.self.href.lastIndexOf("/")+1, obj._links.self.href.length),
catalog: obj
}
})
};
};
export const receiveErrorHandler = (state, action) => (
{
...state,
loading: LoadingStates.LOADED,
errorfetching: true
}
);
export const requestHandler = (state, action) => (
{
...state,
loading: LoadingStates.LOADING
}
);
export const initializeFormHandler = (state, action) => ({
formData: action.payload,
errorfetching: false
})
export const initializeFormErrorHandler = (state, action) => ({
errorfetching: true
})
export const filterDataHandler = (state, action)=>({
...state,
filterText: action.payload
})
// end region
// Default State
export const defaultState = {
catalogData: [],
loading: LoadingStates.CLEAN,
filterText: '',
errorfetching: false
};
// Reducer
export default handleActions({
[REQUEST]: requestHandler,
[RECEIVE_SUCCESS]: receiveHandler,
[RECEIVE_ERROR]: receiveErrorHandler,
[INITIALIZE_EDIT_FORM_SUCCESS]: initializeFormHandler,
[INITIALIZE_EDIT_FORM_ERROR] : initializeFormErrorHandler,
[FILTER_DATA]:filterDataHandler
},defaultState);