diff --git a/jams-react-client/src/components/Drawer/Drawer.js b/jams-react-client/src/components/Drawer/Drawer.js index 8849f531ef84eede19a953c364c5a086e41f5888..c5fff76e72beed9da02201cf4b7df75d84980a50 100644 --- a/jams-react-client/src/components/Drawer/Drawer.js +++ b/jams-react-client/src/components/Drawer/Drawer.js @@ -1,228 +1,332 @@ -import React, { useEffect, useCallback } from 'react'; -import clsx from 'clsx'; -import { makeStyles } from '@material-ui/core/styles'; +import React, { useEffect, useCallback } from "react"; +import clsx from "clsx"; +import { makeStyles } from "@material-ui/core/styles"; import CustomInput from "components/CustomInput/CustomInput.js"; -import Drawer from '@material-ui/core/Drawer'; -import List from '@material-ui/core/List'; -import Divider from '@material-ui/core/Divider'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemText from '@material-ui/core/ListItemText'; -import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline'; -import {api_path_get_user_directory_search, api_path_get_auth_contacts, api_path_get_admin_contacts, api_path_put_update_group} from 'globalUrls' -import { useHistory } from 'react-router-dom'; +import Drawer from "@material-ui/core/Drawer"; +import List from "@material-ui/core/List"; +import Divider from "@material-ui/core/Divider"; +import ListItem from "@material-ui/core/ListItem"; +import ListItemText from "@material-ui/core/ListItemText"; +import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline"; +import Avatar from "@material-ui/core/Avatar"; + +import noProfilePicture from "assets/img/faces/no-profile-picture.png"; + +import { + api_path_get_user_directory_search, + api_path_get_auth_contacts, + api_path_get_admin_contacts, + api_path_put_update_group, +} from "globalUrls"; +import { useHistory } from "react-router-dom"; import axios from "axios"; import configApiCall from "api.js"; -import auth from 'auth.js' +import auth from "auth.js"; import { debounce } from "lodash"; const useStyles = makeStyles({ - list: { - width: 500, - }, - fullList: { - width: 'auto', - }, - search : { - width: "100%" - }, - margin: { - marginLeft: "5px", - marginRight: "5px" - } + list: { + width: 500, + }, + fullList: { + width: "auto", + }, + search: { + width: "100%", + }, + margin: { + marginLeft: "5px", + marginRight: "5px", + }, }); export default function TemporaryDrawer(props) { - const classes = useStyles(); - const history = useHistory(); - const [direction, setDirection] = React.useState(props.direction); - const [users, setUsers] = React.useState([]); - const [existingContacts, setExistingContacts] = React.useState([]); - const [userAdded, setUserAdded] = React.useState(false); - let addingToGroup = props.addingToGroup; - - useEffect(() => { - /** - * Get users list to pass to the drawer to add contacts to user or users to group - */ - - axios(configApiCall(api_path_get_admin_contacts+"?username="+props.username, 'GET', null, null)).then((response)=>{ - /* + const classes = useStyles(); + const history = useHistory(); + const [direction, setDirection] = React.useState(props.direction); + const [users, setUsers] = React.useState([]); + const [existingContacts, setExistingContacts] = React.useState([]); + const [userAdded, setUserAdded] = React.useState(false); + let addingToGroup = props.addingToGroup; + + useEffect(() => { + /** + * Get users list to pass to the drawer to add contacts to user or users to group + */ + + axios( + configApiCall( + api_path_get_admin_contacts + "?username=" + props.username, + "GET", + null, + null + ) + ) + .then((response) => { + /* TODO: Include the username of the user of witch we want to display contacts at the moment the admin sees his contacts in each user profile he visits */ - let originalContacts = response.data - originalContacts.map((contact) => { - contact.display = "" - }) - setExistingContacts(originalContacts) - }).catch((error) =>{ - console.log(error); - if(error.response.status == 401){ - auth.authenticated = false - history.push('/') - } - }); - - axios(configApiCall(api_path_get_user_directory_search, 'GET', {"queryString":"*"}, null)).then((response)=>{ - let resp = response.data - if(!addingToGroup){ - let contacts = resp.filter((data)=>{ - if(data.username !== props.username) - return data - }) - setUsers(contacts); - } - else - setUsers(resp); - }).catch((error) =>{ - console.log(error); - if(error.response.status == 401){ - auth.authenticated = false - history.push('/') - } + let originalContacts = response.data; + originalContacts.map((contact) => { + contact.display = ""; }); - }, [userAdded]) - - const addContactToUser = (firstName, lastName, jamiId) => { - var displayName= firstName+" "+ lastName; - var owner = props.username; - const data = { - "owner": owner, - "uri": jamiId, - "displayName": displayName, - "timestamp": "", - "status": '', - "banned": false, - "confirmed": false - }; - if(props.isAdmin){ - axios(configApiCall(api_path_get_admin_contacts+"?username="+props.username,'PUT', data, null)).then((response)=>{ - setUserAdded(true); - props.setOpenDrawer(false) - }).catch((error) =>{ - console.log("Error adding user: " + error) - props.setOpenDrawer(false) - }); + setExistingContacts(originalContacts); + }) + .catch((error) => { + console.log(error); + if (error.response.status == 401) { + auth.authenticated = false; + history.push("/"); } - else { - axios(configApiCall(api_path_get_auth_contacts, 'PUT', data, null)).then((response)=>{ - setUserAdded(true); - props.setOpenDrawer(false) - }).catch((error) =>{ - console.log("Error adding user: " + error) - props.setOpenDrawer(false) - }); + }); + + axios( + configApiCall( + api_path_get_user_directory_search, + "GET", + { queryString: "*" }, + null + ) + ) + .then((response) => { + let resp = response.data; + if (!addingToGroup) { + let contacts = resp.filter((data) => { + if (data.username !== props.username) return data; + }); + setUsers(contacts); + } else setUsers(resp); + }) + .catch((error) => { + console.log(error); + if (error.response.status == 401) { + auth.authenticated = false; + history.push("/"); } + }); + }, [userAdded]); + const addContactToUser = (firstName, lastName, jamiId) => { + var displayName = firstName + " " + lastName; + var owner = props.username; + const data = { + owner: owner, + uri: jamiId, + displayName: displayName, + timestamp: "", + status: "", + banned: false, + confirmed: false, + }; + if (props.isAdmin) { + axios( + configApiCall( + api_path_get_admin_contacts + "?username=" + props.username, + "PUT", + data, + null + ) + ) + .then((response) => { + setUserAdded(true); + props.setOpenDrawer(false); + }) + .catch((error) => { + console.log("Error adding user: " + error); + props.setOpenDrawer(false); + }); + } else { + axios(configApiCall(api_path_get_auth_contacts, "PUT", data, null)) + .then((response) => { + setUserAdded(true); + props.setOpenDrawer(false); + }) + .catch((error) => { + console.log("Error adding user: " + error); + props.setOpenDrawer(false); + }); } + }; - const addUserToGroup = (username) => { - let url = ''; - console.log(props.blueprintLabel); - - if(props.blueprintLabel == null){ - url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+props.groupName+"&blueprintName=&groupMembers="+username; - }else{ - url = api_path_put_update_group+"?groupName="+props.groupName+"&newName="+props.groupName+"&blueprintName="+props.blueprintLabel+"&groupMembers="+username; - } + const addUserToGroup = (username) => { + let url = ""; + console.log(props.blueprintLabel); - axios(configApiCall(url, 'PUT', null, null)).then((response) => { - setUserAdded(true); - props.getGroup() - props.setOpenDrawer(false) - - }).catch((error) =>{ - console.log("Error adding user: " + error) - props.setOpenDrawer(false) - }); + if (props.blueprintLabel == null) { + url = + api_path_put_update_group + + "?groupName=" + + props.groupName + + "&newName=" + + props.groupName + + "&blueprintName=&groupMembers=" + + username; + } else { + url = + api_path_put_update_group + + "?groupName=" + + props.groupName + + "&newName=" + + props.groupName + + "&blueprintName=" + + props.blueprintLabel + + "&groupMembers=" + + username; } + axios(configApiCall(url, "PUT", null, null)) + .then((response) => { + setUserAdded(true); + props.getGroup(); + props.setOpenDrawer(false); + }) + .catch((error) => { + console.log("Error adding user: " + error); + props.setOpenDrawer(false); + }); + }; - const searchUsers = (value) => { - axios(configApiCall(api_path_get_user_directory_search, 'GET', {"queryString": value ? value : "*"}, null)).then((response)=>{ - setUsers(response.data) - }).catch((error) =>{ - console.log(error); - setUsers([]) - if(error.response.status == 401){ - auth.authenticated = false - history.push('/') - } - }); + const searchUsers = (value) => { + axios( + configApiCall( + api_path_get_user_directory_search, + "GET", + { queryString: value ? value : "*" }, + null + ) + ) + .then((response) => { + setUsers(response.data); + }) + .catch((error) => { + console.log(error); + setUsers([]); + if (error.response.status == 401) { + auth.authenticated = false; + history.push("/"); + } + }); + }; - } + const listUsers = () => ( + <List> + {addingToGroup + ? users.map((user) => ( + <ListItem + button + key={user.username} + onClick={() => { + addUserToGroup(user.username); + }} + > + {/* <AddCircleOutlineIcon style={{ marginRight: "10px" }} /> */} + <Avatar + style={{ marginRight: "10px" }} + alt={user.username} + src={ + user.profilePicture + ? "data:image/png;base64, " + user.profilePicture + : noProfilePicture + } + /> + <ListItemText + primary={ + user.username === "" + ? user.id + : user.firstName === "" || user.lastName === "" + ? user.username + : user.firstName + " " + user.lastName + } + /> + </ListItem> + )) + : users + .filter((data) => { + var added = false; + existingContacts.forEach((contact) => { + if (contact.uri === data.id) added = true; + }); + if (!added) return data; + }) + .map((user) => ( + <ListItem + button + key={user.username} + onClick={() => { + addContactToUser(user.firstName, user.lastName, user.id); + }} + > + {/* <AddCircleOutlineIcon style={{ marginRight: "10px" }} /> */} + <Avatar + style={{ marginRight: "10px" }} + alt={user.username} + src={ + user.profilePicture + ? "data:image/png;base64, " + user.profilePicture + : noProfilePicture + } + /> + <ListItemText + primary={ + user.username === "" + ? user.id + : user.firstName === "" || user.lastName === "" + ? user.username + : user.firstName + " " + user.lastName + } + /> + </ListItem> + ))} + </List> + ); - const listUsers = () => ( - - <List> - { - addingToGroup - ? - users.map((user) => ( - <ListItem button key={user.username} onClick={() => {addUserToGroup(user.username)}} > - <AddCircleOutlineIcon style={{ marginRight: "10px"}} /><ListItemText primary={user.firstName+" "+user.lastName} /> - </ListItem> - )) - : - users.filter((data)=>{ - var added = false; - existingContacts.forEach((contact) => { - if(contact.uri === data.id) - added = true - }) - if(!added) - return data - - }).map((user) => ( - <ListItem button key={user.username} onClick={() => {addContactToUser(user.firstName, user.lastName, user.id)}} > - <AddCircleOutlineIcon style={{ marginRight: "10px"}} /><ListItemText primary={user.firstName+" "+user.lastName} /> - </ListItem> - )) - } - </List> - ); - - const initSearchUsers = useCallback(debounce((searchValue) => searchUsers(searchValue), 500), []) - - const handleSearchUsers = (e) => { - const searchValue = e.target.value; - initSearchUsers(searchValue) - } + const initSearchUsers = useCallback( + debounce((searchValue) => searchUsers(searchValue), 500), + [] + ); + const handleSearchUsers = (e) => { + const searchValue = e.target.value; + initSearchUsers(searchValue); + }; - return ( - <div> - <React.Fragment key={props.direction}> - <Drawer - anchor="right" - open={props.openDrawer} - onClose={() => {props.setOpenDrawer(false)}}> - <div - className={clsx(classes.list, { - [classes.fullList]: direction === 'top' || direction === 'bottom', - })} - role="presentation" - > - <div className={classes.searchWrapper}> - <CustomInput - formControlProps={{ - className: classes.margin + " " + classes.search - }} - inputProps={{ - placeholder: props.placeholder, - inputProps: { - "aria-label": "Add a contact" - }, - onKeyUp: handleSearchUsers, - }} - /> - </div> - <Divider /> - {listUsers()} - </div> - </Drawer> - </React.Fragment> - </div> - ); + return ( + <div> + <React.Fragment key={props.direction}> + <Drawer + anchor="right" + open={props.openDrawer} + onClose={() => { + props.setOpenDrawer(false); + }} + > + <div + className={clsx(classes.list, { + [classes.fullList]: direction === "top" || direction === "bottom", + })} + role="presentation" + > + <div className={classes.searchWrapper}> + <CustomInput + formControlProps={{ + className: classes.margin + " " + classes.search, + }} + inputProps={{ + placeholder: props.placeholder, + inputProps: { + "aria-label": "Add a contact", + }, + onKeyUp: handleSearchUsers, + }} + /> + </div> + <Divider /> + {listUsers()} + </div> + </Drawer> + </React.Fragment> + </div> + ); } diff --git a/jams-react-client/src/views/Contacts/Contacts.js b/jams-react-client/src/views/Contacts/Contacts.js index 967f1282a84d23360e00901226c9e20a18db3e70..ef33b407ae7be335e646dfb2bed729176842e45d 100644 --- a/jams-react-client/src/views/Contacts/Contacts.js +++ b/jams-react-client/src/views/Contacts/Contacts.js @@ -329,6 +329,7 @@ export default function Users(props) { xs={12} sm={12} md={2} + wrap="nowrap" key={contact.uri} style={{ display: contact.display }} > @@ -345,7 +346,10 @@ export default function Users(props) { /> </CardAvatar> <h4 className={classes.cardTitle}> - {contact.firstName} {contact.lastName} + {contact.firstName != "" + ? contact.firstName + : "No first name"}{" "} + {contact.lastName != "" ? contact.lastName : "No last name"} </h4> <ul> <li> diff --git a/jams-react-client/src/views/Users/Users.js b/jams-react-client/src/views/Users/Users.js index 72f20e8edef563b669aa4b1d0b09bb7d5c5d68e2..42f567165fdeacab3dab0033ea5b031bea0367af 100644 --- a/jams-react-client/src/views/Users/Users.js +++ b/jams-react-client/src/views/Users/Users.js @@ -247,7 +247,13 @@ export default function Users(props) { return 0; }) .map((user) => ( - <GridItem xs={12} sm={12} md={2} key={user.username}> + <GridItem + xs={12} + sm={12} + md={2} + wrap="nowrap" + key={user.username} + > <Card profile> <CardBody profile> <a @@ -267,7 +273,10 @@ export default function Users(props) { </CardAvatar> <h4 className={classes.cardTitle}> - {user.firstName} {user.lastName} + {user.firstName != "" + ? user.firstName + : "No first name"}{" "} + {user.lastName != "" ? user.lastName : "No last name"} </h4> <ul> <li>