Refine machine details layout and improve download feedback
This commit is contained in:
parent
5f7efa13e6
commit
1251468b77
6 changed files with 96 additions and 10 deletions
|
|
@ -680,6 +680,50 @@ function formatAbsoluteDateTime(date?: Date | null) {
|
|||
}).format(date)
|
||||
}
|
||||
|
||||
function parseDateish(value: unknown): Date | null {
|
||||
if (!value) return null
|
||||
if (value instanceof Date && !Number.isNaN(value.getTime())) return value
|
||||
if (typeof value === "number" && Number.isFinite(value)) {
|
||||
const numeric = value > 1e12 ? value : value > 1e9 ? value * 1000 : value
|
||||
const date = new Date(numeric)
|
||||
return Number.isNaN(date.getTime()) ? null : date
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
const trimmed = value.trim()
|
||||
if (!trimmed) return null
|
||||
const numericValue = Number(trimmed)
|
||||
if (Number.isFinite(numericValue)) {
|
||||
const asMs = trimmed.length >= 13 ? numericValue : numericValue * 1000
|
||||
const date = new Date(asMs)
|
||||
if (!Number.isNaN(date.getTime())) return date
|
||||
}
|
||||
const date = new Date(trimmed)
|
||||
if (!Number.isNaN(date.getTime())) return date
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function getMetricsTimestamp(metrics: MachineMetrics): Date | null {
|
||||
if (!metrics || typeof metrics !== "object") return null
|
||||
const data = metrics as Record<string, unknown>
|
||||
const candidates = [
|
||||
data["collectedAt"],
|
||||
data["collected_at"],
|
||||
data["collected_at_iso"],
|
||||
data["collected_at_ms"],
|
||||
data["timestamp"],
|
||||
data["updatedAt"],
|
||||
data["updated_at"],
|
||||
data["createdAt"],
|
||||
data["created_at"],
|
||||
]
|
||||
for (const candidate of candidates) {
|
||||
const parsed = parseDateish(candidate)
|
||||
if (parsed) return parsed
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function formatBytes(bytes?: number | null) {
|
||||
if (!bytes || Number.isNaN(bytes)) return "—"
|
||||
const units = ["B", "KB", "MB", "GB", "TB"]
|
||||
|
|
@ -930,6 +974,8 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
const { convexUserId } = useAuth()
|
||||
const router = useRouter()
|
||||
const effectiveStatus = machine ? resolveMachineStatus(machine) : "unknown"
|
||||
const isActive = machine?.isActive ?? true
|
||||
const isDeactivated = !isActive || effectiveStatus === "deactivated"
|
||||
// Company name lookup (by slug)
|
||||
const companyQueryArgs = convexUserId && machine ? { tenantId: machine.tenantId, viewerId: convexUserId as Id<"users"> } : undefined
|
||||
const companies = useQuery(
|
||||
|
|
@ -946,6 +992,7 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
const machineAlertsHistory = alertsHistory ?? []
|
||||
const metadata = machine?.inventory ?? null
|
||||
const metrics = machine?.metrics ?? null
|
||||
const metricsCapturedAt = useMemo(() => getMetricsTimestamp(metrics), [metrics])
|
||||
const hardware = metadata?.hardware
|
||||
const network = metadata?.network ?? null
|
||||
const networkInterfaces = Array.isArray(network) ? network : null
|
||||
|
|
@ -972,7 +1019,6 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
? windowsBaseboardRaw
|
||||
: null
|
||||
const windowsSerialNumber = windowsBaseboard ? readString(toRecord(windowsBaseboard) ?? {}, "SerialNumber", "serialNumber") : undefined
|
||||
const isActive = machine?.isActive ?? true
|
||||
const windowsMemoryModules = useMemo(() => {
|
||||
if (Array.isArray(windowsMemoryModulesRaw)) return windowsMemoryModulesRaw
|
||||
if (windowsMemoryModulesRaw && typeof windowsMemoryModulesRaw === "object") return [windowsMemoryModulesRaw]
|
||||
|
|
@ -1307,9 +1353,9 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
|
||||
return (
|
||||
<Card className="border-slate-200">
|
||||
<CardHeader>
|
||||
<CardHeader className="gap-1">
|
||||
<CardTitle>Detalhes</CardTitle>
|
||||
<CardDescription>Resumo da máquina selecionada.</CardDescription>
|
||||
<CardDescription>Resumo da máquina selecionada</CardDescription>
|
||||
{machine ? (
|
||||
<CardAction>
|
||||
<div className="flex flex-col items-end gap-2 text-xs sm:text-sm">
|
||||
|
|
@ -1318,7 +1364,7 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
{companyName}
|
||||
</div>
|
||||
) : null}
|
||||
<MachineStatusBadge status={effectiveStatus} />
|
||||
{!isDeactivated ? <MachineStatusBadge status={effectiveStatus} /> : null}
|
||||
{!isActive ? (
|
||||
<Badge variant="outline" className="h-7 border-rose-200 bg-rose-50 px-3 font-semibold uppercase text-rose-700">
|
||||
Máquina desativada
|
||||
|
|
@ -1499,7 +1545,14 @@ export function MachineDetails({ machine }: MachineDetailsProps) {
|
|||
</section>
|
||||
|
||||
<section className="space-y-2">
|
||||
<h4 className="text-sm font-semibold">Métricas recentes</h4>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<h4 className="text-sm font-semibold">Métricas recentes</h4>
|
||||
{metricsCapturedAt ? (
|
||||
<span className="text-xs font-medium text-muted-foreground">
|
||||
Última atualização {formatRelativeTime(metricsCapturedAt)}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<MetricsGrid metrics={metrics} hardware={hardware} disks={disks} />
|
||||
</section>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue