Portal/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx

96 lines
3.2 KiB
TypeScript
Raw Normal View History

2024-06-07 20:17:03 +03:00
'use client';
import { useEffect, useMemo, useState } from 'react';
2024-06-07 20:17:03 +03:00
2024-08-03 11:30:47 +03:00
import { IconChild } from '@/components/Icons';
2024-06-07 20:17:03 +03:00
import SelectGraphFilter from '@/components/select/SelectGraphFilter';
import SelectMatchMode from '@/components/select/SelectMatchMode';
2024-08-03 11:30:47 +03:00
import MiniButton from '@/components/ui/MiniButton';
2024-06-07 20:17:03 +03:00
import SearchBar from '@/components/ui/SearchBar';
import useLocalStorage from '@/hooks/useLocalStorage';
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
import { applyGraphFilter } from '@/models/miscellaneousAPI';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
2024-09-23 11:53:46 +03:00
import { matchConstituenta } from '@/models/rsformAPI';
2024-06-07 20:17:03 +03:00
import { storage } from '@/utils/constants';
interface ConstituentsSearchProps {
schema?: IRSForm;
dense?: boolean;
activeID?: ConstituentaID;
activeExpression: string;
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
}
function ConstituentsSearch({ schema, activeID, activeExpression, dense, setFiltered }: ConstituentsSearchProps) {
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL);
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL);
const [filterText, setFilterText] = useState('');
2024-08-03 11:30:47 +03:00
const [showInherited, setShowInherited] = useLocalStorage(storage.cstFilterShowInherited, true);
2024-06-07 20:17:03 +03:00
useEffect(() => {
2024-06-07 20:17:03 +03:00
if (!schema || schema.items.length === 0) {
setFiltered([]);
return;
}
let result: IConstituenta[] = [];
2024-09-23 11:53:46 +03:00
if (!activeID) {
2024-06-07 20:17:03 +03:00
result = schema.items;
} else {
result = applyGraphFilter(schema, activeID, filterSource);
}
if (filterText) {
result = result.filter(cst => matchConstituenta(cst, filterText, filterMatch));
}
2024-08-03 11:30:47 +03:00
if (!showInherited) {
result = result.filter(cst => !cst.is_inherited);
}
2024-06-07 20:17:03 +03:00
setFiltered(result);
2024-08-03 11:30:47 +03:00
}, [
filterText,
setFiltered,
filterSource,
activeExpression,
schema?.items,
schema,
filterMatch,
activeID,
showInherited
]);
2024-06-07 20:17:03 +03:00
const selectGraph = useMemo(
() => <SelectGraphFilter value={filterSource} onChange={newValue => setFilterSource(newValue)} dense={dense} />,
[filterSource, setFilterSource, dense]
);
const selectMatchMode = useMemo(
() => <SelectMatchMode value={filterMatch} onChange={newValue => setFilterMatch(newValue)} dense={dense} />,
[filterMatch, setFilterMatch, dense]
);
return (
2024-10-23 15:18:46 +03:00
<div className='flex border-b clr-input rounded-t-md'>
2024-06-07 20:17:03 +03:00
<SearchBar
id='constituents_search'
noBorder
className='min-w-[6rem] pr-2 flex-grow'
query={filterText}
onChangeQuery={setFilterText}
2024-06-07 20:17:03 +03:00
/>
{selectMatchMode}
{selectGraph}
2024-08-03 11:30:47 +03:00
{schema && schema?.stats.count_inherited > 0 ? (
<MiniButton
noHover
titleHtml={`Наследованные: <b>${showInherited ? 'отображать' : 'скрывать'}</b>`}
icon={<IconChild size='1rem' className={showInherited ? 'icon-primary' : 'clr-text-controls'} />}
className='h-fit self-center'
onClick={() => setShowInherited(prev => !prev)}
/>
) : null}
2024-06-07 20:17:03 +03:00
</div>
);
}
export default ConstituentsSearch;