web/src/connectors/documents-search-connector/documents-search-connector.tsx (162 lines of code) (raw):

// temporary_disabled_rules /* eslint-disable @typescript-eslint/no-unused-vars, react-hooks/exhaustive-deps */ import React, { FC, useEffect, useState, useContext } from 'react'; import styles from './documents-search-connector.module.scss'; import { Checkbox, SearchInput, LinkButton } from '@epam/loveship'; import { FacetName, Facets, FacetValue, FacetValuesFilter } from 'api/typings/search'; import { useFacets } from 'api/hooks/search'; import { DocumentsSearch } from 'shared/contexts/documents-search'; type SearchFacet = { category: string; job_id: string; }; const mapFacetName = (name: FacetName) => { switch (name) { case 'category': return 'Categories'; case 'job_id': return 'Extractions'; } }; export const DocumentsSearchConnector: FC = () => { const { facetFilter, setFacetFilter } = useContext(DocumentsSearch); const [facetState, setFacetState] = useState<Facets[]>([]); const [search, setSearch] = useState<SearchFacet>({ category: '', job_id: '' }); const [limit, setLimit] = useState({ category: 6, job_id: 6 }); const findFilters = (name: FacetName) => { const mapFilters = Object.values(facetFilter[name]).map((filter) => filter); const findFilters = mapFilters.filter((el) => el.value === true); return findFilters.map(({ id }) => id); }; const { data } = useFacets({ query: '', categoryLimit: limit.category, jobLimit: limit.job_id, categoryFilter: findFilters('category'), jobFilter: findFilters('job_id') }); const onFacetFilterChange = (name: FacetName, filterValue: FacetValuesFilter[]) => { setFacetFilter((prevState: any) => { const copyFilters = Object.assign({}, prevState); copyFilters[name] = filterValue; return copyFilters; }); }; const mapFilters = (facets: Facets[]) => { facets.forEach(({ name, values }) => { const facetValues: any = {}; values.forEach(({ id }) => { facetValues[id] = { id: id.toString(), // @ts-ignore: Unreachable code error value: facetFilter[name][id.toString()]?.value ?? false }; }); onFacetFilterChange(name, facetValues); }); }; const onValueChange = (name: FacetName, id: string) => { setFacetFilter((prevState: any) => { const copyFilters = Object.assign({}, prevState); // @ts-ignore: Unreachable code error copyFilters[name][id].value = !copyFilters[name][id].value; return copyFilters; }); }; const findFacet = (facetName: FacetName, facetData: Facets[] = facetState) => { return facetData.find(({ name }) => name === facetName); }; const isShowButton = (facetName: FacetName, facetData: Facets[] = facetState) => { return findFacet(facetName, facetData)?.values.length === 6; }; const [isShowMore, setIsShowMore] = useState({ category: false, job_id: false }); const filterValue = (facetName: FacetName, searchText: string) => { if (data) { const findedFacet = findFacet(facetName, data.facets); const filteredValue = findedFacet?.values.filter( ({ id }) => id.indexOf(searchText, 0) >= 0 ); const indexFacet = data.facets.findIndex(({ name }) => name === facetName); const copyFacets = JSON.parse(JSON.stringify(data.facets)); if (filteredValue) { copyFacets[indexFacet].values = filteredValue; setFacetState(copyFacets); } } }; const isCutValue = (facetName: FacetName, values: FacetValue[]) => { const copyValue = [...values]; return isShowMore[facetName] ? copyValue.splice(0, 5) : copyValue; }; const onLimitChange = (name: FacetName) => { setLimit((prevState) => { const copyLimit = Object.assign({}, prevState); copyLimit[name] = 0; return copyLimit; }); }; useEffect(() => { if (data) { setFacetState(data.facets); setIsShowMore({ category: isShowButton('category', data.facets), job_id: isShowButton('job_id', data.facets) }); mapFilters(data.facets); } }, [data]); if (data && facetState.length) { return ( <div className={styles.sidebar}> <h2 className={styles['sidebar-title']}>Search options</h2> <div className={styles['filter-container']}> {facetState.map(({ name, values }) => ( <div key={name} className={styles['facet']}> <h3 className={styles['facet-name']}>{mapFacetName(name)}</h3> <div className={styles['search']}> <SearchInput value={search[name]} size="24" onValueChange={(value) => { const val = value || ''; const copySearch = Object.assign({}, search); copySearch[name] = val; setSearch(copySearch); filterValue('category', val); }} onClick={() => onLimitChange(name)} placeholder="Search" debounceDelay={0} /> </div> {isCutValue(name, values).map((facet) => ( <div key={facet.id} className={styles['facet-item']}> <Checkbox // @ts-ignore: Unreachable code error value={facetFilter[name][facet.id].value} onValueChange={() => onValueChange(name, facet.id)} /> <span key={facet.id} className={styles['facet-id']}> {`${facet.name} (${facet.count})`} </span> </div> ))} {isShowMore[name] && ( <div className={styles['show-more']}> <LinkButton caption="Show more" onClick={() => onLimitChange(name)} /> </div> )} </div> ))} </div> </div> ); } return <div />; };