fix: ajuste nos filtros gerais
This commit is contained in:
parent
7d65d4583d
commit
69a66a6cab
|
|
@ -8,6 +8,7 @@
|
||||||
"name": "dre-gerencial",
|
"name": "dre-gerencial",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-checkbox": "^1.3.3",
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-label": "^2.1.7",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
|
|
@ -1536,6 +1537,36 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-checkbox": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@radix-ui/primitive": "1.1.3",
|
||||||
|
"@radix-ui/react-compose-refs": "1.1.2",
|
||||||
|
"@radix-ui/react-context": "1.1.2",
|
||||||
|
"@radix-ui/react-presence": "1.1.5",
|
||||||
|
"@radix-ui/react-primitive": "2.1.3",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.2.2",
|
||||||
|
"@radix-ui/react-use-previous": "1.1.1",
|
||||||
|
"@radix-ui/react-use-size": "1.1.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-collection": {
|
"node_modules/@radix-ui/react-collection": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
"lint": "eslint"
|
"lint": "eslint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-checkbox": "^1.3.3",
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-label": "^2.1.7",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import AnaliticoComponent from "./analitico";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import {
|
import {
|
||||||
Sheet,
|
Sheet,
|
||||||
SheetContent,
|
SheetContent,
|
||||||
|
|
@ -77,6 +78,10 @@ export default function Teste() {
|
||||||
valorMax: "",
|
valorMax: "",
|
||||||
buscaTextual: ""
|
buscaTextual: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Estados para multi-seleção
|
||||||
|
const [centrosCustoSelecionados, setCentrosCustoSelecionados] = useState<string[]>([]);
|
||||||
|
const [contasSelecionadas, setContasSelecionadas] = useState<string[]>([]);
|
||||||
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);
|
||||||
|
|
@ -144,6 +149,10 @@ export default function Teste() {
|
||||||
const contasUnicas = [...new Set(dadosCompletos.map((item: DREItem) => item.conta))].sort() as string[];
|
const contasUnicas = [...new Set(dadosCompletos.map((item: DREItem) => item.conta))].sort() as string[];
|
||||||
setOpcoesContas(contasUnicas);
|
setOpcoesContas(contasUnicas);
|
||||||
|
|
||||||
|
// Inicializar com todos os itens selecionados
|
||||||
|
setCentrosCustoSelecionados(centrosCustoUnicos);
|
||||||
|
setContasSelecionadas(contasUnicas);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erro ao carregar períodos:", error);
|
console.error("Erro ao carregar períodos:", error);
|
||||||
}
|
}
|
||||||
|
|
@ -304,6 +313,43 @@ export default function Teste() {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Funções para multi-seleção
|
||||||
|
const toggleCentroCusto = (centro: string) => {
|
||||||
|
setCentrosCustoSelecionados(prev => {
|
||||||
|
if (prev.includes(centro)) {
|
||||||
|
return prev.filter(c => c !== centro);
|
||||||
|
} else {
|
||||||
|
return [...prev, centro];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleConta = (conta: string) => {
|
||||||
|
setContasSelecionadas(prev => {
|
||||||
|
if (prev.includes(conta)) {
|
||||||
|
return prev.filter(c => c !== conta);
|
||||||
|
} else {
|
||||||
|
return [...prev, conta];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const selecionarTodosCentros = () => {
|
||||||
|
setCentrosCustoSelecionados(opcoesCentrosCusto);
|
||||||
|
};
|
||||||
|
|
||||||
|
const limparCentros = () => {
|
||||||
|
setCentrosCustoSelecionados([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const selecionarTodasContas = () => {
|
||||||
|
setContasSelecionadas(opcoesContas);
|
||||||
|
};
|
||||||
|
|
||||||
|
const limparContas = () => {
|
||||||
|
setContasSelecionadas([]);
|
||||||
|
};
|
||||||
|
|
||||||
const limparFiltros = () => {
|
const limparFiltros = () => {
|
||||||
const agora = new Date();
|
const agora = new Date();
|
||||||
const anoAtual = agora.getFullYear();
|
const anoAtual = agora.getFullYear();
|
||||||
|
|
@ -322,11 +368,18 @@ export default function Teste() {
|
||||||
buscaTextual: ""
|
buscaTextual: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Limpar multi-seleções
|
||||||
|
setCentrosCustoSelecionados([]);
|
||||||
|
setContasSelecionadas([]);
|
||||||
|
|
||||||
// Limpar dados da tabela
|
// Limpar dados da tabela
|
||||||
setData([]);
|
setData([]);
|
||||||
setDadosFiltrados([]);
|
setDadosFiltrados([]);
|
||||||
setFiltrosAplicados(false);
|
setFiltrosAplicados(false);
|
||||||
setMesesDisponiveis([]);
|
setMesesDisponiveis([]);
|
||||||
|
|
||||||
|
// Recarregar opções e selecionar todos novamente
|
||||||
|
carregarPeriodosDisponiveis();
|
||||||
};
|
};
|
||||||
|
|
||||||
const aplicarFiltros = async () => {
|
const aplicarFiltros = async () => {
|
||||||
|
|
@ -372,17 +425,17 @@ export default function Teste() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filtro por centro de custo
|
// Filtro por centro de custo (multi-seleção)
|
||||||
if (filtros.centroCusto !== "Todos") {
|
if (centrosCustoSelecionados.length > 0) {
|
||||||
dadosFiltrados = dadosFiltrados.filter((item: DREItem) =>
|
dadosFiltrados = dadosFiltrados.filter((item: DREItem) =>
|
||||||
item.centro_custo === filtros.centroCusto
|
centrosCustoSelecionados.includes(item.centro_custo)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filtro por conta
|
// Filtro por conta (multi-seleção)
|
||||||
if (filtros.conta !== "Todas") {
|
if (contasSelecionadas.length > 0) {
|
||||||
dadosFiltrados = dadosFiltrados.filter((item: DREItem) =>
|
dadosFiltrados = dadosFiltrados.filter((item: DREItem) =>
|
||||||
item.conta === filtros.conta
|
contasSelecionadas.includes(item.conta)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -739,7 +792,8 @@ export default function Teste() {
|
||||||
{row.grupo}
|
{row.grupo}
|
||||||
</span>
|
</span>
|
||||||
{isCalculado && (
|
{isCalculado && (
|
||||||
<span className="text-blue-600 font-bold text-sm">⚡</span>
|
// <span className="text-blue-600 font-bold text-sm">⚡</span>
|
||||||
|
<></>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -914,37 +968,103 @@ export default function Teste() {
|
||||||
</Select>
|
</Select>
|
||||||
</div>*/}
|
</div>*/}
|
||||||
|
|
||||||
{/* Centro de Custo
|
{/* Centro de Custo */}
|
||||||
<div className="grid gap-3">
|
<div className="grid gap-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="centro-custo">CENTRO DE CUSTO</Label>
|
<Label htmlFor="centro-custo">CENTRO DE CUSTO</Label>
|
||||||
<Select value={filtros.centroCusto} onValueChange={(value) => handleFiltroChange('centroCusto', value)}>
|
<div className="flex gap-2">
|
||||||
<SelectTrigger>
|
<Button
|
||||||
<SelectValue placeholder="Selecione" />
|
type="button"
|
||||||
</SelectTrigger>
|
variant="outline"
|
||||||
<SelectContent>
|
size="sm"
|
||||||
<SelectItem value="Todos">Todos</SelectItem>
|
onClick={selecionarTodosCentros}
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
>
|
||||||
|
Todos
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={limparCentros}
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
>
|
||||||
|
Limpar
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="max-h-32 overflow-y-auto border rounded-md p-2 space-y-2">
|
||||||
{opcoesCentrosCusto.map(centro => (
|
{opcoesCentrosCusto.map(centro => (
|
||||||
<SelectItem key={centro} value={centro}>{centro}</SelectItem>
|
<div key={centro} className="flex items-center space-x-2">
|
||||||
|
<Checkbox
|
||||||
|
id={`centro-${centro}`}
|
||||||
|
checked={centrosCustoSelecionados.includes(centro)}
|
||||||
|
onCheckedChange={() => toggleCentroCusto(centro)}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
htmlFor={`centro-${centro}`}
|
||||||
|
className="text-sm font-normal cursor-pointer flex-1"
|
||||||
|
>
|
||||||
|
{centro}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</div>
|
||||||
</Select>
|
{centrosCustoSelecionados.length > 0 && (
|
||||||
</div>*/}
|
<div className="text-xs text-gray-500">
|
||||||
|
{centrosCustoSelecionados.length} centro(s) selecionado(s)
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Conta
|
{/* Conta */}
|
||||||
<div className="grid gap-3">
|
<div className="grid gap-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="conta">CONTA</Label>
|
<Label htmlFor="conta">CONTA</Label>
|
||||||
<Select value={filtros.conta} onValueChange={(value) => handleFiltroChange('conta', value)}>
|
<div className="flex gap-2">
|
||||||
<SelectTrigger>
|
<Button
|
||||||
<SelectValue placeholder="Selecione" />
|
type="button"
|
||||||
</SelectTrigger>
|
variant="outline"
|
||||||
<SelectContent>
|
size="sm"
|
||||||
<SelectItem value="Todas">Todas</SelectItem>
|
onClick={selecionarTodasContas}
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
>
|
||||||
|
Todas
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={limparContas}
|
||||||
|
className="text-xs h-6 px-2"
|
||||||
|
>
|
||||||
|
Limpar
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="max-h-32 overflow-y-auto border rounded-md p-2 space-y-2">
|
||||||
{opcoesContas.map(conta => (
|
{opcoesContas.map(conta => (
|
||||||
<SelectItem key={conta} value={conta}>{conta}</SelectItem>
|
<div key={conta} className="flex items-center space-x-2">
|
||||||
|
<Checkbox
|
||||||
|
id={`conta-${conta}`}
|
||||||
|
checked={contasSelecionadas.includes(conta)}
|
||||||
|
onCheckedChange={() => toggleConta(conta)}
|
||||||
|
/>
|
||||||
|
<Label
|
||||||
|
htmlFor={`conta-${conta}`}
|
||||||
|
className="text-sm font-normal cursor-pointer flex-1"
|
||||||
|
>
|
||||||
|
{conta}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</SelectContent>
|
</div>
|
||||||
</Select>
|
{contasSelecionadas.length > 0 && (
|
||||||
</div>*/}
|
<div className="text-xs text-gray-500">
|
||||||
|
{contasSelecionadas.length} conta(s) selecionada(s)
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Valor
|
{/* Valor
|
||||||
<div className="grid gap-3">
|
<div className="grid gap-3">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
|
||||||
|
import { Check } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Checkbox = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<CheckboxPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<CheckboxPrimitive.Indicator
|
||||||
|
className={cn("flex items-center justify-center text-current")}
|
||||||
|
>
|
||||||
|
<Check className="h-4 w-4" />
|
||||||
|
</CheckboxPrimitive.Indicator>
|
||||||
|
</CheckboxPrimitive.Root>
|
||||||
|
))
|
||||||
|
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Checkbox }
|
||||||
Loading…
Reference in New Issue