+const demoItem = {"queue": "ce", "number": 100, "lastUpdated": "07-23-20 10:11 PM", "headers": [{"type": "Merged-Time", "content": "Tue, 23 Jun 2020 13:31:53 -0400"}, {"type": "Merged-By", "content": "campb303"}, {"type": "QTime", "content": "1"}, {"type": "QTime-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "QTime-Updated-By", "content": "campb303"}, {"type": "Time", "content": "1"}, {"type": "Time-Updated-Time", "content": "Tue, 23 Jun 2020 13:28:50 EDT"}, {"type": "Time-Updated-By", "content": "campb303"}, {"type": "Replied-Time", "content": "Tue, 23 Jun 2020 13:28:48 -0400"}, {"type": "Replied-By", "content": "campb303"}, {"type": "Edited-Time", "content": "Tue, 23 Jun 2020 13:27:56 -0400"}, {"type": "Edited-By", "content": "campb303"}, {"type": "QAssigned-To", "content": "campb303"}, {"type": "QAssigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "QAssigned-To-Updated-By", "content": "campb303"}, {"type": "Assigned-To", "content": "campb303"}, {"type": "Assigned-To-Updated-Time", "content": "Tue, 23 Jun 2020 13:27:00 EDT"}, {"type": "Assigned-To-Updated-By", "content": "campb303"}, {"type": "QStatus", "content": "Dont Delete"}, {"type": "QStatus-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "QStatus-Updated-By", "content": "campb303"}, {"type": "Status", "content": "Dont Delete"}, {"type": "Status-Updated-Time", "content": "Tue, 23 Jun 2020 13:26:55 EDT"}, {"type": "Status-Updated-By", "content": "campb303"}, {"type": "Date", "content": "Tue, 23 Jun 2020 13:25:51 -0400"}, {"type": "From", "content": "Justin Campbell
"}, {"type": "Message-ID", "content": "<911CE050-3240-4980-91DD-9C3EBB8DBCF8@purdue.edu>"}, {"type": "Subject", "content": "Beepboop"}, {"type": "To", "content": "cesite@ecn.purdue.edu"}, {"type": "Content-Type", "content": "text/plain; charset=\"utf-8\""}, {"type": "X-ECN-Queue-Original-Path", "content": "/home/pier/e/queue/Attachments/inbox/2020-06-23/208-original.txt"}], "content": ["Testtest\n", "\n", "*** Status updated by: campb303 at: 6/23/2020 13:26:55 ***\n", "Dont Delete\n", "*** Edited by: campb303 at: 06/23/20 13:27:56 ***\n", "\n", "This be an edit my boy\n", "\n", "\n", "\n", "*** Replied by: campb303 at: 06/23/20 13:28:18 ***\n", "\n", "This be a reply my son\n", "\n", "Justin\n", "ECN\n", "\n", "=== Additional information supplied by user ===\n", "\n", "Subject: Re: Beepboop\n", "From: Justin Campbell \n", "Date: Tue, 23 Jun 2020 13:30:45 -0400\n", "X-ECN-Queue-Original-Path: /home/pier/e/queue/Attachments/inbox/2020-06-23/212-original.txt\n", "X-ECN-Queue-Original-URL: https://engineering.purdue.edu/webqueue/Attachments/inbox/2020-06-23/212-original.txt\n", "\n", "Huzzah!\n", "\n", "===============================================\n"], "isLocked": "ce 100 is locked by knewell using qvi", "userEmail": "campb303@purdue.edu", "userName": "Justin Campbell", "userAlias": "campb303", "assignedTo": "campb303", "subject": "Beepboop", "status": "Dont Delete", "priority": "", "department": "", "building": "", "dateReceived": "Tue, 23 Jun 2020 13:25:51 -0400"};
+
+
```
diff --git a/src/components/ItemTable/ItemTable.js b/src/components/ItemTable/ItemTable.js
index 3cb47b3..b9b0f0b 100644
--- a/src/components/ItemTable/ItemTable.js
+++ b/src/components/ItemTable/ItemTable.js
@@ -1,51 +1,117 @@
-import React from 'react';
+import React, { useState, useEffect } from "react";
+import { useTable, useFilters, useFlexLayout, useSortBy } from "react-table";
+import { makeStyles, Table, TableBody, TableCell, TableHead, TableRow, TableContainer, TableSortLabel, Paper, Grid, IconButton, useTheme, } from "@material-ui/core";
import { useHistory } from "react-router-dom";
-import PropTypes from 'prop-types'
-import MaterialTable from "material-table";
-
-
-export default function ItemTable({ items }) {
-
- const columns = [
- { title: 'Queue', field: 'queue', filterPlaceholder: "Ex: \"ME\"" },
- { title: 'Item #', field: 'number', filterPlaceholder: "Ex: \"42\"" },
- { title: 'From', field: 'userAlias', filterPlaceholder: "Ex: \"campb303\"" },
- { title: 'Assigned To', field: 'assignedTo', filterPlaceholder: "Ex: \"sundeep\"" },
- { title: 'Subject', field: 'subject', filterPlaceholder: "Ex: \"Install Libraries\"" },
- { title: 'Status', field: 'status', filterPlaceholder: "Ex: \"Wating for Reply\"" },
- { title: 'Priority', field: 'priority', filterPlaceholder: "Ex: \"covid\"" },
- { title: 'Last Updated', field: 'lastUpdated', filterPlaceholder: "Ex: \"07-27-20 12:54 PM\"" },
- { title: 'Department', field: 'department', filterPlaceholder: "Ex: \"Business Office\"" },
- { title: 'Building', field: 'building', filterPlaceholder: "Ex: \"KNOY\"" },
- { title: 'Date Received', field: 'dateReceived', filterPlaceholder: "Ex: \"07-20-20 03:32 AM\"" },
- ]
-
- const options = {
- "filtering": true,
- "paging": false,
- "search": false,
- "draggable": false,
- "padding": "dense",
- }
-
- const history = useHistory();
-
- return (
- {
- history.push(`/${rowData.queue}/${rowData.number}`);
- }}
- />
- );
-}
+import ItemTableFilter from "../ItemTableFilter/"
-ItemTable.propTypes = {
+export default function ItemTable({ items, onRowClick }) {
+
+ const theme = useTheme();
+ const useStyles = makeStyles({
+ // Fully visible for active icons
+ activeSortIcon: {
+ opacity: 1,
+ },
+ // Half visible for inactive icons
+ inactiveSortIcon: {
+ opacity: 0.2,
+ },
+ bandedRows: {
+ '&:nth-of-type(even)': {
+ backgroundColor: theme.palette.type === 'light' ? theme.palette.grey[50] : theme.palette.grey[700],
+ },
+ },
+ });
+ const classes = useStyles();
+
+ const history = useHistory();
+
+ const columns = React.useMemo(
+ () => [
+ { Header: 'Queue', accessor: 'queue', },
+ { Header: 'Item #', accessor: 'number' },
+ { Header: 'Assigned To', accessor: 'assignedTo' },
+ { Header: 'Subject', accessor: 'subject' },
+ { Header: 'Status', accessor: 'status', },
+ { Header: 'Priority', accessor: 'priority' },
+ { Header: 'Last Updated', accessor: 'lastUpdated' },
+ { Header: 'Department', accessor: 'department' },
+ { Header: 'Building', accessor: 'building' },
+ { Header: 'Date Received', accessor: 'dateReceived' },
+ ], []);
- /** Array of items from all active queues to display in table. */
- "items": PropTypes.array.isRequired
-
-}
+ const tableInstance = () => useTable(
+ {
+ columns,
+ data,
+ defaultColumn: {
+ Filter: ({ column: { Header, setFilter } }) => {
+ return (
+ setFilter(event.target.value)}
+ />
+ );
+ }
+ }
+ },
+ useFilters, useFlexLayout, useSortBy
+ );
+ const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = tableInstance();
+
+ return (
+
+
+
+ {headerGroups.map(headerGroup => (
+
+ {headerGroup.headers.map(column => (
+
+
+
+
+ {column.render("Filter")}
+
+
+
+
+
+
+
+
+
+ ))}
+
+ ))}
+
+
+ {rows.map((row, i) => {
+ prepareRow(row);
+ return (
+
+ {row.cells.map(cell => (
+
+ {cell.render("Cell")}
+
+ ))}
+
+ );
+ })}
+
+
+
+ );
+};
+
+ItemTable.propTypes = {
+ /** Array of items from all active queues to display in table. */
+ "items": PropTypes.array.isRequi
+};
\ No newline at end of file
diff --git a/src/components/ItemTableFilter/ItemTableFilter.js b/src/components/ItemTableFilter/ItemTableFilter.js
new file mode 100644
index 0000000..cf03ea7
--- /dev/null
+++ b/src/components/ItemTableFilter/ItemTableFilter.js
@@ -0,0 +1,57 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { TextField, useTheme, makeStyles } from "@material-ui/core";
+import { yellow } from '@material-ui/core/colors';
+
+export default function ItemTableFilter({ label, onChange }) {
+ const theme = useTheme();
+ const useStyles = makeStyles({
+ root: {
+ '& label.Mui-focused': {
+ color: theme.palette.type === "light" ? "black" : "white",
+ },
+ '& .MuiOutlinedInput-root': {
+ '& fieldset': {
+ borderColor: theme.palette.type === "light" ? theme.palette.action.disabled : "white",
+ },
+ '&:hover fieldset': {
+ borderColor: theme.palette.type === "light" ? "black" : "white",
+ },
+ '&.Mui-focused fieldset': {
+ borderColor: theme.palette.type === "light" ? "black" : "white",
+ },
+ '&.Mui-focused label': {
+ borderColor: theme.palette.type === "light" ? "black" : "white",
+ },
+ },
+ },
+ });
+
+ const classes = useStyles();
+
+ return (
+ <>
+
+ >
+ );
+
+};
+
+ItemTableFilter.propTypes = {
+ /** The label that appears inside the search box. */
+ "label": PropTypes.string,
+ /** The callback function that sets a column's filter value. */
+ "onChange": PropTypes.func.isRequired
+};
+
+ItemTableFilter.defaultProps = {
+ "label": ""
+}
\ No newline at end of file
diff --git a/src/components/ItemTableFilter/ItemTableFilter.md b/src/components/ItemTableFilter/ItemTableFilter.md
new file mode 100644
index 0000000..d83faec
--- /dev/null
+++ b/src/components/ItemTableFilter/ItemTableFilter.md
@@ -0,0 +1,22 @@
+This ItemTableFilter double as a column header and entry box for filtering in a column. At its core, it is a input element of type search.
+
+```jsx
+import { Paper, makeStyles } from "@material-ui/core";
+import ItemTableFilter from "./ItemTableFilter";
+
+const useStyles = makeStyles({
+ "paper": {
+ width: "200px",
+ }
+});
+
+const classes = useStyles();
+
+
+ null} />
+
+```
+
+```jsx static
+ null} />
+```
\ No newline at end of file
diff --git a/src/components/ItemTableFilter/index.js b/src/components/ItemTableFilter/index.js
new file mode 100644
index 0000000..e97c772
--- /dev/null
+++ b/src/components/ItemTableFilter/index.js
@@ -0,0 +1 @@
+export { default } from "./ItemTableFilter";
\ No newline at end of file
diff --git a/src/components/ItemView/ItemView.js b/src/components/ItemView/ItemView.js
index dc0ba21..1a9eacf 100644
--- a/src/components/ItemView/ItemView.js
+++ b/src/components/ItemView/ItemView.js
@@ -1,7 +1,8 @@
import React from 'react';
import PropTypes from "prop-types";
-import { Paper, Typography, makeStyles } from '@material-ui/core';
+import { Paper, makeStyles } from '@material-ui/core';
import ItemMetadataView from "../ItemMetadataView/"
+import ItemBodyView from "../ItemBodyView";
export default function ItemView({ activeItem }){
@@ -15,14 +16,8 @@ export default function ItemView({ activeItem }){
return(
-
-
-
- {activeItem["content"] ? activeItem["content"].map(line => (
-
- {line}
-
- )): "" }
+
+
);
};
diff --git a/src/components/UserAvatar/UserAvatar.js b/src/components/UserAvatar/UserAvatar.js
new file mode 100644
index 0000000..9a56370
--- /dev/null
+++ b/src/components/UserAvatar/UserAvatar.js
@@ -0,0 +1,21 @@
+import React from "react";
+import PropTypes from "prop-types";
+import { Avatar } from "@material-ui/core";
+
+export default function UserAvatar({userName, userAlias}){
+
+ return(
+
+ {userName === "" ? null : userName.charAt(0)}
+
+ );
+};
+
+UserAvatar.propTypes = {
+ /** The name of the user. */
+ "userName": PropTypes.string
+};
+
+UserAvatar.defaultProps = {
+ "userName": ""
+};
\ No newline at end of file
diff --git a/src/components/UserAvatar/UserAvatar.md b/src/components/UserAvatar/UserAvatar.md
new file mode 100644
index 0000000..40c9a48
--- /dev/null
+++ b/src/components/UserAvatar/UserAvatar.md
@@ -0,0 +1,23 @@
+The UserAvatar displays a graphical representation of a person and is meant to be used in conjunction with other identifiers like names or emails.
+
+---
+
+The UserAvatar will the first letter of the `userName` prop.
+```jsx
+import UserAvatar from "./UserAvatar";
+
+```
+
+```jsx static
+
+```
+
+If no value, a null value, or an empty string is passed to the UserAvatar, it will fall back to a generic icon.
+```jsx
+import UserAvatar from "./UserAvatar";
+
+```
+
+```jsx static
+
+```
\ No newline at end of file
diff --git a/src/components/UserAvatar/index.js b/src/components/UserAvatar/index.js
new file mode 100644
index 0000000..3f9a167
--- /dev/null
+++ b/src/components/UserAvatar/index.js
@@ -0,0 +1,3 @@
+import UserAvatar from "./UserAvatar";
+
+export default UserAvatar;
\ No newline at end of file
diff --git a/src/theme.js b/src/theme.js
index 37236ff..459372e 100644
--- a/src/theme.js
+++ b/src/theme.js
@@ -1,3 +1,4 @@
+import { cyan, deepOrange, deepPurple, lightGreen, lightBlue, teal, purple } from '@material-ui/core/colors';
import { createMuiTheme } from '@material-ui/core/styles'
/**
@@ -8,12 +9,22 @@ import { createMuiTheme } from '@material-ui/core/styles'
* @param {boolean} [darkMode=false] Whether theme should be dark or not.
* @returns {Theme} MUI Theme.
*/
-export default function theme(darkMode=false){
+export default function theme(darkMode = false) {
return (
createMuiTheme({
"palette": {
+ primary: deepPurple,
+
+ secondary: {
+ main: teal[200],
+ },
+
"type": darkMode ? "dark" : "light",
- }
+
+ "edit": {
+ main: "#ffe56433",
+ }
+ },
})
);
}
\ No newline at end of file