Skip to content
Snippets Groups Projects
Commit 68d1ef7f authored by Larbi Gharib's avatar Larbi Gharib Committed by Adrien Béraud
Browse files

Users search bar user display

Change-Id: I5910dcfdace9c0a429c968af0d164b656ddd0878
parent baf311c0
No related branches found
No related tags found
No related merge requests found
...@@ -47,7 +47,7 @@ import { ...@@ -47,7 +47,7 @@ import {
api_path_get_needs_update, api_path_get_needs_update,
api_path_get_start_update, api_path_get_start_update,
api_path_post_create_user, api_path_post_create_user,
api_path_get_user, api_path_get_auth_user,
api_path_post_update_user, api_path_post_update_user,
api_path_get_exists_user, api_path_get_exists_user,
api_path_get_user_directory_search, api_path_get_user_directory_search,
......
...@@ -27,12 +27,6 @@ const cardStyle = { ...@@ -27,12 +27,6 @@ const cardStyle = {
"& li" :{ "& li" :{
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
"& svg": {
marginRight: "10px"
},
"& img": {
marginRight: "10px"
}
} }
}, },
"&:hover": { "&:hover": {
......
...@@ -135,7 +135,6 @@ export default function CaSetup(props) { ...@@ -135,7 +135,6 @@ export default function CaSetup(props) {
axios(configApiCall(api_path_post_install_ca, "POST", jsonData, null)).then((response)=>{ axios(configApiCall(api_path_post_install_ca, "POST", jsonData, null)).then((response)=>{
handleInstallCA(response); handleInstallCA(response);
console.log(response);
}).catch((error)=>{ }).catch((error)=>{
props.setError(error); props.setError(error);
console.log('Error installing CA Setup: ' + error ); console.log('Error installing CA Setup: ' + error );
......
...@@ -34,16 +34,15 @@ export default function Devices(props) { ...@@ -34,16 +34,15 @@ export default function Devices(props) {
axios(configApiCall(api_path_get_admin_devices, 'GET', userData, null)).then((response)=>{ axios(configApiCall(api_path_get_admin_devices, 'GET', userData, null)).then((response)=>{
var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim()); var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
setDevices(resultSet) setDevices(resultSet)
} }).catch((error) =>{
).catch((error) =>{
console.log(error); console.log(error);
}); });
} }
else{ else{
axios(configApiCall(api_path_get_auth_devices, 'GET', null, null)).then((response)=>{ axios(configApiCall(api_path_get_auth_devices, 'GET', null, null)).then((response)=>{
setDevices(response.data) var resultSet = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
} setDevices(resultSet)
).catch((error) =>{ }).catch((error) =>{
console.log(error); console.log(error);
}); });
} }
......
...@@ -203,7 +203,6 @@ export default function IdentityManagement(props) { ...@@ -203,7 +203,6 @@ export default function IdentityManagement(props) {
} }
axios(configApiCall(api_path_post_install_auth,'POST',data,null)).then((response)=>{ axios(configApiCall(api_path_post_install_auth,'POST',data,null)).then((response)=>{
console.log(response)
callbackIdentityManagement() callbackIdentityManagement()
}).catch(()=>{ }).catch(()=>{
props.setErrorMessage('The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again.') props.setErrorMessage('The information provided appears to be incorrect, the connection to the directory has failed. Please check the information and credentials provided and try again.')
......
...@@ -128,14 +128,14 @@ export default function Admin({ ...rest }) { ...@@ -128,14 +128,14 @@ export default function Admin({ ...rest }) {
<div className={classes.map}>{switchRoutes}</div> <div className={classes.map}>{switchRoutes}</div>
)} )}
{getRoute() ? <Footer /> : null} {getRoute() ? <Footer /> : null}
<FixedPlugin {/* <FixedPlugin
handleImageClick={handleImageClick} handleImageClick={handleImageClick}
handleColorClick={handleColorClick} handleColorClick={handleColorClick}
bgColor={color} bgColor={color}
bgImage={image} bgImage={image}
handleFixedClick={handleFixedClick} handleFixedClick={handleFixedClick}
fixedClasses={fixedClasses} fixedClasses={fixedClasses}
/> /> */}
</div> </div>
</div> </div>
); );
......
...@@ -12,6 +12,14 @@ import CardBody from "components/Card/CardBody.js"; ...@@ -12,6 +12,14 @@ import CardBody from "components/Card/CardBody.js";
import CardFooter from "components/Card/CardFooter.js"; import CardFooter from "components/Card/CardFooter.js";
import noProfilePicture from "assets/img/faces/no-profile-picture.png"; import noProfilePicture from "assets/img/faces/no-profile-picture.png";
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import IconButton from '@material-ui/core/IconButton';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import Grid from '@material-ui/core/Grid'; import Grid from '@material-ui/core/Grid';
import BusinessCenterOutlinedIcon from '@material-ui/icons/BusinessCenterOutlined'; import BusinessCenterOutlinedIcon from '@material-ui/icons/BusinessCenterOutlined';
...@@ -21,13 +29,22 @@ import SmartphoneOutlinedIcon from '@material-ui/icons/SmartphoneOutlined'; ...@@ -21,13 +29,22 @@ import SmartphoneOutlinedIcon from '@material-ui/icons/SmartphoneOutlined';
import LocalPrintshopOutlinedIcon from '@material-ui/icons/LocalPrintshopOutlined'; import LocalPrintshopOutlinedIcon from '@material-ui/icons/LocalPrintshopOutlined';
import PhoneForwardedOutlinedIcon from '@material-ui/icons/PhoneForwardedOutlined'; import PhoneForwardedOutlinedIcon from '@material-ui/icons/PhoneForwardedOutlined';
import PersonOutlinedIcon from '@material-ui/icons/PersonOutlined'; import PersonOutlinedIcon from '@material-ui/icons/PersonOutlined';
import AccountBoxOutlinedIcon from '@material-ui/icons/AccountBoxOutlined'; import PermIdentityOutlinedIcon from '@material-ui/icons/PermIdentityOutlined';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import Avatar from '@material-ui/core/Avatar';
import Chip from '@material-ui/core/Chip';
import DoneIcon from '@material-ui/icons/Done';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
import auth from "auth.js" import auth from "auth.js"
import configApiCall from "api.js"; import configApiCall from "api.js";
import { api_path_get_admin_user, api_path_get_user, api_path_get_user_directory_search} from "globalUrls"; import { api_path_get_admin_user, api_path_get_auth_user, api_path_get_user_directory_search, api_path_delete_admin_user_revoke} from "globalUrls";
import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
...@@ -92,7 +109,8 @@ const styles = (theme)=> ( { ...@@ -92,7 +109,8 @@ const styles = (theme)=> ( {
maxHeight: '60vh', maxHeight: '60vh',
minWidth: '80vh', minWidth: '80vh',
maxWidth: '80vh' maxWidth: '80vh'
}, }
// controls: { // controls: {
// padding: 16, // padding: 16,
// display: 'flex', // display: 'flex',
...@@ -130,7 +148,10 @@ export default function DisplayUserProfile(props) { ...@@ -130,7 +148,10 @@ export default function DisplayUserProfile(props) {
const classes = useStyles(); const classes = useStyles();
const [users, setUsers] = React.useState([]) const [users, setUsers] = React.useState([])
const [userStatus, setUserStatus] = React.useState('') const [userStatus, setUserStatus] = React.useState(false)
const [open, setOpen] = React.useState(false);
const [revokedUser, setRevokedUser] = React.useState("");
const searchData = { const searchData = {
"queryString":props.username "queryString":props.username
}; };
...@@ -138,20 +159,22 @@ export default function DisplayUserProfile(props) { ...@@ -138,20 +159,22 @@ export default function DisplayUserProfile(props) {
const userData = { const userData = {
"username":props.username "username":props.username
}; };
const [value, setValue] = React.useState(0);
useEffect(() => { useEffect(() => {
auth.checkDirectoryType(() => { auth.checkDirectoryType(() => {
if(auth.hasAdminScope()){ if(auth.hasAdminScope()){
axios(configApiCall(api_path_get_admin_user, 'GET', userData, null)).then((response)=>{ axios(configApiCall(api_path_get_admin_user, 'GET', userData, null)).then((response)=>{
setStatus(response.data) const result = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
setUserStatus(result.revoked)
} }
).catch((error) =>{ ).catch((error) =>{
console.log(error); console.log(error);
}); });
} }
else{ else{
axios(configApiCall(api_path_get_user, 'GET', null, null)).then((response)=>{ axios(configApiCall(api_path_get_auth_user, 'GET', null, null)).then((response)=>{
setStatus(response.data) const result = JSON.parse(response.data.replace(/\s+/g, ' ').trim());
setUserStatus(result.revoked)
} }
).catch((error) =>{ ).catch((error) =>{
console.log(error); console.log(error);
...@@ -166,92 +189,179 @@ export default function DisplayUserProfile(props) { ...@@ -166,92 +189,179 @@ export default function DisplayUserProfile(props) {
}); });
}, []); }, []);
function setStatus(data) { const getUserStatus = (user) => {
if (data.revoked) if(userStatus == false) {
setUserStatus("Revoked"); return <Chip label="Active" avatar={<Avatar alt={user.username} src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} />} color="primary" deleteIcon={<DoneIcon />}/>
else }else{
setUserStatus("Active"); return <Chip label="Revoked" avatar={<Avatar alt={user.username} src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} />} deleteIcon={<DoneIcon />}/>
}
}
function revokeUser(){
const data = {
'username': revokedUser
} }
console.log(userStatus)
axios(configApiCall(api_path_delete_admin_user_revoke, 'DELETE', data, null)).then(()=>{
setUserStatus(true)
}).catch((error)=> {
console.log("Error revoking user: " + revokedUser + ' with error: ' + error);
});
setOpen(false);
}
const handleClickOpen = (username) => {
setRevokedUser(username)
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return ( return (
<div> <div>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Revoke user account"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Are you sure you want to revoke <strong>{revokedUser}</strong> ?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={revokeUser} color="danger" autoFocus>
Revoke
</Button>
</DialogActions>
</Dialog>
{users.map(user => {users.map(user =>
<GridContainer> <GridContainer>
<Grid item xs={12} sm={12} md={8}> <Grid item xs={12} sm={12} md={8}>
<Card profile> <Card profile>
<CardHeader color="info" stats icon> <CardHeader color="info" stats icon>
<CardIcon color="info"> <CardIcon color="info">
<AccountBoxOutlinedIcon /> <PermIdentityOutlinedIcon />
</CardIcon> </CardIcon>
<p className={classes.cardCategory}>{"Profile information"}</p> <p className={classes.cardCategory}>{"Profile information"}</p>
<h3 className={classes.cardTitle}>{user.username}</h3> <h3 className={classes.cardTitle}>{user.username}</h3>
{getUserStatus(user)}
</CardHeader> </CardHeader>
<CardBody profile> <CardBody profile>
<div className={classes.root}> <div className={classes.root}>
<GridContainer spacing={5}> <Grid container spacing={2}>
<Grid item xs={12} sm={12} md={6}>
<Grid container spacing={5} >
<Grid item align="center" xs={12} sm={12} md={12}> <Grid item align="center" xs={12} sm={12} md={12}>
<img src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} className={classes.editProfilePicture} alt="..." /> <img src={user.profilePicture ? ('data:image/png;base64, ' + user.profilePicture) : noProfilePicture} className={classes.editProfilePicture} alt="..." />
<h4>{user.username ? user.username : 'no username'}</h4>
</Grid> </Grid>
</Grid>
</Grid>
<GridItem xs={12} sm={12} md={6}>
<Grid container spacing={5}>
<Grid item xs={12} sm={12} md={12}>
<FormControl className={classes.margin} fullWidth>
<span><AccountCircleIcon /> {user.username ? user.username : 'no username'}, {userStatus ? userStatus: "no user status"}</span>
</FormControl>
</Grid>
<Grid item xs={12} sm={12} md={12}>
<FormControl className={classes.margin} fullWidth>
<span> <PersonIcon /> {user.firstName ? user.firstName : 'no firstname'}</span>
</FormControl>
</Grid>
<Grid item xs={12} sm={12} md={12}>
<FormControl className={classes.margin} fullWidth>
<span><PersonOutlinedIcon/> {user.lastName ? user.lastName : 'no lastname'}</span>
</FormControl>
</Grid>
</Grid>
</GridItem>
<Grid item xs={12} sm={12} md={6}> <Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth> <List dense={false}>
<span> <AlternateEmailOutlinedIcon/> {user.email ? user.email : 'no email'} </span> <ListItem>
</FormControl> <ListItemAvatar>
</Grid> <Avatar>
<Grid item xs={12} sm={12} md={6}> <PersonIcon />
<FormControl className={classes.margin} fullWidth> </Avatar>
<span> <BusinessCenterOutlinedIcon/> {user.organization ? user.organization : 'no organization'} </span> </ListItemAvatar>
</FormControl> <ListItemText
</Grid> primary={user.firstName ? user.firstName : 'no firstname'}
<Grid item xs={12} sm={12} md={6}> />
<FormControl className={classes.margin} fullWidth> </ListItem>
<span> <PhoneInTalkOutlinedIcon/> {user.phoneNumber ? user.phoneNumber : 'no phone number'} </span> <ListItem>
</FormControl> <ListItemAvatar>
</Grid> <Avatar>
<Grid item xs={12} sm={12} md={6}> <PersonOutlinedIcon/>
<FormControl className={classes.margin} fullWidth> </Avatar>
<span> <PhoneForwardedOutlinedIcon/> {user.phoneNumberExtension ? user.phoneNumberExtension : 'no Extension'} </span> </ListItemAvatar>
</FormControl> <ListItemText
primary={user.lastName ? user.lastName : 'no lastname'}
/>
</ListItem>
<ListItem>
<ListItemAvatar>
<Avatar>
<AlternateEmailOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.email ? user.email : 'no email'}
/>
</ListItem>
<ListItem>
<ListItemAvatar>
<Avatar>
<BusinessCenterOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.organization ? user.organization : 'no organization'}
/>
</ListItem>
</List>
</Grid> </Grid>
<Grid item xs={12} sm={12} md={6}> <Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth> <List dense={false}>
<span> <SmartphoneOutlinedIcon/> {user.mobileNumber ? user.mobileNumber : 'no mobile number'} </span> <ListItem>
</FormControl> <ListItemAvatar>
<Avatar>
<PhoneInTalkOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.phoneNumber ? user.phoneNumber : 'no phone number'}
/>
</ListItem>
<ListItem>
<ListItemAvatar>
<Avatar>
<PhoneForwardedOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.phoneNumberExtension ? user.phoneNumberExtension : 'no Extension'}
/>
</ListItem>
<ListItem>
<ListItemAvatar>
<Avatar>
<SmartphoneOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.mobileNumber ? user.mobileNumber : 'no mobile number'}
/>
</ListItem>
<ListItem>
<ListItemAvatar>
<Avatar>
<LocalPrintshopOutlinedIcon/>
</Avatar>
</ListItemAvatar>
<ListItemText
primary={user.faxNumber ? user.faxNumber : 'no fax number'}
/>
</ListItem>
</List>
</Grid> </Grid>
<Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth>
<span> <LocalPrintshopOutlinedIcon/> {user.faxNumber ? user.faxNumber : 'no fax number'} </span>
</FormControl>
</Grid> </Grid>
</GridContainer>
</div> </div>
</CardBody> </CardBody>
<CardFooter> <CardFooter>
<Button color="info" onClick={() => props.setDisplayUser(false)}>Edit Profile</Button> {auth.isLocalDirectory() && <Button color="info" onClick={() => props.setDisplayUser(false)}>
{auth.hasAdminScope() && (userStatus == "Active" || userStatus == '') && <Button color="danger">Revoke Profile</Button>} <EditIcon /> Edit Profile
</Button>}
{auth.hasAdminScope() && (userStatus == "Active" || userStatus == '') &&
<Button color="danger" onClick={() => handleClickOpen(user.username)} >
<DeleteIcon fontSize="small"/> Revoke user
</Button>}
</CardFooter> </CardFooter>
</Card> </Card>
</Grid> </Grid>
......
...@@ -56,7 +56,8 @@ import { ...@@ -56,7 +56,8 @@ import {
api_path_put_update_user_profile, api_path_put_update_user_profile,
api_path_post_create_user, api_path_post_create_user,
api_path_post_create_user_profile, api_path_post_create_user_profile,
api_path_get_user_directory_search api_path_get_user_directory_search,
api_path_get_exists_user
} from "../../globalUrls" } from "../../globalUrls"
import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js"; import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
...@@ -157,6 +158,7 @@ export default function EditCreateUserProfile(props) { ...@@ -157,6 +158,7 @@ export default function EditCreateUserProfile(props) {
const classes = useStyles(); const classes = useStyles();
const history = useHistory(); const history = useHistory();
const [createUser, setCreateUser] = React.useState(props.createUser); const [createUser, setCreateUser] = React.useState(props.createUser);
const [userExists, setUserExists] = React.useState(false)
const [firstName, setFirstName] = React.useState("") const [firstName, setFirstName] = React.useState("")
const [lastName, setLastName] = React.useState("") const [lastName, setLastName] = React.useState("")
...@@ -170,6 +172,8 @@ export default function EditCreateUserProfile(props) { ...@@ -170,6 +172,8 @@ export default function EditCreateUserProfile(props) {
const [phoneNumber, setPhoneNumber] = React.useState("") const [phoneNumber, setPhoneNumber] = React.useState("")
const [extension, setExtension] = React.useState("") const [extension, setExtension] = React.useState("")
const [mobileNumber, setMobileNumber] = React.useState("") const [mobileNumber, setMobileNumber] = React.useState("")
const [openPassword, setOpenPassword] = React.useState(false)
const [temporaryPassword, setTemporaryPassword] = React.useState("")
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const [crop, setCrop] = React.useState({ x: 0, y: 0 }) const [crop, setCrop] = React.useState({ x: 0, y: 0 })
...@@ -219,13 +223,10 @@ export default function EditCreateUserProfile(props) { ...@@ -219,13 +223,10 @@ export default function EditCreateUserProfile(props) {
} }
const handleUserProfileCreation = (data) => { const handleUserProfileCreation = (data) => {
axios(configApiCall(api_path_post_create_user + "?username="+ data.username, 'POST', null, null)).then((response) => { axios(configApiCall(api_path_post_create_user_profile, 'POST', data, null)).then(() => {
console.log("New user successfully created. Here is the one time password: " + response.data["password"]) setOpenPassword(true)
history.push('/admin');
}).catch((error) => { }).catch((error) => {
console.log("Failed to create new user. This is either because the username is already in use" + console.log("Error creating user profile: " + error)
" on the public nameserver, or another unknown error has occurred. " +
"Please choose another one.");
}) })
} }
...@@ -243,11 +244,26 @@ export default function EditCreateUserProfile(props) { ...@@ -243,11 +244,26 @@ export default function EditCreateUserProfile(props) {
'mobileNumber': mobileNumber 'mobileNumber': mobileNumber
} }
axios(configApiCall(api_path_post_create_user_profile, 'POST', data, null)).then(() => { axios(configApiCall(api_path_post_create_user + "?username="+ data.username, 'POST', null, null)).then((response) => {
setTemporaryPassword(response.data["password"])
handleUserProfileCreation(data) handleUserProfileCreation(data)
}).catch((error) => {
console.log("Failed to create new user. This is either because the username is already in use" +
" on the public nameserver, or another unknown error has occurred. " +
"Please choose another one.");
})
}
const handleUserExists = (input) => {
const data = {
"username": input
}
axios(configApiCall(api_path_get_exists_user, 'GET', data, null)).then((response) =>{
if(response.data == "[]"){
setUserExists(true)
}
}).catch((error) => { }).catch((error) => {
console.log("Error updating user: " + error) console.log("Error checking for existing users: " + error)
}) })
} }
...@@ -287,7 +303,6 @@ export default function EditCreateUserProfile(props) { ...@@ -287,7 +303,6 @@ export default function EditCreateUserProfile(props) {
rotation rotation
).then((value) => { ).then((value) => {
setProfilePicturePreview(value) setProfilePicturePreview(value)
console.log(value)
}) })
} }
...@@ -305,9 +320,30 @@ export default function EditCreateUserProfile(props) { ...@@ -305,9 +320,30 @@ export default function EditCreateUserProfile(props) {
setOpen(false) setOpen(false)
} }
const handleClosePassword = () => {
setOpenPassword(false);
history.push('/admin');
}
return( return(
<div> <div>
<Dialog
open={openPassword}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Temporary password"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
New user successfully created. Here is the one time password: <strong>{temporaryPassword}</strong> ?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClosePassword} color="primary">
Ok
</Button>
</DialogActions>
</Dialog>
<Dialog <Dialog
open={open} open={open}
onClose={handleClose} onClose={handleClose}
...@@ -385,7 +421,7 @@ export default function EditCreateUserProfile(props) { ...@@ -385,7 +421,7 @@ export default function EditCreateUserProfile(props) {
<CardBody profile> <CardBody profile>
<div className={classes.root}> <div className={classes.root}>
<Grid container spacing={5}> <Grid container spacing={5}>
<Grid item xs={12} sm={12} md={6}> <Grid item xs={12} sm={12} md={12}>
<Grid container spacing={5} > <Grid container spacing={5} >
<Grid item align="center" xs={12} sm={12} md={12} > <Grid item align="center" xs={12} sm={12} md={12} >
<img src={profilePicturePreview} alt="..." className={classes.editProfilePicture} /> <img src={profilePicturePreview} alt="..." className={classes.editProfilePicture} />
...@@ -398,14 +434,10 @@ export default function EditCreateUserProfile(props) { ...@@ -398,14 +434,10 @@ export default function EditCreateUserProfile(props) {
</IconButton> Update profile image </IconButton> Update profile image
</label> </label>
</Grid> </Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={12} md={6}>
<Grid container spacing={5}>
<Grid item xs={12} sm={12} md={12}>
{createUser && {createUser &&
<FormControl className={classes.margin} fullWidth> <Grid item align="center" xs={12} sm={12} md={12}>
<InputLabel htmlFor="username">Username</InputLabel> <FormControl className={classes.margin} size="medium" error={userExists}>
<InputLabel htmlFor="username">{userExists ? "Error username exists" : "Username"}</InputLabel>
<Input <Input
id="username" id="username"
placeholder={userName} placeholder={userName}
...@@ -414,12 +446,17 @@ export default function EditCreateUserProfile(props) { ...@@ -414,12 +446,17 @@ export default function EditCreateUserProfile(props) {
<AccountCircleIcon /> <AccountCircleIcon />
</InputAdornment> </InputAdornment>
} }
onChange={e => setUserName(e.target.value)} onChange={e => {
setUserName(e.target.value);
handleUserExists(e.target.value)
}}
/> />
</FormControl> </FormControl>
</Grid>
} }
</Grid> </Grid>
<Grid item xs={12} sm={12} md={12}> </Grid>
<Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth> <FormControl className={classes.margin} fullWidth>
<InputLabel htmlFor="firstname">First Name</InputLabel> <InputLabel htmlFor="firstname">First Name</InputLabel>
<Input <Input
...@@ -434,7 +471,7 @@ export default function EditCreateUserProfile(props) { ...@@ -434,7 +471,7 @@ export default function EditCreateUserProfile(props) {
/> />
</FormControl> </FormControl>
</Grid> </Grid>
<Grid item xs={12} sm={12} md={12}> <Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth> <FormControl className={classes.margin} fullWidth>
<InputLabel htmlFor="lastname">Last Name</InputLabel> <InputLabel htmlFor="lastname">Last Name</InputLabel>
<Input <Input
...@@ -449,9 +486,6 @@ export default function EditCreateUserProfile(props) { ...@@ -449,9 +486,6 @@ export default function EditCreateUserProfile(props) {
/> />
</FormControl> </FormControl>
</Grid> </Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={12} md={6}> <Grid item xs={12} sm={12} md={6}>
<FormControl className={classes.margin} fullWidth> <FormControl className={classes.margin} fullWidth>
<InputLabel htmlFor="email">Email</InputLabel> <InputLabel htmlFor="email">Email</InputLabel>
......
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useHistory } from 'react-router-dom';
import { Switch, Route, Redirect } from "react-router-dom"; import { Switch, Route, Redirect } from "react-router-dom";
// @material-ui/core components // @material-ui/core components
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
...@@ -15,28 +16,18 @@ import CardBody from "components/Card/CardBody.js"; ...@@ -15,28 +16,18 @@ import CardBody from "components/Card/CardBody.js";
import CardFooter from "components/Card/CardFooter.js"; import CardFooter from "components/Card/CardFooter.js";
import UserProfile from "views/UserProfile/UserProfile.js" import UserProfile from "views/UserProfile/UserProfile.js"
import Divider from '@material-ui/core/Divider'; import Divider from '@material-ui/core/Divider';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import PersonIcon from '@material-ui/icons/Person'; import PersonIcon from '@material-ui/icons/Person';
import PermIdentityIcon from '@material-ui/icons/PermIdentity'; import PermIdentityIcon from '@material-ui/icons/PermIdentity';
import PhoneOutlinedIcon from '@material-ui/icons/PhoneOutlined'; import PhoneOutlinedIcon from '@material-ui/icons/PhoneOutlined';
import BusinessOutlinedIcon from '@material-ui/icons/BusinessOutlined'; import BusinessOutlinedIcon from '@material-ui/icons/BusinessOutlined';
import DeleteIcon from '@material-ui/icons/Delete';
import Search from "@material-ui/icons/Search"; import Search from "@material-ui/icons/Search";
import IconButton from '@material-ui/core/IconButton';
import MailOutlineIcon from '@material-ui/icons/MailOutline'; import MailOutlineIcon from '@material-ui/icons/MailOutline';
import axios from "axios"; import axios from "axios";
import configApiCall from "api.js"; import configApiCall from "api.js";
import auth from 'auth.js' import auth from 'auth.js'
import { import { api_path_get_user_directory_search } from "globalUrls";
api_path_get_user_directory_search,
api_path_delete_admin_user_revoke
} from "globalUrls";
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
import KeyboardReturnIcon from '@material-ui/icons/KeyboardReturn'; import KeyboardReturnIcon from '@material-ui/icons/KeyboardReturn';
...@@ -45,6 +36,7 @@ import jami from "assets/img/faces/jami.png"; ...@@ -45,6 +36,7 @@ import jami from "assets/img/faces/jami.png";
import noProfilePicture from "assets/img/faces/no-profile-picture.png"; import noProfilePicture from "assets/img/faces/no-profile-picture.png";
import EditCreateUserProfile from "views/UserProfile/EditCreateUserProfile"; import EditCreateUserProfile from "views/UserProfile/EditCreateUserProfile";
import LinearProgress from '@material-ui/core/LinearProgress';
import headerLinksStyle from "assets/jss/material-dashboard-react/components/headerLinksStyle.js"; import headerLinksStyle from "assets/jss/material-dashboard-react/components/headerLinksStyle.js";
...@@ -68,6 +60,12 @@ const styles = { ...@@ -68,6 +60,12 @@ const styles = {
}, },
deleteIcon : { deleteIcon : {
float: "right" float: "right"
},
search : {
width: "90%"
},
loading: {
width: '100%',
} }
}; };
...@@ -75,20 +73,42 @@ const useStyles = makeStyles(styles); ...@@ -75,20 +73,42 @@ const useStyles = makeStyles(styles);
export default function Users() { export default function Users() {
const classes = useStyles(); const classes = useStyles();
const history = useHistory();
const [users, setUsers] = React.useState([]) const [users, setUsers] = React.useState([])
const [open, setOpen] = React.useState(false);
const [revokedUser, setRevokedUser] = React.useState("");
const [selectedUsername, setSelectedUsername] = React.useState("") const [selectedUsername, setSelectedUsername] = React.useState("")
const [createUser, setCreateUser] = React.useState(false) const [createUser, setCreateUser] = React.useState(false)
const [searchValue, setSearchValue] = React.useState(null)
const [loading, setLoading] = React.useState(false)
const [progress, setProgress] = React.useState(0);
useEffect(() => { useEffect(() => {
setRevokedUser('') setLoading(true)
axios(configApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null)).then((response)=>{ const timer = setInterval(() => {
setUsers(response.data) setProgress((oldProgress) => {
if (oldProgress === 100) {
return 0;
} }
).catch((error) =>{ const diff = Math.random() * 10;
return Math.min(oldProgress + diff, 100);
});
}, 500);
axios(configApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null)).then((response)=>{
let orginalUsers = response.data
orginalUsers.map((user) => {
user.display = ""
})
setUsers(orginalUsers)
setLoading(false)
}).catch((error) =>{
console.log(error); console.log(error);
if(error.response.status == 401){
auth.authenticated = false
history.push('/')
}
}); });
return () => {
clearInterval(timer);
};
}, []); }, []);
const [selectedProfile, setSelectedProfile] = useState(false); const [selectedProfile, setSelectedProfile] = useState(false);
...@@ -101,32 +121,10 @@ export default function Users() { ...@@ -101,32 +121,10 @@ export default function Users() {
function redirectToUsers(e) { function redirectToUsers(e) {
e.preventDefault() e.preventDefault()
setSelectedProfile(false); setSelectedProfile(false);
history.push('/admin')
} }
function revokeUser(){ if (!auth.hasAdminScope()) {
const data = {
'username': revokedUser
}
axios(configApiCall(api_path_delete_admin_user_revoke, 'DELETE', data, null)).then((result)=>{
console.log("Revoked user: " + revokedUser);
}).catch((error)=> {
console.log("Error revoking user: " + revokedUser + ' with error: ' + error);
});
setOpen(false);
}
const handleClickOpen = (username) => {
setRevokedUser(username)
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
if (selectedProfile && !auth.hasAdminScope()) {
return ( return (
<div> <div>
<UserProfile username={auth.getUsername()}/> <UserProfile username={auth.getUsername()}/>
...@@ -149,27 +147,6 @@ export default function Users() { ...@@ -149,27 +147,6 @@ export default function Users() {
else { else {
return ( return (
<div> <div>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Revoke user account"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Are you sure you want to revoke <strong>{revokedUser}</strong> ?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={revokeUser} color="danger" autoFocus>
Revoke
</Button>
</DialogActions>
</Dialog>
<GridContainer> <GridContainer>
<GridItem xs={12} sm={12} md={12}> <GridItem xs={12} sm={12} md={12}>
{auth.isLocalDirectory() && {auth.isLocalDirectory() &&
...@@ -183,18 +160,37 @@ export default function Users() { ...@@ -183,18 +160,37 @@ export default function Users() {
className: classes.margin + " " + classes.search className: classes.margin + " " + classes.search
}} }}
inputProps={{ inputProps={{
placeholder: "Search users", placeholder: "Search users using (username, name, phone, email, ...)",
inputProps: { inputProps: {
"aria-label": "Search users" "aria-label": "Search users"
} },
onKeyUp: (e) => setSearchValue(e.target.value),
}} }}
/> />
<Search /> <Search />
<div className={classes.loading}>
{loading && <LinearProgress variant="determinate" value={progress} />}
</div>
</div> </div>
</GridItem> </GridItem>
{ {
users.map(user => users.filter((data)=>{
<GridItem xs={12} sm={12} md={2} key={user.username}> if(searchValue == null)
return data
else if((data.username != null ) && data.username.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.firstName != null ) && data.firstName.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.lastName != null ) && data.lastName.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.organization != null ) && data.organization.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.email != null ) && data.email.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.phoneNumber != null ) && data.phoneNumber.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.phoneNumberExtension != null ) && data.phoneNumberExtension.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.mobileNumber != null ) && data.mobileNumber.toLowerCase().includes(searchValue.toLowerCase()) ||
(data.faxNumber != null ) && data.faxNumber.toLowerCase().includes(searchValue.toLowerCase())
){
return data
}
}).map(user =>
<GridItem xs={12} sm={12} md={2} key={user.username} style={{display: user.display}}>
<Card profile> <Card profile>
<CardBody profile> <CardBody profile>
...@@ -205,14 +201,10 @@ export default function Users() { ...@@ -205,14 +201,10 @@ export default function Users() {
<h4 className={classes.cardTitle}>{user.firstName} {user.lastName}</h4> <h4 className={classes.cardTitle}>{user.firstName} {user.lastName}</h4>
<ul> <ul>
<li><img src={jami} width="20" alt="Jami" /> {user.username}</li> <li><img src={jami} width="20" alt="Jami" style={{marginRight: "10px"}} /> {user.username}</li>
<li><BusinessOutlinedIcon fontSize='small' /> {user.organization ? user.organization : 'No organization'}</li> <li><BusinessOutlinedIcon fontSize='small' style={{marginRight: "10px"}} /> {user.organization ? user.organization : 'No organization'}</li>
</ul> </ul>
</a> </a>
<Divider variant="middle" />
<IconButton aria-label="delete" className={classes.deleteIcon} onClick={() => handleClickOpen(user.username)}>
<DeleteIcon fontSize="small" color="error" />
</IconButton>
</CardBody> </CardBody>
</Card> </Card>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment