Skip to content

Commit

Permalink
Merge pull request #66 from ECN/feature-ItemRouting
Browse files Browse the repository at this point in the history
Feature item routing
  • Loading branch information
campb303 authored Oct 19, 2020
2 parents 1244ad3 + a021813 commit c0c2f70
Show file tree
Hide file tree
Showing 12 changed files with 2,489 additions and 1,518 deletions.
3,805 changes: 2,357 additions & 1,448 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"material-table": "^1.63.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1"
},
"scripts": {
Expand Down
65 changes: 55 additions & 10 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import { Route } from "react-router-dom";
import clsx from "clsx";
import { ThemeProvider } from "@material-ui/core/styles";
import webqueueTheme from "./theme";
import { Box, makeStyles } from "@material-ui/core";
import ItemTableAppBar from "./components/ItemTableAppBar/";
import ItemTable from "./components/ItemTable/";
import ItemViewAppBar from "./components/ItemViewAppBar/";
import ItemView from "./components/ItemView/";
import clsx from "clsx";

const testItem = {"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 <campb303@purdue.edu>"}, {"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 <campb303@purdue.edu>\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"}
const testItem = { "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 <campb303@purdue.edu>" }, { "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 <campb303@purdue.edu>\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" }

function App(){
function App() {
const [darkMode, setDarkMode] = useState(false);
const [activeItem, setActiveItem] = useState(testItem);
const [sidebarOpen, setSidebarOpen] = useState(true);
const [sidebarOpen, setSidebarOpen] = useState(false);

const theme = webqueueTheme(darkMode);

const [itemQueue, setItemQueue] = useState([])

useEffect(() => {
fetch("/api/ce").then(res => res.json()).then(queue => {
setItemQueue(queue.items)
})
}, [])

const transitionWidth = theme.transitions.create(["width"], {
duration: theme.transitions.duration.enteringScreen,
easing: theme.transitions.easing.easeInOut
Expand Down Expand Up @@ -52,19 +61,55 @@ function App(){
const classes = useStyles();

return (

<ThemeProvider theme={theme}>
<Box display="flex">

<Box className={classes.leftCol}>
<ItemTableAppBar title="webqueue2" darkMode={darkMode} setDarkMode={setDarkMode} theme={theme}/>
<ItemTable setActiveItem={setActiveItem} setSidebarOpen={setSidebarOpen}/>
<ItemTableAppBar title="webqueue2" setDarkMode={setDarkMode} />
<ItemTable items={itemQueue} />
</Box>

<Box className={clsx(classes.rightCol, sidebarOpen && classes.rightColShift)}>
<ItemViewAppBar title={activeItem["queue"] + " " + activeItem["number"]} setSidebarOpen={setSidebarOpen} />
<ItemView activeItem={activeItem} setActiveItem={setActiveItem} setSidebarOpen={setSidebarOpen}/>
{itemQueue.length === 0 ? null :
<Route
path="/:queue/:number"
render={({ match }) => {

/**
* Returns true if an item matches the URL parameters.
* @param item {Object} The item to compare.
* @param match {Object} The match parameters.
* @returns {boolean}
*/
function itemMatchesURL(item, match){
let queueMatches = item.queue === match.params.queue;
let numberMatches = item.number === match.params.number;
return queueMatches && numberMatches;
}

let item = itemQueue.find( item => itemMatchesURL(item, match) );

if (item === undefined) {
setSidebarOpen(true);
return "Item doesn't exist :(";
}

setActiveItem(item);
setSidebarOpen(true);

return (
<>
<ItemViewAppBar title={activeItem["queue"] + " " + activeItem["number"]} setSidebarOpen={setSidebarOpen} />
<ItemView activeItem={activeItem} />
</>
);
}}
/>}
</Box>
</Box>
</ThemeProvider>
);
}

export default App;
export default App;
31 changes: 13 additions & 18 deletions src/components/ItemTable/ItemTable.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { useState, useEffect } from 'react';
import React from 'react';
import { useHistory } from "react-router-dom";
import PropTypes from 'prop-types'
import MaterialTable from "material-table";

export default function ItemTable({ setActiveItem, setSidebarOpen }) {

export default function ItemTable({ items }) {

const columns = [
{ title: 'Queue', field: 'queue', filterPlaceholder: "Ex: \"ME\"" },
Expand All @@ -18,14 +20,6 @@ export default function ItemTable({ setActiveItem, setSidebarOpen }) {
{ title: 'Date Received', field: 'dateReceived', filterPlaceholder: "Ex: \"07-20-20 03:32 AM\"" },
]

const [data, setData] = useState([])

useEffect(() => {
fetch("/api/ce").then(res => res.json()).then(queue => {
setData(queue.items)
})
}, [])

const options = {
"filtering": true,
"paging": false,
Expand All @@ -34,23 +28,24 @@ export default function ItemTable({ setActiveItem, setSidebarOpen }) {
"padding": "dense",
}

const history = useHistory();

return (
<MaterialTable
columns={columns}
data={data}
data={items}
title={"Demo Table"}
options={options}
onRowClick={(event, rowData) => {
setActiveItem(rowData);
setSidebarOpen(true);
onRowClick={(_event, rowData) => {
history.push(`/${rowData.queue}/${rowData.number}`);
}}
/>
);
}

ItemTable.propTypes = {
/** Function to set active item on row click. */
"setActiveItem": PropTypes.func.isRequired,
/** Function to toggle sidebar on row click. */
"setSidebarOpen": PropTypes.func.isRequired

/** Array of items from all active queues to display in table. */
"items": PropTypes.array.isRequired

}
18 changes: 14 additions & 4 deletions src/components/ItemTable/ItemTable.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
The ItemTable is the primary view for webqueue2. It displays item metadata for items of selected queues and allows for filtering by field and opening an item by clicking. By default, it is pre-configured to fetch data from the webqueue2 API. It is to be used with the [ItemTableAppBar](/#/Components/ItemTableAppBar).
The ItemTable is the primary view for webqueue2. It displays item metadata for items of selected queues and allows for filtering by field and opening an item by clicking. Items are passed in as a required parameter. It is to be used with the [ItemTableAppBar](/#/Components/ItemTableAppBar).

It is based on [material-table](https://material-table.com/).
```jsx
import React, { useState } from "react";
import React, { useState, useEffect } from "react";

const [activeItem, setActiveItem] = useState({});
const [sidebarOpen, setSidebarOpen] = useState({});
const [itemQueue, setItemQueue] = useState([]);

<ItemTable setActiveItem={activeItem} setSidebarOpen={setSidebarOpen} />
const testItems = [{"queue": "ce", "number": 9, "lastUpdated": "09-11-20 12:14 PM", "isLocked": false, "userEmail": "lslusher@purdue.edu", "userName": "Slusher, Laura M", "userAlias": "lslusher", "assignedTo": "bekuma", "subject": "RE: New laptop", "status": "waiting on reply/time to call", "priority": "deploy", "department": "che", "building": "frny", "dateReceived": "2020-03-12T18:07:27+0000"}, {"queue": "ce", "number": 42, "lastUpdated": "09-11-20 12:14 PM", "isLocked": false, "userEmail": "feng293@purdue.edu", "userName": "", "userAlias": "feng293", "assignedTo": "schmid22", "subject": "Upgrade system and Abaqus", "status": "", "priority": "", "department": "", "building": "", "dateReceived": "2020-05-14T10:21:32-0400"}, {"queue": "ce", "number": 51, "lastUpdated": "09-11-20 12:14 PM", "isLocked": false, "userEmail": "jclauso@purdue.edu", "userName": "", "userAlias": "jclauso", "assignedTo": "schmid22", "subject": "ECN privileges for future grad student", "status": "Waiting for reply", "priority": "", "department": "", "building": "", "dateReceived": "2020-05-14T15:03:07-0400"}];


useEffect(() => {

setItemQueue(testItems)

}, []);

<ItemTable items={itemQueue} />
```

```jsx static
<ItemTable setActiveItem={{}} setSidebarOpen={{}} />
<ItemTable items={someArray} />
```
22 changes: 10 additions & 12 deletions src/components/ItemTableAppBar/ItemTableAppBar.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from "react";
import PropTypes from 'prop-types';
import {makeStyles, Tooltip, Typography, AppBar, Toolbar, IconButton, Zoom} from "@material-ui/core"
import {makeStyles, Tooltip, Typography, AppBar, Toolbar, IconButton, Zoom, useTheme} from "@material-ui/core"
import DarkModeIcon from '@material-ui/icons/Brightness4';
import LightModeIcon from '@material-ui/icons/Brightness7';


export default function ItemTableAppBar(props){
export default function ItemTableAppBar({ title, setDarkMode }){

const theme = useTheme();
const useStyles = makeStyles((theme) => ({
menuButton: {
marginLeft: theme.spacing(2),
Expand All @@ -14,26 +16,26 @@ export default function ItemTableAppBar(props){
flexGrow: "1"
},
}));
const classes = useStyles(theme);
const darkMode = theme.palette.type === "dark"

const classes = useStyles(props.theme);

const toggleDarkMode = () => props.setDarkMode(!props.darkMode);
const toggleDarkMode = () => setDarkMode(!darkMode);

return(
<>
<AppBar position="sticky" elevation={2} >
<Toolbar variant="dense">
<Typography variant="h6" className={classes.title}>
{props.title}
{title}
</Typography>

<Tooltip title={"Turn " + (props.darkMode ? "off" : "on") + " dark mode"}
<Tooltip title={"Turn " + (darkMode ? "off" : "on") + " dark mode"}
arrow
onClick={toggleDarkMode}
TransitionComponent={Zoom}
>
<IconButton color="inherit">
{props.darkMode ? <DarkModeIcon /> : <LightModeIcon />}
{darkMode ? <DarkModeIcon /> : <LightModeIcon />}
</IconButton>
</Tooltip>
</Toolbar>
Expand All @@ -47,10 +49,6 @@ ItemTableAppBar.propTypes = {
"title": PropTypes.string,
/** Function to toggle darkMode. */
"setDarkMode": PropTypes.func.isRequired,
/** State variable for darkMode */
"darkMode": PropTypes.bool.isRequired,
/** The webqueue2 MUI theme. */
"theme": PropTypes.object.isRequired
};

ItemTableAppBar.defaultProps = {
Expand Down
4 changes: 2 additions & 2 deletions src/components/ItemTableAppBar/ItemTableAppBar.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const [darkMode, setDarkMode] = useState(false);

const theme = webqueue2Theme(darkMode);

<ItemTableAppBar title="webqueue2" darkMode={darkMode} setDarkMode={setDarkMode} theme={theme} />
<ItemTableAppBar title="webqueue2" darkMode={darkMode} setDarkMode={setDarkMode} />
```

```jsx static
<ItemTableAppBar title="webqueue2" darkMode={darkMode} setDarkMode={setDarkMode} theme={theme} />
<ItemTableAppBar title="webqueue2" darkMode={darkMode} setDarkMode={setDarkMode} />
```
6 changes: 3 additions & 3 deletions src/components/ItemView/ItemView.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { Paper, Typography, makeStyles } from '@material-ui/core';
import ItemMetadataView from "../ItemMetadataView/"

export default function ItemView(props){
export default function ItemView({ activeItem }){

const useStyles = makeStyles((theme) => ({
"paperPadding": {
Expand All @@ -16,9 +16,9 @@ export default function ItemView(props){
return(
<Paper classes={{root: classes.paperPadding}} square>

<ItemMetadataView item={props.activeItem} />
<ItemMetadataView item={activeItem} />

{props.activeItem["content"] ? props.activeItem["content"].map(line => (
{activeItem["content"] ? activeItem["content"].map(line => (
<Typography variant="body1" paragraph>
{line}
</Typography>
Expand Down
Loading

0 comments on commit c0c2f70

Please sign in to comment.