Skip to content

Commit

Permalink
Merge pull request #126 from ECN/improve-QueueSelector
Browse files Browse the repository at this point in the history
Improve queue selector
  • Loading branch information
campb303 authored Nov 20, 2020
2 parents 27bca3e + f8fa092 commit 4ec7d5e
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 62 deletions.
35 changes: 13 additions & 22 deletions src/components/AppView/AppView.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ export default function AppView({ setDarkMode }){
const [queues, setQueues] = useState([]);
const [items, setItems] = useState([]);
const [selectedQueues, setSelectedQueues] = useState([]);
const [queueCounts, setQueueCounts] = useState([]);
const [queueSelectorOpen, setQueueSelectorOpen] = useState(false);

const access_token = useToken();

useEffect( _ => {
async function getQueues(){
if (access_token === null){
return
return undefined
}

if (queueSelectorOpen){
return undefined
}

if (selectedQueues.length > 0){
Expand All @@ -45,7 +49,7 @@ export default function AppView({ setDarkMode }){
}
}
getQueues();
}, [selectedQueues, access_token]);
}, [selectedQueues, access_token, queueSelectorOpen]);

useEffect( _ => {
let tempItems = [];
Expand All @@ -55,24 +59,6 @@ export default function AppView({ setDarkMode }){
setItems(tempItems);
}, [queues]);

useEffect( _ => {
async function getQueueCounts(){
if (access_token === null){
return
}

let myHeaders = new Headers();
myHeaders.append("Authorization", `Bearer ${access_token}`);
let requestOptions = { headers: myHeaders };

const apiResponse = await fetch(`/api/get_queues`, requestOptions);
const queueCountJson = await apiResponse.json();
setQueueCounts(queueCountJson);
};
getQueueCounts();
return _ => setQueueCounts([]);
}, [selectedQueues, access_token]);

const theme = useTheme();
const transitionWidth = theme.transitions.create(["width"], {
duration: theme.transitions.duration.enteringScreen,
Expand Down Expand Up @@ -111,7 +97,12 @@ export default function AppView({ setDarkMode }){

<Box className={classes.leftCol}>
<ItemTableAppBar title="webqueue2" setDarkMode={setDarkMode} />
<QueueSelector queues={queueCounts} selectedQueues={selectedQueues} setSelectedQueues={setSelectedQueues} />
<QueueSelector
queueSelectorOpen={queueSelectorOpen}
setQueueSelectorOpen={setQueueSelectorOpen}
selectedQueues={selectedQueues}
setSelectedQueues={setSelectedQueues}
/>
<ItemTable data={items} rowCanBeSelected={sidebarOpen}/>
</Box>

Expand Down
147 changes: 107 additions & 40 deletions src/components/QueueSelector/QueueSelector.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,124 @@
import React from "react";
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { TextField, Checkbox} from "@material-ui/core";
import { TextField, Checkbox, InputAdornment, Box, useTheme } from "@material-ui/core";
import { Autocomplete } from "@material-ui/lab";
import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
import CheckBoxIcon from '@material-ui/icons/CheckBox';
import CircularProgress from '@material-ui/core/CircularProgress';
import { useToken } from "../AuthProvider/";

export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen, selectedQueues, setSelectedQueues }) {
const open = queueSelectorOpen;
const setOpen = setQueueSelectorOpen;
const [queueCounts, setQueueCounts] = useState([]);
const access_token = useToken();
const loading = open && queueCounts.length === 0;

useEffect( _ => {
const getQueueCounts = async _ => {
if (access_token === null){
return undefined
}

let myHeaders = new Headers();
myHeaders.append("Authorization", `Bearer ${access_token}`);
let requestOptions = { headers: myHeaders };

const apiResponse = await fetch(`/api/get_queues`, requestOptions);
const queueCountJson = await apiResponse.json();
setQueueCounts(queueCountJson);
};

if (loading) {
getQueueCounts();
}

}, [loading, access_token]);

useEffect(() => {
if (!open) {
setQueueCounts([]);
}
}, [open]);

const theme = useTheme();

const handleChange = (event, newValue) => {
setSelectedQueues(newValue)
};

const optionRenderer = (option, { selected }) => (
<>
<Checkbox
icon={<CheckBoxOutlineBlankIcon fontSize="small" />}
checkedIcon={<CheckBoxIcon fontSize="small" />}
style={{ marginRight: 8 }}
checked={selected}
/>
{`${option.name} (${option.number_of_items})`}
</>
);

export default function QueueSelector({ queues, selectedQueues, setSelectedQueues }) {
return(
<Autocomplete
options={queues}
onChange={(event, newValue) => {
setSelectedQueues(newValue)
}}
renderInput={(params) => {
return(
<Box margin={`${theme.spacing(1)}px`}>
<Autocomplete
renderInput={(params) => (
<TextField
{...params}
placeholder={selectedQueues.length === 0 ? "Click to select queues." : ""}
variant="outlined"
placeholder={selectedQueues.length === 0 ? "Click or type to select queues." : ""}
autoFocus
// The MUI Autocomplete component uses the InputProps.startAdornment to store chips fpr multi-selection.
// Using InputProps.startAdornment directly will override those chips. Code below is a workaround.
// See: https://github.com/mui-org/material-ui/issues/19479
InputProps={{
...params.InputProps,
startAdornment: (
<>
<InputAdornment position="start">
Active Queues:
</InputAdornment>
{params.InputProps.startAdornment}
</>
),
endAdornment: (
<>
{loading ? <CircularProgress color="inherit" size={20} /> : null}
{params.InputProps.endAdornment}
</>
)
}}
/>
);
}}
getOptionLabel={(option) => `${option.name} (${option.number_of_items})`}
renderOption={(option, { selected }) => (
<>
<Checkbox
icon={<CheckBoxOutlineBlankIcon fontSize="small" />}
checkedIcon={<CheckBoxIcon fontSize="small" />}
style={{ marginRight: 8 }}
checked={selected}
/>
{`${option.name} (${option.number_of_items})`}
</>
)}
getOptionSelected={ (option, value) => option.name === value.name }
disableCloseOnSelect
autoComplete
disableListWrap
openOnFocus
fullWidth
multiple
/>
)}

options={queueCounts}
value={selectedQueues}
onChange={handleChange}
getOptionLabel={(option) => `${option.name} (${option.number_of_items})`}
renderOption={optionRenderer}
getOptionSelected={ (option, value) => option.name === value.name }
size="small"
open={open}
onOpen={_ => setOpen(true)}
onClose={_ => setOpen(false)}
loading={true}
disableCloseOnSelect
disableListWrap
fullWidth
multiple
autoHighlight
/>
</Box>
);
};

QueueSelector.propTypes = {
/** An array of objects with keys of name and number of items for each queue. */
"queues": PropTypes.array,
/** State variable to manage open status. */
"queueSelectorOpen": PropTypes.bool.isRequired,
/** Function to update state variable that manages open status. */
"setQueueSelectorOpen": PropTypes.func.isRequired,
/** State variable to manage selected queues. */
"selectedQueues": PropTypes.array.isRequired,
/** Function to update state variable that manages selected queues. */
"setSelectedQueues": PropTypes.func.isRequired
};

QueueSelector.defaultProps = {
"queues": []
"setSelectedQueues": PropTypes.func.isRequired,
};

0 comments on commit 4ec7d5e

Please sign in to comment.