feta: inclusão da funcionalidade de expandir e recolher os dados sintéticos

This commit is contained in:
Alessandro Gonçaalves 2025-10-22 10:51:41 -03:00
parent 324730c830
commit acb094271b
1 changed files with 157 additions and 22 deletions

View File

@ -202,6 +202,7 @@ export default function Teste() {
const [isFilterOpen, setIsFilterOpen] = useState(false); const [isFilterOpen, setIsFilterOpen] = useState(false);
const [dadosFiltrados, setDadosFiltrados] = useState<DREItem[]>([]); const [dadosFiltrados, setDadosFiltrados] = useState<DREItem[]>([]);
const [filtrosAplicados, setFiltrosAplicados] = useState(false); const [filtrosAplicados, setFiltrosAplicados] = useState(false);
const [ordemHierarquiaContasPrimeiro, setOrdemHierarquiaContasPrimeiro] = useState(false);
// Estados para opções dos filtros // Estados para opções dos filtros
const [opcoesGrupos, setOpcoesGrupos] = useState<string[]>([]); const [opcoesGrupos, setOpcoesGrupos] = useState<string[]>([]);
@ -526,6 +527,7 @@ export default function Teste() {
setFiltrosAplicados(false); setFiltrosAplicados(false);
setMesesDisponiveis([]); setMesesDisponiveis([]);
setIsAllExpanded(false); setIsAllExpanded(false);
setOrdemHierarquiaContasPrimeiro(false);
// Recarregar opções e selecionar todos novamente // Recarregar opções e selecionar todos novamente
carregarPeriodosDisponiveis(); carregarPeriodosDisponiveis();
@ -786,6 +788,92 @@ export default function Teste() {
}); });
if (expandedSubgrupos.has(`${grupo}-${subgrupo}`)) { if (expandedSubgrupos.has(`${grupo}-${subgrupo}`)) {
if (ordemHierarquiaContasPrimeiro) {
// NOVA ORDEM: Contas primeiro, depois Centros de Custo
// Agrupar por conta dentro do subgrupo
const contas = subgrupoItems.reduce((acc, item) => {
if (!acc[item.conta]) {
acc[item.conta] = [];
}
acc[item.conta].push(item);
return acc;
}, {} as Record<string, DREItem[]>);
// Ordenar contas
const sortedContas = Object.entries(contas).sort(([a], [b]) =>
a.localeCompare(b)
);
sortedContas.forEach(([conta, contaItems]) => {
const totalConta = contaItems.reduce(
(sum, item) => sum + parseFloat(item.valor),
0
);
// Linha da conta (Level 2 - antes era Level 3)
const valoresContaPorMes = calcularValoresPorMes(contaItems);
rows.push({
type: "conta",
level: 2,
grupo,
subgrupo,
conta,
codigo_conta: contaItems[0].codigo_conta,
total: totalConta,
isExpanded: expandedCentros.has(
`${grupo}-${subgrupo}-${conta}`
),
valoresPorMes: valoresContaPorMes,
percentuaisPorMes: calcularPercentuaisPorMes(
valoresContaPorMes,
grupo
),
});
if (expandedCentros.has(`${grupo}-${subgrupo}-${conta}`)) {
// Agrupar por centro de custo dentro da conta
const centros = contaItems.reduce((acc, item) => {
if (!acc[item.centro_custo]) {
acc[item.centro_custo] = [];
}
acc[item.centro_custo].push(item);
return acc;
}, {} as Record<string, DREItem[]>);
// Ordenar centros de custo
const sortedCentros = Object.entries(centros).sort(([a], [b]) =>
a.localeCompare(b)
);
sortedCentros.forEach(([centro, centroItems]) => {
const totalCentro = centroItems.reduce(
(sum, item) => sum + parseFloat(item.valor),
0
);
// Linha do centro de custo (Level 3 - antes era Level 2)
const valoresCentroPorMes = calcularValoresPorMes(centroItems);
rows.push({
type: "centro_custo",
level: 3,
grupo,
subgrupo,
centro_custo: centro,
conta,
total: totalCentro,
valoresPorMes: valoresCentroPorMes,
percentuaisPorMes: calcularPercentuaisPorMes(
valoresCentroPorMes,
grupo
),
});
});
}
});
} else {
// ORDEM ORIGINAL: Centros de Custo primeiro, depois Contas
// Agrupar por centro de custo dentro do subgrupo // Agrupar por centro de custo dentro do subgrupo
const centros = subgrupoItems.reduce((acc, item) => { const centros = subgrupoItems.reduce((acc, item) => {
if (!acc[item.centro_custo]) { if (!acc[item.centro_custo]) {
@ -846,7 +934,7 @@ export default function Teste() {
0 0
); );
// Linha da conta (sem ano/mês no nome) // Linha da conta
const valoresContaPorMes = calcularValoresPorMes(contaItems); const valoresContaPorMes = calcularValoresPorMes(contaItems);
rows.push({ rows.push({
type: "conta", type: "conta",
@ -867,6 +955,7 @@ export default function Teste() {
} }
}); });
} }
}
}); });
} }
}); });
@ -976,6 +1065,13 @@ export default function Teste() {
case "centro_custo": case "centro_custo":
return ( return (
<div className="flex items-center gap-2 whitespace-nowrap"> <div className="flex items-center gap-2 whitespace-nowrap">
{ordemHierarquiaContasPrimeiro ? (
// Nova ordem: Centro de custo é level 3 (sem botão de toggle)
<div className="w-8 h-8 flex items-center justify-center flex-shrink-0">
<span className="text-gray-400 font-bold text-lg"></span>
</div>
) : (
// Ordem original: Centro de custo é level 2 (com botão de toggle)
<button <button
onClick={() => onClick={() =>
toggleCentro(`${row.grupo}-${row.subgrupo}-${row.centro_custo}`) toggleCentro(`${row.grupo}-${row.subgrupo}-${row.centro_custo}`)
@ -988,6 +1084,7 @@ export default function Teste() {
<ChevronRight className="w-4 h-4 text-blue-600 transition-transform duration-150" /> <ChevronRight className="w-4 h-4 text-blue-600 transition-transform duration-150" />
)} )}
</button> </button>
)}
<button <button
onClick={() => handleRowClick(row)} onClick={() => handleRowClick(row)}
className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate" className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate"
@ -1001,9 +1098,26 @@ export default function Teste() {
case "conta": case "conta":
return ( return (
<div className="flex items-center gap-2 whitespace-nowrap"> <div className="flex items-center gap-2 whitespace-nowrap">
{ordemHierarquiaContasPrimeiro ? (
// Nova ordem: Conta é level 2 (com botão de toggle)
<button
onClick={() =>
toggleCentro(`${row.grupo}-${row.subgrupo}-${row.conta}`)
}
className="p-2 hover:bg-blue-100 rounded-lg transition-all duration-150 ease-in-out flex items-center justify-center w-8 h-8 flex-shrink-0 transform hover:scale-105"
>
{row.isExpanded ? (
<ChevronDown className="w-4 h-4 text-blue-600 transition-transform duration-150" />
) : (
<ChevronRight className="w-4 h-4 text-blue-600 transition-transform duration-150" />
)}
</button>
) : (
// Ordem original: Conta é level 3 (sem botão de toggle)
<div className="w-8 h-8 flex items-center justify-center flex-shrink-0"> <div className="w-8 h-8 flex items-center justify-center flex-shrink-0">
<span className="text-gray-400 font-bold text-lg"></span> <span className="text-gray-400 font-bold text-lg"></span>
</div> </div>
)}
<button <button
onClick={() => handleRowClick(row)} onClick={() => handleRowClick(row)}
className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate" className="flex-1 text-left hover:bg-blue-50/50 p-2 rounded-lg cursor-pointer transition-all duration-200 truncate"
@ -1283,6 +1397,27 @@ export default function Teste() {
placeholder="Pesquise por grupo, subgrupo, centro ou conta" placeholder="Pesquise por grupo, subgrupo, centro ou conta"
/> />
</div>*/} </div>*/}
{/* Ordem da Hierarquia */}
<div className="grid gap-2">
<Label>Ordem da Hierarquia</Label>
<div className="flex items-center space-x-2">
<Checkbox
id="ordem-hierarquia"
checked={ordemHierarquiaContasPrimeiro}
onCheckedChange={(checked: boolean) => setOrdemHierarquiaContasPrimeiro(checked)}
/>
<Label htmlFor="ordem-hierarquia" className="text-sm">
Contas antes de Centros de Custo
</Label>
</div>
<div className="text-xs text-gray-500">
{ordemHierarquiaContasPrimeiro
? "📄 Contas → 🏢 Centros de Custo"
: "🏢 Centros de Custo → 📄 Contas"
}
</div>
</div>
</div> </div>
<SheetFooter className="flex gap-2"> <SheetFooter className="flex gap-2">