import { toSnakeCase, ucfirst } from './core';
export const changeOperators = {
ADD: 'add',
UPDATE: 'update',
DELETE: 'delete',
RECONFIGURE: 'reconfigure',
SETPROPERTY: 'setProperty'
}
const statuses = ['start', 'success', 'error'];
const propNames = {
start: 'record',
success: 'record',
error: ''
};
|
export function createActionTypes(resourceName, async){
let actionTypes = {};
if(async){
statuses.forEach(st => {
let type = resourceName + ucfirst(st);
actionTypes[toSnakeCase(type)] = {
type,
status: st
}
})
}else{
let type = resourceName + ucfirst('action');
actionTypes[toSnakeCase(type)] = {
type,
status: 'action'
}
}
return actionTypes;
}
|
export function createActionCreators(resourceName, actionTypes){
actionTypes = actionTypes || createActionTypes(resourceName);
const actionCreators = {};
for(let type in actionTypes){
let obj = actionTypes[type];
if(propNames[obj.status]){
actionCreators['$' + obj.type] = (...args) => {
return { type: type, payload: {[propNames[obj.status]]: args[0], status: obj.status} };
}
}else{
actionCreators['$' + obj.type] = (...args) => {
return { type: type, payload: {record: args[0], status: obj.status} };
}
}
}
return actionCreators;
}
function merge(o, t, attrs){
o = o.asMutable ? o.asMutable() : o;
if(attrs){
attrs.forEach(attr => o[attr] = t[attr]);
return o;
}else{
return Object.assign(o, t);
}
}
function extra(o, attrs){
if(attrs){
const newO = {};
attrs.forEach(attr => o[attr] = t[attr]);
return newO;
}else{
return o;
}
}
|
export function applyCrudReducer(immutableState, payload, initialState){
if(payload.changes){
let _records = payload.record === undefined ? payload.records : payload.record;
let generatorKey = payload.cid;
let newState;
payload.changes.forEach(change => {
switch(change.type){
case changeOperators.ADD:
|
if(Object(_records) === _records){
if(Array.isArray(immutableState[change.name])){
|
immutableState = immutableState.update(change.name, (records) => {
let recordMap = {};
let _recordArr = [].concat(_records);
_recordArr.forEach(r => recordMap[r[generatorKey]] = r);
records = records.asMutable().map(r => {
if(recordMap[r[generatorKey]] === undefined){
return r;
}else{
_recordArr.splice(_recordArr.indexOf(recordMap[r[generatorKey]]), 1);
return merge(r, recordMap[r[generatorKey]], change.attrs);
}
});
for(var i = _recordArr.length; i--;){
records.unshift(_recordArr[i]);
}
return records;
});
}else{
immutableState = immutableState.set(change.name, _records);
}
}
break;
case changeOperators.UPDATE:
|
if(Object(_records) === _records){
if(Array.isArray(immutableState[change.name])){
immutableState = immutableState.update(change.name, (records) => {
let recordMap = {};
let _recordArr = [].concat(_records);
_recordArr.forEach(r => recordMap[r[generatorKey]] = r);
records = records.asMutable().map(r => {
if(recordMap[r[generatorKey]] === undefined){
return r;
}else{
return merge(r, recordMap[r[generatorKey]], change.attrs);
}
});
return records;
});
}else if(immutableState[change.name][generatorKey] == _records[generatorKey]){
|
immutableState = immutableState.set(change.name, extra(_records, change.attrs));
}
}
break;
case changeOperators.DELETE:
|
if(Object(_records) === _records){
if(Array.isArray(immutableState[change.name])){
immutableState = immutableState.update(change.name, (records) => {
let recordMap = {};
let _recordArr = [].concat(_records);
_recordArr.forEach(r => recordMap[r[generatorKey]] = r);
return records.filter(r => recordMap[r[generatorKey]] === undefined);
});
}else if(immutableState[change.name][generatorKey] == _records[generatorKey]){
immutableState = immutableState.set(change.name, null);
}
}
break;
case changeOperators.RECONFIGURE:
immutableState = immutableState.set(change.name, _records === undefined? initialState[change.name] : _records);
break;
case changeOperators.SETPROPERTY:
newState = change.getData(_records, immutableState[change.name]);
immutableState = immutableState.set(change.name, newState === undefined ? initialState[change.name] : newState);
break;
default:
if(change.callback){
newState = change.callback(_records, immutableState[change.name], payload.params, immutableState, initialState);
}else if(change[payload.status]){
newState = change[payload.status](_records, immutableState[change.name], payload.params, immutableState, initialState);
}
if(change.name){
immutableState = immutableState.set(change.name, newState === undefined ? initialState[change.name] : newState);
}else if(newState === undefined){
immutableState = initialState;
}else{
immutableState = newState;
}
break;
}
});
return immutableState;
}else{
|
return immutableState;
}
}
|
export function createActions(crudResourceNames, resourceNames){
let map = {};
crudResourceNames.forEach(resourceName => {
map[resourceName] = createActionTypes(resourceName, true);
});
resourceNames.forEach(resourceName => {
map[resourceName] = createActionTypes(resourceName);
});
return {
getActionTypes(){
let actionsMap = {};
for(let key in map){
Object.assign(actionsMap, map[key]);
}
return actionsMap;
},
getActionCreators(){
let creatorsMap = {};
for(let key in map){
Object.assign(creatorsMap, createActionCreators(key, map[key]));
}
return creatorsMap;
}
}
}
|