2023-12-13 14:32:57 +03:00
|
|
|
'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-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';
|
2024-01-04 19:38:12 +03:00
|
|
|
import SearchBar from '@/components/ui/SearchBar';
|
2023-12-13 14:32:57 +03:00
|
|
|
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';
|
2023-12-13 14:32:57 +03:00
|
|
|
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) {
|
2024-03-27 15:32:59 +03:00
|
|
|
const [filterMatch, setFilterMatch] = useLocalStorage(storage.cstFilterMatch, CstMatchMode.ALL);
|
|
|
|
const [filterSource, setFilterSource] = useLocalStorage(storage.cstFilterGraph, DependencyMode.ALL);
|
|
|
|
const [filterText, setFilterText] = useState('');
|
2024-08-03 11:31:13 +03:00
|
|
|
const [showInherited, setShowInherited] = useLocalStorage(storage.cstFilterShowInherited, true);
|
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));
|
2023-12-15 17:34:50 +03:00
|
|
|
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));
|
|
|
|
}
|
2024-08-03 11:31:13 +03:00
|
|
|
if (!showInherited) {
|
|
|
|
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
|
|
|
}, [
|
|
|
|
filterText,
|
|
|
|
setFiltered,
|
|
|
|
filterSource,
|
|
|
|
activeExpression,
|
|
|
|
schema?.items,
|
|
|
|
schema,
|
|
|
|
filterMatch,
|
|
|
|
activeID,
|
|
|
|
showInherited
|
|
|
|
]);
|
2023-12-08 19:24:08 +03:00
|
|
|
|
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'>
|
2024-03-18 16:21:39 +03:00
|
|
|
<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}
|
2024-08-03 11:31:13 +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}
|
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;
|