From 2295f24622359872192dca382954781806c17f05 Mon Sep 17 00:00:00 2001 From: Johannes Kettmann Date: Tue, 13 Dec 2022 15:11:45 +0100 Subject: [PATCH 1/5] Use URL params as single source of truth --- .../issues/components/filters/filters.tsx | 44 ++---------------- features/issues/context/filters-context.tsx | 46 ------------------- features/issues/context/index.ts | 1 - features/issues/hooks/use-filters.ts | 21 +++++++-- features/issues/index.ts | 1 - features/ui/page-container/page-container.tsx | 33 ++++++------- pages/dashboard/issues.tsx | 15 +++--- 7 files changed, 43 insertions(+), 118 deletions(-) delete mode 100644 features/issues/context/filters-context.tsx delete mode 100644 features/issues/context/index.ts diff --git a/features/issues/components/filters/filters.tsx b/features/issues/components/filters/filters.tsx index 5b92d0d..4410de5 100644 --- a/features/issues/components/filters/filters.tsx +++ b/features/issues/components/filters/filters.tsx @@ -1,11 +1,4 @@ -import React, { - useState, - useEffect, - useCallback, - useRef, - useContext, -} from "react"; -import { useRouter } from "next/router"; +import React, { useState, useCallback, useContext } from "react"; import { useWindowSize } from "react-use"; import { Select, Option, Input, NavigationContext } from "@features/ui"; import { useFilters } from "../../hooks/use-filters"; @@ -16,15 +9,14 @@ import * as S from "./filters.styled"; export function Filters() { const { handleFilters, filters } = useFilters(); const { data: projects } = useProjects(); - const router = useRouter(); - const routerQueryProjectName = - (router.query.projectName as string)?.toLowerCase() || undefined; + const [inputValue, setInputValue] = useState(""); const projectNames = projects?.map((project) => project.name.toLowerCase()); - const isFirst = useRef(true); + const { width } = useWindowSize(); const isMobileScreen = width <= 1023; const { isMobileMenuOpen } = useContext(NavigationContext); + const handleChange = (input: string) => { setInputValue(input); @@ -65,34 +57,6 @@ export function Filters() { [handleFilters] ); - useEffect(() => { - const newObj: { [key: string]: string } = { - ...filters, - }; - - Object.keys(newObj).forEach((key) => { - if (newObj[key] === undefined) { - delete newObj[key]; - } - }); - - const url = { - pathname: router.pathname, - query: { - page: router.query.page || 1, - ...newObj, - }, - }; - - if (routerQueryProjectName && isFirst) { - handleProjectName(routerQueryProjectName); - setInputValue(routerQueryProjectName || ""); - isFirst.current = false; - } - - router.push(url, undefined, { shallow: false }); - }, [filters.level, filters.status, filters.project, router.query.page]); - return ( Date: Tue, 13 Dec 2022 16:01:45 +0100 Subject: [PATCH 3/5] Replace project input autocomplete with debounce --- .../issues/components/filters/filters.tsx | 35 +++++-------------- package-lock.json | 20 ++++++++++- package.json | 3 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/features/issues/components/filters/filters.tsx b/features/issues/components/filters/filters.tsx index 3db0749..c5d03ed 100644 --- a/features/issues/components/filters/filters.tsx +++ b/features/issues/components/filters/filters.tsx @@ -1,11 +1,11 @@ -import React, { useState, useCallback, useContext } from "react"; +import React, { useState, useContext } from "react"; import { useWindowSize } from "react-use"; +import { useDebouncedCallback } from "use-debounce"; +import { capitalize } from "lodash"; import { Select, Option, Input, NavigationContext } from "@features/ui"; -import { useFilters } from "../../hooks/use-filters"; import { IssueFilters, IssueLevel, IssueStatus } from "@api/issues.types"; -import { useProjects } from "@features/projects"; +import { useFilters } from "../../hooks/use-filters"; import * as S from "./filters.styled"; -import { capitalize } from "lodash"; function getStatusDefaultValue(filters: IssueFilters) { if (!filters.status) { @@ -26,30 +26,17 @@ function getLevelDefaultValue(filters: IssueFilters) { export function Filters() { const { handleFilters, filters } = useFilters(); - const { data: projects } = useProjects(); + const debouncedHandleFilters = useDebouncedCallback(handleFilters, 300); const [inputValue, setInputValue] = useState(filters.project || ""); - const projectNames = projects?.map((project) => project.name.toLowerCase()); const { width } = useWindowSize(); const isMobileScreen = width <= 1023; const { isMobileMenuOpen } = useContext(NavigationContext); - const handleChange = (input: string) => { - setInputValue(input); - - if (inputValue?.length < 2) { - handleProjectName(undefined); - return; - } - - const name = projectNames?.find((name) => - name?.toLowerCase().includes(inputValue.toLowerCase()) - ); - - if (name) { - handleProjectName(name); - } + const handleChange = (project: string) => { + setInputValue(project); + debouncedHandleFilters({ project: project.toLowerCase() }); }; const handleLevel = (level?: string) => { @@ -69,12 +56,6 @@ export function Filters() { handleFilters({ status: status as IssueStatus }); }; - const handleProjectName = useCallback( - (projectName?: string) => - handleFilters({ project: projectName?.toLowerCase() }), - [handleFilters] - ); - return ( - + - + -