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 */}
-
{isAllExpanded ? (
<>
@@ -934,7 +1058,7 @@ export default function Teste() {
Expandir Tudo
>
)}
-
+
{/* 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}
+ />
))}