import { ArrowRightOutlined, DownOutlined, MoreOutlined, RightOutlined } from '@ant-design/icons'; import { Button, Dropdown, Space, message } from 'antd'; import type { ColumnsType, TableProps } from 'antd/es/table'; import { memo, useCallback, useMemo } from 'react'; import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; import { ColumnSettings, DataTable, type TableConfig, isGroup, useFilteredRows, useVisibleColumns } from '../../components/GenericTable'; import { useTableFilters } from '../../components/GenericTable/useTableFilters'; import { useAppSelector } from '../../store/store'; import type { ConsRow } from '../../types/consolidations/consolidations'; import { consConfigBase } from './config'; import { flattenCons } from './flatten'; import { groupAdjacent } from './groupAdjacent'; import { useGrouping } from './useGrouping'; type ActionKey = 'copy' | 'disable_confirm' | 'history'; const ITEMS = [ { key: 'copy', label: 'Добавить версию' }, { key: 'disable_confirm', label: 'Отключить подвтерждение КФО' }, { key: 'history', label: 'История изменений' }, {}, ] as const; const RowActions = memo(function RowActions({ row, onAction, }: { row: ConsRow; onAction: (key: ActionKey, _row: ConsRow) => void; }) { return ( { domEvent.stopPropagation(); onAction(key as ActionKey, row); }, }}> } onClick={(e) => e.stopPropagation()} /> ); }); export function ConsoleTableWidget() { const navigate = useNavigate(); const { group_id } = useParams(); const [searchParams, setSearchParams] = useSearchParams(); const consolidations = useAppSelector((s) => s.consolidations.consolidations); const loading = useAppSelector((s) => s.consolidations.loading); const { columnFilters, setColumnFilters, sort, setSort, resetAll, hasActiveFilters } = useTableFilters(); const rawRows = useMemo(() => flattenCons(consolidations), [consolidations]); // const [sort, setSort] = useState>(null); // no globalQuery state at all const { rows: filtered } = useFilteredRows(rawRows, consConfigBase, '', columnFilters, sort); const grouped = useMemo(() => groupAdjacent(filtered), [filtered]); const { visibleRows, expanded, toggle } = useGrouping(grouped); const config: TableConfig = useMemo( () => ({ ...consConfigBase, columns: consConfigBase.columns.map((col) => isGroup(col) || col.key !== 'year' ? col : { ...col, render: (value, row: ConsRow) => { if (row.isPrimary && row.groupSize > 1) { const open = expanded.has(row.group_id); return ( { e.stopPropagation(); toggle(row.group_id); }} style={{ cursor: 'pointer', display: 'inline-flex', background: 'none', border: 0, padding: 0 }}> {open ? : } {String(value)} ({row.groupSize}) ); } if (!row.isPrimary) { return ( ↳ {String(value)} ); } return {String(value)}; }, }, ), }), [expanded, toggle], ); const { visibleKeys, setVisibleKeys } = useVisibleColumns(config); const handleDropdownAction = useCallback( (key: ActionKey, _row: ConsRow) => { if (key === 'history') { navigate('/logging'); } else { message.info('Будет позже'); } }, [navigate], ); const extraColumns: ColumnsType = useMemo( () => [ { key: 'actions', title: '', width: 120, render: (_: unknown, row: ConsRow) => ( { // иначе клик всплывает до onRow строки, и его setSearchParams(replace) отменяет переход e.stopPropagation(); navigate(`/groups/${group_id}/versions/${row.id}/osv`); }}> К отчётности ), }, ], [navigate, group_id, handleDropdownAction], ); const onRow: TableProps['onRow'] = (row) => ({ // выбранная версия живёт в URL (?version=): переживает уход на «К отчётности» и «Назад» onClick: () => setSearchParams({ version: row.id }, { replace: true }), // выбранная версия подсвечена, как в макете [34] style: row.id === searchParams.get('version') ? { background: '#f0f7ee' } : undefined, }); return ( Консолидации {rawRows.length} шт. {hasActiveFilters && ( { resetAll(); }}> Сбросить фильтры )} ); }