2024-06-07 20:17:03 +03:00
|
|
|
|
'use client';
|
|
|
|
|
|
2024-08-30 09:58:31 +03:00
|
|
|
|
import { useCallback, useLayoutEffect, useMemo } from 'react';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
|
|
|
|
import BadgeConstituenta from '@/components/info/BadgeConstituenta';
|
2024-08-30 09:58:31 +03:00
|
|
|
|
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
|
2024-06-21 19:16:41 +03:00
|
|
|
|
import NoData from '@/components/ui/NoData';
|
2024-09-02 17:59:43 +03:00
|
|
|
|
import TextContent from '@/components/ui/TextContent';
|
2024-06-26 19:47:05 +03:00
|
|
|
|
import { useConceptOptions } from '@/context/ConceptOptionsContext';
|
2024-06-07 20:17:03 +03:00
|
|
|
|
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
|
|
|
|
import { isMockCst } from '@/models/rsformAPI';
|
|
|
|
|
import { PARAMETER, prefixes } from '@/utils/constants';
|
|
|
|
|
import { describeConstituenta } from '@/utils/labels';
|
|
|
|
|
|
2024-09-02 17:59:43 +03:00
|
|
|
|
const DESCRIPTION_MAX_SYMBOLS = 280;
|
|
|
|
|
|
2024-06-26 19:47:05 +03:00
|
|
|
|
interface TableSideConstituentsProps {
|
2024-06-07 20:17:03 +03:00
|
|
|
|
items: IConstituenta[];
|
|
|
|
|
activeCst?: IConstituenta;
|
|
|
|
|
onOpenEdit: (cstID: ConstituentaID) => void;
|
2024-08-24 08:24:05 +03:00
|
|
|
|
autoScroll?: boolean;
|
2024-06-07 20:17:03 +03:00
|
|
|
|
maxHeight: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const columnHelper = createColumnHelper<IConstituenta>();
|
|
|
|
|
|
2024-06-26 19:47:05 +03:00
|
|
|
|
function TableSideConstituents({
|
|
|
|
|
items,
|
|
|
|
|
activeCst,
|
2024-08-24 08:24:05 +03:00
|
|
|
|
autoScroll = true,
|
2024-06-26 19:47:05 +03:00
|
|
|
|
onOpenEdit,
|
2024-08-30 09:58:31 +03:00
|
|
|
|
maxHeight
|
2024-06-26 19:47:05 +03:00
|
|
|
|
}: TableSideConstituentsProps) {
|
2024-06-07 20:17:03 +03:00
|
|
|
|
const { colors } = useConceptOptions();
|
|
|
|
|
|
|
|
|
|
useLayoutEffect(() => {
|
|
|
|
|
if (!activeCst) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-24 08:24:05 +03:00
|
|
|
|
if (autoScroll) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
const element = document.getElementById(`${prefixes.cst_side_table}${activeCst.alias}`);
|
|
|
|
|
if (element) {
|
|
|
|
|
element.scrollIntoView({
|
|
|
|
|
behavior: 'smooth',
|
|
|
|
|
block: 'center',
|
|
|
|
|
inline: 'end'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, PARAMETER.refreshTimeout);
|
|
|
|
|
}
|
|
|
|
|
}, [activeCst, autoScroll]);
|
2024-06-07 20:17:03 +03:00
|
|
|
|
|
|
|
|
|
const handleRowClicked = useCallback(
|
|
|
|
|
(cst: IConstituenta) => {
|
|
|
|
|
if (!isMockCst(cst)) {
|
|
|
|
|
onOpenEdit(cst.id);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[onOpenEdit]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const columns = useMemo(
|
|
|
|
|
() => [
|
|
|
|
|
columnHelper.accessor('alias', {
|
|
|
|
|
id: 'alias',
|
|
|
|
|
header: () => <span className='pl-3'>Имя</span>,
|
|
|
|
|
size: 65,
|
|
|
|
|
minSize: 65,
|
|
|
|
|
footer: undefined,
|
|
|
|
|
cell: props => (
|
2024-09-06 13:49:36 +03:00
|
|
|
|
<BadgeConstituenta
|
|
|
|
|
className='mr-[-0.5rem]'
|
|
|
|
|
theme={colors}
|
|
|
|
|
value={props.row.original}
|
|
|
|
|
prefixID={prefixes.cst_side_table}
|
|
|
|
|
/>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
)
|
|
|
|
|
}),
|
|
|
|
|
columnHelper.accessor(cst => describeConstituenta(cst), {
|
|
|
|
|
id: 'description',
|
|
|
|
|
header: 'Описание',
|
|
|
|
|
size: 1000,
|
|
|
|
|
minSize: 250,
|
|
|
|
|
maxSize: 1000,
|
|
|
|
|
cell: props => (
|
2024-09-02 17:59:43 +03:00
|
|
|
|
<TextContent
|
|
|
|
|
noTooltip
|
|
|
|
|
text={props.getValue()}
|
|
|
|
|
maxLength={DESCRIPTION_MAX_SYMBOLS}
|
2024-06-07 20:17:03 +03:00
|
|
|
|
style={{
|
|
|
|
|
textWrap: 'pretty',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: isMockCst(props.row.original) ? colors.fgWarning : undefined
|
|
|
|
|
}}
|
2024-09-02 17:59:43 +03:00
|
|
|
|
/>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
],
|
|
|
|
|
[colors]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const conditionalRowStyles = useMemo(
|
|
|
|
|
(): IConditionalStyle<IConstituenta>[] => [
|
|
|
|
|
{
|
2024-08-21 17:06:32 +03:00
|
|
|
|
when: (cst: IConstituenta) => !!activeCst && cst.id === activeCst?.id,
|
2024-06-07 20:17:03 +03:00
|
|
|
|
style: {
|
|
|
|
|
backgroundColor: colors.bgSelected
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
2024-08-21 17:06:32 +03:00
|
|
|
|
when: (cst: IConstituenta) => !!activeCst && cst.parent === activeCst?.id && cst.id !== activeCst?.id,
|
2024-06-07 20:17:03 +03:00
|
|
|
|
style: {
|
|
|
|
|
backgroundColor: colors.bgOrange50
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
when: (cst: IConstituenta) => activeCst?.id !== undefined && cst.children.includes(activeCst.id),
|
|
|
|
|
style: {
|
|
|
|
|
backgroundColor: colors.bgGreen50
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
[activeCst, colors]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<DataTable
|
|
|
|
|
dense
|
|
|
|
|
noFooter
|
|
|
|
|
className='text-sm select-none cc-scroll-y'
|
|
|
|
|
style={{ maxHeight: maxHeight }}
|
|
|
|
|
data={items}
|
|
|
|
|
columns={columns}
|
|
|
|
|
conditionalRowStyles={conditionalRowStyles}
|
|
|
|
|
headPosition='0'
|
|
|
|
|
enableHiding
|
|
|
|
|
noDataComponent={
|
2024-06-21 19:16:41 +03:00
|
|
|
|
<NoData className='min-h-[5rem]'>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
<p>Список конституент пуст</p>
|
|
|
|
|
<p>Измените параметры фильтра</p>
|
2024-06-21 19:16:41 +03:00
|
|
|
|
</NoData>
|
2024-06-07 20:17:03 +03:00
|
|
|
|
}
|
|
|
|
|
onRowClicked={handleRowClicked}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-26 19:47:05 +03:00
|
|
|
|
export default TableSideConstituents;
|