2019-05-07 16:51:16 +02:00
|
|
|
// @flow
|
|
|
|
|
import { apiClient } from "@scm-manager/ui-components";
|
|
|
|
|
import { isPending } from "../../modules/pending";
|
|
|
|
|
import { getFailure } from "../../modules/failure";
|
|
|
|
|
import * as types from "../../modules/types";
|
|
|
|
|
import { combineReducers, Dispatch } from "redux";
|
2019-05-08 13:17:06 +02:00
|
|
|
import type { Action, PagedCollection, Role } from "@scm-manager/ui-types";
|
2019-05-07 16:51:16 +02:00
|
|
|
|
|
|
|
|
export const FETCH_ROLES = "scm/roles/FETCH_ROLES";
|
|
|
|
|
export const FETCH_ROLES_PENDING = `${FETCH_ROLES}_${types.PENDING_SUFFIX}`;
|
|
|
|
|
export const FETCH_ROLES_SUCCESS = `${FETCH_ROLES}_${types.SUCCESS_SUFFIX}`;
|
|
|
|
|
export const FETCH_ROLES_FAILURE = `${FETCH_ROLES}_${types.FAILURE_SUFFIX}`;
|
|
|
|
|
|
|
|
|
|
export const FETCH_ROLE = "scm/roles/FETCH_ROLE";
|
|
|
|
|
export const FETCH_ROLE_PENDING = `${FETCH_ROLE}_${types.PENDING_SUFFIX}`;
|
|
|
|
|
export const FETCH_ROLE_SUCCESS = `${FETCH_ROLE}_${types.SUCCESS_SUFFIX}`;
|
|
|
|
|
export const FETCH_ROLE_FAILURE = `${FETCH_ROLE}_${types.FAILURE_SUFFIX}`;
|
|
|
|
|
|
|
|
|
|
export const CREATE_ROLE = "scm/roles/CREATE_ROLE";
|
|
|
|
|
export const CREATE_ROLE_PENDING = `${CREATE_ROLE}_${types.PENDING_SUFFIX}`;
|
|
|
|
|
export const CREATE_ROLE_SUCCESS = `${CREATE_ROLE}_${types.SUCCESS_SUFFIX}`;
|
|
|
|
|
export const CREATE_ROLE_FAILURE = `${CREATE_ROLE}_${types.FAILURE_SUFFIX}`;
|
|
|
|
|
export const CREATE_ROLE_RESET = `${CREATE_ROLE}_${types.RESET_SUFFIX}`;
|
|
|
|
|
|
|
|
|
|
export const MODIFY_ROLE = "scm/roles/MODIFY_ROLE";
|
|
|
|
|
export const MODIFY_ROLE_PENDING = `${MODIFY_ROLE}_${types.PENDING_SUFFIX}`;
|
|
|
|
|
export const MODIFY_ROLE_SUCCESS = `${MODIFY_ROLE}_${types.SUCCESS_SUFFIX}`;
|
|
|
|
|
export const MODIFY_ROLE_FAILURE = `${MODIFY_ROLE}_${types.FAILURE_SUFFIX}`;
|
|
|
|
|
export const MODIFY_ROLE_RESET = `${MODIFY_ROLE}_${types.RESET_SUFFIX}`;
|
|
|
|
|
|
|
|
|
|
export const DELETE_ROLE = "scm/roles/DELETE_ROLE";
|
|
|
|
|
export const DELETE_ROLE_PENDING = `${DELETE_ROLE}_${types.PENDING_SUFFIX}`;
|
|
|
|
|
export const DELETE_ROLE_SUCCESS = `${DELETE_ROLE}_${types.SUCCESS_SUFFIX}`;
|
|
|
|
|
export const DELETE_ROLE_FAILURE = `${DELETE_ROLE}_${types.FAILURE_SUFFIX}`;
|
|
|
|
|
|
|
|
|
|
const CONTENT_TYPE_ROLE = "application/vnd.scmm-role+json;v=2";
|
|
|
|
|
|
|
|
|
|
// fetch roles
|
|
|
|
|
export function fetchRolesPending(): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLES_PENDING
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRolesSuccess(roles: any): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLES_SUCCESS,
|
|
|
|
|
payload: roles
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRolesFailure(url: string, error: Error): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLES_FAILURE,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
url
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRolesByLink(link: string) {
|
|
|
|
|
return function(dispatch: any) {
|
|
|
|
|
dispatch(fetchRolesPending());
|
|
|
|
|
return apiClient
|
|
|
|
|
.get(link)
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
dispatch(fetchRolesSuccess(data));
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
dispatch(fetchRolesFailure(link, error));
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRoles(link: string) {
|
|
|
|
|
return fetchRolesByLink(link);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRolesByPage(link: string, page: number, filter?: string) {
|
|
|
|
|
// backend start counting by 0
|
|
|
|
|
if (filter) {
|
|
|
|
|
return fetchRolesByLink(
|
|
|
|
|
`${link}?page=${page - 1}&q=${decodeURIComponent(filter)}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return fetchRolesByLink(`${link}?page=${page - 1}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fetch role
|
|
|
|
|
export function fetchRolePending(name: string): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLE_PENDING,
|
|
|
|
|
payload: name,
|
|
|
|
|
itemId: name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRoleSuccess(role: any): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLE_SUCCESS,
|
|
|
|
|
payload: role,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRoleFailure(name: string, error: Error): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: FETCH_ROLE_FAILURE,
|
|
|
|
|
payload: {
|
|
|
|
|
name,
|
|
|
|
|
error
|
|
|
|
|
},
|
|
|
|
|
itemId: name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function fetchRole(link: string, name: string) {
|
|
|
|
|
return function(dispatch: any) {
|
|
|
|
|
dispatch(fetchRolePending(name));
|
|
|
|
|
return apiClient
|
|
|
|
|
.get(link)
|
|
|
|
|
.then(response => {
|
|
|
|
|
return response.json();
|
|
|
|
|
})
|
|
|
|
|
.then(data => {
|
|
|
|
|
dispatch(fetchRoleSuccess(data));
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
dispatch(fetchRoleFailure(name, error));
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRoleByName(link: string, name: string) {
|
|
|
|
|
const roleUrl = link.endsWith("/") ? link + name : link + "/" + name;
|
|
|
|
|
return fetchRole(roleUrl, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function fetchRoleByLink(role: Role) {
|
|
|
|
|
return fetchRole(role._links.self.href, role.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create role
|
|
|
|
|
export function createRolePending(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: CREATE_ROLE_PENDING,
|
|
|
|
|
role
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createRoleSuccess(): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: CREATE_ROLE_SUCCESS
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createRoleFailure(error: Error): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: CREATE_ROLE_FAILURE,
|
|
|
|
|
payload: error
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createRoleReset() {
|
|
|
|
|
return {
|
|
|
|
|
type: CREATE_ROLE_RESET
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createRole(link: string, role: Role, callback?: () => void) {
|
|
|
|
|
return function(dispatch: Dispatch) {
|
|
|
|
|
dispatch(createRolePending(role));
|
|
|
|
|
return apiClient
|
|
|
|
|
.post(link, role, CONTENT_TYPE_ROLE)
|
|
|
|
|
.then(() => {
|
|
|
|
|
dispatch(createRoleSuccess());
|
|
|
|
|
if (callback) {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => dispatch(createRoleFailure(error)));
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// modify group
|
|
|
|
|
export function modifyRolePending(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: MODIFY_ROLE_PENDING,
|
|
|
|
|
payload: role,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function modifyRoleSuccess(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: MODIFY_ROLE_SUCCESS,
|
|
|
|
|
payload: role,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function modifyRoleFailure(role: Role, error: Error): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: MODIFY_ROLE_FAILURE,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
role
|
|
|
|
|
},
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function modifyRoleReset(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: MODIFY_ROLE_RESET,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function modifyRole(role: Role, callback?: () => void) {
|
|
|
|
|
return function(dispatch: Dispatch) {
|
|
|
|
|
dispatch(modifyRolePending(role));
|
|
|
|
|
return apiClient
|
|
|
|
|
.put(role._links.update.href, role, CONTENT_TYPE_ROLE)
|
|
|
|
|
.then(() => {
|
|
|
|
|
dispatch(modifyRoleSuccess(role));
|
|
|
|
|
if (callback) {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.then(() => {
|
|
|
|
|
dispatch(fetchRoleByLink(role));
|
|
|
|
|
})
|
|
|
|
|
.catch(err => {
|
|
|
|
|
dispatch(modifyRoleFailure(role, err));
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// delete role
|
|
|
|
|
export function deleteRolePending(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: DELETE_ROLE_PENDING,
|
|
|
|
|
payload: role,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteRoleSuccess(role: Role): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: DELETE_ROLE_SUCCESS,
|
|
|
|
|
payload: role,
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteRoleFailure(role: Role, error: Error): Action {
|
|
|
|
|
return {
|
|
|
|
|
type: DELETE_ROLE_FAILURE,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
role
|
|
|
|
|
},
|
|
|
|
|
itemId: role.name
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function deleteRole(role: Role, callback?: () => void) {
|
|
|
|
|
return function(dispatch: any) {
|
|
|
|
|
dispatch(deleteRolePending(role));
|
|
|
|
|
return apiClient
|
|
|
|
|
.delete(role._links.delete.href)
|
|
|
|
|
.then(() => {
|
|
|
|
|
dispatch(deleteRoleSuccess(role));
|
|
|
|
|
if (callback) {
|
|
|
|
|
callback();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
dispatch(deleteRoleFailure(role, error));
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function extractRolesByNames(
|
|
|
|
|
roles: Role[],
|
|
|
|
|
roleNames: string[],
|
|
|
|
|
oldRolesByNames: Object
|
|
|
|
|
) {
|
|
|
|
|
const rolesByNames = {};
|
|
|
|
|
|
|
|
|
|
for (let role of roles) {
|
|
|
|
|
rolesByNames[role.name] = role;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (let roleName in oldRolesByNames) {
|
|
|
|
|
rolesByNames[roleName] = oldRolesByNames[roleName];
|
|
|
|
|
}
|
|
|
|
|
return rolesByNames;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deleteRoleInRolesByNames(roles: {}, roleName: string) {
|
|
|
|
|
let newRoles = {};
|
|
|
|
|
for (let rolename in roles) {
|
|
|
|
|
if (rolename !== roleName) newRoles[rolename] = roles[rolename];
|
|
|
|
|
}
|
|
|
|
|
return newRoles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deleteRoleInEntries(roles: [], roleName: string) {
|
|
|
|
|
let newRoles = [];
|
|
|
|
|
for (let role of roles) {
|
|
|
|
|
if (role !== roleName) newRoles.push(role);
|
|
|
|
|
}
|
|
|
|
|
return newRoles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const reducerByName = (state: any, rolename: string, newRoleState: any) => {
|
2019-05-08 13:17:06 +02:00
|
|
|
return {
|
2019-05-07 16:51:16 +02:00
|
|
|
...state,
|
|
|
|
|
[rolename]: newRoleState
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function listReducer(state: any = {}, action: any = {}) {
|
|
|
|
|
switch (action.type) {
|
|
|
|
|
case FETCH_ROLES_SUCCESS:
|
2019-05-08 13:17:06 +02:00
|
|
|
const roles = action.payload._embedded.repositoryRoles;
|
2019-05-07 16:51:16 +02:00
|
|
|
const roleNames = roles.map(role => role.name);
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
entries: roleNames,
|
|
|
|
|
entry: {
|
2019-05-08 13:17:06 +02:00
|
|
|
roleCreatePermission: !!action.payload._links.create,
|
2019-05-07 16:51:16 +02:00
|
|
|
page: action.payload.page,
|
|
|
|
|
pageTotal: action.payload.pageTotal,
|
|
|
|
|
_links: action.payload._links
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Delete single role actions
|
|
|
|
|
case DELETE_ROLE_SUCCESS:
|
|
|
|
|
const newRoleEntries = deleteRoleInEntries(
|
|
|
|
|
state.entries,
|
|
|
|
|
action.payload.name
|
|
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
...state,
|
|
|
|
|
entries: newRoleEntries
|
|
|
|
|
};
|
|
|
|
|
default:
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function byNamesReducer(state: any = {}, action: any = {}) {
|
|
|
|
|
switch (action.type) {
|
|
|
|
|
// Fetch all roles actions
|
|
|
|
|
case FETCH_ROLES_SUCCESS:
|
2019-05-08 13:17:06 +02:00
|
|
|
const roles = action.payload._embedded.repositoryRoles;
|
2019-05-07 16:51:16 +02:00
|
|
|
const roleNames = roles.map(role => role.name);
|
|
|
|
|
const byNames = extractRolesByNames(roles, roleNames, state.byNames);
|
|
|
|
|
return {
|
|
|
|
|
...byNames
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Fetch single role actions
|
|
|
|
|
case FETCH_ROLE_SUCCESS:
|
|
|
|
|
return reducerByName(state, action.payload.name, action.payload);
|
|
|
|
|
|
|
|
|
|
case DELETE_ROLE_SUCCESS:
|
2019-05-08 13:17:06 +02:00
|
|
|
return deleteRoleInRolesByNames(state, action.payload.name);
|
2019-05-07 16:51:16 +02:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default combineReducers({
|
|
|
|
|
list: listReducer,
|
|
|
|
|
byNames: byNamesReducer
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// selectors
|
|
|
|
|
const selectList = (state: Object) => {
|
2019-05-08 13:17:06 +02:00
|
|
|
if (state.repositoryRoles && state.repositoryRoles.list) {
|
|
|
|
|
return state.repositoryRoles.list;
|
2019-05-07 16:51:16 +02:00
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const selectListEntry = (state: Object): Object => {
|
|
|
|
|
const list = selectList(state);
|
|
|
|
|
if (list.entry) {
|
|
|
|
|
return list.entry;
|
|
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const selectListAsCollection = (state: Object): PagedCollection => {
|
|
|
|
|
return selectListEntry(state);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const isPermittedToCreateRoles = (state: Object): boolean => {
|
2019-05-08 13:17:06 +02:00
|
|
|
return selectListEntry(state).roleCreatePermission;
|
2019-05-07 16:51:16 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function getRolesFromState(state: Object) {
|
|
|
|
|
const roleNames = selectList(state).entries;
|
|
|
|
|
if (!roleNames) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
const roleEntries: Role[] = [];
|
|
|
|
|
|
|
|
|
|
for (let roleName of roleNames) {
|
2019-05-08 13:17:06 +02:00
|
|
|
roleEntries.push(state.repositoryRoles.byNames[roleName]);
|
2019-05-07 16:51:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return roleEntries;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isFetchRolesPending(state: Object) {
|
|
|
|
|
return isPending(state, FETCH_ROLES);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getFetchRolesFailure(state: Object) {
|
|
|
|
|
return getFailure(state, FETCH_ROLES);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isCreateRolePending(state: Object) {
|
|
|
|
|
return isPending(state, CREATE_ROLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getCreateRoleFailure(state: Object) {
|
|
|
|
|
return getFailure(state, CREATE_ROLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getRoleByName(state: Object, name: string) {
|
2019-05-08 13:17:06 +02:00
|
|
|
if (state.repositoryRoles && state.repositoryRoles.byNames) {
|
|
|
|
|
return state.repositoryRoles.byNames[name];
|
2019-05-07 16:51:16 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isFetchRolePending(state: Object, name: string) {
|
|
|
|
|
return isPending(state, FETCH_ROLE, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getFetchRoleFailure(state: Object, name: string) {
|
|
|
|
|
return getFailure(state, FETCH_ROLE, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isModifyRolePending(state: Object, name: string) {
|
|
|
|
|
return isPending(state, MODIFY_ROLE, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getModifyRoleFailure(state: Object, name: string) {
|
|
|
|
|
return getFailure(state, MODIFY_ROLE, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function isDeleteRolePending(state: Object, name: string) {
|
|
|
|
|
return isPending(state, DELETE_ROLE, name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function getDeleteRoleFailure(state: Object, name: string) {
|
|
|
|
|
return getFailure(state, DELETE_ROLE, name);
|
|
|
|
|
}
|