add error notification if user deletion is unsuccessful and add DELETE_USER_SUCCESS

This commit is contained in:
Maren Süwer
2018-07-19 11:23:20 +02:00
parent 2689a20ee8
commit 9593a18a55
3 changed files with 101 additions and 19 deletions

View File

@@ -51,9 +51,13 @@ class Users extends React.Component<Props, User> {
const mapStateToProps = state => { const mapStateToProps = state => {
const userEntries = getUsersFromState(state); const userEntries = getUsersFromState(state);
let error = null;
if (state.users && state.users.users) {
error = state.users.users.error
}
return { return {
userEntries, userEntries,
error: state.users.error error
}; };
}; };

View File

@@ -1,8 +1,17 @@
// @flow // @flow
import { apiClient, NOT_FOUND_ERROR } from "../../apiclient"; import {
import type { User } from "../types/User"; apiClient,
import type { UserEntry } from "../types/UserEntry"; NOT_FOUND_ERROR
import { Dispatch } from "redux"; } from "../../apiclient";
import type {
User
} from "../types/User";
import type {
UserEntry
} from "../types/UserEntry";
import {
Dispatch
} from "redux";
export const FETCH_USERS = "scm/users/FETCH"; export const FETCH_USERS = "scm/users/FETCH";
export const FETCH_USERS_SUCCESS = "scm/users/FETCH_SUCCESS"; export const FETCH_USERS_SUCCESS = "scm/users/FETCH_SUCCESS";
@@ -53,7 +62,7 @@ function usersNotFound(url: string) {
} }
export function fetchUsers() { export function fetchUsers() {
return function(dispatch: any) { return function (dispatch: any) {
dispatch(requestUsers()); dispatch(requestUsers());
return apiClient return apiClient
.get(USERS_URL) .get(USERS_URL)
@@ -96,7 +105,7 @@ function requestUser(name: string) {
export function fetchUser(name: string) { export function fetchUser(name: string) {
const userUrl = USER_URL + name; const userUrl = USER_URL + name;
return function(dispatch: any) { return function (dispatch: any) {
dispatch(requestUsers()); dispatch(requestUsers());
return apiClient return apiClient
.get(userUrl) .get(userUrl)
@@ -136,7 +145,7 @@ function requestAddUser(user: User) {
} }
export function addUser(user: User) { export function addUser(user: User) {
return function(dispatch: Dispatch) { return function (dispatch: Dispatch) {
dispatch(requestAddUser(user)); dispatch(requestAddUser(user));
return apiClient return apiClient
.postWithContentType(USERS_URL, user, CONTENT_TYPE_USER) .postWithContentType(USERS_URL, user, CONTENT_TYPE_USER)
@@ -170,7 +179,7 @@ function requestUpdateUser(user: User) {
} }
export function updateUser(user: User) { export function updateUser(user: User) {
return function(dispatch: Dispatch) { return function (dispatch: Dispatch) {
dispatch(requestUpdateUser(user)); dispatch(requestUpdateUser(user));
return apiClient return apiClient
.putWithContentType(user._links.update.href, user, CONTENT_TYPE_USER) .putWithContentType(user._links.update.href, user, CONTENT_TYPE_USER)
@@ -203,7 +212,7 @@ export function requestDeleteUser(user: User) {
}; };
} }
function deleteUserSuccess(user: User) { export function deleteUserSuccess(user: User) {
return { return {
type: DELETE_USER_SUCCESS, type: DELETE_USER_SUCCESS,
payload: user payload: user
@@ -221,7 +230,7 @@ export function deleteUserFailure(user: User, error: Error) {
} }
export function deleteUser(user: User) { export function deleteUser(user: User) {
return function(dispatch: any) { return function (dispatch: any) {
dispatch(requestDeleteUser(user)); dispatch(requestDeleteUser(user));
return apiClient return apiClient
.delete(user._links.delete.href) .delete(user._links.delete.href)
@@ -229,7 +238,10 @@ export function deleteUser(user: User) {
dispatch(deleteUserSuccess(user)); dispatch(deleteUserSuccess(user));
dispatch(fetchUsers()); dispatch(fetchUsers());
}) })
.catch(err => dispatch(deleteUserFailure(user, err))); .catch(cause => {
const error = new Error(`could not delete user ${user.name}: ${cause.message}`);
dispatch(deleteUserFailure(user, error));
});
}; };
} }
@@ -241,7 +253,7 @@ export function getUsersFromState(state) {
if (!userNames) { if (!userNames) {
return null; return null;
} }
const userEntries: Array<UserEntry> = []; const userEntries: Array < UserEntry > = [];
for (let userName of userNames) { for (let userName of userNames) {
userEntries.push(state.users.usersByNames[userName]); userEntries.push(state.users.usersByNames[userName]);
@@ -251,8 +263,8 @@ export function getUsersFromState(state) {
} }
function extractUsersByNames( function extractUsersByNames(
users: Array<User>, users: Array < User > ,
userNames: Array<string>, userNames: Array < string > ,
oldUsersByNames: {} oldUsersByNames: {}
) { ) {
const usersByNames = {}; const usersByNames = {};
@@ -276,6 +288,24 @@ export function editUser(user: User) {
}; };
} }
function deleteUserInUsersByNames(users:{}, userName: any){
let newUsers = {};
for(let username in users){
if(username != userName)
newUsers[username] = users[username];
}
return newUsers;
}
function deleteUserInEntries(users:[], userName: any){
let newUsers = [];
for(let user of users){
if(user != userName)
newUsers.push(user);
}
return newUsers;
}
const reduceUsersByNames = ( const reduceUsersByNames = (
state: any, state: any,
username: string, username: string,
@@ -332,8 +362,7 @@ export default function reducer(state: any = {}, action: any = {}) {
}; };
case FETCH_USER_SUCCESS: case FETCH_USER_SUCCESS:
const ubn = extractUsersByNames( const ubn = extractUsersByNames(
[action.payload], [action.payload], [action.payload.name],
[action.payload.name],
state.usersByNames state.usersByNames
); );
return { return {
@@ -345,7 +374,17 @@ export default function reducer(state: any = {}, action: any = {}) {
}, },
usersByNames: ubn usersByNames: ubn
}; };
case DELETE_USER_SUCCESS:
const newUserByNames = deleteUserInUsersByNames(state.usersByNames, [action.payload.name]);
const newUserEntries = deleteUserInEntries(state.users.entries, [action.payload.name]);
return {
...state,
users: {
...state.users,
entries: newUserEntries
},
usersByNames: newUserByNames
}
case FETCH_USERS_FAILURE: case FETCH_USERS_FAILURE:
case DELETE_USER_FAILURE: case DELETE_USER_FAILURE:
const newState = reduceUsersByNames(state, action.payload.user.name, { const newState = reduceUsersByNames(state, action.payload.user.name, {

View File

@@ -23,7 +23,8 @@ import {
DELETE_USER_SUCCESS, DELETE_USER_SUCCESS,
DELETE_USER_FAILURE, DELETE_USER_FAILURE,
deleteUser, deleteUser,
updateUserFailure updateUserFailure,
deleteUserSuccess
} from "./users"; } from "./users";
import reducer from "./users"; import reducer from "./users";
@@ -365,6 +366,44 @@ describe("users reducer", () => {
expect(ford.loading).toBeFalsy(); expect(ford.loading).toBeFalsy();
}); });
it("should delete deleted user in users in state if delete user action is successful", () => {
const state = {
users: {
entries: [
"zaphod",
"ford"
]
}
};
const newState = reducer(state, deleteUserSuccess(userZaphod));
expect(newState.users.entries).toContain("ford");
expect(newState.users.entries).not.toContain("zaphod");
});
it("should delete deleted user in usersByNames in state if delete user action is successful", () => {
const state = {
users: {
entries: [
"zaphod",
"ford"
]
},
usersByNames: {
zaphod: {
entry: userZaphod
},
ford: {
entry: userFord
}
}
};
const newState = reducer(state, deleteUserSuccess(userZaphod));
const ford = newState.usersByNames["ford"];
const zaphod = newState.usersByNames["zaphod"];
expect(zaphod).toBeUndefined();
expect(ford.entry).toBe(userFord);
});
it("should set global error state if one user could not be deleted", () => { it("should set global error state if one user could not be deleted", () => {
const state = { const state = {
users: { users: {