Skip to content

Commit

Permalink
Added redux store for maniplating dynamic registrations
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Nov 17, 2022
1 parent 4899699 commit f5ee608
Show file tree
Hide file tree
Showing 33 changed files with 14,677 additions and 10,076 deletions.
23,285 changes: 13,874 additions & 9,411 deletions ui/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
"@fortawesome/react-fontawesome": "^0.1.18",
"@reduxjs/toolkit": "^1.9.0",
"@rjsf/core": "^4.1.1",
"bootstrap": "^5.1.3",
"date-fns": "^2.28.0",
Expand All @@ -23,6 +24,7 @@
"react-dom": "^18.0.0",
"react-hook-form": "^7.34.0",
"react-infinite-scroll-component": "^6.1.0",
"react-redux": "^8.0.5",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
"react-scroll": "^1.8.7",
Expand Down
1 change: 0 additions & 1 deletion ui/src/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { BASE_PATH } from './App.constant';
import { ProtectRoute } from './core/components/ProtectRoute';
import { IdpConfiguration } from './admin/IdpConfiguration';
import { DynamicRegistration } from './dynamic-registration/DynamicRegistration';
import { DynamicRegistrationsApi } from './dynamic-registration/hoc/DynamicRegistrationContext';

function App() {

Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/admin/component/AccessRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function AccessRequest({ users, roles, onDeleteUser, onChangeUserRole })
{(!users || !users.length) ?
<>
<div className="d-flex justify-content-center">
<div className="w-25 alert alert-info m-3">
<div className="w-50 alert alert-info m-3">
<p className="text-center">There are no new user requests at this time.</p>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions ui/src/app/admin/component/UserMaintenance.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export default function UserMaintenance({ users, roles, loading, onDeleteUser, o
id={`role-${user.username}`}
name={`role-${user.username}`}
className="form-control"
onChange={(event) => onChangeUserRole(user, event.target.value)}
value={user.role}
onChange={(event) => onChangeUserRole({user, role: event.target.value})}
defaultValue={user.role}
disabled={loading || currentUser.username === user.username}
disablevalidation="true">
{roles.map((role, ridx) => (
Expand All @@ -67,7 +67,7 @@ export default function UserMaintenance({ users, roles, loading, onDeleteUser, o
id={`group-${user.username}`}
name={`group-${user.username}`}
className="form-control"
onChange={(event) => onChangeUserGroup(user, event.target.value)}
onChange={(event) => onChangeUserGroup({user, groupId: event.target.value})}
value={user.groupId ? user.groupId : ''}
disabled={loading || loadingGroups || currentUser.username === user.username || user.role === 'ROLE_ADMIN'}
disablevalidation="true">
Expand Down
60 changes: 34 additions & 26 deletions ui/src/app/admin/container/MetadataActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DeleteConfirmation } from '../../core/components/DeleteConfirmation';
import { useMetadataActivator, useMetadataApprover, useMetadataEntity } from '../../metadata/hooks/api';

import { NotificationContext, createNotificationAction, NotificationTypes } from '../../notifications/hoc/Notifications';
import { useApproveSourceMutation, useDeleteSourceMutation, useEnableSourceMutation } from '../../store/metadata/SourceSlice';

export function MetadataActions ({type, children}) {

Expand All @@ -15,62 +16,69 @@ export function MetadataActions ({type, children}) {
const activator = useMetadataActivator(type);

async function enableEntity(entity, enabled, cb = () => {}) {
await activator.patch(`/${type === 'source' ? entity.id : entity.resourceId}/${enabled ? 'enable' : 'disable'}`);
await activator.patch(`/${entity.resourceId}/${enabled ? 'enable' : 'disable'}`);
if (activator?.response.ok) {
dispatch(createNotificationAction(
`Metadata ${type} has been ${enabled ? 'enabled' : 'disabled'}.`
));
toastEnableSuccess(type, enabled);
cb();
} else {
const { errorCode, errorMessage, cause } = activator?.response?.data;
dispatch(createNotificationAction(
`${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`,
NotificationTypes.ERROR
));
toastError(errorCode, errorMessage, cause);
}
}

async function deleteEntity(id, cb = () => {}) {
await del(`/${id}`);
if (response.ok) {
dispatch(createNotificationAction(
`Metadata ${type} has been deleted.`
));
toastDeleteSuccess(type);
cb();
} else {
const { errorCode, errorMessage, cause } = activator?.response?.data;
dispatch(createNotificationAction(
`${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`,
NotificationTypes.ERROR
));
toastError(errorCode, errorMessage, cause);
}
}

const approver = useMetadataApprover('source');

async function approveEntity(entity, enabled, cb = () => {}) {
await approver.patch(`${type === 'source' ? entity.id : entity.resourceId}/${enabled ? 'approve' : 'unapprove'}`);
await approver.patch(`${entity.resourceId}/${enabled ? 'approve' : 'unapprove'}`);
if (approver?.response.ok) {
dispatch(createNotificationAction(
`Metadata ${type} has been ${enabled ? 'approved' : 'unapproved'}.`
));
toastApproveSuccess(type, enabled);
cb();
} else {
const { errorCode, errorMessage, cause } = approver?.response?.data;
dispatch(createNotificationAction(
`${errorCode}: ${errorMessage} ${cause ? `-${cause}` : ''}`,
NotificationTypes.ERROR
));
toastError(errorCode, errorMessage, cause);
}
}

const toast = (message, type) => dispatch(createNotificationAction(message, type));

const toastApproveSuccess = (type, enabled) => toast(`Metadata ${type} has been ${enabled ? 'approved' : 'unapproved'}.`);
const toastEnableSuccess = (type, enabled) => toast(`Metadata ${type} has been ${enabled ? 'enabled' : 'disabled'}.`);
const toastDeleteSuccess = (type) => toast(`Metadata ${type} has been deleted.`);
const toastError = (code, message, cause) => toast(`${code}: ${message} ${cause ? `-${cause}` : ''}`, NotificationTypes.ERROR);

const [approveSource] = useApproveSourceMutation();
const [enableSource] = useEnableSourceMutation();
const [deleteSource] = useDeleteSourceMutation();

const remove = type === 'source' ?
(id) => deleteSource({id}) :
deleteEntity;
const enable = type === 'source' ?
({id}, enabled) => enableSource({id, enabled}) :
enableEntity;
const approve = type === 'source' ?
({id}, approved) => approveSource({id, approved}) :
approveEntity;


return (
<DeleteConfirmation title={`message.delete-${type}-title`} body={`message.delete-${type}-body`}>
{(block) =>
<>{children({
enable: enableEntity,
remove: (id, cb) => block(() => deleteEntity(id, cb)),
approve: approveEntity
enable,
remove: (id, cb) => block(() => remove(id, cb)),
approve
})}</>
}
</DeleteConfirmation>
Expand Down
50 changes: 7 additions & 43 deletions ui/src/app/admin/container/UserManagement.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import Button from 'react-bootstrap/Button';
import Translate from '../../i18n/components/translate';
import API_BASE_PATH from '../../App.constant';
import { NotificationContext, createNotificationAction} from '../../notifications/hoc/Notifications';
import { useRemoveUserMutation, useSetUserGroupRequestMutation, useSetUserRoleRequestMutation } from '../../store/user/UserSlice';

export default function UserManagement({ users, children, reload}) {

const [roles, setRoles] = React.useState([]);

const { dispatch } = React.useContext(NotificationContext);

const { get, patch, del, response, loading } = useFetch(`${API_BASE_PATH}`, {});
const { get, response, loading } = useFetch(`${API_BASE_PATH}`, {});

async function loadRoles() {
const roles = await get('/supportedRoles')
Expand All @@ -25,65 +26,28 @@ export default function UserManagement({ users, children, reload}) {
}
}

async function setUserRoleRequest(user, role) {
user.role = role;
await patch(`/admin/users/${user.username}`, {
...user,
role
});
if (response.ok && reload) {
dispatch(createNotificationAction(
`User update successful for ${user.username}.`
));
reload();
}
}
const [setUserGroupRequest] = useSetUserGroupRequestMutation();
const [setUserRoleRequest] = useSetUserRoleRequestMutation();
const [deleteUserRequest] = useRemoveUserMutation();

async function setUserGroupRequest(user, groupId) {
user.groupId = groupId;
await patch(`/admin/users/${user.username}`, {
...user,
groupId
});
if (response.ok && reload) {
dispatch(createNotificationAction(
`User update successful for ${user.username}.`
));
reload();
}
}

async function deleteUserRequest(id) {
await del(`/admin/users/${id}`);
if (response.ok && reload) {
dispatch(createNotificationAction(
`User deleted.`
));
reload();
}
}

/*eslint-disable react-hooks/exhaustive-deps*/
React.useEffect(() => {
loadRoles();
}, []);

const [modal, setModal] = React.useState(false);

const toggle = () => setModal(!modal);

const [deleting, setDeleting] = React.useState(null);

const deleteUser = (id) => {
deleteUserRequest(deleting);
deleteUserRequest({ id });
setDeleting(null);
};

return (
<div className="user-management">
{children(users, roles, setUserRoleRequest, setUserGroupRequest, (id) => setDeleting(id), loading)}
<Modal show={!!deleting} onHide={() => setDeleting(null)}>
<Modal.Header toggle={toggle}><Translate value="message.delete-user-title">Delete User?</Translate></Modal.Header>
<Modal.Header><Translate value="message.delete-user-title">Delete User?</Translate></Modal.Header>
<Modal.Body className="d-flex align-content-center">
<FontAwesomeIcon className="text-danger me-4" size="4x" icon={faExclamationTriangle} />
<p className="text-danger font-weight-bold mb-0">
Expand Down
Loading

0 comments on commit f5ee608

Please sign in to comment.