From 261775f1c6ce42d27b11c5620687257274209afb Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Wed, 10 Feb 2021 16:27:27 -0500 Subject: [PATCH 01/11] Added props necessary to get user alias --- src/components/EmailHeader/EmailHeader.js | 25 ++++++++--------- src/components/ItemBodyView/ItemBodyView.js | 18 ++++++++----- src/components/MessageView/MessageView.js | 30 ++++++++++----------- src/components/UserAvatar/UserAvatar.js | 6 ++--- 4 files changed, 43 insertions(+), 36 deletions(-) diff --git a/src/components/EmailHeader/EmailHeader.js b/src/components/EmailHeader/EmailHeader.js index d3c5ccf..7465153 100644 --- a/src/components/EmailHeader/EmailHeader.js +++ b/src/components/EmailHeader/EmailHeader.js @@ -4,7 +4,7 @@ import { Paper, Grid, makeStyles, useTheme, Typography } from "@material-ui/core import RelativeTime from "react-relative-time"; import UserAvatar from "../UserAvatar/"; -export default function EmailHeader({ datetime, from_name, from_email, to, cc }){ +export default function EmailHeader({ datetime, userAlias, from_name, from_email, to, cc }) { const theme = useTheme(); const useStyles = makeStyles({ @@ -38,15 +38,15 @@ export default function EmailHeader({ datetime, from_name, from_email, to, cc }) * return "" * @returns {string} */ - function buildEmailNameString(name, email){ - let emailNameString = ""; + function buildEmailNameString(name, email) { + let emailNameString = ""; const isNotEmpty = (value) => { return value === "" || value === null ? false : true; }; - if (isNotEmpty(name)){ + if (isNotEmpty(name)) { emailNameString += `${name}`; }; - if (isNotEmpty(email)){ + if (isNotEmpty(email)) { emailNameString += ` <${email}>` } return emailNameString; @@ -57,13 +57,13 @@ export default function EmailHeader({ datetime, from_name, from_email, to, cc }) * @param {array} Array of objects containing names and emails. * @returns {string} String of email with names. */ - function buildRecipientString(recipients){ - if (recipients.length === 0){ + function buildRecipientString(recipients) { + if (recipients.length === 0) { return "Tits"; } let recipientString = ""; - recipients.map( (recipient, index) => { + recipients.map((recipient, index) => { recipientString += buildEmailNameString(recipient.name, recipient.email); index < recipients.length - 1 ? recipientString += ", " : recipientString += ""; return true; @@ -71,13 +71,14 @@ export default function EmailHeader({ datetime, from_name, from_email, to, cc }) return recipientString; }; - return( + return ( - @@ -95,7 +96,7 @@ export default function EmailHeader({ datetime, from_name, from_email, to, cc }) {to.length === 0 ? null : <>To: {buildRecipientString(to)}} - {cc.length === 0 ? null : <>Cc: {buildRecipientString(cc)} } + {cc.length === 0 ? null : <>Cc: {buildRecipientString(cc)}} } diff --git a/src/components/ItemBodyView/ItemBodyView.js b/src/components/ItemBodyView/ItemBodyView.js index 08a57f9..f2132a0 100644 --- a/src/components/ItemBodyView/ItemBodyView.js +++ b/src/components/ItemBodyView/ItemBodyView.js @@ -11,6 +11,8 @@ import { objectIsEmpty } from "../../utilities"; export default function ItemBodyView({ item }) { + + const useStyles = makeStyles(() => ({ "Timeline-root": { padding: "0", @@ -30,22 +32,25 @@ export default function ItemBodyView({ item }) { })); const classes = useStyles(); - const generateTimelineItem = (section) => { + const generateTimelineItem = (section, item) => { + + + switch (section.type) { case "directory_information": return case "initial_message": - return + return case "edit": - return + return case "status": return case "assignment": - return + return case "reply_to_user": return case "reply_from_user": - return + return case "parse_error": return default: @@ -56,6 +61,7 @@ export default function ItemBodyView({ item }) { return ( {objectIsEmpty(item) ? "" : item.content.map((section) => ( + - {generateTimelineItem(section)} + {generateTimelineItem(section, item)} ))} diff --git a/src/components/MessageView/MessageView.js b/src/components/MessageView/MessageView.js index e902a79..22a0316 100644 --- a/src/components/MessageView/MessageView.js +++ b/src/components/MessageView/MessageView.js @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import { Paper, Typography, makeStyles, useTheme } from "@material-ui/core"; import EmailHeader from "../EmailHeader/"; -export default function MessageView({ datetime, from_name, from_email, to, cc, content }){ +export default function MessageView({ datetime, userAlias, from_name, from_email, to, cc, content }) { const theme = useTheme(); const useStyles = makeStyles({ @@ -16,7 +16,7 @@ export default function MessageView({ datetime, from_name, from_email, to, cc, c return ( - + {content.map((line) => ( line === "\n" ?
: {line} @@ -27,25 +27,25 @@ export default function MessageView({ datetime, from_name, from_email, to, cc, c }; MessageView.propTypes = { - /** Name of message sender. */ - "from_name": PropTypes.string, - /** Date the message was sent in ISO 8601 format. */ - "datetime": PropTypes.string, - /** Email address of message sender. */ - "from_email": PropTypes.string, - /** Array of people the message was sent to. */ - "to": PropTypes.array, - /** Array of people the message was cc'd to. */ + /** Name of message sender. */ + "from_name": PropTypes.string, + /** Date the message was sent in ISO 8601 format. */ + "datetime": PropTypes.string, + /** Email address of message sender. */ + "from_email": PropTypes.string, + /** Array of people the message was sent to. */ + "to": PropTypes.array, + /** Array of people the message was cc'd to. */ "cc": PropTypes.array, /** The content of the message as an array of line with non-printable characters. */ "content": PropTypes.array }; MessageView.defaultProps = { - "from_name": "Name Unavailable", - "datetime": new Date(1970, 1, 1, 0, 0, 0, 0), - "from_email": "Email Unavailable", - "to": [], + "from_name": "Name Unavailable", + "datetime": new Date(1970, 1, 1, 0, 0, 0, 0), + "from_email": "Email Unavailable", + "to": [], "cc": [], "content": [] }; \ No newline at end of file diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index 652ce37..92407aa 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -1,9 +1,9 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import PropTypes from "prop-types"; import { Avatar } from "@material-ui/core"; -export default function UserAvatar({ name, ...avatarProps }){ - return( +export default function UserAvatar({ name, alias, ...avatarProps }) { + return ( {name === "" ? null : name.charAt(0)} From 14ed84d4bebb10ef70cd2df9741a426cfcf7838c Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Mon, 15 Feb 2021 15:09:52 -0500 Subject: [PATCH 02/11] Implemented useEffect hook to get user Image based on their alias --- src/components/UserAvatar/UserAvatar.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index 92407aa..7dd0648 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -3,8 +3,19 @@ import PropTypes from "prop-types"; import { Avatar } from "@material-ui/core"; export default function UserAvatar({ name, alias, ...avatarProps }) { + const [userImage, setUserImage] = useState([]); + + useEffect(() => { + const getImage = async () => { + const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); + const jsonResponse = await response.json(); + setUserImage(jsonResponse); + }; + getImage(); + }, [alias]) + return ( - + {name === "" ? null : name.charAt(0)} ); @@ -12,9 +23,12 @@ export default function UserAvatar({ name, alias, ...avatarProps }) { UserAvatar.propTypes = { /** The name of the user. */ - "name": PropTypes.string + "name": PropTypes.string, + /** The user's career account alias. */ + "alias": PropTypes.string }; UserAvatar.defaultProps = { - "name": "" + "name": "", + "alias": "", }; \ No newline at end of file From 493ad74719e8244eba495bd3a7885035706301cc Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Wed, 17 Mar 2021 17:33:38 -0400 Subject: [PATCH 03/11] Deleted duplicate columns in ItemTable --- src/components/ItemTable/ItemTable.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/ItemTable/ItemTable.js b/src/components/ItemTable/ItemTable.js index d94dc72..d843dcc 100644 --- a/src/components/ItemTable/ItemTable.js +++ b/src/components/ItemTable/ItemTable.js @@ -16,7 +16,7 @@ export default function ItemTable({ data, rowCanBeSelected }) { const useStyles = makeStyles({ hoverBackgroundColor: { "&:hover": { - // The !important is placed here to enforce CSS specificity. + // The !important is placed here to enforce CSS specificity. // See: https://material-ui.com/styles/advanced/#css-injection-order backgroundColor: `${theme.palette.primary[200]} !important`, }, @@ -52,10 +52,7 @@ export default function ItemTable({ data, rowCanBeSelected }) { { Header: 'Department', accessor: 'department' }, { Header: 'Building', accessor: 'building' }, { Header: 'Date Received', accessor: 'dateReceived', sortInverted: true, Cell: ({ value }) => }, - { Header: 'Last Updated', accessor: 'lastUpdated', }, - { Header: 'Department', accessor: 'department' }, - { Header: 'Building', accessor: 'building' }, - { Header: 'Date Received', accessor: 'dateReceived', }, + ], []); const tableInstance = useTable( { @@ -148,7 +145,7 @@ export default function ItemTable({ data, rowCanBeSelected }) { history.push(`/${row.original.queue}/${row.original.number}`); setSelectedRow({ queue: row.original.queue, number: row.original.number }); }} - // This functionality should be achieved by using the selected prop and + // This functionality should be achieved by using the selected prop and // overriding the selected class but this applied the secondary color at 0.08% opacity. // Overridding the root class is a workaround. classes={{ From 9cf03016639287cd466607ef90515091575c83b9 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Wed, 17 Mar 2021 19:25:01 -0400 Subject: [PATCH 04/11] Fixed formatting errors --- src/components/EmailHeader/EmailHeader.js | 2 +- src/components/ItemBodyView/ItemBodyView.js | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/EmailHeader/EmailHeader.js b/src/components/EmailHeader/EmailHeader.js index 7465153..a3b658f 100644 --- a/src/components/EmailHeader/EmailHeader.js +++ b/src/components/EmailHeader/EmailHeader.js @@ -59,7 +59,7 @@ export default function EmailHeader({ datetime, userAlias, from_name, from_email */ function buildRecipientString(recipients) { if (recipients.length === 0) { - return "Tits"; + return ""; } let recipientString = ""; diff --git a/src/components/ItemBodyView/ItemBodyView.js b/src/components/ItemBodyView/ItemBodyView.js index f2132a0..85b5626 100644 --- a/src/components/ItemBodyView/ItemBodyView.js +++ b/src/components/ItemBodyView/ItemBodyView.js @@ -10,9 +10,6 @@ import ParseError from "../ParseError/"; import { objectIsEmpty } from "../../utilities"; export default function ItemBodyView({ item }) { - - - const useStyles = makeStyles(() => ({ "Timeline-root": { padding: "0", @@ -33,9 +30,6 @@ export default function ItemBodyView({ item }) { const classes = useStyles(); const generateTimelineItem = (section, item) => { - - - switch (section.type) { case "directory_information": return @@ -61,7 +55,6 @@ export default function ItemBodyView({ item }) { return ( {objectIsEmpty(item) ? "" : item.content.map((section) => ( - Date: Wed, 17 Mar 2021 19:31:11 -0400 Subject: [PATCH 05/11] Removed unnecessary prop expansion --- src/components/UserAvatar/UserAvatar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index 7dd0648..c88c50e 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -2,9 +2,9 @@ import React, { useEffect, useState } from "react"; import PropTypes from "prop-types"; import { Avatar } from "@material-ui/core"; -export default function UserAvatar({ name, alias, ...avatarProps }) { +export default function UserAvatar({ name, alias }) { const [userImage, setUserImage] = useState([]); - + useEffect(() => { const getImage = async () => { const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); @@ -15,7 +15,7 @@ export default function UserAvatar({ name, alias, ...avatarProps }) { }, [alias]) return ( - + {name === "" ? null : name.charAt(0)} ); From 922d5d3b12287ee20ae6f3b0daf7c26a10320482 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Mon, 22 Mar 2021 10:37:18 -0400 Subject: [PATCH 06/11] Added userAlias to prop types --- src/components/MessageView/MessageView.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/MessageView/MessageView.js b/src/components/MessageView/MessageView.js index 22a0316..95e7403 100644 --- a/src/components/MessageView/MessageView.js +++ b/src/components/MessageView/MessageView.js @@ -29,6 +29,8 @@ export default function MessageView({ datetime, userAlias, from_name, from_email MessageView.propTypes = { /** Name of message sender. */ "from_name": PropTypes.string, + /** Account alias of message sender. */ + "userAlias": PropTypes.string, /** Date the message was sent in ISO 8601 format. */ "datetime": PropTypes.string, /** Email address of message sender. */ @@ -43,6 +45,7 @@ MessageView.propTypes = { MessageView.defaultProps = { "from_name": "Name Unavailable", + "userAlias": "Alias Unavailable", "datetime": new Date(1970, 1, 1, 0, 0, 0, 0), "from_email": "Email Unavailable", "to": [], From 66470c8a446d159d3afb1db84e461e5ea3fed7a4 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Mon, 22 Mar 2021 11:04:49 -0400 Subject: [PATCH 07/11] Renammed state variable and function for getting image for clarity --- src/components/UserAvatar/UserAvatar.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index c88c50e..c4cab9c 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -3,19 +3,19 @@ import PropTypes from "prop-types"; import { Avatar } from "@material-ui/core"; export default function UserAvatar({ name, alias }) { - const [userImage, setUserImage] = useState([]); + const [userImageURL, setUserImageURL] = useState([]); useEffect(() => { - const getImage = async () => { + const getImageURL = async () => { const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); const jsonResponse = await response.json(); - setUserImage(jsonResponse); + setUserImageURL(jsonResponse); }; - getImage(); + getImageURL(); }, [alias]) return ( - + {name === "" ? null : name.charAt(0)} ); From b6866e887528004a91d5cfe486d6332f7f7daee8 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Mon, 22 Mar 2021 15:46:48 -0400 Subject: [PATCH 08/11] Impleted useItem hook to get alias from the active item, removed uneccsary prop --- src/components/MessageView/MessageView.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/MessageView/MessageView.js b/src/components/MessageView/MessageView.js index 95e7403..d7a265a 100644 --- a/src/components/MessageView/MessageView.js +++ b/src/components/MessageView/MessageView.js @@ -2,9 +2,10 @@ import React from "react"; import PropTypes from "prop-types"; import { Paper, Typography, makeStyles, useTheme } from "@material-ui/core"; import EmailHeader from "../EmailHeader/"; +import { useItem } from "../ItemProvider" -export default function MessageView({ datetime, userAlias, from_name, from_email, to, cc, content }) { - +export default function MessageView({ datetime, from_name, from_email, to, cc, content }) { + const activeItem = useItem() const theme = useTheme(); const useStyles = makeStyles({ "content": { @@ -16,7 +17,7 @@ export default function MessageView({ datetime, userAlias, from_name, from_email return ( - + {content.map((line) => ( line === "\n" ?
: {line} @@ -29,8 +30,6 @@ export default function MessageView({ datetime, userAlias, from_name, from_email MessageView.propTypes = { /** Name of message sender. */ "from_name": PropTypes.string, - /** Account alias of message sender. */ - "userAlias": PropTypes.string, /** Date the message was sent in ISO 8601 format. */ "datetime": PropTypes.string, /** Email address of message sender. */ From fa846ebd655686c2301a79f75844f461ce3bfae7 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Wed, 31 Mar 2021 17:31:06 -0400 Subject: [PATCH 09/11] Implemented IIFE function to get UserAvatar image src URL --- src/components/UserAvatar/UserAvatar.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index c4cab9c..a04c495 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -6,12 +6,16 @@ export default function UserAvatar({ name, alias }) { const [userImageURL, setUserImageURL] = useState([]); useEffect(() => { - const getImageURL = async () => { - const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); + (async () => { + const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`) const jsonResponse = await response.json(); setUserImageURL(jsonResponse); - }; - getImageURL(); + })(); + // const getImageURL = async () => { + // const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); + // const jsonResponse = await response.json(); + // setUserImageURL(jsonResponse); + // }; }, [alias]) return ( From 39f1615626560c89424c1ccc67cff2235ff3f433 Mon Sep 17 00:00:00 2001 From: wrigh393 Date: Fri, 2 Apr 2021 09:52:23 -0400 Subject: [PATCH 10/11] Refactored UserAvatar component to use IIFE; Implemented error handling. --- src/components/UserAvatar/UserAvatar.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index a04c495..d4341a2 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -6,16 +6,15 @@ export default function UserAvatar({ name, alias }) { const [userImageURL, setUserImageURL] = useState([]); useEffect(() => { - (async () => { - const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`) - const jsonResponse = await response.json(); - setUserImageURL(jsonResponse); + const getImageURL = (async () => { + const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); + if (response.status >= 200 && response.status <= 299) { + const jsonResponse = await response.json(); + setUserImageURL(jsonResponse); + } else { + console.log(response.status, response.statusText) + } })(); - // const getImageURL = async () => { - // const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); - // const jsonResponse = await response.json(); - // setUserImageURL(jsonResponse); - // }; }, [alias]) return ( From 6cd750fddc770000f9e5982b71e58784d1c4c4b3 Mon Sep 17 00:00:00 2001 From: Justin Campbell Date: Tue, 20 Apr 2021 18:02:01 -0400 Subject: [PATCH 11/11] Replace uncalled function with IIFE --- src/components/UserAvatar/UserAvatar.js | 34 +++++++++++++++++-------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js index d4341a2..b6f7965 100644 --- a/src/components/UserAvatar/UserAvatar.js +++ b/src/components/UserAvatar/UserAvatar.js @@ -3,22 +3,34 @@ import PropTypes from "prop-types"; import { Avatar } from "@material-ui/core"; export default function UserAvatar({ name, alias }) { - const [userImageURL, setUserImageURL] = useState([]); - - useEffect(() => { - const getImageURL = (async () => { - const response = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); - if (response.status >= 200 && response.status <= 299) { - const jsonResponse = await response.json(); - setUserImageURL(jsonResponse); - } else { - console.log(response.status, response.statusText) + const [userImageURL, setUserImageURL] = useState(""); + + // Load User Image from ECNDB + useEffect(_ => { + (async function getUserImage() { + if (alias === "") { + return null; + } + + const userImageResponse = await fetch(`https://engineering.purdue.edu/ECN/PersonPhotos/getPhoto?json=1&alias=${alias}`); + + if (userImageResponse.status !== 200) { + console.error(`Failed to load user image from ECNDB. Got code ${userImageResponse.status} (${userImageResponse.statusText})`); + return null; } + + let userImageData = await userImageResponse.json(); + if (userImageData.imagePath === "") { + return null; + } + + setUserImageURL(`https://engineering.purdue.edu/${userImageData.imagePath}`); + return null; })(); }, [alias]) return ( - + {name === "" ? null : name.charAt(0)} );