feta: inclusão da funcionalidade de expandir e recolher os dados sintéticos
This commit is contained in:
parent
324730c830
commit
acb094271b
|
|
@ -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,8 +788,52 @@ export default function Teste() {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (expandedSubgrupos.has(`${grupo}-${subgrupo}`)) {
|
if (expandedSubgrupos.has(`${grupo}-${subgrupo}`)) {
|
||||||
// Agrupar por centro de custo dentro do subgrupo
|
if (ordemHierarquiaContasPrimeiro) {
|
||||||
const centros = subgrupoItems.reduce((acc, item) => {
|
// 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]) {
|
if (!acc[item.centro_custo]) {
|
||||||
acc[item.centro_custo] = [];
|
acc[item.centro_custo] = [];
|
||||||
}
|
}
|
||||||
|
|
@ -796,9 +842,51 @@ export default function Teste() {
|
||||||
}, {} as Record<string, DREItem[]>);
|
}, {} as Record<string, DREItem[]>);
|
||||||
|
|
||||||
// Ordenar centros de custo
|
// Ordenar centros de custo
|
||||||
const sortedCentros = Object.entries(centros).sort(([a], [b]) =>
|
const sortedCentros = Object.entries(centros).sort(([a], [b]) =>
|
||||||
a.localeCompare(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
|
||||||
|
const centros = subgrupoItems.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]) => {
|
sortedCentros.forEach(([centro, centroItems]) => {
|
||||||
const totalCentro = centroItems.reduce(
|
const totalCentro = centroItems.reduce(
|
||||||
|
|
@ -809,7 +897,7 @@ export default function Teste() {
|
||||||
// Linha do centro de custo
|
// Linha do centro de custo
|
||||||
const valoresCentroPorMes = calcularValoresPorMes(centroItems);
|
const valoresCentroPorMes = calcularValoresPorMes(centroItems);
|
||||||
rows.push({
|
rows.push({
|
||||||
type: "centro_custo",
|
type: "centro_custo",
|
||||||
level: 2,
|
level: 2,
|
||||||
grupo,
|
grupo,
|
||||||
subgrupo,
|
subgrupo,
|
||||||
|
|
@ -836,9 +924,9 @@ export default function Teste() {
|
||||||
}, {} as Record<string, DREItem[]>);
|
}, {} as Record<string, DREItem[]>);
|
||||||
|
|
||||||
// Ordenar contas
|
// Ordenar contas
|
||||||
const sortedContas = Object.entries(contas).sort(([a], [b]) =>
|
const sortedContas = Object.entries(contas).sort(([a], [b]) =>
|
||||||
a.localeCompare(b)
|
a.localeCompare(b)
|
||||||
);
|
);
|
||||||
|
|
||||||
sortedContas.forEach(([conta, contaItems]) => {
|
sortedContas.forEach(([conta, contaItems]) => {
|
||||||
const totalConta = contaItems.reduce(
|
const totalConta = contaItems.reduce(
|
||||||
|
|
@ -846,10 +934,10 @@ 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",
|
||||||
level: 3,
|
level: 3,
|
||||||
grupo,
|
grupo,
|
||||||
subgrupo,
|
subgrupo,
|
||||||
|
|
@ -866,6 +954,7 @@ export default function Teste() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -976,18 +1065,26 @@ 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}`)
|
||||||
}
|
}
|
||||||
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"
|
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 ? (
|
{row.isExpanded ? (
|
||||||
<ChevronDown className="w-4 h-4 text-blue-600 transition-transform duration-150" />
|
<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" />
|
<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">
|
||||||
<div className="w-8 h-8 flex items-center justify-center flex-shrink-0">
|
{ordemHierarquiaContasPrimeiro ? (
|
||||||
<span className="text-gray-400 font-bold text-lg">•</span>
|
// Nova ordem: Conta é level 2 (com botão de toggle)
|
||||||
</div>
|
<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">
|
||||||
|
<span className="text-gray-400 font-bold text-lg">•</span>
|
||||||
|
</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"
|
||||||
|
|
@ -1214,7 +1328,7 @@ export default function Teste() {
|
||||||
>
|
>
|
||||||
Limpar
|
Limpar
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-32 overflow-y-auto border rounded-md p-1 space-y-1">
|
<div className="max-h-32 overflow-y-auto border rounded-md p-1 space-y-1">
|
||||||
{opcoesContas.map(conta => (
|
{opcoesContas.map(conta => (
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue