Optimistic Updates (#114)
* Optimistic Updates structure * Optimistic update for Editorial Workflow
This commit is contained in:
@ -1,10 +1,11 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import { routerReducer } from 'react-router-redux';
|
||||
import { reducer as notifReducer } from 'redux-notifications';
|
||||
import optimist from 'redux-optimist';
|
||||
import reducers from '.';
|
||||
|
||||
export default combineReducers({
|
||||
export default optimist(combineReducers({
|
||||
...reducers,
|
||||
notifs: notifReducer,
|
||||
routing: routerReducer,
|
||||
});
|
||||
}));
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
UNPUBLISHED_ENTRY_SUCCESS,
|
||||
UNPUBLISHED_ENTRIES_REQUEST,
|
||||
UNPUBLISHED_ENTRIES_SUCCESS,
|
||||
UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS,
|
||||
UNPUBLISHED_ENTRY_PUBLISH_SUCCESS
|
||||
UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST,
|
||||
UNPUBLISHED_ENTRY_PUBLISH_REQUEST,
|
||||
} from '../actions/editorialWorkflow';
|
||||
import { CONFIG_SUCCESS } from '../actions/config';
|
||||
|
||||
@ -21,11 +21,11 @@ const unpublishedEntries = (state = null, action) => {
|
||||
return state;
|
||||
}
|
||||
case UNPUBLISHED_ENTRY_REQUEST:
|
||||
return state.setIn(['entities', `${action.payload.status}.${action.payload.slug}`, 'isFetching'], true);
|
||||
return state.setIn(['entities', `${ action.payload.status }.${ action.payload.slug }`, 'isFetching'], true);
|
||||
|
||||
case UNPUBLISHED_ENTRY_SUCCESS:
|
||||
return state.setIn(
|
||||
['entities', `${action.payload.status}.${action.payload.entry.slug}`],
|
||||
['entities', `${ action.payload.status }.${ action.payload.entry.slug }`],
|
||||
fromJS(action.payload.entry)
|
||||
);
|
||||
|
||||
@ -36,30 +36,32 @@ const unpublishedEntries = (state = null, action) => {
|
||||
case UNPUBLISHED_ENTRIES_SUCCESS:
|
||||
const { entries, pages } = action.payload;
|
||||
return state.withMutations((map) => {
|
||||
entries.forEach((entry) => (
|
||||
map.setIn(['entities', `${entry.metaData.status}.${entry.slug}`], fromJS(entry).set('isFetching', false))
|
||||
entries.forEach(entry => (
|
||||
map.setIn(['entities', `${ entry.metaData.status }.${ entry.slug }`], fromJS(entry).set('isFetching', false))
|
||||
));
|
||||
map.set('pages', Map({
|
||||
...pages,
|
||||
ids: List(entries.map((entry) => entry.slug))
|
||||
ids: List(entries.map(entry => entry.slug)),
|
||||
}));
|
||||
});
|
||||
|
||||
case UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS:
|
||||
case UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST:
|
||||
// Update Optimistically
|
||||
return state.withMutations((map) => {
|
||||
let entry = map.getIn(['entities', `${action.payload.oldStatus}.${action.payload.slug}`]);
|
||||
let entry = map.getIn(['entities', `${ action.payload.oldStatus }.${ action.payload.slug }`]);
|
||||
entry = entry.setIn(['metaData', 'status'], action.payload.newStatus);
|
||||
|
||||
let entities = map.get('entities').filter((val, key) => (
|
||||
key !== `${action.payload.oldStatus}.${action.payload.slug}`
|
||||
key !== `${ action.payload.oldStatus }.${ action.payload.slug }`
|
||||
));
|
||||
entities = entities.set(`${action.payload.newStatus}.${action.payload.slug}`, entry);
|
||||
entities = entities.set(`${ action.payload.newStatus }.${ action.payload.slug }`, entry);
|
||||
|
||||
map.set('entities', entities);
|
||||
});
|
||||
|
||||
case UNPUBLISHED_ENTRY_PUBLISH_SUCCESS:
|
||||
return state.deleteIn(['entities', `${action.payload.status}.${action.payload.slug}`]);
|
||||
case UNPUBLISHED_ENTRY_PUBLISH_REQUEST:
|
||||
// Update Optimistically
|
||||
return state.deleteIn(['entities', `${ action.payload.status }.${ action.payload.slug }`]);
|
||||
|
||||
default:
|
||||
return state;
|
||||
@ -67,7 +69,7 @@ const unpublishedEntries = (state = null, action) => {
|
||||
};
|
||||
|
||||
export const selectUnpublishedEntry = (state, status, slug) => {
|
||||
return state && state.getIn(['entities', `${status}.${slug}`]);
|
||||
return state && state.getIn(['entities', `${ status }.${ slug }`]);
|
||||
};
|
||||
|
||||
export const selectUnpublishedEntries = (state, status) => {
|
||||
|
@ -2,7 +2,7 @@ import auth from './auth';
|
||||
import config from './config';
|
||||
import editor from './editor';
|
||||
import integrations, * as fromIntegrations from './integrations';
|
||||
import entries, * as fromEntries from './entries';
|
||||
import entries, * as fromEntries from './entries';
|
||||
import editorialWorkflow, * as fromEditorialWorkflow from './editorialWorkflow';
|
||||
import entryDraft from './entryDraft';
|
||||
import collections from './collections';
|
||||
@ -17,7 +17,7 @@ const reducers = {
|
||||
entries,
|
||||
editorialWorkflow,
|
||||
entryDraft,
|
||||
medias
|
||||
medias,
|
||||
};
|
||||
|
||||
export default reducers;
|
||||
@ -31,7 +31,7 @@ export const selectEntry = (state, collection, slug) =>
|
||||
export const selectEntries = (state, collection) =>
|
||||
fromEntries.selectEntries(state.entries, collection);
|
||||
|
||||
export const selectSearchedEntries = (state) =>
|
||||
export const selectSearchedEntries = state =>
|
||||
fromEntries.selectSearchedEntries(state.entries);
|
||||
|
||||
export const selectUnpublishedEntry = (state, status, slug) =>
|
||||
|
Reference in New Issue
Block a user