diff --git a/src/app/DRE/analitico.tsx b/src/app/DRE/analitico.tsx index b0bbb5d..19d5972 100644 --- a/src/app/DRE/analitico.tsx +++ b/src/app/DRE/analitico.tsx @@ -106,6 +106,11 @@ const ExcelFilter: React.FC = ({ const [selectedValues, setSelectedValues] = React.useState(currentFilter); const [selectAll, setSelectAll] = React.useState(false); + // Sincronizar selectedValues com currentFilter quando ele mudar + React.useEffect(() => { + setSelectedValues(currentFilter); + }, [currentFilter]); + // Obter valores únicos da coluna baseado nos dados filtrados const uniqueValues = React.useMemo(() => { const values = filteredData @@ -128,30 +133,25 @@ const ExcelFilter: React.FC = ({ ); }, [uniqueValues, searchTerm]); - // Sincronizar estado local com filtros atuais - React.useEffect(() => { - setSelectedValues(currentFilter); - }, [currentFilter]); - - // Verificar se todos estão selecionados - React.useEffect(() => { - setSelectAll(selectedValues.length === filteredValues.length && filteredValues.length > 0); - }, [selectedValues, filteredValues]); - const handleSelectAll = (checked: boolean) => { if (checked) { setSelectedValues(filteredValues); + setSelectAll(true); } else { setSelectedValues([]); + setSelectAll(false); } }; const handleValueToggle = (value: string, checked: boolean) => { + let newValues: string[]; if (checked) { - setSelectedValues([...selectedValues, value]); + newValues = [...selectedValues, value]; } else { - setSelectedValues(selectedValues.filter((v) => v !== value)); + newValues = selectedValues.filter((v) => v !== value); } + setSelectedValues(newValues); + setSelectAll(newValues.length === filteredValues.length && filteredValues.length > 0); }; const handleApply = () => { @@ -294,6 +294,9 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { { column: "", operator: "contains", value: "" }, ]); + // Estados para o card de agregação customizado (simplificado) + const [aggregationCardRef, setAggregationCardRef] = React.useState(null); + // Estado para armazenar filtros externos (vindos do teste.tsx) const [filtrosExternos, setFiltrosExternos] = React.useState(filtros); @@ -426,6 +429,26 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { })); }, [data, columnFilters]); + // Função para renderizar header com filtro Excel + const renderHeaderWithFilter = React.useCallback((column: GridColDef) => { + return (params: any) => ( +
+ {column.headerName} +
+ +
+
+ ); + }, [data, filteredData, columnFilters, columnSorts, handleColumnFilterChange, handleColumnSortChange]); + // Definir colunas do DataGridPro const columns = React.useMemo(() => { const baseColumns = [ @@ -511,7 +534,6 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { width: 140, sortable: true, resizable: true, - aggregable: true, renderCell: (params: any) => { const value = params.value; if (value === null || value === undefined || value === "") return "-"; @@ -535,7 +557,6 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { width: 130, sortable: true, resizable: true, - aggregable: true, renderCell: (params: any) => { const value = params.value; if (value === null || value === undefined || value === "" || value === 0) return "-"; @@ -559,7 +580,6 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { width: 140, sortable: true, resizable: true, - aggregable: true, renderCell: (params: any) => { const value = params.value; if (value === null || value === undefined || value === "" || value === 0) return "-"; @@ -583,7 +603,6 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { width: 130, sortable: true, resizable: true, - aggregable: true, renderCell: (params: any) => { const value = params.value; if (value === null || value === undefined || value === "" || value === 0) return "-"; @@ -629,24 +648,9 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { // Adicionar renderHeader com filtro Excel para todas as colunas return baseColumns.map((col) => ({ ...col, - renderHeader: (params: any) => ( -
- {col.headerName} -
- -
-
- ), + renderHeader: renderHeaderWithFilter(col), })); - }, [data, filteredData, columnFilters, columnSorts, handleColumnFilterChange, handleColumnSortChange]); + }, [renderHeaderWithFilter]); // Ordenar dados baseado na ordenação de coluna const sortedAndFilteredData = React.useMemo(() => { @@ -676,6 +680,16 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { return sortedAndFilteredData.reduce((sum, item) => sum + (Number(item.valor) || 0), 0); }, [sortedAndFilteredData]); + // Calcular totais das colunas de valor para o card de agregação + const columnTotals = React.useMemo(() => { + return { + valor: sortedAndFilteredData.reduce((sum, item) => sum + (Number(item.valor) || 0), 0), + valor_previsto: sortedAndFilteredData.reduce((sum, item) => sum + (Number(item.valor_previsto) || 0), 0), + valor_confirmado: sortedAndFilteredData.reduce((sum, item) => sum + (Number(item.valor_confirmado) || 0), 0), + valor_pago: sortedAndFilteredData.reduce((sum, item) => sum + (Number(item.valor_pago) || 0), 0), + }; + }, [sortedAndFilteredData]); + // Limpar filtros de colunas que não têm mais valores disponíveis React.useEffect(() => { const updatedFilters = { ...columnFilters }; @@ -771,7 +785,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { }; return ( -
+
{/* Header Section */}
@@ -880,8 +894,8 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
{/* DataGridPro */} - - + +

@@ -911,18 +925,9 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { disableColumnSorting={true} pagination={false} disableVirtualization={false} - initialState={{ - aggregation: { - model: { - valor: 'sum', - valor_previsto: 'sum', - valor_confirmado: 'sum', - valor_pago: 'sum', - }, - }, - }} getRowId={(row: any) => row.id || `row-${row.recnum || Math.random()}`} sx={{ + overflowAnchor: 'none', "& .MuiDataGrid-columnHeaders": { position: "sticky", top: 0, @@ -936,7 +941,8 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { }, "& .MuiDataGrid-virtualScroller": { overflowY: "auto", - maxHeight: "calc(40vh - 120px)" + maxHeight: "calc(40vh - 120px)", + overflowAnchor: 'none' }, "& .MuiDataGrid-toolbarContainer": { backgroundColor: "#f8fafc", @@ -1004,7 +1010,66 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { }} /> + {/* Card de Agregação Customizado - Usando position: sticky */} + {sortedAndFilteredData.length > 0 && ( +
+
+
+
+
+ Vl.Realizado: + + {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(columnTotals.valor)} +
+ +
+ Vl.Previsto: + + {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(columnTotals.valor_previsto)} + +
+ +
+ Vl.Confirmado: + + {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(columnTotals.valor_confirmado)} + +
+ +
+ Vl.Pago: + + {new Intl.NumberFormat("pt-BR", { + style: "currency", + currency: "BRL", + }).format(columnTotals.valor_pago)} + +
+
+ +
+ Total de Registros: {sortedAndFilteredData.length} +
+
+
+
+ )} + +

@@ -1052,7 +1117,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) { ))} -
+
); }