Skip to content

Commit

Permalink
Add support for storing active queues across page reloads
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Campbell committed Dec 1, 2020
1 parent 1e06378 commit 77c40a4
Showing 1 changed file with 76 additions and 29 deletions.
105 changes: 76 additions & 29 deletions src/components/QueueSelector/QueueSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,73 @@ 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 { useCookies } from "react-cookie";
import { useToken } from "../AuthProvider/";

export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen, selectedQueues, setSelectedQueues }) {
const open = queueSelectorOpen;
const setOpen = setQueueSelectorOpen;
/**
* Get queue names and number of items.
* @param {String} access_token A valid API access token.
* @returns Array of objects containing queue names and item counts.
*/
const getQueueCounts = async (access_token) => {
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();

return queueCountJson;
};

export default function QueueSelector({ open, setOpen, value, setValue }) {
const [queueCounts, setQueueCounts] = useState([]);
const [isFirstRender, setIsFirstRender] = useState(true);
const access_token = useToken();
const loading = open && queueCounts.length === 0;

// Get queue counts if QueueSelector is open
const [cookies, setCookie] = useCookies(["active-queues"]);
const activeQueues = cookies['active-queues'] !== undefined ? cookies['active-queues'].split(',') : [];

const theme = useTheme();

// Prepopulate Active Queues from Cookies
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 (access_token === null){
return undefined;
}

if (loading) {
getQueueCounts();
if (isFirstRender) {
( async _ => {
// Get queue counts
let queueCountsJson = await getQueueCounts(access_token);

// Find queue count info for queue names in active queues
let activeQueuesInfo = activeQueues.map((queueName) => (
queueCountsJson.find( ({ name }) => queueName === name )
));

// Filter undefined values
activeQueuesInfo = activeQueuesInfo.filter( (entry) => entry !== undefined);

setValue(activeQueuesInfo);
setIsFirstRender(false);
})();
}
}, []);

// Get queue counts if QueueSelector is open
useEffect( _ => {
(async _ => {
if (loading) {
let queueCountsJson = await getQueueCounts(access_token);
setQueueCounts(queueCountsJson);
}
})()
}, [loading, access_token]);

// Delete queue counts if QueueSelector is closed
Expand All @@ -43,10 +81,20 @@ export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen,
}
}, [open]);

const theme = useTheme();

const handleChange = (event, newValue) => {
setSelectedQueues(newValue)
setValue(newValue)

// Set active-queues cookie to csv of selected queue names
const activeQueueOptions = {
path: "/",
expires: (_ => {
let expiration_date = new Date();
expiration_date.setDate(expiration_date.getDate() + 365);
return expiration_date;
})()
};
const activeQueues = newValue.map( (value) => value.name).join(',');
setCookie("active-queues", activeQueues, activeQueueOptions);
};

// Function to render checkboxes in dropdown
Expand All @@ -71,7 +119,7 @@ export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen,
<TextField
{...params}
variant="outlined"
placeholder={selectedQueues.length === 0 ? "Click or type to select queues." : ""}
placeholder={value.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.
Expand All @@ -95,9 +143,8 @@ export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen,
}}
/>
)}

options={queueCounts}
value={selectedQueues}
value={value}
onChange={handleChange}
getOptionLabel={(option) => `${option.name} (${option.number_of_items})`}
renderOption={optionRenderer}
Expand All @@ -119,11 +166,11 @@ export default function QueueSelector({ queueSelectorOpen, setQueueSelectorOpen,

QueueSelector.propTypes = {
/** State variable to manage open status. */
"queueSelectorOpen": PropTypes.bool.isRequired,
"open": PropTypes.bool.isRequired,
/** Function to update state variable that manages open status. */
"setQueueSelectorOpen": PropTypes.func.isRequired,
"setOpen": PropTypes.func.isRequired,
/** State variable to manage selected queues. */
"selectedQueues": PropTypes.array.isRequired,
"value": PropTypes.array.isRequired,
/** Function to update state variable that manages selected queues. */
"setSelectedQueues": PropTypes.func.isRequired,
"setValue": PropTypes.func.isRequired,
};

0 comments on commit 77c40a4

Please sign in to comment.