From a69b62e66a71b76e990d12ac8ab52e992d754819 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 1 Mar 2024 13:35:46 +0300 Subject: [PATCH] (fix) Improvements to the search experience --- package.json | 2 +- .../dashboard/dashboard.component.tsx | 67 +-- src/components/dashboard/dashboard.scss | 2 +- src/components/empty-state/empty-state.scss | 6 +- yarn.lock | 402 +++++++++++++----- 5 files changed, 340 insertions(+), 139 deletions(-) diff --git a/package.json b/package.json index dfd3c62..5388d65 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "build": "webpack --mode production", "analyze": "webpack --mode=production --env.analyze=true", "lint": "TIMING=1 eslint src --ext js,jsx,ts,tsx --max-warnings=0", - "prettier": "prettier --write \"src/**/*.{ts,tsx}\"", + "prettier": "prettier --write \"src/**/*.{ts,tsx}\" --list-different", "typescript": "tsc", "test": "jest --config jest.config.js", "test-e2e": "playwright test", diff --git a/src/components/dashboard/dashboard.component.tsx b/src/components/dashboard/dashboard.component.tsx index e730483..7c8df5e 100644 --- a/src/components/dashboard/dashboard.component.tsx +++ b/src/components/dashboard/dashboard.component.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useMemo, useState } from 'react'; -import fuzzy from 'fuzzy'; import type { TFunction } from 'i18next'; import { useTranslation } from 'react-i18next'; import { @@ -36,7 +35,6 @@ import { useConfig, useLayoutType, usePagination, - useDebounce, openmrsFetch, } from '@openmrs/esm-framework'; import { type KeyedMutator, preload } from 'swr'; @@ -253,36 +251,27 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) { const isTablet = useLayoutType() === 'tablet'; const responsiveSize = isTablet ? 'lg' : 'sm'; const [filter, setFilter] = useState(''); - const [searchTerm, setSearchTerm] = useState(''); - const debouncedSearchTerm = useDebounce(searchTerm); + const [searchString, setSearchString] = useState(''); - const filteredForms: Array = useMemo(() => { - if (!debouncedSearchTerm) { - if (filter === 'Retired') { - return forms.filter((form) => form.retired); - } + const filteredRows = useMemo(() => { + if (!filter) { + return forms; + } - if (filter === 'Published') { - return forms.filter((form) => form.published); - } + if (filter === 'Published') { + return forms.filter((form) => form.published); + } - if (filter === 'Unpublished') { - return forms.filter((form) => !form.published); - } + if (filter === 'Unpublished') { + return forms.filter((form) => !form.published); + } - return forms; + if (filter === 'Retired') { + return forms.filter((form) => form.retired); } - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return debouncedSearchTerm - ? fuzzy - .filter(debouncedSearchTerm, forms, { - extract: (form: TypedForm) => `${form.name} ${form.version}`, - }) - .sort((r1, r2) => r1.score - r2.score) - .map((result) => result.original as unknown as TypedForm) - : forms; - }, [filter, forms, debouncedSearchTerm]); + return forms; + }, [filter, forms]); const tableHeaders = [ { @@ -308,7 +297,16 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) { ]; const editSchemaUrl = '${openmrsSpaBase}/form-builder/edit/${formUuid}'; - const { paginated, goTo, results, currentPage } = usePagination(filteredForms, pageSize); + + const searchResults = useMemo(() => { + if (searchString && searchString.trim() !== '') { + return filteredRows.filter((form) => form.name.toLowerCase().includes(searchString.toLowerCase())); + } + + return filteredRows; + }, [searchString, filteredRows]); + + const { paginated, goTo, results, currentPage } = usePagination(searchResults, pageSize); const tableRows = results?.map((form: TypedForm) => ({ ...form, @@ -330,6 +328,14 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) { const handleFilter = ({ selectedItem }: { selectedItem: string }) => setFilter(selectedItem); + const handleSearch = useCallback( + (e: React.ChangeEvent) => { + goTo(1); + setSearchString(e.target.value); + }, + [goTo, setSearchString], + ); + return ( <> {config.showSchemaSaveWarning && ( @@ -369,8 +375,9 @@ function FormsList({ forms, isValidating, mutate, t }: FormsListProps) { ) => setSearchTerm(e.target.value)} + onChange={handleSearch} placeholder={t('searchThisList', 'Search this list')} />