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 { Input } from "@/components/ui/input"
|
||||
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 { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
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 [q, setQ] = useState("")
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all")
|
||||
const [osFilter, setOsFilter] = useState<string>("all")
|
||||
const [companyQuery, setCompanyQuery] = useState<string>("")
|
||||
const [companyFilterSlug, setCompanyFilterSlug] = useState<string>("all")
|
||||
const [companySearch, setCompanySearch] = useState<string>("")
|
||||
const [onlyAlerts, setOnlyAlerts] = useState<boolean>(false)
|
||||
const { convexUserId } = useAuth()
|
||||
const companies = useQuery(
|
||||
|
|
@ -986,13 +987,7 @@ export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
|
|||
return map
|
||||
}, [companies])
|
||||
|
||||
const osOptions = useMemo(() => {
|
||||
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 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 filteredMachines = useMemo(() => {
|
||||
const text = q.trim().toLowerCase()
|
||||
|
|
@ -1002,11 +997,7 @@ const filteredMachines = useMemo(() => {
|
|||
const s = resolveMachineStatus(m).toLowerCase()
|
||||
if (s !== statusFilter) return false
|
||||
}
|
||||
if (osFilter !== "all" && (m.osName ?? "").toLowerCase() !== osFilter.toLowerCase()) return false
|
||||
if (companyQuery && companyQuery.trim().length > 0) {
|
||||
const name = companyNameBySlug.get(m.companySlug ?? "")?.toLowerCase() ?? ""
|
||||
if (!name.includes(companyQuery.trim().toLowerCase())) return false
|
||||
}
|
||||
if (companyFilterSlug !== "all" && (m.companySlug ?? "") !== companyFilterSlug) return false
|
||||
if (!text) return true
|
||||
const hay = [
|
||||
m.hostname,
|
||||
|
|
@ -1018,7 +1009,7 @@ const filteredMachines = useMemo(() => {
|
|||
.toLowerCase()
|
||||
return hay.includes(text)
|
||||
})
|
||||
}, [machines, q, statusFilter, osFilter, companyQuery, onlyAlerts, companyNameBySlug])
|
||||
}, [machines, q, statusFilter, companyFilterSlug, onlyAlerts])
|
||||
|
||||
return (
|
||||
<div className="grid gap-6">
|
||||
|
|
@ -1044,47 +1035,53 @@ const filteredMachines = useMemo(() => {
|
|||
<SelectItem value="unknown">Desconhecido</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select value={osFilter} onValueChange={setOsFilter}>
|
||||
<SelectTrigger className="min-w-40">
|
||||
<SelectValue placeholder="Sistema" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Todos sistemas</SelectItem>
|
||||
{osOptions.map((os) => (
|
||||
<SelectItem key={os} value={os}>{os}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<div className="relative">
|
||||
<Input
|
||||
value={companyQuery}
|
||||
onChange={(e) => setCompanyQuery(e.target.value)}
|
||||
placeholder="Buscar empresa"
|
||||
className="min-w-[220px]"
|
||||
/>
|
||||
{companyQuery && companyNameOptions.filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase())).slice(0,6).length > 0 ? (
|
||||
<div className="absolute z-10 mt-1 max-h-52 w-full overflow-auto rounded-md border bg-white p-1 shadow-sm">
|
||||
{companyNameOptions
|
||||
.filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase()))
|
||||
.slice(0, 8)
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c}
|
||||
type="button"
|
||||
onClick={() => setCompanyQuery(c)}
|
||||
className="w-full rounded px-2 py-1 text-left text-sm hover:bg-slate-100"
|
||||
>
|
||||
{c}
|
||||
</button>
|
||||
))}
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" className="min-w-56 justify-between">
|
||||
{(() => {
|
||||
if (companyFilterSlug === "all") return "Todas empresas"
|
||||
const found = companyOptions.find((c) => c.slug === companyFilterSlug)
|
||||
return found?.name ?? companyFilterSlug
|
||||
})()}
|
||||
<span className="ml-2 text-slate-400">▾</span>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-72 p-2" align="start">
|
||||
<div className="space-y-2">
|
||||
<Input
|
||||
value={companySearch}
|
||||
onChange={(e) => setCompanySearch(e.target.value)}
|
||||
placeholder="Buscar empresa..."
|
||||
/>
|
||||
<div className="max-h-64 overflow-auto rounded-md border border-slate-200">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { setCompanyFilterSlug("all"); setCompanySearch("") }}
|
||||
className="block w-full px-3 py-2 text-left text-sm hover:bg-slate-100"
|
||||
>
|
||||
Todas empresas
|
||||
</button>
|
||||
{companyOptions
|
||||
.filter((c) => c.name.toLowerCase().includes(companySearch.toLowerCase()))
|
||||
.map((c) => (
|
||||
<button
|
||||
key={c.slug}
|
||||
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>
|
||||
) : null}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</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">
|
||||
<Checkbox checked={onlyAlerts} onCheckedChange={(v) => setOnlyAlerts(Boolean(v))} />
|
||||
<span>Somente com alertas</span>
|
||||
</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>
|
||||
{machines.length === 0 ? (
|
||||
<EmptyState />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue