Files
SCM-Manager/scm-ui/src/repos/permissions/modules/permissions.js
2018-09-11 16:00:15 +02:00

626 lines
15 KiB
JavaScript

// @flow
import { apiClient } from "../../../../../scm-ui-components/packages/ui-components/src/index";
import * as types from "../../../modules/types";
import type { Action } from "../../../../../scm-ui-components/packages/ui-types/src/index";
import type {
PermissionCollection,
Permission,
PermissionEntry
} from "../types/Permissions";
import { isPending } from "../../../modules/pending";
import { getFailure } from "../../../modules/failure";
import { Dispatch } from "redux";
export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
types.PENDING_SUFFIX
}`;
export const FETCH_PERMISSIONS_SUCCESS = `${FETCH_PERMISSIONS}_${
types.SUCCESS_SUFFIX
}`;
export const FETCH_PERMISSIONS_FAILURE = `${FETCH_PERMISSIONS}_${
types.FAILURE_SUFFIX
}`;
export const MODIFY_PERMISSION = "scm/permissions/MODFIY_PERMISSION";
export const MODIFY_PERMISSION_PENDING = `${MODIFY_PERMISSION}_${
types.PENDING_SUFFIX
}`;
export const MODIFY_PERMISSION_SUCCESS = `${MODIFY_PERMISSION}_${
types.SUCCESS_SUFFIX
}`;
export const MODIFY_PERMISSION_FAILURE = `${MODIFY_PERMISSION}_${
types.FAILURE_SUFFIX
}`;
export const MODIFY_PERMISSION_RESET = `${MODIFY_PERMISSION}_${
types.RESET_SUFFIX
}`;
export const CREATE_PERMISSION = "scm/permissions/CREATE_PERMISSION";
export const CREATE_PERMISSION_PENDING = `${CREATE_PERMISSION}_${
types.PENDING_SUFFIX
}`;
export const CREATE_PERMISSION_SUCCESS = `${CREATE_PERMISSION}_${
types.SUCCESS_SUFFIX
}`;
export const CREATE_PERMISSION_FAILURE = `${CREATE_PERMISSION}_${
types.FAILURE_SUFFIX
}`;
export const CREATE_PERMISSION_RESET = `${CREATE_PERMISSION}_${
types.RESET_SUFFIX
}`;
export const DELETE_PERMISSION = "scm/permissions/DELETE_PERMISSION";
export const DELETE_PERMISSION_PENDING = `${DELETE_PERMISSION}_${
types.PENDING_SUFFIX
}`;
export const DELETE_PERMISSION_SUCCESS = `${DELETE_PERMISSION}_${
types.SUCCESS_SUFFIX
}`;
export const DELETE_PERMISSION_FAILURE = `${DELETE_PERMISSION}_${
types.FAILURE_SUFFIX
}`;
export const DELETE_PERMISSION_RESET = `${DELETE_PERMISSION}_${
types.RESET_SUFFIX
}`;
const REPOS_URL = "repositories";
const PERMISSIONS_URL = "permissions";
const CONTENT_TYPE = "application/vnd.scmm-permission+json";
// fetch permissions
export function fetchPermissions(namespace: string, repoName: string) {
return function(dispatch: any) {
dispatch(fetchPermissionsPending(namespace, repoName));
return apiClient
.get(`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`)
.then(response => response.json())
.then(permissions => {
dispatch(fetchPermissionsSuccess(permissions, namespace, repoName));
})
.catch(err => {
dispatch(fetchPermissionsFailure(namespace, repoName, err));
});
};
}
export function fetchPermissionsPending(
namespace: string,
repoName: string
): Action {
return {
type: FETCH_PERMISSIONS_PENDING,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
export function fetchPermissionsSuccess(
permissions: any,
namespace: string,
repoName: string
): Action {
return {
type: FETCH_PERMISSIONS_SUCCESS,
payload: permissions,
itemId: namespace + "/" + repoName
};
}
export function fetchPermissionsFailure(
namespace: string,
repoName: string,
error: Error
): Action {
return {
type: FETCH_PERMISSIONS_FAILURE,
payload: {
namespace,
repoName,
error
},
itemId: namespace + "/" + repoName
};
}
// modify permission
export function modifyPermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: any) {
dispatch(modifyPermissionPending(permission, namespace, repoName));
return apiClient
.put(permission._links.update.href, permission, CONTENT_TYPE)
.then(() => {
dispatch(modifyPermissionSuccess(permission, namespace, repoName));
if (callback) {
callback();
}
})
.catch(cause => {
const error = new Error(
`failed to modify permission: ${cause.message}`
);
dispatch(
modifyPermissionFailure(permission, error, namespace, repoName)
);
});
};
}
export function modifyPermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function modifyPermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function modifyPermissionFailure(
permission: Permission,
error: Error,
namespace: string,
repoName: string
): Action {
return {
type: MODIFY_PERMISSION_FAILURE,
payload: { error, permission },
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
function newPermissions(
oldPermissions: PermissionCollection,
newPermission: Permission
) {
for (let i = 0; i < oldPermissions.length; i++) {
if (oldPermissions[i].name === newPermission.name) {
oldPermissions.splice(i, 1, newPermission);
return oldPermissions;
}
}
}
export function modifyPermissionReset(namespace: string, repoName: string) {
return {
type: MODIFY_PERMISSION_RESET,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
// create permission
export function createPermission(
permission: PermissionEntry,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: Dispatch) {
dispatch(createPermissionPending(permission, namespace, repoName));
return apiClient
.post(
`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`,
permission,
CONTENT_TYPE
)
.then(response => {
const location = response.headers.get("Location");
return apiClient.get(location);
})
.then(response => response.json())
.then(createdPermission => {
dispatch(
createPermissionSuccess(createdPermission, namespace, repoName)
);
if (callback) {
callback();
}
})
.catch(err =>
dispatch(
createPermissionFailure(
new Error(
`failed to add permission ${permission.name}: ${err.message}`
),
namespace,
repoName
)
)
);
};
}
export function createPermissionPending(
permission: PermissionEntry,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName
};
}
export function createPermissionSuccess(
permission: PermissionEntry,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName
};
}
export function createPermissionFailure(
error: Error,
namespace: string,
repoName: string
): Action {
return {
type: CREATE_PERMISSION_FAILURE,
payload: error,
itemId: namespace + "/" + repoName
};
}
export function createPermissionReset(namespace: string, repoName: string) {
return {
type: CREATE_PERMISSION_RESET,
itemId: namespace + "/" + repoName
};
}
// delete permission
export function deletePermission(
permission: Permission,
namespace: string,
repoName: string,
callback?: () => void
) {
return function(dispatch: any) {
dispatch(deletePermissionPending(permission, namespace, repoName));
return apiClient
.delete(permission._links.delete.href)
.then(() => {
dispatch(deletePermissionSuccess(permission, namespace, repoName));
if (callback) {
callback();
}
})
.catch(cause => {
const error = new Error(
`could not delete permission ${permission.name}: ${cause.message}`
);
dispatch(
deletePermissionFailure(permission, namespace, repoName, error)
);
});
};
}
export function deletePermissionPending(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: DELETE_PERMISSION_PENDING,
payload: permission,
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionSuccess(
permission: Permission,
namespace: string,
repoName: string
): Action {
return {
type: DELETE_PERMISSION_SUCCESS,
payload: {
permission,
position: namespace + "/" + repoName
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionFailure(
permission: Permission,
namespace: string,
repoName: string,
error: Error
): Action {
return {
type: DELETE_PERMISSION_FAILURE,
payload: {
error,
permission
},
itemId: namespace + "/" + repoName + "/" + permission.name
};
}
export function deletePermissionReset(namespace: string, repoName: string) {
return {
type: DELETE_PERMISSION_RESET,
payload: {
namespace,
repoName
},
itemId: namespace + "/" + repoName
};
}
function deletePermissionFromState(
oldPermissions: PermissionCollection,
permission: Permission
) {
let newPermission = [];
for (let i = 0; i < oldPermissions.length; i++) {
if (oldPermissions[i] !== permission) {
newPermission.push(oldPermissions[i]);
}
}
return newPermission;
}
// reducer
export default function reducer(
state: Object = {},
action: Action = { type: "UNKNOWN" }
): Object {
if (!action.payload) {
return state;
}
switch (action.type) {
case FETCH_PERMISSIONS_SUCCESS:
return {
...state,
[action.itemId]: {
entries: action.payload._embedded.permissions,
createPermission: action.payload._links.create ? true : false
}
};
case MODIFY_PERMISSION_SUCCESS:
const positionOfPermission = action.payload.position;
const newPermission = newPermissions(
state[action.payload.position].entries,
action.payload.permission
);
return {
...state,
[positionOfPermission]: {
...state[positionOfPermission],
entries: newPermission
}
};
case CREATE_PERMISSION_SUCCESS:
// return state;
const position = action.payload.position;
const permissions = state[action.payload.position].entries;
permissions.push(action.payload.permission);
return {
...state,
[position]: {
...state[position],
entries: permissions
}
};
case DELETE_PERMISSION_SUCCESS:
const permissionPosition = action.payload.position;
const new_Permissions = deletePermissionFromState(
state[action.payload.position].entries,
action.payload.permission
);
return {
...state,
[permissionPosition]: {
...state[permissionPosition],
entries: new_Permissions
}
};
default:
return state;
}
}
// selectors
export function getPermissionsOfRepo(
state: Object,
namespace: string,
repoName: string
) {
if (state.permissions && state.permissions[namespace + "/" + repoName]) {
const permissions = state.permissions[namespace + "/" + repoName].entries;
return permissions;
}
}
export function isFetchPermissionsPending(
state: Object,
namespace: string,
repoName: string
) {
return isPending(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
export function getFetchPermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
return getFailure(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
}
export function isModifyPermissionPending(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return isPending(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getModifyPermissionFailure(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return getFailure(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function hasCreatePermission(
state: Object,
namespace: string,
repoName: string
) {
if (state.permissions && state.permissions[namespace + "/" + repoName])
return state.permissions[namespace + "/" + repoName].createPermission;
else return null;
}
export function isCreatePermissionPending(
state: Object,
namespace: string,
repoName: string
) {
return isPending(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function getCreatePermissionFailure(
state: Object,
namespace: string,
repoName: string
) {
return getFailure(state, CREATE_PERMISSION, namespace + "/" + repoName);
}
export function isDeletePermissionPending(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return isPending(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getDeletePermissionFailure(
state: Object,
namespace: string,
repoName: string,
permissionname: string
) {
return getFailure(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissionname
);
}
export function getDeletePermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getDeletePermissionFailure(
state,
namespace,
repoName,
permissions[i].name
)
) {
return getFailure(
state,
DELETE_PERMISSION,
namespace + "/" + repoName + "/" + permissions[i].name
);
}
}
return null;
}
export function getModifyPermissionsFailure(
state: Object,
namespace: string,
repoName: string
) {
const permissions =
state.permissions && state.permissions[namespace + "/" + repoName]
? state.permissions[namespace + "/" + repoName].entries
: null;
if (permissions == null) return undefined;
for (let i = 0; i < permissions.length; i++) {
if (
getModifyPermissionFailure(
state,
namespace,
repoName,
permissions[i].name
)
) {
return getFailure(
state,
MODIFY_PERMISSION,
namespace + "/" + repoName + "/" + permissions[i].name
);
}
}
return null;
}