import React, { useMemo, useState } from "react"; import { useMaterialReactTable, MaterialReactTable, } from 'material-react-table'; import { Box, Paper, Typography, } from "@mui/material"; import { useNavigate } from 'react-router-dom'; import { firstTableData, secondTableData } from "./mockData"; import { createFirstColumns, secondColumns } from "./columns"; import EditModal from "./components/EditModal/EditModal"; import TableFilters from "./components/TableFilters/TableFilters"; // Импортируем компонент фильтров 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;