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 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
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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, {
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user