fix: remoção dos filtros avançados

This commit is contained in:
Alessandro Gonçaalves 2025-10-22 19:20:44 -03:00
parent a7adda84a5
commit 7b0c5d2070
1 changed files with 143 additions and 24 deletions

View File

@ -112,6 +112,11 @@ const ExcelFilter: React.FC<ExcelFilterProps> = ({
);
}, [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);
@ -140,6 +145,7 @@ const ExcelFilter: React.FC<ExcelFilterProps> = ({
const handleClear = () => {
setSelectedValues([]);
setSelectAll(false);
onFilterChange(column.field, []);
setIsOpen(false);
};
@ -155,10 +161,10 @@ const ExcelFilter: React.FC<ExcelFilterProps> = ({
<Button
variant="ghost"
size="sm"
className="h-8 w-8 p-0"
className="h-6 w-6 p-0 hover:bg-gray-200 rounded-sm"
onClick={() => setIsOpen(true)}
>
<ArrowUpDown className="h-4 w-4" />
<ArrowUpDown className="h-3 w-3 text-gray-600" />
</Button>
</DialogTrigger>
<DialogContent className="max-w-md">
@ -290,6 +296,12 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
}));
}, []);
// Função para limpar todos os filtros
const clearAllFilters = React.useCallback(() => {
setColumnFilters({});
setColumnSorts({});
}, []);
// Atualizar filtros externos quando os props mudarem
React.useEffect(() => {
console.log('🔄 Analítico - useEffect dos filtros chamado');
@ -559,22 +571,66 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
renderHeader: (params: any) => (
<div className="flex items-center justify-between w-full">
<span className="text-sm font-medium">{col.headerName}</span>
<ExcelFilter
column={col}
data={data}
onFilterChange={handleColumnFilterChange}
onSortChange={handleColumnSortChange}
currentFilter={columnFilters[col.field] || []}
currentSort={columnSorts[col.field] || null}
/>
<div className="flex items-center">
<ExcelFilter
column={col}
data={data}
onFilterChange={handleColumnFilterChange}
onSortChange={handleColumnSortChange}
currentFilter={columnFilters[col.field] || []}
currentSort={columnSorts[col.field] || null}
/>
</div>
</div>
),
}));
}, [data, columnFilters, columnSorts, handleColumnFilterChange, handleColumnSortChange]);
// Calcular totais das colunas de valores
// Filtrar dados baseado nos filtros de coluna
const filteredData = React.useMemo(() => {
if (!data || data.length === 0) return data;
return data.filter((row) => {
return Object.entries(columnFilters).every(([field, filterValues]) => {
if (!filterValues || filterValues.length === 0) return true;
const cellValue = (row as any)[field];
const stringValue = cellValue === null || cellValue === undefined ? "" : String(cellValue);
return filterValues.includes(stringValue);
});
}).map((row, index) => ({
...row,
id: `filtered-${row.id || row.recnum || index}` // Garantir ID único e estável
}));
}, [data, columnFilters]);
// Ordenar dados baseado na ordenação de coluna
const sortedAndFilteredData = React.useMemo(() => {
if (!filteredData || filteredData.length === 0) return filteredData;
const sortField = Object.keys(columnSorts).find(field => columnSorts[field] !== null);
if (!sortField || !columnSorts[sortField]) return filteredData;
return [...filteredData].sort((a, b) => {
const aValue = (a as any)[sortField];
const bValue = (b as any)[sortField];
// Converter para string para comparação
const aString = aValue === null || aValue === undefined ? "" : String(aValue);
const bString = bValue === null || bValue === undefined ? "" : String(bValue);
if (columnSorts[sortField] === 'asc') {
return aString.localeCompare(bString);
} else {
return bString.localeCompare(aString);
}
});
}, [filteredData, columnSorts]);
// Calcular totais das colunas de valores (usando dados filtrados)
const columnTotals = React.useMemo(() => {
if (!data || data.length === 0) {
if (!sortedAndFilteredData || sortedAndFilteredData.length === 0) {
return {
valorRealizado: 0,
valorPrevisto: 0,
@ -583,22 +639,22 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
};
}
const valorRealizado = data.reduce((sum, item) => {
const valorRealizado = sortedAndFilteredData.reduce((sum, item) => {
const valor = typeof item.valor === "string" ? parseFloat(item.valor) : item.valor;
return sum + (isNaN(valor) ? 0 : valor);
}, 0);
const valorPrevisto = data.reduce((sum, item) => {
const valorPrevisto = sortedAndFilteredData.reduce((sum, item) => {
const valor = typeof item.valor_previsto === "string" ? parseFloat(item.valor_previsto) : (item.valor_previsto || 0);
return sum + (isNaN(valor) ? 0 : valor);
}, 0);
const valorConfirmado = data.reduce((sum, item) => {
const valorConfirmado = sortedAndFilteredData.reduce((sum, item) => {
const valor = typeof item.valor_confirmado === "string" ? parseFloat(item.valor_confirmado) : (item.valor_confirmado || 0);
return sum + (isNaN(valor) ? 0 : valor);
}, 0);
const valorPago = data.reduce((sum, item) => {
const valorPago = sortedAndFilteredData.reduce((sum, item) => {
const valor = typeof item.valor_pago === "string" ? parseFloat(item.valor_pago) : (item.valor_pago || 0);
return sum + (isNaN(valor) ? 0 : valor);
}, 0);
@ -609,13 +665,13 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
valorConfirmado,
valorPago,
};
}, [data]);
}, [sortedAndFilteredData]);
// Exportação XLSX
const exportToExcel = () => {
if (data.length === 0) return;
if (sortedAndFilteredData.length === 0) return;
const exportData = data.map((item) => ({
const exportData = sortedAndFilteredData.map((item) => ({
"Data Competência": item.data_competencia
? new Date(item.data_competencia).toLocaleDateString("pt-BR")
: "-",
@ -684,7 +740,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
{/* Controls */}
<div className="flex gap-2 flex-wrap">
<Input
{/* <Input
placeholder="Filtrar tudo..."
value={globalFilter ?? ""}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
@ -699,7 +755,7 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
>
<Filter className="w-4 h-4 mr-2" />
Filtros Avançados
</Button>
</Button> */}
{globalFilter && (
<Button
variant="outline"
@ -711,15 +767,26 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
</Button>
)}
{data.length > 0 && (
<div className="flex items-center gap-2">
<Button
onClick={clearAllFilters}
variant="outline"
size="sm"
className="flex items-center gap-2 bg-white border-gray-300 hover:bg-red-50 hover:border-red-300 text-gray-700"
>
<X className="h-4 w-4" />
Limpar Filtros
</Button>
<Button
onClick={exportToExcel}
variant="outline"
size="sm"
className="flex items-center gap-2 bg-white border-gray-300 hover:bg-green-50 hover:border-green-300 text-gray-700"
className="flex items-center gap-2 bg-white border-gray-300 hover:bg-green-50 hover:border-green-300 text-gray-700"
>
<Download className="h-4 w-4" />
Exportar XLSX
</Button>
</div>
)}
</div>
</div>
@ -778,12 +845,16 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
<div style={{ height: "calc(100% - 2rem)", width: "100%" }}>
<DataGrid
rows={data}
key={`datagrid-${sortedAndFilteredData.length}-${Object.keys(columnFilters).length}`}
rows={sortedAndFilteredData}
columns={columns}
loading={loading}
disableRowSelectionOnClick
density="compact"
slots={{ toolbar: GridToolbar }}
disableColumnMenu={true}
disableColumnSorting={true}
getRowId={(row) => row.id || `row-${row.recnum || Math.random()}`}
initialState={{
sorting: { sortModel: [{ field: "data_vencimento", sort: "desc" }] },
}}
@ -805,6 +876,54 @@ export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
borderBottom: "1px solid #e5e7eb",
padding: "8px 16px",
},
// Ocultar todos os ícones nativos das colunas
"& .MuiDataGrid-columnHeaderMenuContainer": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderMenuButton": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderSortIcon": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderSortIconContainer": {
display: "none !important",
},
"& .MuiDataGrid-iconButtonContainer": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderSeparator": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderSortButton": {
display: "none !important",
},
// Ocultar qualquer ícone de menu adicional
"& .MuiDataGrid-menuIcon": {
display: "none !important",
},
"& .MuiDataGrid-menuIconButton": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderMenuIcon": {
display: "none !important",
},
"& .MuiDataGrid-columnHeaderMenuIconButton": {
display: "none !important",
},
"& .MuiDataGrid-menuContainer": {
display: "none !important",
},
"& .MuiDataGrid-menu": {
display: "none !important",
},
// Garantir que nosso botão customizado apareça
"& .MuiDataGrid-columnHeaderTitleContainer": {
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
},
"& .MuiDataGrid-footerContainer": {
backgroundColor: "#f8fafc",
borderTop: "1px solid #e5e7eb",