ConceptPortal-public/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ConstituentsSearch.tsx

80 lines
3.0 KiB
TypeScript
Raw Normal View History

'use client';
2024-05-02 17:04:18 +03:00
import { useLayoutEffect, useMemo, useState } from 'react';
2023-12-08 19:24:08 +03:00
2024-05-02 17:04:18 +03:00
import SelectGraphFilter from '@/components/select/SelectGraphFilter';
import SelectMatchMode from '@/components/select/SelectMatchMode';
import SearchBar from '@/components/ui/SearchBar';
import useLocalStorage from '@/hooks/useLocalStorage';
2023-12-26 14:23:51 +03:00
import { CstMatchMode, DependencyMode } from '@/models/miscellaneous';
import { applyGraphFilter } from '@/models/miscellaneousAPI';
2024-03-17 19:24:12 +03:00
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { createMockConstituenta, matchConstituenta } from '@/models/rsformAPI';
import { extractGlobals } from '@/models/rslangAPI';
2024-05-02 17:04:18 +03:00
import { storage } from '@/utils/constants';
2023-12-08 19:24:08 +03:00
interface ConstituentsSearchProps {
2023-12-28 14:04:44 +03:00
schema?: IRSForm;
2024-06-04 14:20:43 +03:00
dense?: boolean;
2024-03-17 19:24:12 +03:00
activeID?: ConstituentaID;
2023-12-28 14:04:44 +03:00
activeExpression: string;
setFiltered: React.Dispatch<React.SetStateAction<IConstituenta[]>>;
2023-12-08 19:24:08 +03:00
}
2024-06-04 14:20:43 +03:00
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('');
2023-12-08 19:24:08 +03:00
2023-12-28 14:04:44 +03:00
useLayoutEffect(() => {
2023-12-08 19:24:08 +03:00
if (!schema || schema.items.length === 0) {
setFiltered([]);
return;
}
let result: IConstituenta[] = [];
if (filterSource === DependencyMode.EXPRESSION) {
const aliases = extractGlobals(activeExpression);
2023-12-28 14:04:44 +03:00
result = schema.items.filter(cst => aliases.has(cst.alias));
const names = result.map(cst => cst.alias);
2023-12-08 19:24:08 +03:00
const diff = Array.from(aliases).filter(name => !names.includes(name));
if (diff.length > 0) {
2023-12-28 14:04:44 +03:00
diff.forEach((alias, index) => result.push(createMockConstituenta(-index, alias, 'Конституента отсутствует')));
2023-12-08 19:24:08 +03:00
}
} else if (!activeID) {
result = schema.items;
} else {
result = applyGraphFilter(schema, activeID, filterSource);
}
if (filterText) {
result = result.filter(cst => matchConstituenta(cst, filterText, filterMatch));
}
setFiltered(result);
}, [filterText, setFiltered, filterSource, activeExpression, schema?.items, schema, filterMatch, activeID]);
2024-05-02 17:04:18 +03:00
const selectGraph = useMemo(
2024-06-04 14:20:43 +03:00
() => <SelectGraphFilter value={filterSource} onChange={newValue => setFilterSource(newValue)} dense={dense} />,
[filterSource, setFilterSource, dense]
2023-12-28 14:04:44 +03:00
);
2023-12-08 19:24:08 +03:00
2024-05-02 17:04:18 +03:00
const selectMatchMode = useMemo(
2024-06-04 14:20:43 +03:00
() => <SelectMatchMode value={filterMatch} onChange={newValue => setFilterMatch(newValue)} dense={dense} />,
[filterMatch, setFilterMatch, dense]
2023-12-28 14:04:44 +03:00
);
2023-12-08 19:24:08 +03:00
return (
2024-08-01 00:36:06 +03:00
<div className='flex border-b clr-input'>
<SearchBar
id='constituents_search'
noBorder
className='min-w-[6rem] pr-2 flex-grow'
value={filterText}
onChange={setFilterText}
/>
2024-05-02 17:04:18 +03:00
{selectMatchMode}
{selectGraph}
2023-12-08 19:24:08 +03:00
</div>
2023-12-28 14:04:44 +03:00
);
2023-12-08 19:24:08 +03:00
}
2023-12-28 14:04:44 +03:00
export default ConstituentsSearch;