From 975e5ea734773219c7522912aaa3766ea044e748 Mon Sep 17 00:00:00 2001 From: John Darragh Date: Mon, 25 Nov 2024 15:24:17 -0800 Subject: [PATCH] Implement My Project multi-column sort, session persistence (#1982) --- .../src/components/Button/TertiaryButton.jsx | 14 +- .../ProjectTableColumnHeader.jsx | 2 +- .../src/components/Projects/ProjectsPage.jsx | 191 ++++++++---------- client/src/hooks/useSessionStorage.js | 48 +++++ 4 files changed, 141 insertions(+), 114 deletions(-) create mode 100644 client/src/hooks/useSessionStorage.js diff --git a/client/src/components/Button/TertiaryButton.jsx b/client/src/components/Button/TertiaryButton.jsx index b1b7978c..80c4c53a 100644 --- a/client/src/components/Button/TertiaryButton.jsx +++ b/client/src/components/Button/TertiaryButton.jsx @@ -3,7 +3,13 @@ import PropTypes from "prop-types"; import Button from "./Button"; import { MdPrint } from "react-icons/md"; -const TertiaryButton = ({ id, onClick, isDisabled, isDisplayed, children }) => { +const TertiaryButton = ({ + id, + onClick, + isDisabled, + isDisplayed = false, + children +}) => { return ( - ) : null} */} @@ -972,11 +940,15 @@ const ProjectsPage = ({ contentContainerRef }) => { projects={projects} filter={filter} header={header} - criteria={criteria} - setCriteria={setCriteria} + criteria={filterCriteria} + setCriteria={setFilter} setSort={setSort} - order={order} - orderBy={orderBy} + orderBy={ + sortCriteria[sortCriteria.length - 1].field + } + order={ + sortCriteria[sortCriteria.length - 1].direction + } setCheckedProjectIds={setCheckedProjectIds} setSelectAllChecked={setSelectAllChecked} /> @@ -1032,7 +1004,7 @@ const ProjectsPage = ({ contentContainerRef }) => { maxNumOfVisiblePages={5} /> handlePerPageChange(e.target.value)} name="perPage" @@ -1040,6 +1012,7 @@ const ProjectsPage = ({ contentContainerRef }) => { /> Items per page +
{JSON.stringify(sortCriteria, null, 2)}
{(selectedProject || checkedProjectsStatusData) && ( <> diff --git a/client/src/hooks/useSessionStorage.js b/client/src/hooks/useSessionStorage.js new file mode 100644 index 00000000..e34ddb05 --- /dev/null +++ b/client/src/hooks/useSessionStorage.js @@ -0,0 +1,48 @@ +import { useState } from "react"; + +// from https://usehooks.com/useSessionStorage/ +// Usage: +// const [name, setName] = useSessionStorage('name', 'Bob'); +// searches sessionStorage for 'name' value or sets 'name=Bob' + +const useSessionStorage = (key, initialValue) => { + // State to store our value + // Pass initial state function to useState so logic is only executed once + const [storedValue, setStoredValue] = useState(() => { + try { + // Get from session storage by key + const item = window.sessionStorage.getItem(key); + // if no item exists, set item to initialValue + if (item === null) { + window.sessionStorage.setItem(key, JSON.stringify(initialValue)); + } + // Parse stored json or if none return initialValue + return item ? JSON.parse(item) : initialValue; + } catch (error) { + // If error also return initialValue + console.error(error); + return initialValue; + } + }); + + // Return a wrapped version of useState's setter function that ... + // ... persists the new value to sessionStorage. + const setValue = value => { + try { + // Allow value to be a function so we have same API as useState + const valueToStore = + value instanceof Function ? value(storedValue) : value; + // Save state + setStoredValue(valueToStore); + // Save to session storage + window.sessionStorage.setItem(key, JSON.stringify(valueToStore)); + } catch (error) { + // A more advanced implementation would handle the error case + console.error("error in session storage", error); + } + }; + + return [storedValue, setValue]; +}; + +export default useSessionStorage;