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

88 lines
3.0 KiB
TypeScript
Raw Normal View History

'use client';
import { useEffect } from 'react';
2023-12-08 19:24:08 +03:00
2024-08-03 11:31:13 +03:00
import { IconChild } from '@/components/Icons';
2024-05-02 17:04:18 +03:00
import SelectGraphFilter from '@/components/select/SelectGraphFilter';
import SelectMatchMode from '@/components/select/SelectMatchMode';
2024-08-03 11:31:13 +03:00
import MiniButton from '@/components/ui/MiniButton';
import SearchBar from '@/components/ui/SearchBar';
2023-12-26 14:23:51 +03:00
import { applyGraphFilter } from '@/models/miscellaneousAPI';
2024-03-17 19:24:12 +03:00
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
2024-09-23 11:54:18 +03:00
import { matchConstituenta } from '@/models/rsformAPI';
import { useCstSearchStore } from '@/stores/cstSearch';
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 query = useCstSearchStore(state => state.query);
const filterMatch = useCstSearchStore(state => state.match);
const filterSource = useCstSearchStore(state => state.source);
const includeInherited = useCstSearchStore(state => state.includeInherited);
const setQuery = useCstSearchStore(state => state.setQuery);
const setMatch = useCstSearchStore(state => state.setMatch);
const setSource = useCstSearchStore(state => state.setSource);
const toggleInherited = useCstSearchStore(state => state.toggleInherited);
2023-12-08 19:24:08 +03:00
useEffect(() => {
2023-12-08 19:24:08 +03:00
if (!schema || schema.items.length === 0) {
setFiltered([]);
return;
}
let result: IConstituenta[] = [];
2024-09-23 11:54:18 +03:00
if (!activeID) {
2023-12-08 19:24:08 +03:00
result = schema.items;
} else {
result = applyGraphFilter(schema, activeID, filterSource);
}
if (query) {
result = result.filter(cst => matchConstituenta(cst, query, filterMatch));
2023-12-08 19:24:08 +03:00
}
if (!includeInherited) {
2024-08-03 11:31:13 +03:00
result = result.filter(cst => !cst.is_inherited);
}
2023-12-08 19:24:08 +03:00
setFiltered(result);
2024-08-03 11:31:13 +03:00
}, [
query,
2024-08-03 11:31:13 +03:00
setFiltered,
filterSource,
activeExpression,
schema?.items,
schema,
filterMatch,
activeID,
includeInherited
2024-08-03 11:31:13 +03:00
]);
2023-12-08 19:24:08 +03:00
return (
<div className='flex border-b clr-input rounded-t-md'>
<SearchBar
id='constituents_search'
noBorder
2024-12-18 14:41:59 +03:00
className='min-w-[6rem] w-[6rem] mr-2 flex-grow'
query={query}
onChangeQuery={setQuery}
/>
<SelectMatchMode value={filterMatch} onChange={newValue => setMatch(newValue)} dense={dense} />
<SelectGraphFilter value={filterSource} onChange={newValue => setSource(newValue)} dense={dense} />
2024-08-03 11:31:13 +03:00
{schema && schema?.stats.count_inherited > 0 ? (
<MiniButton
noHover
titleHtml={`Наследованные: <b>${includeInherited ? 'отображать' : 'скрывать'}</b>`}
icon={<IconChild size='1rem' className={includeInherited ? 'icon-primary' : 'clr-text-controls'} />}
2024-08-03 11:31:13 +03:00
className='h-fit self-center'
onClick={toggleInherited}
2024-08-03 11:31:13 +03:00
/>
) : null}
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;