import { Box, Paper, Typography } from '@mui/material'; import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; import { useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { createFirstColumns, secondColumns } from './columns'; import EditModal from './components/EditModal/EditModal'; import TableFilters from './components/TableFilters/TableFilters'; // Импортируем компонент фильтров import { firstTableData, secondTableData } from './mockData'; import { handleEditClick, handleNavigateClick, handleSaveEdit } from './utils/tableHandlers'; const SummaryPage = () => { const navigate = useNavigate(); const [selectedRow, setSelectedRow] = useState(null); const [editModalOpen, setEditModalOpen] = useState(false); const [selectedRowData, setSelectedRowData] = useState(null); const [tableData, setTableData] = useState(firstTableData); // Состояния для фильтров const [selectedBranch, setSelectedBranch] = useState(''); const [searchQuery, setSearchQuery] = useState(''); const getFilteredData = () => { if (!selectedBranch && !searchQuery) { return tableData; } return tableData .filter((item) => { // Фильтр по филиалу (только для корневых) if (selectedBranch) { return item.org_unit_id === selectedBranch.id; } return true; }) .map((item) => { if (!searchQuery) { return item; } const query = searchQuery.toLowerCase().trim(); // Проверяем, совпадает ли родитель const parentMatches = item.project.toLowerCase().includes(query); // Фильтруем дочерние элементы - оставляем только те, что совпадают с поиском const filteredSubRows = item.subRows?.filter((subItem) => subItem.project.toLowerCase().includes(query)) || []; // Возвращаем элемент с отфильтрованными дочерними элементами return { ...item, subRows: filteredSubRows, }; }) .filter((item) => { if (!searchQuery) { return true; } const query = searchQuery.toLowerCase().trim(); const parentMatches = item.project.toLowerCase().includes(query); const hasMatchingChildren = item.subRows && item.subRows.length > 0; return parentMatches || hasMatchingChildren; }); }; const filteredData = getFilteredData(); const handleRowClick = (row) => { if (row.depth === 0 && row) { setSelectedRow(row); } }; const isChildOfSelectedRow = (row) => { if (!selectedRow) return false; const parentRowId = row.parentId; return parentRowId === selectedRow.id; }; const onEdit = (row) => { handleEditClick(row, setEditModalOpen, setSelectedRowData); }; const onNavigate = (row) => { handleNavigateClick(row, navigate); }; const onSaveEdit = (formData) => { handleSaveEdit(formData, updateTableData); }; const updateTableData = (updatedData) => { setTableData((prevData) => prevData.map((item) => (item.id === updatedData.id ? { ...item, ...updatedData } : item))); }; const firstColumns = useMemo(() => createFirstColumns({ onEdit, onNavigate }), [onEdit, onNavigate]); const tableHeadCellStyles = { fontWeight: 700, fontSize: '12px', lineHeight: 1.15, textAlign: 'left', backgroundColor: 'rgb(248, 249, 250)', borderRight: '1px solid #e0e0e0', '&:last-child': { borderRight: 'none', }, whiteSpace: 'nowrap', position: 'sticky', top: 0, boxShadow: 'none', padding: '0.5rem 1rem', '& .MuiTableSortLabel-icon': { fontSize: '0.875rem', }, '& .MuiTableSortLabel-iconDirectionDesc': { fontSize: '0.875rem', }, '& .MuiTableSortLabel-iconDirectionAsc': { fontSize: '0.875rem', }, }; const summaryProjectsTableOptions = { enableColumnActions: false, enableColumnFilters: false, enablePagination: false, enableSorting: true, enableBottomToolbar: false, enableTopToolbar: false, enableExpanding: true, getSubRows: (row) => row.subRows, muiTableHeadCellProps: { sx: tableHeadCellStyles, }, muiExpandButtonProps: { sx: { width: '1.5rem', height: '1.5rem', minWidth: '1.5rem', '& .MuiSvgIcon-root': { fontSize: '0.875rem', }, }, }, muiTableBodyRowProps: ({ row }) => { const isSelected = selectedRow && row.id === selectedRow.id; const isChild = isChildOfSelectedRow(row); return { sx: { backgroundColor: '#ffffff', '&:hover': { backgroundColor: 'rgb(248, 250, 252)', }, '&:hover td::after': { backgroundColor: 'transparent !important', }, ...(row.depth > 0 && { backgroundColor: 'rgb(252, 252, 253)', }), ...((isSelected || isChild) && { backgroundColor: 'rgb(234, 247, 236)', '&:hover': { backgroundColor: 'rgb(225, 242, 229) !important', }, }), }, onClick: () => handleRowClick(row), }; }, muiTableBodyCellProps: ({ row, column }) => ({ sx: { borderRight: '1px solid #e0e0e0', '&:last-child': { borderRight: 'none', }, '&:hover td::after': { backgroundColor: 'transparent !important', }, textAlign: 'left', fontSize: '0.875rem', padding: '0.5rem 1rem', ...(column.id === 'mrt-row-expand' && { width: '1.5rem', maxWidth: '1.5rem', minWidth: '1.5rem', padding: '0.5rem 0.25rem', }), ...(column.id === 'project' && row.depth > 0 && { pl: `${2 + row.depth * 0.5}rem`, }), }, }), muiTablePaperProps: { elevation: 0, sx: { border: '1px solid #e0e0e0', borderRadius: '1rem', overflow: 'hidden', height: '45vh', display: 'flex', flexDirection: 'column', }, }, muiTableContainerProps: { sx: { flex: 1, overflow: 'auto', '& thead': { position: 'sticky', top: 0, zIndex: 10, }, }, }, }; const projectTableOptions = { enableColumnActions: false, enableColumnFilters: false, enablePagination: false, enableSorting: true, enableBottomToolbar: false, enableTopToolbar: false, enableExpanding: false, muiTableBodyRowProps: ({ row }) => ({ sx: { backgroundColor: '#ffffff', '&:hover': { backgroundColor: 'rgb(248, 250, 252)', }, '&:hover td::after': { backgroundColor: 'transparent !important', }, boxShadow: 'none', }, }), muiTableHeadCellProps: { sx: tableHeadCellStyles, }, muiTableBodyCellProps: ({ column }) => ({ sx: { borderRight: '1px solid #e0e0e0', '&:last-child': { borderRight: 'none', }, textAlign: 'left', fontSize: '0.875rem', padding: '0.5rem 1rem', }, }), muiTablePaperProps: { elevation: 0, sx: { border: '1px solid #e0e0e0', borderRadius: '0 0 1rem 1rem', overflow: 'hidden', height: '35vh', display: 'flex', flexDirection: 'column', }, }, muiTableContainerProps: { sx: { flex: 1, overflow: 'auto', '& thead': { position: 'sticky', top: 0, zIndex: 10, }, }, }, initialState: { columnPinning: { left: ['project'] }, }, }; const summaryProjectsTable = useMaterialReactTable({ columns: firstColumns, data: filteredData, ...summaryProjectsTableOptions, initialState: { columnPinning: { right: ['actions'], left: ['mrt-row-expand', 'project'] }, }, }); const projectTable = useMaterialReactTable({ columns: secondColumns, data: selectedRow ? secondTableData[selectedRow.original.id] : [], ...projectTableOptions, }); const getSelectedProjectTitle = () => { if (selectedRow && selectedRow.original.project) { return selectedRow.original.project; } return 'Проект не выбран'; }; // Обработчики фильтров const handleBranchChange = (value) => { setSelectedBranch(value); }; const handleSearchChange = (value) => { setSearchQuery(value); }; return ( {/* Компонент фильтров */} {}} // Можно использовать для дополнительной логики selectedBranch={selectedBranch} onBranchChange={handleBranchChange} searchQuery={searchQuery} onSearchChange={handleSearchChange} /> {/* Первая таблица */} {/* Вторая таблица */} {getSelectedProjectTitle()} {selectedRow ? ( ) : ( Разверните или выберите проект в верхней таблице )} {/* Модалка редактирования */} setEditModalOpen(false)} rowData={selectedRowData} onSave={onSaveEdit} /> ); }; export default SummaryPage;