From 151d69632ed4f6ff99dc60691ceeae147af1f14f Mon Sep 17 00:00:00 2001 From: Infinite Date: Sun, 16 Feb 2020 11:56:53 +0100 Subject: [PATCH] Refactor list hook filter storag --- ui/v2.5/src/hooks/ListHook.tsx | 105 ++++++++++++++--------- ui/v2.5/src/models/list-filter/filter.ts | 8 +- ui/v2.5/src/utils/table.tsx | 2 +- 3 files changed, 70 insertions(+), 45 deletions(-) diff --git a/ui/v2.5/src/hooks/ListHook.tsx b/ui/v2.5/src/hooks/ListHook.tsx index 8edf7dd60..ee9173796 100644 --- a/ui/v2.5/src/hooks/ListHook.tsx +++ b/ui/v2.5/src/hooks/ListHook.tsx @@ -1,6 +1,6 @@ import _ from "lodash"; import queryString from "query-string"; -import React, { useState, useEffect, useRef } from "react"; +import React, { useCallback, useState, useEffect } from "react"; import { ApolloError } from "apollo-client"; import { useHistory, useLocation } from "react-router-dom"; import { @@ -79,7 +79,7 @@ const useList = ( options: IListHookOptions & IQuery ): IListHookData => { const [interfaceState, setInterfaceState] = useInterfaceLocalForage(); - const forageInitialised = useRef(false); + const [forageInitialised, setForageInitialised] = useState(false); const history = useHistory(); const location = useLocation(); const [filter, setFilter] = useState( @@ -96,39 +96,72 @@ const useList = ( const totalCount = options.getCount(result); const items = options.getData(result); + const updateInterfaceConfig = useCallback((filter: ListFilterModel) => { + setInterfaceState(config => { + const data = { ...config } as IInterfaceConfig; + data.queries = { + [options.filterMode]: { + filter: filter.makeQueryParameters(), + itemsPerPage: filter.itemsPerPage, + currentPage: filter.currentPage + } + }; + return data; + }); + }, [location.search, options.filterMode, setInterfaceState]); + useEffect(() => { - if (!forageInitialised.current && !interfaceState.loading) { - forageInitialised.current = true; + if(interfaceState.loading) + return; + if(!forageInitialised) + setForageInitialised(true); - // Don't use query parameters for sub-components - if (options.subComponent) return; - // Don't read localForage if page already had query parameters - if (history.location.search) return; + // Don't use query parameters for sub-components + if (options.subComponent) return; - const queryData = interfaceState.data?.queries?.[options.filterMode]; - if (!queryData) return; + const storedQuery = interfaceState.data?.queries?.[options.filterMode]; + if (!storedQuery) return; - const newFilter = new ListFilterModel( - options.filterMode, - queryString.parse(queryData.filter) - ); - newFilter.currentPage = queryData.currentPage; - newFilter.itemsPerPage = queryData.itemsPerPage; + const queryFilter = queryString.parse(location.search); + const storedFilter = queryString.parse(storedQuery.filter); + const query = location.search ? { + sortby: storedFilter.sortby, + sortdir: storedFilter.sortdir, + disp: storedFilter.disp, + perPage: storedFilter.perPage, + ...queryFilter + } : storedFilter; - const newLocation = { ...history.location }; - newLocation.search = queryData.filter; + const newFilter = new ListFilterModel( + options.filterMode, + query + ); + + // Compare constructed filter with current filter. + // If different it's the result of navigation, and we update the filter. + const newLocation = { ...location }; + newLocation.search = newFilter.makeQueryParameters(); + if(newLocation.search !== filter.makeQueryParameters()) { + setFilter(newFilter); + updateInterfaceConfig(newFilter); + const newLocation = { ...location }; + newLocation.search = newFilter.makeQueryParameters(); history.replace(newLocation); } }, [ + filter, interfaceState.data, interfaceState.loading, - history, + location, options.subComponent, - options.filterMode + options.filterMode, + forageInitialised, + updateInterfaceConfig ]); + /* useEffect(() => { - if (options.subComponent) return; + if (options.subComponent || !forageInitialised) return; const newFilter = new ListFilterModel( options.filterMode, @@ -136,20 +169,8 @@ const useList = ( ); setFilter(newFilter); - if (forageInitialised.current) { - setInterfaceState(config => { - const data = { ...config } as IInterfaceConfig; - data.queries = { - [options.filterMode]: { - filter: location.search, - itemsPerPage: newFilter.itemsPerPage, - currentPage: newFilter.currentPage - } - }; - return data; - }); - } - }, [location, options.filterMode, options.subComponent, setInterfaceState]); + }, [location, options.filterMode, options.subComponent, setInterfaceState, forageInitialised]); + */ function getFilter() { if (!options.filterHook) { @@ -161,10 +182,14 @@ const useList = ( return options.filterHook(newFilter); } - function updateQueryParams(listfilter: ListFilterModel) { - const newLocation = { ...history.location }; - newLocation.search = listfilter.makeQueryParameters(); - history.replace(newLocation); + function updateQueryParams(listFilter: ListFilterModel) { + setFilter(listFilter); + if(!options.subComponent) { + const newLocation = { ...location }; + newLocation.search = listFilter.makeQueryParameters(); + history.replace(newLocation); + updateInterfaceConfig(listFilter); + } } function onChangePageSize(pageSize: number) { @@ -328,7 +353,7 @@ const useList = ( : undefined; let template; - if (result.loading || !forageInitialised.current) { + if (result.loading || !forageInitialised) { template = ; } else if (result.error) { template =

{result.error.message}

; diff --git a/ui/v2.5/src/models/list-filter/filter.ts b/ui/v2.5/src/models/list-filter/filter.ts index 95ed12c8e..c2c00f251 100644 --- a/ui/v2.5/src/models/list-filter/filter.ts +++ b/ui/v2.5/src/models/list-filter/filter.ts @@ -48,7 +48,7 @@ import { makeCriteria } from "./criteria/utils"; import { DisplayMode, FilterMode } from "./types"; interface IQueryParameters { - items?: string; + perPage?: string; sortby?: string; sortdir?: string; disp?: string; @@ -221,7 +221,7 @@ export class ListFilterModel { if (params.p) { this.currentPage = Number.parseInt(params.p, 10); } - if (params.items) this.itemsPerPage = Number.parseInt(params.items, 10); + if (params.perPage) this.itemsPerPage = Number.parseInt(params.perPage, 10); if (params.c !== undefined) { this.criteria = []; @@ -278,11 +278,11 @@ export class ListFilterModel { }); const result = { - items: + perPage: this.itemsPerPage !== DEFAULT_PARAMS.itemsPerPage ? this.itemsPerPage : undefined, - sortby: this.getSortBy(), + sortby: this.sortBy !== "date" ? this.getSortBy() : undefined, sortdir: this.sortDirection === SortDirectionEnum.Desc ? "desc" : undefined, disp: diff --git a/ui/v2.5/src/utils/table.tsx b/ui/v2.5/src/utils/table.tsx index 0428ae9f7..783b887ae 100644 --- a/ui/v2.5/src/utils/table.tsx +++ b/ui/v2.5/src/utils/table.tsx @@ -87,7 +87,7 @@ const renderHtmlSelect = (options: { ) =>