Skip to content

Commit

Permalink
Merge pull request #2756 from marmelab/fix-optimistic-handling
Browse files Browse the repository at this point in the history
[RFR] Fix incomplete optimistic handling from #2684
  • Loading branch information
fzaninotto authored Jan 11, 2019
2 parents e43ffd8 + acf1d68 commit ac76b03
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 49 deletions.
42 changes: 22 additions & 20 deletions packages/ra-core/src/reducer/admin/resource/list/ids.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import uniq from 'lodash/uniq';
import {
CRUD_GET_LIST_SUCCESS,
CRUD_DELETE_OPTIMISTIC,
CRUD_DELETE_MANY_OPTIMISTIC,
CRUD_GET_MANY_SUCCESS,
CRUD_GET_MANY_REFERENCE_SUCCESS,
CRUD_GET_ONE_SUCCESS,
Expand All @@ -11,6 +9,7 @@ import {
} from '../../../../actions/dataActions';

import getFetchedAt from '../../../../util/getFetchedAt';
import { DELETE, DELETE_MANY } from '../../../../dataFetchActions';

export const addRecordIdsFactory = getFetchedAt => (
newRecordIds = [],
Expand All @@ -29,23 +28,9 @@ export const addRecordIdsFactory = getFetchedAt => (

const addRecordIds = addRecordIdsFactory(getFetchedAt);

export default (previousState = [], { type, payload }) => {
switch (type) {
case CRUD_GET_LIST_SUCCESS:
return addRecordIds(payload.data.map(({ id }) => id), []);
case CRUD_GET_MANY_SUCCESS:
case CRUD_GET_MANY_REFERENCE_SUCCESS:
return addRecordIds(
payload.data
.map(({ id }) => id)
.filter(id => previousState.indexOf(id) !== -1),
previousState
);
case CRUD_GET_ONE_SUCCESS:
case CRUD_CREATE_SUCCESS:
case CRUD_UPDATE_SUCCESS:
return addRecordIds([payload.data.id], previousState);
case CRUD_DELETE_OPTIMISTIC: {
export default (previousState = [], { type, payload, meta }) => {
if (meta && meta.optimistic) {
if (meta.fetch === DELETE) {
const index = previousState
.map(el => el == payload.id) // eslint-disable-line eqeqeq
.indexOf(true);
Expand All @@ -63,7 +48,7 @@ export default (previousState = [], { type, payload }) => {

return newState;
}
case CRUD_DELETE_MANY_OPTIMISTIC: {
if (meta.fetch === DELETE_MANY) {
const newState = previousState.filter(
el => !payload.ids.includes(el)
);
Expand All @@ -73,6 +58,23 @@ export default (previousState = [], { type, payload }) => {

return newState;
}
}

switch (type) {
case CRUD_GET_LIST_SUCCESS:
return addRecordIds(payload.data.map(({ id }) => id), []);
case CRUD_GET_MANY_SUCCESS:
case CRUD_GET_MANY_REFERENCE_SUCCESS:
return addRecordIds(
payload.data
.map(({ id }) => id)
.filter(id => previousState.indexOf(id) !== -1),
previousState
);
case CRUD_GET_ONE_SUCCESS:
case CRUD_CREATE_SUCCESS:
case CRUD_UPDATE_SUCCESS:
return addRecordIds([payload.data.id], previousState);
default:
return previousState;
}
Expand Down
59 changes: 38 additions & 21 deletions packages/ra-core/src/reducer/admin/resource/list/selectedIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
TOGGLE_LIST_ITEM,
ToggleListItemAction,
} from '../../../../actions/listActions';
import { CRUD_DELETE_OPTIMISTIC } from '../../../../actions/dataActions';
import { DELETE, DELETE_MANY } from '../../../../dataFetchActions';

const initialState = [];

Expand All @@ -14,28 +14,38 @@ type State = any[];
type ActionTypes =
| SetListLelectedIdsAction
| ToggleListItemAction
| { type: typeof CRUD_DELETE_OPTIMISTIC; payload: { id: string } } // FIXME use type from action creator
| { type: 'OTHER_ACTION'; meta?: any };
| {
type: 'DELETE_ACTION';
meta: { optimistic: true; fetch: string };
payload: any;
}
| {
type: 'OTHER_ACTION';
meta: any;
payload: any;
};

const selectedIdsReducer: Reducer<State> = (
previousState: State = initialState,
action: ActionTypes
) => {
switch (action.type) {
case SET_LIST_SELECTED_IDS:
return action.payload;
case TOGGLE_LIST_ITEM: {
const index = previousState.indexOf(action.payload);
if (index > -1) {
return [
...previousState.slice(0, index),
...previousState.slice(index + 1),
];
} else {
return [...previousState, action.payload];
}
if (action.type === SET_LIST_SELECTED_IDS) {
return action.payload;
}
if (action.type === TOGGLE_LIST_ITEM) {
const index = previousState.indexOf(action.payload);
if (index > -1) {
return [
...previousState.slice(0, index),
...previousState.slice(index + 1),
];
} else {
return [...previousState, action.payload];
}
case CRUD_DELETE_OPTIMISTIC: {
}

if (action.meta && action.meta.optimistic) {
if (action.meta.fetch === DELETE) {
const index = previousState.indexOf(action.payload.id);
if (index === -1) {
return previousState;
Expand All @@ -45,11 +55,18 @@ const selectedIdsReducer: Reducer<State> = (
...previousState.slice(index + 1),
];
}
default:
return action.meta && action.meta.unselectAll
? initialState
: previousState;
if (action.meta.fetch === DELETE_MANY) {
const index = previousState.indexOf(action.payload.ids);
if (index === -1) {
return previousState;
}
return previousState.filter(id => !action.payload.ids.includes(id));
}
}

return action.meta && action.meta.unselectAll
? initialState
: previousState;
};

export default selectedIdsReducer;
17 changes: 9 additions & 8 deletions packages/ra-core/src/reducer/admin/resource/list/total.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import {
CRUD_GET_ONE_SUCCESS,
CRUD_GET_LIST_SUCCESS,
CRUD_DELETE_OPTIMISTIC,
CRUD_DELETE_MANY_OPTIMISTIC,
} from '../../../../actions/dataActions';
import { DELETE, DELETE_MANY } from '../../../../dataFetchActions';

export default (previousState = 0, { type, payload }) => {
export default (previousState = 0, { type, payload, meta }) => {
if (type === CRUD_GET_ONE_SUCCESS) {
return previousState == 0 ? 1 : previousState;
}
if (type === CRUD_GET_LIST_SUCCESS) {
return payload.total;
}
if (type === CRUD_DELETE_OPTIMISTIC) {
return previousState - 1;
}
if (type === CRUD_DELETE_MANY_OPTIMISTIC) {
return previousState - payload.ids.length;
if (meta && meta.optimistic) {
if (meta.fetch === DELETE) {
return previousState - 1;
}
if (meta.fetch === DELETE_MANY) {
return previousState - payload.ids.length;
}
}
return previousState;
};
1 change: 1 addition & 0 deletions packages/ra-ui-materialui/src/input/CheckboxGroupInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ CheckboxGroupInput.propTypes = {

CheckboxGroupInput.defaultProps = {
choices: [],
classes: {},
options: {},
optionText: 'name',
optionValue: 'id',
Expand Down

0 comments on commit ac76b03

Please sign in to comment.