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

Filtered permissions data comp #1808

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import addProject from './components/manageProjects/addProject';
import HealthCheck from './pages/HealthCheck';
import SecretPassword from './pages/SecretPassword';
import UserWelcome from './pages/UserWelcome';
// Added User Permission Search component
import UserPermissionSearch from './pages/UserPermissionSearch';

import { ThemeProvider } from '@mui/material';
import theme from './theme';
Expand All @@ -47,6 +49,8 @@ const routes = [
{ path: '/emailsent', name: 'emailsent', Component: EmailSent },
{ path: '/events', name: 'events', Component: Events },
{ path: '/useradmin', name: 'useradmin', Component: UserAdmin },
// Added User Permission Search component
{ path: '/users/permission-search', name: 'useradmin', Component: UserPermissionSearch },
{ path: '/projects', name: 'projects', Component: ProjectList },
{ path: '/projects/create', name: 'projectform', Component: addProject},
{
Expand Down
3 changes: 2 additions & 1 deletion client/src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ const Navbar = (props) => {
{/* Admin auth -> Displays 2 links -> 'Users' and 'Projects'. */}
{auth?.user?.accessLevel === 'admin' && (
<>
<StyledButton component={NavLink} to="/useradmin">
{/* <StyledButton component={NavLink} to="/useradmin"> */}
<StyledButton component={NavLink} to="/users/permission-search">
jng34 marked this conversation as resolved.
Show resolved Hide resolved
USERS
</StyledButton>
<StyledButton component={NavLink} to="/projects">
Expand Down
6 changes: 4 additions & 2 deletions client/src/pages/UserAdmin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { Redirect } from 'react-router-dom';
import '../sass/UserAdmin.scss';
import useAuth from '../hooks/useAuth';
import EditUsers from '../components/user-admin/EditUsers';
import UserManagement from '../components/user-admin/UserManagement';
import UserApiService from '../api/UserApiService';
import ProjectApiService from '../api/ProjectApiService';
import UserManagement from '../components/user-admin/UserManagement';
import UserPermissionSearch from './UserPermissionSearch';

const UserAdmin = () => {
// Initialize state hooks
Expand Down Expand Up @@ -65,7 +66,8 @@ const UserAdmin = () => {
}

if (Object.keys(userToEdit).length === 0) {
return <UserManagement users={users} setUserToEdit={setUserToEdit} />;
return <UserPermissionSearch users={users} setUserToEdit={setUserToEdit} />;
// return <UserManagement users={users} setUserToEdit={setUserToEdit} />;
Copy link
Member

@vorleakyek vorleakyek Oct 31, 2024

Choose a reason for hiding this comment

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

From my understanding, there shouldn't be any changes to the "UserAdmin.jsx" file. Refer to the mockup Low-fi mockups created by Bonnie / Jack - see page 1.

So, the "UserPermissionSearch" component should render when clicking on the "User Permission Search" button on the "Users" page.

But, it looks like we do need the useState hooks and functions in the UserAdmin page (or a similar structure) to handle the User Permission Search. Not sure if creating a new page with the same code structure would be a good approach. But, that code is probably needed to handle the filter and make each data element renders a link to the associated user profile, which is part of #1754.

Copy link
Member Author

Choose a reason for hiding this comment

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

Forgot to change it back to UserManagement when testing the code earlier, so thank you for catching that.

I left the props users and setUserToEdit in the UserPermissionSearch component as placeholders for now so they can be used for integration with the filter permissions data component (#1754).

If there should be changes in the props that are appropriate for the filter component, just let me know.

} else {
return (
<EditUsers
Expand Down
288 changes: 288 additions & 0 deletions client/src/pages/UserPermissionSearch.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
import React, { useState, useEffect } from 'react';
import {Box, Button, ButtonGroup, Grid, TextField, Typography, List, ListItem, ListItemButton} from '@mui/material';
import { useLocation } from 'react-router-dom';

import '../sass/UserAdmin.scss';

const Buttonsx = {
px: 2,
py: 0.5,
}

const dummyData = [
{
"_id": 1,
"name": {
"firstName": "John",
"lastName": "Doe",
},
"accessLevel": "admin",
"email": "[email protected]",
"projects": []
},
{
"_id": 2,
"name": {
"firstName": "Vinny",
"lastName": "Harris",
},
"accessLevel": "admin",
"email": "[email protected]",
"projects": []
},
{
"_id": 3,
"name": {
"firstName": "Gary",
"lastName": "Jones",
},
"accessLevel": "admin",
"email": "[email protected]",
"projects": []
},
{
"_id": 4,
"name": {
"firstName": "Jane",
"lastName": "Smith",
},
"accessLevel": "projectLead",
"email": "[email protected]",
"projects": ["VRMS", "Mobile"]
},
{
"_id": 5,
"name": {
"firstName": "Bonnie",
"lastName": "Wolfe",
},
"accessLevel": "projectLead",
"email": "[email protected]",
"projects": ["Home Unite Us"]
},
{
"_id": 6,
"name": {
"firstName": "Diana",
"lastName": "Loeb",
},
"accessLevel": "projectLead",
"email": "[email protected]",
"projects": ["HackforLA Mobile", "LA TDM Calculator"]
},
{
"_id": 7,
"name": {
"firstName": "Zack",
"lastName": "Cruz",
},
"accessLevel": "projectLead",
"email": "[email protected]",
"projects": ["LA TDM Calculator", "VRMS backend"]
},
{
"_id": 8,
"name": {
"firstName": "Iris",
"lastName": "Sosa",
},
"accessLevel": "projectLead",
"email": "[email protected]",
"projects": ["Home Unite Us", "VRMS Support"]
},
];

const DummyComponent = ({ data, type }) => {
return (
<List className="search-results disablePadding">
{data.map((u, idx) => {
jng34 marked this conversation as resolved.
Show resolved Hide resolved
// Destructure user object
const { _id, name, email } = u;
// return projects.length === 0 ?
return type === 'admin' ?
(
<ListItem
sx={{
px: 2.4,
py: 1,
borderBottom: 1.6,
borderBottomColor: 'grey.300',
}}
key={`result_${_id}/${idx}`}>
<ListItemButton
sx={{
px: 0.25,
py: 0.36,
color: 'primary.main',
mx: 0.16,
}}
className="search-results-button"
type="button"
onClick={() => setUserToEdit(u)}
>
<Grid container>
<Grid item>
<Typography style={{fontWeight: 600}}>
{`${name.firstName.toUpperCase()} ${name.lastName.toUpperCase()} ( ${email.toUpperCase()} )`}
</Typography>
</Grid>
</Grid>
</ListItemButton>
</ListItem>
) :
<ListItem
style={{display: 'flex', justifyContent: 'flex-end'}}
sx={{
px: 2.4,
py: 1,
borderBottom: 1.6,
borderBottomColor: 'grey.300',
}}
key={`result_${_id}/${idx}`}>
<ListItemButton
sx={{
px: 0.25,
py: 0.36,
color: 'primary.main',
mx: 0.16,
}}
className="search-results-button"
type="button"
onClick={() => setUserToEdit(u)}
>
<Grid container justifyContent={"space-between"}>
<Grid item>
<Typography style={{fontWeight: 600}}>{name.firstName.toUpperCase() + " " + name.lastName.toUpperCase()}</Typography>
</Grid>
<Grid item>
<Typography style={{fontWeight: 600}} color='black'>{u.project}</Typography>
</Grid>
</Grid>
</ListItemButton>
</ListItem>
})
}
</List>
)
}


const UserPermissionSearch = ({ users, setUserToEdit }) => {
const [userType, setUserType] = useState('admin'); // Which results will diplay
const [searchText, setSearchText] = useState(''); // Serch term for the admin/PM search
jng34 marked this conversation as resolved.
Show resolved Hide resolved

const location = useLocation();

useEffect(() => {
// Edit url by adding '/admin' upon loading
let editURL = '';
if (userType === 'admin') {
editURL = location.pathname + '/admin';
} else {
editURL = location.pathname + '/projects';
}
window.history.replaceState({}, "", editURL);
}, [userType]);


// Swaps the buttons and displayed panels for the search results, by email or by name
const buttonSwap = () =>
userType === 'projectLead'
? setUserType('admin')
: setUserType('projectLead');

// Handle change on input in search form
const handleChange = (event) => {
setSearchText(event.target.value);
};

// Filtering logic
let filteredData;
if (!searchText) {
filteredData = dummyData.filter((user) => user.accessLevel === userType);
if (userType === 'admin') {
// Default display for admins, sorted ASC based on first name
filteredData.sort((u1, u2) => u1.name?.firstName.localeCompare(u2.name?.firstName))
} else {
// Default display of all PMs, sorted ASC based on project name, then first name
let tempFilter = [];
filteredData.forEach((user) => {
user.projects.forEach((project) => {
tempFilter.push({ ...user, project })
})
})
tempFilter.sort((u1, u2) => u1.project.localeCompare(u2.project) || u1.name?.firstName.localeCompare(u2.name?.firstName))
filteredData = [...tempFilter];
}
}

return (
<Box className="container--usermanagement" sx={{px: '1.8rem', mb: 0,}}>
<Box sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
pt: 5,
height: '100%',
width: 1/1,
}}>
<Typography variant="h4" style={{marginBottom: 20, fontWeight: 'bold'}}>User Permission Search</Typography>
<Box className="tab-buttons">
<ButtonGroup fullWidth sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
whiteSpace: 'nowrap',
mx: 1,
}}>
<Button
sx={Buttonsx}
type="button"
variant={
userType === 'admin'
? 'contained'
: 'secondary'
}
onClick={buttonSwap}
>
Admins
</Button>
<Button
sx={Buttonsx}
type="button"
variant={
userType === 'projectLead'
? 'contained'
: 'secondary'
}
onClick={buttonSwap}
>
Project Leads
</Button>
</ButtonGroup>
</Box>
<TextField
type="text"
placeholder={userType === "admin" ? "Search name" : "Search name or project"}
variant='standard'
value={searchText}
onChange={handleChange}
/>
<Box sx={{
bgcolor: dummyData.length>0? '#F5F5F5': 'transparent',
my: 1.2,
borderRadius: 1,
flexGrow: 1,
width: 1/1,
}}>
<Box>
{/*Component to render admins and PMs*/}
<DummyComponent data={filteredData} type={userType} />
</Box>
</Box>
</Box>
</Box>
);
};

export default UserPermissionSearch;
Loading