Skip to content

Commit

Permalink
Merge pull request #1374 from OneCommunityGlobal/Nathan-reset-permiss…
Browse files Browse the repository at this point in the history
…ions-to-default

Nathan reset permissions to default
  • Loading branch information
one-community authored Oct 14, 2023
2 parents 833ec52 + 9f4758a commit 896e50b
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 12 deletions.
77 changes: 77 additions & 0 deletions src/actions/rolePermissionPresets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import axios from 'axios';
import { ENDPOINTS } from '../utils/URL';
import * as types from "../constants/rolePermissionPresets";

export const fetchPresets = (presets) => {
return {
type: types.RECEIVE_PRESETS,
presets,
};
};

export const postNewPreset = payload => {
return {
type: types.ADD_NEW_PRESET,
payload,
};
};

export const deletePreset = presetId => {
return {
type: types.DELETE_PRESET,
presetId,
};
};

export const updatePreset = payload => {
return {
type: types.UPDATE_PRESET,
payload,
};
};

export const getPresetsByRole = (roleName) => async dispatch => {
const URL = ENDPOINTS.PRESETS_BY_ID(roleName);
const { data } = await axios.get(URL);
return dispatch(fetchPresets(data));
};

export const createNewPreset = newPreset => {
return async dispatch => {
try {
const res = await axios.post(ENDPOINTS.PRESETS(), newPreset);
if (res.status === 201){
dispatch(postNewPreset(res.data.newPreset));
}
} catch (error) {
console.log(error)
}
return status;
};
};

export const updatePresetById = (updatedPreset) => {
return async dispatch => {
try {
const res = await axios.put(ENDPOINTS.PRESETS_BY_ID(updatedPreset._id), updatedPreset);
if (res.status === 200){
dispatch(updatePreset(updatedPreset));
}
} catch (err) {
console.log(err);
}
};
};

export const deletePresetById = (presetId) => {
return async dispatch => {
try {
const res = await axios.delete(ENDPOINTS.PRESETS_BY_ID(presetId));
if (res.status === 200){
dispatch(deletePreset(presetId));
}
} catch (error) {
console.log(error);
}
};
};
32 changes: 32 additions & 0 deletions src/components/PermissionsManagement/PermissionsPresetsModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { useState } from 'react';
import { FormCheck } from 'react-bootstrap';
import { Alert, Button, Form, FormGroup, Input, Label } from 'reactstrap';
import { toast } from 'react-toastify';
import { connect } from 'react-redux';
import Preset from './Preset';
import { boxStyle } from 'styles';


const PermissionsPresetsModal = (props) => {
return (
<>
{props.presetsList?.length===0 ? 'There are no presets for this role.' : props.presetsList?.map((preset) => (
<div key={preset._id}>
<Preset
preset={preset}
roleId={props.roleId}
roleName={props.roleName}
onApply={props.onApply}
/>
</div>
))}
</>
);
};

const mapStateToProps = state => ({ presetsList: state.rolePreset.presets });

// const mapDispatchToProps = dispatch => ({
// });

export default connect(mapStateToProps, null)(PermissionsPresetsModal);
130 changes: 130 additions & 0 deletions src/components/PermissionsManagement/Preset.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { useState, useRef } from 'react';
import { FormCheck } from 'react-bootstrap';
import { Alert, Button, Form, FormGroup, Input, Label, Row } from 'reactstrap';
import { permissionLabel } from './UserRoleTab';
import { mainPermissions } from './RolePermissions';
import { toast } from 'react-toastify';
import { connect } from 'react-redux';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEdit } from '@fortawesome/free-regular-svg-icons';
import { updateRole } from '../../actions/role';
import { updatePresetById, deletePresetById } from '../../actions/rolePermissionPresets';
import { BsFillCaretDownFill, BsFillCaretUpFill } from 'react-icons/bs';
import { boxStyle } from 'styles';
import { update } from 'lodash';


const Preset = (props) => {
const [isOpen, setIsOpen] = useState(false);
const [editing, setEditing] = useState(false);
const ref = useRef(null);

const onNameClicked = (e) => {
if(editing){
e.stopPropagation();
}
}

const onEditIconClicked = (e) => {
e.stopPropagation();
setEditing(!editing);
setTimeout(()=>{ref.current.focus()}, 0);
};

const onSaveNameChangeClicked = (e) => {
e.stopPropagation();
var newName = ref.current.textContent;
props.updatePreset({...props.preset, presetName: newName});
setEditing(false);
};

const applyPreset = async (preset) => {
try {
const updatedRole = {
roleId: props.roleId,
roleName: props.roleName,
permissions: preset.permissions
};
props.updateRole(props.roleId, updatedRole);
props.onApply(preset.permissions);
} catch (error) {
console.log(error.message);
}
};

return (
<>
<div
style={{
display: 'flex',
flexDirection: Row,
cursor: 'pointer',
width: '100%',
borderBottom: 'solid',
borderColor: 'grey',
justifyContent: 'space-between'
}}
onClick={()=>setIsOpen(!isOpen)}
>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '10px'
}}>
<h3 ref={ref} contentEditable={editing} suppressContentEditableWarning={true} onClick={onNameClicked} >{props.preset.presetName}</h3>
<FontAwesomeIcon
icon={faEdit}
size="lg"
className="user-role-tab__icon edit-icon"
onClick={onEditIconClicked}
/>
{editing &&
<Button
color='primary'
onClick={onSaveNameChangeClicked}>
Save Name
</Button>}
{isOpen ? <BsFillCaretUpFill/>:<BsFillCaretDownFill/> }
</div>
<div
style={{
display: 'flex',
gap: '10px'
}}>
<Button color='danger' onClick={(event)=>{event.stopPropagation(); props.deletePreset(props.preset._id);}}>
Delete
</Button>
<Button
color='primary'
onClick={(event)=>{event.stopPropagation(); applyPreset(props.preset);}}>
Apply
</Button>
</div>
</div>
{isOpen ? Object.keys(permissionLabel).map((permission) => (
<li className="user-role-tab__permissions" key={permission}>
<p style={{
color: props.preset.permissions.includes(permission) ? 'green' : 'red' ,
fontSize: mainPermissions.includes(permissionLabel[permission]) ? '20px':'',
paddingLeft: mainPermissions.includes(permissionLabel[permission]) ? '0': '50px'
}}>
{permissionLabel[permission]}
</p>
</li>
)):<></>}
</>
);
};



const mapStateToProps = state => ({ roles: state.role.roles });

const mapDispatchToProps = dispatch => ({
updateRole: (roleId, updatedRole) => dispatch(updateRole(roleId, updatedRole)),
deletePreset: (presetId) => dispatch(deletePresetById(presetId)),
updatePreset: (newPreset) => dispatch(updatePresetById(newPreset))
});

export default connect(mapStateToProps, mapDispatchToProps)(Preset);
76 changes: 65 additions & 11 deletions src/components/PermissionsManagement/RolePermissions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import axios from 'axios';
import { useHistory } from 'react-router-dom';
import { boxStyle } from 'styles';
import EditableInfoModal from 'components/UserProfile/EditableModal/EditableInfoModal';
import PermissionsPresetsModal from './PermissionsPresetsModal.jsx'
import { getPresetsByRole, createNewPreset } from 'actions/rolePermissionPresets';

function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
Expand All @@ -29,6 +31,8 @@ const mapPermissionToLabel = permissions => {
return label;
};

export const mainPermissions = ['See All the Reports Tab', 'See User Management Tab (Full Functionality)', 'See Badge Management Tab (Full Functionality)', 'See Project Management Tab (Full Functionality)', 'Edit Task', 'See Teams Management Tab (Full Functionality)', 'Edit Timelog Information', 'Edit User Profile', 'See Popup Management Tab (create and update popups)', 'See Permissions Management Tab', 'See Summary Indicator', 'See Visibility Icon' ]

export const modalInfo = {
'See Only Weekly Summary Reports Tab':
'Make the "Other Links" -> "Reports" button appear/accessible.',
Expand Down Expand Up @@ -124,8 +128,6 @@ export const modalInfo = {
};

function RolePermissions(props) {

const mainPermissions = ['See All the Reports Tab', 'See User Management Tab (Full Functionality)', 'See Badge Management Tab (Full Functionality)', 'See Project Management Tab (Full Functionality)', 'Edit Project', 'See Teams Management Tab (Full Functionality)', 'Edit Timelog Information', 'Edit User Profile', 'See Permissions Management Tab' ]

const [permissions, setPermissions] = useState(mapPermissionToLabel(props.permissions));
const [deleteRoleModal, setDeleteRoleModal] = useState(false);
Expand All @@ -136,11 +138,17 @@ function RolePermissions(props) {
const history = useHistory();
const [infoRoleModal, setinfoRoleModal] = useState(false);
const [modalContent, setContent] = useState(null);

const [showPresetModal, setShowPresetModal] = useState(false);

useEffect(() => {
setRoleName(props.role);
props.getPresets(props.role);
}, []);

useEffect(() => {
setPermissions(mapPermissionToLabel(props.permissions));
}, [props.roles]);

const toggleDeleteRoleModal = () => {
setDeleteRoleModal(!deleteRoleModal);
};
Expand Down Expand Up @@ -176,6 +184,21 @@ function RolePermissions(props) {
setPermissions(previous => [...previous, permission]);
};

const saveNewPreset = async () => {
let count = 1;
while(props.presets.some(preset => preset.presetName === 'New Preset '+count)){
count+=1;
}
const newPreset = {
presetName: 'New Preset '+count,
roleName: props.role,
permissions: permissions.map(perm => {
return getKeyByValue(permissionLabel, perm);
}),
}
props.createNewPreset(newPreset);
}

const updateInfo = async () => {
const permissionsObjectName = permissions.map(perm => {
return getKeyByValue(permissionLabel, perm);
Expand Down Expand Up @@ -231,13 +254,23 @@ function RolePermissions(props) {
)}
</div>
{props?.userRole === 'Owner' && (
<div className="name-container__btns">
<Button className="btn_save" color="success" onClick={() => updateInfo()} style={boxStyle}>
Save
</Button>
<Button color="danger" onClick={toggleDeleteRoleModal} style={boxStyle}>
Delete Role
</Button>
<div className="name-container__btn_columns">
<div className="name-container__btns">
<Button className="btn_save" color="success" onClick={()=>{ saveNewPreset()}} style={boxStyle}>
Create New Preset
</Button>
<Button color="primary" onClick={()=>{setShowPresetModal(!showPresetModal);}} style={boxStyle}>
Load Presets
</Button>
</div>
<div className="name-container__btns">
<Button className="btn_save" color="success" onClick={() => updateInfo()} style={boxStyle}>
Save
</Button>
<Button color="danger" onClick={toggleDeleteRoleModal} style={boxStyle}>
Delete Role
</Button>
</div>
</div>
)}
<Modal isOpen={editRoleNameModal} toggle={toggleEditRoleNameModal}>
Expand Down Expand Up @@ -343,15 +376,36 @@ function RolePermissions(props) {
</Button>
</ModalFooter>
</Modal>
<Modal
isOpen={showPresetModal}
toggle={()=>{setShowPresetModal((previous)=>!previous)}}
id="modal-content__new-role"
>
<ModalHeader
toggle={()=>{setShowPresetModal((previous)=>!previous)}}
cssModule={{ 'modal-title': 'w-100 text-center my-auto' }}
>
Role Presets
</ModalHeader>
<ModalBody id="modal-body_new-role--padding">
<PermissionsPresetsModal
roleId={props.roleId}
roleName={props.role}
onApply={(perms)=>setPermissions(mapPermissionToLabel(perms))}
/>
</ModalBody>
</Modal>
</>
);
}

const mapStateToProps = state => ({ roles: state.role.roles });
const mapStateToProps = state => ({ roles: state.role.roles, presets: state.rolePreset.presets });

const mapDispatchToProps = dispatch => ({
getAllRoles: () => dispatch(getAllRoles()),
updateRole: (roleId, updatedRole) => dispatch(updateRole(roleId, updatedRole)),
getPresets: (role) => dispatch(getPresetsByRole(role)),
createNewPreset: (newPreset) => dispatch(createNewPreset(newPreset)),
});

export default connect(mapStateToProps, mapDispatchToProps)(RolePermissions);
Loading

0 comments on commit 896e50b

Please sign in to comment.