chore: expand reports coverage and upgrade next
This commit is contained in:
parent
2fb587b01d
commit
8b82284e8c
21 changed files with 2952 additions and 2713 deletions
|
|
@ -102,6 +102,12 @@ type MachineTicketSummary = {
|
|||
assignee: { name: string | null; email: string | null } | null
|
||||
}
|
||||
|
||||
type MachineOpenTicketsSummary = {
|
||||
totalOpen: number
|
||||
hasMore: boolean
|
||||
tickets: MachineTicketSummary[]
|
||||
}
|
||||
|
||||
|
||||
type DetailLineProps = {
|
||||
label: string
|
||||
|
|
@ -1454,9 +1460,14 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
const machineAlertsHistory = alertsHistory ?? []
|
||||
const openTickets = useQuery(
|
||||
machine ? api.machines.listOpenTickets : "skip",
|
||||
machine ? { machineId: machine.id as Id<"machines">, limit: 8 } : ("skip" as const)
|
||||
) as MachineTicketSummary[] | undefined
|
||||
const machineTickets = openTickets ?? []
|
||||
machine ? { machineId: machine.id as Id<"machines">, limit: 6 } : ("skip" as const)
|
||||
) as MachineOpenTicketsSummary | undefined
|
||||
const machineTickets = openTickets?.tickets ?? []
|
||||
const totalOpenTickets = openTickets?.totalOpen ?? machineTickets.length
|
||||
const displayLimit = 3
|
||||
const displayedMachineTickets = machineTickets.slice(0, displayLimit)
|
||||
const hasAdditionalOpenTickets = totalOpenTickets > displayedMachineTickets.length
|
||||
const machineTicketsHref = machine ? `/admin/machines/${machine.id}/tickets` : null
|
||||
const metadata = machine?.inventory ?? null
|
||||
const metrics = machine?.metrics ?? null
|
||||
const metricsCapturedAt = useMemo(() => getMetricsTimestamp(metrics), [metrics])
|
||||
|
|
@ -2356,45 +2367,65 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
</div>
|
||||
<div className="rounded-2xl border border-[color:var(--accent)] bg-[color:var(--accent)]/80 px-4 py-4">
|
||||
<div className="grid gap-3 sm:grid-cols-[1fr_auto] sm:items-center">
|
||||
<div className="space-y-1">
|
||||
<h4 className="text-sm font-semibold text-accent-foreground">Tickets abertos por esta máquina</h4>
|
||||
{machineTickets.length === 0 ? (
|
||||
<p className="text-xs text-[color:var(--accent-foreground)]/80">Nenhum chamado em aberto registrado diretamente por esta máquina.</p>
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap items-center justify-between gap-2">
|
||||
<h4 className="text-sm font-semibold text-accent-foreground">Tickets abertos por esta máquina</h4>
|
||||
{machineTicketsHref ? (
|
||||
<Link
|
||||
href={machineTicketsHref}
|
||||
className="text-xs font-semibold text-accent-foreground underline-offset-4 transition hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent-foreground)] focus-visible:ring-offset-2"
|
||||
>
|
||||
Ver todos
|
||||
</Link>
|
||||
) : null}
|
||||
</div>
|
||||
{totalOpenTickets === 0 ? (
|
||||
<p className="text-xs text-[color:var(--accent-foreground)]/80">
|
||||
Nenhum chamado em aberto registrado diretamente por esta máquina.
|
||||
</p>
|
||||
) : (
|
||||
<ul className="space-y-2">
|
||||
{machineTickets.map((ticket) => {
|
||||
const priorityMeta = getTicketPriorityMeta(ticket.priority)
|
||||
return (
|
||||
<li key={ticket.id}>
|
||||
<Link
|
||||
href={`/tickets/${ticket.id}`}
|
||||
className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-[color:var(--accent)] bg-white px-3 py-2 text-sm shadow-sm transition hover:-translate-y-0.5 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent)] focus-visible:ring-offset-2"
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate font-medium text-neutral-900">
|
||||
#{ticket.reference} · {ticket.subject}
|
||||
</p>
|
||||
<p className="text-xs text-neutral-500">
|
||||
Atualizado {formatRelativeTime(new Date(ticket.updatedAt))}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge className={cn("rounded-full px-3 py-1 text-xs font-semibold", priorityMeta.badgeClass)}>
|
||||
{priorityMeta.label}
|
||||
</Badge>
|
||||
<TicketStatusBadge status={ticket.status} className="h-7 px-3 text-xs font-semibold" />
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
<div className="space-y-2">
|
||||
{hasAdditionalOpenTickets ? (
|
||||
<p className="text-[10px] font-semibold uppercase tracking-[0.14em] text-[color:var(--accent-foreground)]/70">
|
||||
Mostrando últimos {Math.min(displayLimit, totalOpenTickets)} de {totalOpenTickets} chamados
|
||||
em aberto
|
||||
</p>
|
||||
) : null}
|
||||
<ul className="space-y-2">
|
||||
{displayedMachineTickets.map((ticket) => {
|
||||
const priorityMeta = getTicketPriorityMeta(ticket.priority)
|
||||
return (
|
||||
<li key={ticket.id}>
|
||||
<Link
|
||||
href={`/tickets/${ticket.id}`}
|
||||
className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-[color:var(--accent)] bg-white px-3 py-2 text-sm shadow-sm transition hover:-translate-y-0.5 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--accent)] focus-visible:ring-offset-2"
|
||||
>
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate font-medium text-neutral-900">
|
||||
#{ticket.reference} · {ticket.subject}
|
||||
</p>
|
||||
<p className="text-xs text-neutral-500">
|
||||
Atualizado {formatRelativeTime(new Date(ticket.updatedAt))}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge className={cn("rounded-full px-3 py-1 text-xs font-semibold", priorityMeta.badgeClass)}>
|
||||
{priorityMeta.label}
|
||||
</Badge>
|
||||
<TicketStatusBadge status={ticket.status} className="h-7 px-3 text-xs font-semibold" />
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="self-center justify-self-end">
|
||||
<div className="flex h-12 min-w-[72px] items-center justify-center rounded-2xl border border-[color:var(--accent)] bg-white px-5 shadow-sm sm:min-w-[88px]">
|
||||
<span className="text-2xl font-semibold leading-none text-accent-foreground tabular-nums sm:text-3xl">
|
||||
{machineTickets.length}
|
||||
{totalOpenTickets}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue