Machines: replace OS filter with searchable company dropdown; remove OS filter logic
This commit is contained in:
parent
904c2ef457
commit
e04888ff4d
1 changed files with 48 additions and 51 deletions
|
|
@ -37,6 +37,7 @@ import { Badge } from "@/components/ui/badge"
|
||||||
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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
|
||||||
import { Checkbox } from "@/components/ui/checkbox"
|
import { Checkbox } from "@/components/ui/checkbox"
|
||||||
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
||||||
|
|
@ -972,8 +973,8 @@ export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
|
||||||
const machines = useMachinesQuery(tenantId)
|
const machines = useMachinesQuery(tenantId)
|
||||||
const [q, setQ] = useState("")
|
const [q, setQ] = useState("")
|
||||||
const [statusFilter, setStatusFilter] = useState<string>("all")
|
const [statusFilter, setStatusFilter] = useState<string>("all")
|
||||||
const [osFilter, setOsFilter] = useState<string>("all")
|
const [companyFilterSlug, setCompanyFilterSlug] = useState<string>("all")
|
||||||
const [companyQuery, setCompanyQuery] = useState<string>("")
|
const [companySearch, setCompanySearch] = useState<string>("")
|
||||||
const [onlyAlerts, setOnlyAlerts] = useState<boolean>(false)
|
const [onlyAlerts, setOnlyAlerts] = useState<boolean>(false)
|
||||||
const { convexUserId } = useAuth()
|
const { convexUserId } = useAuth()
|
||||||
const companies = useQuery(
|
const companies = useQuery(
|
||||||
|
|
@ -986,13 +987,7 @@ export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
|
||||||
return map
|
return map
|
||||||
}, [companies])
|
}, [companies])
|
||||||
|
|
||||||
const osOptions = useMemo(() => {
|
const companyOptions = useMemo(() => (companies ?? []).map((c) => ({ slug: c.slug ?? c.id, name: c.name })).sort((a,b)=>a.name.localeCompare(b.name,"pt-BR")), [companies])
|
||||||
const set = new Set<string>()
|
|
||||||
machines.forEach((m) => m.osName && set.add(m.osName))
|
|
||||||
return Array.from(set).sort()
|
|
||||||
}, [machines])
|
|
||||||
|
|
||||||
const companyNameOptions = useMemo(() => (companies ?? []).map((c) => c.name).sort((a,b)=>a.localeCompare(b,"pt-BR")), [companies])
|
|
||||||
|
|
||||||
const filteredMachines = useMemo(() => {
|
const filteredMachines = useMemo(() => {
|
||||||
const text = q.trim().toLowerCase()
|
const text = q.trim().toLowerCase()
|
||||||
|
|
@ -1002,11 +997,7 @@ const filteredMachines = useMemo(() => {
|
||||||
const s = resolveMachineStatus(m).toLowerCase()
|
const s = resolveMachineStatus(m).toLowerCase()
|
||||||
if (s !== statusFilter) return false
|
if (s !== statusFilter) return false
|
||||||
}
|
}
|
||||||
if (osFilter !== "all" && (m.osName ?? "").toLowerCase() !== osFilter.toLowerCase()) return false
|
if (companyFilterSlug !== "all" && (m.companySlug ?? "") !== companyFilterSlug) return false
|
||||||
if (companyQuery && companyQuery.trim().length > 0) {
|
|
||||||
const name = companyNameBySlug.get(m.companySlug ?? "")?.toLowerCase() ?? ""
|
|
||||||
if (!name.includes(companyQuery.trim().toLowerCase())) return false
|
|
||||||
}
|
|
||||||
if (!text) return true
|
if (!text) return true
|
||||||
const hay = [
|
const hay = [
|
||||||
m.hostname,
|
m.hostname,
|
||||||
|
|
@ -1018,7 +1009,7 @@ const filteredMachines = useMemo(() => {
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
return hay.includes(text)
|
return hay.includes(text)
|
||||||
})
|
})
|
||||||
}, [machines, q, statusFilter, osFilter, companyQuery, onlyAlerts, companyNameBySlug])
|
}, [machines, q, statusFilter, companyFilterSlug, onlyAlerts])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-6">
|
<div className="grid gap-6">
|
||||||
|
|
@ -1044,47 +1035,53 @@ const filteredMachines = useMemo(() => {
|
||||||
<SelectItem value="unknown">Desconhecido</SelectItem>
|
<SelectItem value="unknown">Desconhecido</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
<Select value={osFilter} onValueChange={setOsFilter}>
|
<Popover>
|
||||||
<SelectTrigger className="min-w-40">
|
<PopoverTrigger asChild>
|
||||||
<SelectValue placeholder="Sistema" />
|
<Button variant="outline" className="min-w-56 justify-between">
|
||||||
</SelectTrigger>
|
{(() => {
|
||||||
<SelectContent>
|
if (companyFilterSlug === "all") return "Todas empresas"
|
||||||
<SelectItem value="all">Todos sistemas</SelectItem>
|
const found = companyOptions.find((c) => c.slug === companyFilterSlug)
|
||||||
{osOptions.map((os) => (
|
return found?.name ?? companyFilterSlug
|
||||||
<SelectItem key={os} value={os}>{os}</SelectItem>
|
})()}
|
||||||
))}
|
<span className="ml-2 text-slate-400">▾</span>
|
||||||
</SelectContent>
|
</Button>
|
||||||
</Select>
|
</PopoverTrigger>
|
||||||
<div className="relative">
|
<PopoverContent className="w-72 p-2" align="start">
|
||||||
<Input
|
<div className="space-y-2">
|
||||||
value={companyQuery}
|
<Input
|
||||||
onChange={(e) => setCompanyQuery(e.target.value)}
|
value={companySearch}
|
||||||
placeholder="Buscar empresa"
|
onChange={(e) => setCompanySearch(e.target.value)}
|
||||||
className="min-w-[220px]"
|
placeholder="Buscar empresa..."
|
||||||
/>
|
/>
|
||||||
{companyQuery && companyNameOptions.filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase())).slice(0,6).length > 0 ? (
|
<div className="max-h-64 overflow-auto rounded-md border border-slate-200">
|
||||||
<div className="absolute z-10 mt-1 max-h-52 w-full overflow-auto rounded-md border bg-white p-1 shadow-sm">
|
<button
|
||||||
{companyNameOptions
|
type="button"
|
||||||
.filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase()))
|
onClick={() => { setCompanyFilterSlug("all"); setCompanySearch("") }}
|
||||||
.slice(0, 8)
|
className="block w-full px-3 py-2 text-left text-sm hover:bg-slate-100"
|
||||||
.map((c) => (
|
>
|
||||||
<button
|
Todas empresas
|
||||||
key={c}
|
</button>
|
||||||
type="button"
|
{companyOptions
|
||||||
onClick={() => setCompanyQuery(c)}
|
.filter((c) => c.name.toLowerCase().includes(companySearch.toLowerCase()))
|
||||||
className="w-full rounded px-2 py-1 text-left text-sm hover:bg-slate-100"
|
.map((c) => (
|
||||||
>
|
<button
|
||||||
{c}
|
key={c.slug}
|
||||||
</button>
|
type="button"
|
||||||
))}
|
onClick={() => { setCompanyFilterSlug(c.slug); setCompanySearch("") }}
|
||||||
|
className="block w-full px-3 py-2 text-left text-sm hover:bg-slate-100"
|
||||||
|
>
|
||||||
|
{c.name}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
</PopoverContent>
|
||||||
</div>
|
</Popover>
|
||||||
<label className="inline-flex items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-3 py-1.5 text-sm">
|
<label className="inline-flex items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-3 py-1.5 text-sm">
|
||||||
<Checkbox checked={onlyAlerts} onCheckedChange={(v) => setOnlyAlerts(Boolean(v))} />
|
<Checkbox checked={onlyAlerts} onCheckedChange={(v) => setOnlyAlerts(Boolean(v))} />
|
||||||
<span>Somente com alertas</span>
|
<span>Somente com alertas</span>
|
||||||
</label>
|
</label>
|
||||||
<Button variant="outline" onClick={() => { setQ(""); setStatusFilter("all"); setOsFilter("all"); setCompanyQuery(""); setOnlyAlerts(false) }}>Limpar</Button>
|
<Button variant="outline" onClick={() => { setQ(""); setStatusFilter("all"); setCompanyFilterSlug("all"); setCompanySearch(""); setOnlyAlerts(false) }}>Limpar</Button>
|
||||||
</div>
|
</div>
|
||||||
{machines.length === 0 ? (
|
{machines.length === 0 ? (
|
||||||
<EmptyState />
|
<EmptyState />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue