mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-08 14:35:45 +01:00
add error notification if user deletion is unsuccessful and add DELETE_USER_SUCCESS
This commit is contained in:
@@ -51,9 +51,13 @@ class Users extends React.Component<Props, User> {
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const userEntries = getUsersFromState(state);
|
||||
let error = null;
|
||||
if (state.users && state.users.users) {
|
||||
error = state.users.users.error
|
||||
}
|
||||
return {
|
||||
userEntries,
|
||||
error: state.users.error
|
||||
error
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
// @flow
|
||||
import { apiClient, NOT_FOUND_ERROR } from "../../apiclient";
|
||||
import type { User } from "../types/User";
|
||||
import type { UserEntry } from "../types/UserEntry";
|
||||
import { Dispatch } from "redux";
|
||||
import {
|
||||
apiClient,
|
||||
NOT_FOUND_ERROR
|
||||
} 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_SUCCESS = "scm/users/FETCH_SUCCESS";
|
||||
@@ -53,7 +62,7 @@ function usersNotFound(url: string) {
|
||||
}
|
||||
|
||||
export function fetchUsers() {
|
||||
return function(dispatch: any) {
|
||||
return function (dispatch: any) {
|
||||
dispatch(requestUsers());
|
||||
return apiClient
|
||||
.get(USERS_URL)
|
||||
@@ -96,7 +105,7 @@ function requestUser(name: string) {
|
||||
|
||||
export function fetchUser(name: string) {
|
||||
const userUrl = USER_URL + name;
|
||||
return function(dispatch: any) {
|
||||
return function (dispatch: any) {
|
||||
dispatch(requestUsers());
|
||||
return apiClient
|
||||
.get(userUrl)
|
||||
@@ -136,7 +145,7 @@ function requestAddUser(user: User) {
|
||||
}
|
||||
|
||||
export function addUser(user: User) {
|
||||
return function(dispatch: Dispatch) {
|
||||
return function (dispatch: Dispatch) {
|
||||
dispatch(requestAddUser(user));
|
||||
return apiClient
|
||||
.postWithContentType(USERS_URL, user, CONTENT_TYPE_USER)
|
||||
@@ -170,7 +179,7 @@ function requestUpdateUser(user: User) {
|
||||
}
|
||||
|
||||
export function updateUser(user: User) {
|
||||
return function(dispatch: Dispatch) {
|
||||
return function (dispatch: Dispatch) {
|
||||
dispatch(requestUpdateUser(user));
|
||||
return apiClient
|
||||
.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 {
|
||||
type: DELETE_USER_SUCCESS,
|
||||
payload: user
|
||||
@@ -221,7 +230,7 @@ export function deleteUserFailure(user: User, error: Error) {
|
||||
}
|
||||
|
||||
export function deleteUser(user: User) {
|
||||
return function(dispatch: any) {
|
||||
return function (dispatch: any) {
|
||||
dispatch(requestDeleteUser(user));
|
||||
return apiClient
|
||||
.delete(user._links.delete.href)
|
||||
@@ -229,7 +238,10 @@ export function deleteUser(user: User) {
|
||||
dispatch(deleteUserSuccess(user));
|
||||
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) {
|
||||
return null;
|
||||
}
|
||||
const userEntries: Array<UserEntry> = [];
|
||||
const userEntries: Array < UserEntry > = [];
|
||||
|
||||
for (let userName of userNames) {
|
||||
userEntries.push(state.users.usersByNames[userName]);
|
||||
@@ -251,8 +263,8 @@ export function getUsersFromState(state) {
|
||||
}
|
||||
|
||||
function extractUsersByNames(
|
||||
users: Array<User>,
|
||||
userNames: Array<string>,
|
||||
users: Array < User > ,
|
||||
userNames: Array < string > ,
|
||||
oldUsersByNames: {}
|
||||
) {
|
||||
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 = (
|
||||
state: any,
|
||||
username: string,
|
||||
@@ -332,8 +362,7 @@ export default function reducer(state: any = {}, action: any = {}) {
|
||||
};
|
||||
case FETCH_USER_SUCCESS:
|
||||
const ubn = extractUsersByNames(
|
||||
[action.payload],
|
||||
[action.payload.name],
|
||||
[action.payload], [action.payload.name],
|
||||
state.usersByNames
|
||||
);
|
||||
return {
|
||||
@@ -345,7 +374,17 @@ export default function reducer(state: any = {}, action: any = {}) {
|
||||
},
|
||||
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 DELETE_USER_FAILURE:
|
||||
const newState = reduceUsersByNames(state, action.payload.user.name, {
|
||||
|
||||
@@ -23,7 +23,8 @@ import {
|
||||
DELETE_USER_SUCCESS,
|
||||
DELETE_USER_FAILURE,
|
||||
deleteUser,
|
||||
updateUserFailure
|
||||
updateUserFailure,
|
||||
deleteUserSuccess
|
||||
} from "./users";
|
||||
|
||||
import reducer from "./users";
|
||||
@@ -365,6 +366,44 @@ describe("users reducer", () => {
|
||||
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", () => {
|
||||
const state = {
|
||||
users: {
|
||||
|
||||
Reference in New Issue
Block a user