diff --git a/client/src/containers/Users/withUsers.js b/client/src/containers/Users/withUsers.js index 2062c9e01..90aa4ca16 100644 --- a/client/src/containers/Users/withUsers.js +++ b/client/src/containers/Users/withUsers.js @@ -1,9 +1,10 @@ import { connect } from 'react-redux'; +import { getExpensesCurrentPageFactory } from 'store/users/users.selectors'; export default (mapState) => { const mapStateToProps = (state, props) => { const mapped = { - usersList: state.users.list, + usersList: getExpensesCurrentPageFactory(state, props), usersLoading: state.users.loading, }; return mapState ? mapState(mapped, state, props) : mapped; diff --git a/client/src/store/users/users.actions.js b/client/src/store/users/users.actions.js index 729f81d62..5dcc18d08 100644 --- a/client/src/store/users/users.actions.js +++ b/client/src/store/users/users.actions.js @@ -13,7 +13,9 @@ export const fetchUsers = () => { .then((response) => { dispatch({ type: t.USERS_LIST_SET, - users: response.data.users, + payload: { + users: response.data.users, + }, }); dispatch({ type: t.USERS_TABLE_LOADING, @@ -34,7 +36,10 @@ export const fetchUser = ({ id }) => { .then((response) => { dispatch({ type: t.USER_DETAILS_SET, - user: response.data.user, + payload: { + id, + user: response.data.user, + }, }); resolve(response); }) @@ -45,24 +50,49 @@ export const fetchUser = ({ id }) => { }; export const deleteUser = ({ id }) => { - return (dispatch) => ApiService.delete(`users/${id}`); + return (dispatch) => + new Promise((resolve, reject) => { + ApiService.delete(`users/${id}`) + .then((response) => { + dispatch({ type: t.USER_DELETE, id }); + resolve(response); + }) + .catch((error) => { + reject(error.response.data.errors || []); + }); + }); }; export const submitInvite = ({ form }) => { - return (dispatch) => new Promise((resolve, reject) => { - ApiService.post(`invite/send`, form) - .then((response) => { resolve(response); }) - .catch((error) => { - const { response } = error; - const { data } = response; + return (dispatch) => + new Promise((resolve, reject) => { + ApiService.post(`invite/send`, form) + .then((response) => { + resolve(response); + }) + .catch((error) => { + const { response } = error; + const { data } = response; - reject(data?.errors); + reject(data?.errors); + }); }); - }); }; export const editUser = ({ form, id }) => { - return (dispatch) => ApiService.post(`users/${id}`, form); + return (dispatch) => + new Promise((resolve, reject) => { + ApiService.post(`users/${id}`, form) + .then((response) => { + resolve(response); + }) + .catch((error) => { + const { response } = error; + const { data } = response; + + reject(data?.errors); + }); + }); }; export const inactiveUser = ({ id }) => { diff --git a/client/src/store/users/users.reducer.js b/client/src/store/users/users.reducer.js index 5f2ac0aa2..41119b344 100644 --- a/client/src/store/users/users.reducer.js +++ b/client/src/store/users/users.reducer.js @@ -1,25 +1,41 @@ import { createReducer } from '@reduxjs/toolkit'; +import { createTableQueryReducers } from 'store/queryReducers'; import t from 'store/types'; const initialState = { - list: {}, + items: {}, userById: {}, loading: false, }; export default createReducer(initialState, { [t.USERS_LIST_SET]: (state, action) => { - state.list = action.users; + const { users } = action.payload; + const _users = {}; + + users.forEach((user) => { + _users[user.id] = { + ...user, + }; + }); + state.items = { + ...state.items, + ..._users, + }; }, [t.USER_DETAILS_SET]: (state, action) => { - state.userById[action.user.id] = action.user; + const { id, user } = action.payload; + const _user = state.items[id] || {}; + state.items[id] = { ..._user, ...user }; }, [t.USERS_TABLE_LOADING]: (state, action) => { const { loading } = action.payload; - state.loading = !!loading; + state.loading = loading; }, + + ...createTableQueryReducers('USERS'), }); /** diff --git a/client/src/store/users/users.selectors.js b/client/src/store/users/users.selectors.js new file mode 100644 index 000000000..a6bb22112 --- /dev/null +++ b/client/src/store/users/users.selectors.js @@ -0,0 +1,21 @@ +import { createSelector } from '@reduxjs/toolkit'; +import { pickItemsFromIds, getItemById } from 'store/selectors'; + +const usersItemsSelector = (state) => state.users.items; +const userIdPropSelector = (state, props) => props.userId; + +export const getExpensesCurrentPageFactory = createSelector( + usersItemsSelector, + (users) => { + return Object.values(users); + }, +); + + +export const getUserByIdFactory = () => createSelector( + usersItemsSelector, + userIdPropSelector, + (users, userId) => { + return getItemById(users, userId); + }, +); diff --git a/client/src/store/users/users.types.js b/client/src/store/users/users.types.js index e6f2a3df0..1837cdb78 100644 --- a/client/src/store/users/users.types.js +++ b/client/src/store/users/users.types.js @@ -2,4 +2,5 @@ export default { USERS_LIST_SET: 'USERS_LIST_SET', USERS_TABLE_LOADING: 'USERS_TABLE_LOADING', USER_DETAILS_SET: 'USER_DETAILS_SET', + USER_DELETE: 'USER_DELETE', };