From f14c485e6adf552ea9293293e57d973f06847387 Mon Sep 17 00:00:00 2001 From: Elad Kaplan Date: Wed, 26 Aug 2020 21:24:29 +0300 Subject: [PATCH 1/2] support direct table filter link --- ui/src/Hooks/TableHooks.js | 28 +++++++++++++ ui/src/components/Dashboard/FilterBar.js | 2 +- ui/src/components/Dashboard/Index.js | 4 +- ui/src/components/Dashboard/ResourceTable.js | 43 +++++++++++++++++--- ui/src/utils/History.js | 9 +++- 5 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 ui/src/Hooks/TableHooks.js diff --git a/ui/src/Hooks/TableHooks.js b/ui/src/Hooks/TableHooks.js new file mode 100644 index 00000000..c532a415 --- /dev/null +++ b/ui/src/Hooks/TableHooks.js @@ -0,0 +1,28 @@ +import { useState, useEffect } from "react"; + +export const useTableFilters = () => { + const [state, setState] = useState({}); + + // filter table was changed when the state (table properties) was changed + useEffect(() => { + const searchParams = new window.URLSearchParams(window.location.search); + Object.keys(state).map((key) => { + searchParams.set(key, state[key]); + }); + + // We don't want keep table action in browser back/forward history + window.history.replaceState( + null, + null, + decodeURIComponent(`?${searchParams.toString()}`) + ); + }, [state]); + + const handleChange = (filters = []) => { + const newFilters = {}; + filters.forEach((filter) => (newFilters[filter.key] = filter.value)); + Object.assign(state, newFilters); + setState({ ...state }); + }; + return [state, handleChange]; +}; diff --git a/ui/src/components/Dashboard/FilterBar.js b/ui/src/components/Dashboard/FilterBar.js index b70882c5..bca3271e 100644 --- a/ui/src/components/Dashboard/FilterBar.js +++ b/ui/src/components/Dashboard/FilterBar.js @@ -150,7 +150,7 @@ const FilterBar = ({ } }); - updateFilters(filters); + setFilters(filters); if (resource) { setResource(resource); } diff --git a/ui/src/components/Dashboard/Index.js b/ui/src/components/Dashboard/Index.js index b6b6f3c4..a137f8e9 100644 --- a/ui/src/components/Dashboard/Index.js +++ b/ui/src/components/Dashboard/Index.js @@ -41,7 +41,6 @@ const DashboardIndex = ({ filters, }) => { const classes = useStyles(); - /** * Will clear selected filter and show main page */ @@ -73,8 +72,7 @@ const DashboardIndex = ({ - {!currentResource && } - {currentResource && } + {currentResource ? : } ); }; diff --git a/ui/src/components/Dashboard/ResourceTable.js b/ui/src/components/Dashboard/ResourceTable.js index 2b89ed7a..3068f1d1 100644 --- a/ui/src/components/Dashboard/ResourceTable.js +++ b/ui/src/components/Dashboard/ResourceTable.js @@ -6,6 +6,8 @@ import MUIDataTable from "mui-datatables"; import TextUtils from "utils/Text"; import TagsDialog from "../Dialog/Tags"; import ReportProblemIcon from "@material-ui/icons/ReportProblem"; +import { getHistory } from "../../utils/History"; +import { useTableFilters } from "../../Hooks/TableHooks"; import { makeStyles, @@ -54,13 +56,24 @@ const ResourceTable = ({ const [headers, setHeaders] = useState([]); const [errorMessage, setErrorMessage] = useState(false); const [hasError, setHasError] = useState(false); - const classes = useStyles(); + // eslint-disable-next-line + const [tableFilters, setTableFilters] = useTableFilters({}); + const [tableOptions, setTableOptions] = useState({}); - const tableOptions = { - selectableRows: "none", - responsive: "standard", - }; + // setting table configuration on first load + useEffect(() => { + setTableOptions({ + page: parseInt(getHistory("page", 0)), + searchText: getHistory("search", ""), + sortOrder: { + name: getHistory("sortColumn", ""), + direction: getHistory("direction", "desc"), + }, + selectableRows: "none", + responsive: "standard", + }); + }, []); /** * format table cell by type @@ -191,6 +204,26 @@ const ResourceTable = ({ data={currentResourceData} columns={headers} options={Object.assign(tableOptions, { + onSearchChange: (searchText) => { + setTableFilters([ + { + key: "search", + value: searchText ? searchText : "", + }, + ]); + }, + onColumnSortChange: (changedColumn, direction) => { + setTableFilters([ + { key: "sortColumn", value: changedColumn }, + { key: "direction", value: direction }, + ]); + }, + onChangePage: (currentPage) => { + setTableFilters([{ key: "page", value: currentPage }]); + }, + onChangeRowsPerPage: (numberOfRows) => { + setTableFilters([{ key: "rows", value: numberOfRows }]); + }, downloadOptions: { filename: `${currentResource}.csv`, }, diff --git a/ui/src/utils/History.js b/ui/src/utils/History.js index 1a64089c..3d0f3221 100644 --- a/ui/src/utils/History.js +++ b/ui/src/utils/History.js @@ -62,10 +62,15 @@ export const setHistory = (historyParams = {}) => { /** * * @param {string} query params name from url + * @param {any} default return default value in case the query not exists * @returns {string} Param value from url */ -export const getHistory = (query) => { +export const getHistory = (query, defaultReturn = null) => { const searchParams = new window.URLSearchParams(window.location.search); const searchQuery = searchParams.get(query); - return searchQuery; + if (searchQuery) { + return searchQuery; + } else { + return defaultReturn; + } }; From c83cbefdc9b0fb893f72c8ca7ad8e8f8dcced511 Mon Sep 17 00:00:00 2001 From: Elad Kaplan Date: Tue, 1 Sep 2020 10:40:40 +0300 Subject: [PATCH 2/2] review changes --- ui/src/Hooks/TableHooks.js | 2 +- ui/src/components/Dashboard/ResourceTable.js | 3 +-- ui/src/utils/History.js | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/src/Hooks/TableHooks.js b/ui/src/Hooks/TableHooks.js index c532a415..318945a2 100644 --- a/ui/src/Hooks/TableHooks.js +++ b/ui/src/Hooks/TableHooks.js @@ -24,5 +24,5 @@ export const useTableFilters = () => { Object.assign(state, newFilters); setState({ ...state }); }; - return [state, handleChange]; + return [handleChange]; }; diff --git a/ui/src/components/Dashboard/ResourceTable.js b/ui/src/components/Dashboard/ResourceTable.js index 3068f1d1..74abdfb1 100644 --- a/ui/src/components/Dashboard/ResourceTable.js +++ b/ui/src/components/Dashboard/ResourceTable.js @@ -57,8 +57,7 @@ const ResourceTable = ({ const [errorMessage, setErrorMessage] = useState(false); const [hasError, setHasError] = useState(false); const classes = useStyles(); - // eslint-disable-next-line - const [tableFilters, setTableFilters] = useTableFilters({}); + const [setTableFilters] = useTableFilters({}); const [tableOptions, setTableOptions] = useState({}); // setting table configuration on first load diff --git a/ui/src/utils/History.js b/ui/src/utils/History.js index 3d0f3221..9f57b85e 100644 --- a/ui/src/utils/History.js +++ b/ui/src/utils/History.js @@ -62,15 +62,15 @@ export const setHistory = (historyParams = {}) => { /** * * @param {string} query params name from url - * @param {any} default return default value in case the query not exists + * @param {any} defaultValue return default value in case the query not exists * @returns {string} Param value from url */ -export const getHistory = (query, defaultReturn = null) => { +export const getHistory = (query, defaultValue = null) => { const searchParams = new window.URLSearchParams(window.location.search); const searchQuery = searchParams.get(query); if (searchQuery) { return searchQuery; } else { - return defaultReturn; + return defaultValue; } };