2023-07-25 20:27:29 +03:00
|
|
|
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
|
|
|
2023-07-28 00:03:37 +03:00
|
|
|
|
import Checkbox from '../../../components/Common/Checkbox';
|
|
|
|
|
import DataTableThemed from '../../../components/Common/DataTableThemed';
|
|
|
|
|
import { useRSForm } from '../../../context/RSFormContext';
|
|
|
|
|
import useLocalStorage from '../../../hooks/useLocalStorage';
|
|
|
|
|
import { CstType, type IConstituenta, matchConstituenta } from '../../../utils/models';
|
|
|
|
|
import { extractGlobals, getMockConstituenta } from '../../../utils/staticUI';
|
2023-07-20 17:11:03 +03:00
|
|
|
|
|
2023-07-28 00:03:37 +03:00
|
|
|
|
interface ViewSideConstituentsProps {
|
2023-07-20 17:11:03 +03:00
|
|
|
|
expression: string
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-28 00:03:37 +03:00
|
|
|
|
function ViewSideConstituents({ expression }: ViewSideConstituentsProps) {
|
2023-07-24 22:34:03 +03:00
|
|
|
|
const { schema, setActiveID } = useRSForm();
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const [filteredData, setFilteredData] = useState<IConstituenta[]>(schema?.items ?? []);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
const [filterText, setFilterText] = useLocalStorage('side-filter-text', '')
|
|
|
|
|
const [onlyExpression, setOnlyExpression] = useLocalStorage('side-filter-flag', false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!schema?.items) {
|
|
|
|
|
setFilteredData([]);
|
2023-07-26 23:11:00 +03:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (onlyExpression) {
|
2023-07-22 03:18:48 +03:00
|
|
|
|
const aliases = extractGlobals(expression);
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const filtered = schema?.items.filter((cst) => aliases.has(cst.alias));
|
2023-07-22 03:18:48 +03:00
|
|
|
|
const names = filtered.map(cst => cst.alias)
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const diff = Array.from(aliases).filter(name => !names.includes(name));
|
2023-07-22 03:18:48 +03:00
|
|
|
|
if (diff.length > 0) {
|
|
|
|
|
diff.forEach(
|
2023-07-26 23:11:00 +03:00
|
|
|
|
(alias, index) => filtered.push(getMockConstituenta(-index, alias, CstType.BASE, 'Конституента отсутствует')));
|
2023-07-22 03:18:48 +03:00
|
|
|
|
}
|
|
|
|
|
setFilteredData(filtered);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
} else if (!filterText) {
|
|
|
|
|
setFilteredData(schema?.items);
|
|
|
|
|
} else {
|
|
|
|
|
setFilteredData(schema?.items.filter((cst) => matchConstituenta(filterText, cst)));
|
|
|
|
|
}
|
|
|
|
|
}, [filterText, setFilteredData, onlyExpression, expression, schema]);
|
|
|
|
|
|
|
|
|
|
const handleRowClicked = useCallback(
|
2023-07-25 20:27:29 +03:00
|
|
|
|
(cst: IConstituenta, event: React.MouseEvent<Element, MouseEvent>) => {
|
|
|
|
|
if (event.altKey && cst.id > 0) {
|
2023-07-24 22:34:03 +03:00
|
|
|
|
setActiveID(cst.id);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
}, [setActiveID]);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
|
|
|
|
|
const handleDoubleClick = useCallback(
|
2023-07-26 23:11:00 +03:00
|
|
|
|
(cst: IConstituenta) => {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
if (cst.id > 0) setActiveID(cst.id);
|
|
|
|
|
}, [setActiveID]);
|
2023-07-20 17:11:03 +03:00
|
|
|
|
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const columns = useMemo(() =>
|
2023-07-20 17:11:03 +03:00
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
id: 'id',
|
2023-07-24 22:34:03 +03:00
|
|
|
|
selector: (cst: IConstituenta) => cst.id,
|
2023-07-25 20:27:29 +03:00
|
|
|
|
omit: true
|
2023-07-20 17:11:03 +03:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'ID',
|
|
|
|
|
id: 'alias',
|
|
|
|
|
selector: (cst: IConstituenta) => cst.alias,
|
|
|
|
|
width: '62px',
|
|
|
|
|
maxWidth: '62px',
|
2023-07-22 03:18:48 +03:00
|
|
|
|
conditionalCellStyles: [
|
|
|
|
|
{
|
2023-07-24 22:34:03 +03:00
|
|
|
|
when: (cst: IConstituenta) => cst.id <= 0,
|
2023-07-22 03:18:48 +03:00
|
|
|
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
2023-07-25 20:27:29 +03:00
|
|
|
|
}
|
|
|
|
|
]
|
2023-07-20 17:11:03 +03:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'Описание',
|
|
|
|
|
id: 'description',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
selector: (cst: IConstituenta) =>
|
2023-07-29 03:31:21 +03:00
|
|
|
|
cst.term.resolved || cst.definition.text.resolved || cst.definition.formal || cst.convention,
|
2023-07-20 17:11:03 +03:00
|
|
|
|
minWidth: '350px',
|
|
|
|
|
wrap: true,
|
2023-07-22 03:18:48 +03:00
|
|
|
|
conditionalCellStyles: [
|
|
|
|
|
{
|
2023-07-24 22:34:03 +03:00
|
|
|
|
when: (cst: IConstituenta) => cst.id <= 0,
|
2023-07-22 03:18:48 +03:00
|
|
|
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
2023-07-25 20:27:29 +03:00
|
|
|
|
}
|
|
|
|
|
]
|
2023-07-20 17:11:03 +03:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'Выражение',
|
|
|
|
|
id: 'expression',
|
2023-07-25 20:27:29 +03:00
|
|
|
|
selector: (cst: IConstituenta) => cst.definition?.formal ?? '',
|
2023-07-20 17:11:03 +03:00
|
|
|
|
minWidth: '200px',
|
|
|
|
|
hide: 1600,
|
|
|
|
|
grow: 2,
|
|
|
|
|
wrap: true,
|
2023-07-22 03:18:48 +03:00
|
|
|
|
conditionalCellStyles: [
|
|
|
|
|
{
|
2023-07-24 22:34:03 +03:00
|
|
|
|
when: (cst: IConstituenta) => cst.id <= 0,
|
2023-07-22 03:18:48 +03:00
|
|
|
|
classNames: ['bg-[#ffc9c9]', 'dark:bg-[#592b2b]']
|
2023-07-25 20:27:29 +03:00
|
|
|
|
}
|
|
|
|
|
]
|
2023-07-20 17:11:03 +03:00
|
|
|
|
}
|
|
|
|
|
], []
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className='max-h-[80vh] overflow-y-scroll border flex-grow w-full'>
|
2023-07-21 01:50:57 +03:00
|
|
|
|
<div className='sticky top-0 left-0 right-0 z-10 flex items-center justify-between w-full gap-1 px-2 py-1 bg-white border-b-2 border-gray-400 rounded dark:bg-gray-700 dark:border-gray-300'>
|
2023-07-20 17:11:03 +03:00
|
|
|
|
<div className='w-full'>
|
|
|
|
|
<input type='text'
|
|
|
|
|
className='w-full px-2 outline-none dark:bg-gray-700 hover:text-clip'
|
|
|
|
|
placeholder='текст для фильтрации списка'
|
|
|
|
|
value={filterText}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
onChange={event => { setFilterText(event.target.value); }}
|
2023-07-20 17:11:03 +03:00
|
|
|
|
disabled={onlyExpression}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='w-fit min-w-[8rem]'>
|
|
|
|
|
<Checkbox
|
|
|
|
|
label='из выражения'
|
|
|
|
|
value={onlyExpression}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
onChange={event => { setOnlyExpression(event.target.checked); }}
|
2023-07-20 17:11:03 +03:00
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<DataTableThemed
|
|
|
|
|
data={filteredData}
|
|
|
|
|
columns={columns}
|
|
|
|
|
keyField='id'
|
|
|
|
|
noContextMenu
|
2023-07-23 21:38:04 +03:00
|
|
|
|
noDataComponent={<span className='flex flex-col justify-center p-2 text-center'>
|
2023-07-22 12:24:14 +03:00
|
|
|
|
<p>Список конституент пуст</p>
|
|
|
|
|
<p>Измените параметры фильтра</p>
|
|
|
|
|
</span>}
|
2023-07-20 17:11:03 +03:00
|
|
|
|
|
|
|
|
|
striped
|
|
|
|
|
highlightOnHover
|
|
|
|
|
pointerOnHover
|
|
|
|
|
|
|
|
|
|
onRowDoubleClicked={handleDoubleClick}
|
|
|
|
|
onRowClicked={handleRowClicked}
|
|
|
|
|
dense
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-28 00:03:37 +03:00
|
|
|
|
export default ViewSideConstituents;
|