From 324730c8302378839570e5b81a4e94441c6fe7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Gon=C3=A7aalves?= Date: Wed, 22 Oct 2025 10:23:54 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20otimiza=C3=A7=C3=A3o=20do=20processo=20d?= =?UTF-8?q?e=20expans=C3=A3o=20do=20drill=20da=20tabela=20sint=C3=A9tica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/DRE/teste.tsx | 330 +++++++++++++++++++++++++----------------- 1 file changed, 195 insertions(+), 135 deletions(-) diff --git a/src/app/DRE/teste.tsx b/src/app/DRE/teste.tsx index d6b605c..51a44ea 100644 --- a/src/app/DRE/teste.tsx +++ b/src/app/DRE/teste.tsx @@ -1,7 +1,7 @@ "use client"; import { LoaderPinwheel, ChevronDown, ChevronRight, Filter, Maximize2, Minimize2 } from "lucide-react"; -import { useEffect, useState } from "react"; +import { useEffect, useState, useCallback, startTransition, memo } from "react"; import AnaliticoComponent from "./analitico"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -53,6 +53,123 @@ interface HierarchicalRow { isCalculado?: boolean; } +// Componente memoizado para linhas da tabela +const TableRow = memo(({ + row, + index, + toggleGroup, + toggleSubgrupo, + toggleCentro, + handleRowClick, + getRowStyle, + getIndentStyle, + renderCellContent, + mesesDisponiveis, + formatCurrency, + formatCurrencyWithColor +}: { + row: HierarchicalRow; + index: number; + toggleGroup: (grupo: string) => void; + toggleSubgrupo: (subgrupo: string) => void; + toggleCentro: (centro: string) => void; + handleRowClick: (row: HierarchicalRow, mes?: string) => void; + getRowStyle: (row: HierarchicalRow) => string; + getIndentStyle: (level: number) => React.CSSProperties; + renderCellContent: (row: HierarchicalRow) => React.ReactNode; + mesesDisponiveis: string[]; + formatCurrency: (value: number) => string; + formatCurrencyWithColor: (value: number) => { formatted: string; isNegative: boolean }; +}) => { + return ( +
+
+ {renderCellContent(row)} +
+ + {/* Colunas de valores por mês */} + {mesesDisponiveis.map((mes) => ( +
+
handleRowClick(row, mes)} + title={ + row.valoresPorMes && row.valoresPorMes[mes] + ? formatCurrency(row.valoresPorMes[mes]) + : "-" + } + > + {row.valoresPorMes && row.valoresPorMes[mes] + ? (() => { + const { formatted, isNegative } = + formatCurrencyWithColor(row.valoresPorMes[mes]); + return ( + + {formatted} + + ); + })() + : "-"} +
+
handleRowClick(row, mes)} + title={ + row.percentuaisPorMes && + row.percentuaisPorMes[mes] !== undefined + ? `${row.percentuaisPorMes[mes].toFixed(1)}%` + : "-" + } + > + {row.percentuaisPorMes && + row.percentuaisPorMes[mes] !== undefined + ? `${row.percentuaisPorMes[mes].toFixed(1)}%` + : "-"} +
+
+ ))} + + {/* Coluna Total */} +
handleRowClick(row)} + title={row.total ? formatCurrency(row.total) : "-"} + > + {(() => { + const { formatted, isNegative } = formatCurrencyWithColor( + row.total! + ); + return ( + + {formatted} + + ); + })()} +
+
+ ); +}); + +TableRow.displayName = 'TableRow'; + export default function Teste() { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); @@ -277,35 +394,41 @@ export default function Teste() { setAnaliticoFiltros(novosFiltros); }; - const toggleGroup = (grupo: string) => { - const newExpanded = new Set(expandedGroups); + const toggleGroup = useCallback((grupo: string) => { + setExpandedGroups(prev => { + const newExpanded = new Set(prev); if (newExpanded.has(grupo)) { newExpanded.delete(grupo); } else { newExpanded.add(grupo); } - setExpandedGroups(newExpanded); - }; + return newExpanded; + }); + }, []); - const toggleSubgrupo = (subgrupo: string) => { - const newExpanded = new Set(expandedSubgrupos); + const toggleSubgrupo = useCallback((subgrupo: string) => { + setExpandedSubgrupos(prev => { + const newExpanded = new Set(prev); if (newExpanded.has(subgrupo)) { newExpanded.delete(subgrupo); } else { newExpanded.add(subgrupo); } - setExpandedSubgrupos(newExpanded); - }; + return newExpanded; + }); + }, []); - const toggleCentro = (centro: string) => { - const newExpanded = new Set(expandedCentros); + const toggleCentro = useCallback((centro: string) => { + setExpandedCentros(prev => { + const newExpanded = new Set(prev); if (newExpanded.has(centro)) { newExpanded.delete(centro); } else { newExpanded.add(centro); } - setExpandedCentros(newExpanded); - }; + return newExpanded; + }); + }, []); const handleFiltroChange = (campo: string, valor: string) => { setFiltros(prev => ({ @@ -351,28 +474,29 @@ export default function Teste() { setContasSelecionadas([]); }; - const toggleExpandAll = () => { + const toggleExpandAll = useCallback(() => { if (isAllExpanded) { - // Recolher tudo - setExpandedGroups(new Set()); - setExpandedSubgrupos(new Set()); - setExpandedCentros(new Set()); - setIsAllExpanded(false); + // Recolher tudo - usar startTransition para atualizações não urgentes + startTransition(() => { + setExpandedGroups(new Set()); + setExpandedSubgrupos(new Set()); + setExpandedCentros(new Set()); + setIsAllExpanded(false); + }); } else { - // Expandir todos os grupos usando dados originais - const todosGrupos = [...new Set(data.map(item => item.grupo))]; - setExpandedGroups(new Set(todosGrupos)); - - // Expandir todos os subgrupos usando dados originais - const todosSubgrupos = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}`))]; - setExpandedSubgrupos(new Set(todosSubgrupos)); - - // Expandir todos os centros de custo usando dados originais (isso também expande as contas automaticamente) - const todosCentros = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}-${item.centro_custo}`))]; - setExpandedCentros(new Set(todosCentros)); - setIsAllExpanded(true); + // Expandir todos os grupos usando dados originais - usar startTransition para atualizações não urgentes + startTransition(() => { + const todosGrupos = [...new Set(data.map(item => item.grupo))]; + const todosSubgrupos = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}`))]; + const todosCentros = [...new Set(data.map(item => `${item.grupo}-${item.subgrupo}-${item.centro_custo}`))]; + + setExpandedGroups(new Set(todosGrupos)); + setExpandedSubgrupos(new Set(todosSubgrupos)); + setExpandedCentros(new Set(todosCentros)); + setIsAllExpanded(true); + }); } - }; + }, [isAllExpanded, data]); const limparFiltros = () => { const agora = new Date(); @@ -802,12 +926,12 @@ export default function Teste() {
- + + {/* Controles */}
{/* Botão de Expandir/Recolher */} - + {/* Botão de Filtro */} @@ -969,7 +1093,7 @@ export default function Teste() { ))} -
+
-
- + + {/* Grupo
@@ -1023,7 +1147,7 @@ export default function Teste() {
-
-
+
{opcoesCentrosCusto.map(centro => (
@@ -1065,7 +1189,7 @@ export default function Teste() { {centrosCustoSelecionados.length} centro(s) selecionado(s)
)} -
+ {/* Conta */}
@@ -1090,7 +1214,7 @@ export default function Teste() { > Limpar -
+
{opcoesContas.map(conta => ( @@ -1252,96 +1376,32 @@ export default function Teste() {
{mes}
% +
- - ))} + ))}
Total
+ - {/* Table Body */}
{hierarchicalData.map((row, index) => ( -
-
- {renderCellContent(row)} -
- {mesesDisponiveis.map((mes) => ( -
-
handleRowClick(row, mes)} - title={ - row.valoresPorMes && row.valoresPorMes[mes] - ? formatCurrency(row.valoresPorMes[mes]) - : "-" - } - > - {row.valoresPorMes && row.valoresPorMes[mes] - ? (() => { - const { formatted, isNegative } = - formatCurrencyWithColor(row.valoresPorMes[mes]); - return ( - - {formatted} - - ); - })() - : "-"} -
-
handleRowClick(row, mes)} - title={ - row.percentuaisPorMes && - row.percentuaisPorMes[mes] !== undefined - ? `${row.percentuaisPorMes[mes].toFixed(1)}%` - : "-" - } - > - {row.percentuaisPorMes && - row.percentuaisPorMes[mes] !== undefined - ? `${row.percentuaisPorMes[mes].toFixed(1)}%` - : "-"} -
-
- ))} -
handleRowClick(row)} - title={row.total ? formatCurrency(row.total) : "-"} - > - {(() => { - const { formatted, isNegative } = formatCurrencyWithColor( - row.total! - ); - return ( - - {formatted} - - ); - })()} -
-
+ row={row} + index={index} + toggleGroup={toggleGroup} + toggleSubgrupo={toggleSubgrupo} + toggleCentro={toggleCentro} + handleRowClick={handleRowClick} + getRowStyle={getRowStyle} + getIndentStyle={getIndentStyle} + renderCellContent={renderCellContent} + mesesDisponiveis={mesesDisponiveis} + formatCurrency={formatCurrency} + formatCurrencyWithColor={formatCurrencyWithColor} + /> ))}