fix(reports): remove truncation cap in range collectors to avoid dropped records
feat(calendar): migrate to react-day-picker v9 and polish UI - Update classNames and CSS import (style.css) - Custom Dropdown via shadcn Select - Nav arrows aligned with caption (around) - Today highlight with cyan tone, weekdays in sentence case - Wider layout to avoid overflow; remove inner wrapper chore(tickets): make 'Patrimônio do computador (se houver)' optional - Backend hotfix to enforce optional + label on existing tenants - Hide required asterisk for this field in portal/new-ticket refactor(new-ticket): remove channel dropdown from admin/agent flow - Keep default channel as MANUAL feat(ux): simplify requester section and enlarge combobox trigger - Remove RequesterPreview redundancy; show company badge in trigger
This commit is contained in:
parent
e0ef66555d
commit
a8333c010f
28 changed files with 1752 additions and 455 deletions
|
|
@ -935,6 +935,13 @@ const DEVICE_TYPE_LABELS: Record<string, string> = {
|
|||
tablet: "Tablet",
|
||||
}
|
||||
|
||||
const DEVICE_TYPE_FILTER_OPTIONS = [
|
||||
{ value: "all", label: "Todos os tipos" },
|
||||
{ value: "desktop", label: DEVICE_TYPE_LABELS.desktop },
|
||||
{ value: "mobile", label: DEVICE_TYPE_LABELS.mobile },
|
||||
{ value: "tablet", label: DEVICE_TYPE_LABELS.tablet },
|
||||
]
|
||||
|
||||
function formatDeviceTypeLabel(value?: string | null): string {
|
||||
if (!value) return "Desconhecido"
|
||||
const normalized = value.toLowerCase()
|
||||
|
|
@ -1257,6 +1264,7 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
|
|||
const { devices, isLoading } = useDevicesQuery(tenantId)
|
||||
const [q, setQ] = useState("")
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all")
|
||||
const [deviceTypeFilter, setDeviceTypeFilter] = useState<string>("all")
|
||||
const [companyFilterSlug, setCompanyFilterSlug] = useState<string>(initialCompanyFilterSlug)
|
||||
const [companySearch, setCompanySearch] = useState<string>("")
|
||||
const [isCompanyPopoverOpen, setIsCompanyPopoverOpen] = useState(false)
|
||||
|
|
@ -1595,6 +1603,10 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
|
|||
const s = resolveDeviceStatus(m).toLowerCase()
|
||||
if (s !== statusFilter) return false
|
||||
}
|
||||
if (deviceTypeFilter !== "all") {
|
||||
const type = (m.deviceType ?? "desktop").toLowerCase()
|
||||
if (type !== deviceTypeFilter) return false
|
||||
}
|
||||
if (companyFilterSlug !== "all" && (m.companySlug ?? "") !== companyFilterSlug) return false
|
||||
if (!text) return true
|
||||
const hay = [
|
||||
|
|
@ -1607,7 +1619,7 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
|
|||
.toLowerCase()
|
||||
return hay.includes(text)
|
||||
})
|
||||
}, [devices, q, statusFilter, companyFilterSlug, onlyAlerts])
|
||||
}, [devices, q, statusFilter, companyFilterSlug, onlyAlerts, deviceTypeFilter])
|
||||
const handleOpenExportDialog = useCallback(() => {
|
||||
if (filteredDevices.length === 0) {
|
||||
toast.info("Não há dispositivos para exportar com os filtros atuais.")
|
||||
|
|
@ -1771,10 +1783,7 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
|
|||
<CardDescription>Sincronizadas via agente local ou Fleet. Atualiza em tempo real.</CardDescription>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={handleOpenCreateDevice}
|
||||
>
|
||||
<Button size="sm" onClick={handleOpenCreateDevice}>
|
||||
<Plus className="size-4" />
|
||||
Novo dispositivo
|
||||
</Button>
|
||||
|
|
@ -1797,6 +1806,18 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
|
|||
<SelectItem value="unknown">Desconhecido</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select value={deviceTypeFilter} onValueChange={setDeviceTypeFilter}>
|
||||
<SelectTrigger className="min-w-40">
|
||||
<SelectValue placeholder="Tipo de dispositivo" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{DEVICE_TYPE_FILTER_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Popover open={isCompanyPopoverOpen} onOpenChange={setIsCompanyPopoverOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" className="min-w-56 justify-between">
|
||||
|
|
@ -2392,12 +2413,12 @@ export function DeviceDetails({ device }: DeviceDetailsProps) {
|
|||
const isDeactivated = !isActiveLocal || effectiveStatus === "deactivated"
|
||||
const alertsHistory = useQuery(
|
||||
api.devices.listAlerts,
|
||||
device ? { deviceId: device.id as Id<"machines">, limit: 50 } : "skip"
|
||||
device ? { machineId: device.id as Id<"machines">, limit: 50 } : "skip"
|
||||
) as DeviceAlertEntry[] | undefined
|
||||
const deviceAlertsHistory = alertsHistory ?? []
|
||||
const openTickets = useQuery(
|
||||
api.devices.listOpenTickets,
|
||||
device ? { deviceId: device.id as Id<"machines">, limit: 6 } : "skip"
|
||||
device ? { machineId: device.id as Id<"machines">, limit: 6 } : "skip"
|
||||
) as DeviceOpenTicketsSummary | undefined
|
||||
const deviceTickets = openTickets?.tickets ?? []
|
||||
const totalOpenTickets = openTickets?.totalOpen ?? deviceTickets.length
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue