Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1486 - Giving the capability for admin to change user access level for any user #1750

Merged
merged 2 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion backend/models/user.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const userSchema = mongoose.Schema({
lastName: { type: String },
},
email: { type: String, unique: true },
accessLevel: { type: String, default: "user" },
accessLevel: {
type: String,
enum: ["user", "admin"], // restricts values to "user" and "admin"
default: "user"
},
createdDate: { type: Date, default: Date.now },
currentRole: { type: String }, // will remove but need to update check-in form
desiredRole: { type: String }, // will remove but need to update check-in form
Expand Down
17 changes: 17 additions & 0 deletions client/src/api/UserApiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,23 @@ class UserApiService {
alert('server not responding. Please try again.');
}
}

// Update user's access level (admin/user)
async updateUserAccessLevel(userToEdit, accessLevel) {
const url = `${this.baseUserUrl}${userToEdit._id}`;
const requestOptions = {
method: 'PATCH',
headers: this.headers,
body: JSON.stringify({ accessLevel }),
};

try {
return await fetch(url, requestOptions);
} catch (err) {
console.error('update access level error', err);
alert('server not responding. Please try again.');
}
}
}

export default UserApiService;
26 changes: 21 additions & 5 deletions client/src/components/user-admin/EditUsers.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import '../../sass/UserAdmin.scss';
import { FormGroup, FormControlLabel, Switch } from '@mui/material'

// child of UserAdmin. Displays form to update users.
const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUserActiveStatus }) => {
const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUserActiveStatus, updateUserAccessLevel }) => {
const [userManagedProjects, setUserManagedProjects] = useState([]); // The projects that the selected user is assigned
const [projectValue, setProjectValue] = useState(''); // State and handler for form in EditUsers
const [isActive, setIsActive] = useState(userToEdit.isActive);
const [isAdmin, setIsAdmin] = useState(userToEdit.accessLevel === "admin");

// Prepare data for display
const userName = `${userToEdit.name?.firstName} ${userToEdit.name?.lastName}`;
Expand Down Expand Up @@ -64,6 +65,12 @@ const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUse
updateUserActiveStatus(userToEdit, !isActive)
}

const handleSetAccessLevel = () => {
const newAccessLevel = isAdmin ? "user" : "admin";
setIsAdmin(!isAdmin);
updateUserAccessLevel(userToEdit, newAccessLevel);
};

return (
<div className="edit-users">
<div className="ua-row">
Expand All @@ -74,15 +81,24 @@ const EditUsers = ({ userToEdit, backToSearch, updateUserDb, projects, updateUse
<div className="user-display-column-left">Email:</div>
<div className="user-display-column-right">{userEmail}</div>
</div>
<div className="ua-row is-active-flex">
<div className="user-is-active-column-left">Is Active:</div>
<div className="is-active-flex">
<span className="active-status">{isActive.toString()}</span>
<div className="ua-row toggle-flex">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid class rename

<div className="user-toggle-column-left">Is Active:</div>
<div className="toggle-flex">
<span className="toggle-status">{isActive.toString()}</span>
<FormGroup>
<FormControlLabel control={<Switch checked={isActive} />} onClick={() => handleSetIsActive()} />
</FormGroup>
</div>
</div>
<div className="ua-row toggle-flex">
<div className="user-toggle-column-left">VRSM Admin:</div>
<div className="toggle-flex">
<span className="toggle-status">{isAdmin ? "Yes" : "No"}</span>
<FormGroup>
<FormControlLabel control={<Switch checked={isAdmin} />} onClick={() => handleSetAccessLevel()} />
</FormGroup>
</div>
</div>
<div className="ua-row">
<div className="user-display-column-left">Projects:</div>
<div className="user-display-column-right">
Expand Down
10 changes: 10 additions & 0 deletions client/src/pages/UserAdmin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ const UserAdmin = () => {
}, [userApiService, fetchUsers]
)

// Update user's access level (admin/user)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for following convention by keeping the bd calls in one spot here

const updateUserAccessLevel = useCallback(
async (user, newAccessLevel) => {
await userApiService.updateUserAccessLevel(user, newAccessLevel);
fetchUsers();
},
[userApiService, fetchUsers]
);

const fetchProjects = useCallback(async () => {
const projectRes = await projectApiService.fetchProjects();
setProjects(projectRes);
Expand Down Expand Up @@ -65,6 +74,7 @@ const UserAdmin = () => {
updateUserDb={updateUserDb}
backToSearch={backToSearch}
updateUserActiveStatus={updateUserActiveStatus}
updateUserAccessLevel={updateUserAccessLevel}
/>
);
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/sass/UserAdmin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,18 @@
margin-bottom: 8px;
}

.user-is-active-column-left {
.user-toggle-column-left {
display: flex;
flex-direction: column;
flex-basis: 15%;
}

.active-status {
.toggle-status {
margin-right: 15px;
width: 25px;
}

.is-active-flex {
.toggle-flex {
display: flex;
align-items: center;
}
Expand Down
Loading