feat: improve quick actions and remote access
This commit is contained in:
parent
aeb6d50377
commit
4f8dad2255
10 changed files with 906 additions and 154 deletions
98
src/hooks/use-ticket-remote-access.ts
Normal file
98
src/hooks/use-ticket-remote-access.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
"use client"
|
||||
|
||||
import { useCallback, useMemo } from "react"
|
||||
import { useQuery } from "convex/react"
|
||||
import { toast } from "sonner"
|
||||
|
||||
import { api } from "@/convex/_generated/api"
|
||||
import type { Id } from "@/convex/_generated/dataModel"
|
||||
import { useAuth } from "@/lib/auth-client"
|
||||
import type { TicketWithDetails } from "@/lib/schemas/ticket"
|
||||
import {
|
||||
buildRustDeskUri,
|
||||
isRustDeskAccess,
|
||||
normalizeDeviceRemoteAccessList,
|
||||
type DeviceRemoteAccessEntry,
|
||||
} from "@/components/admin/devices/admin-devices-overview"
|
||||
import { DEVICE_STATUS_LABELS, resolveDeviceStatus } from "@/lib/device-status"
|
||||
|
||||
type RemoteAccessResult = {
|
||||
canShowRemoteAccess: boolean
|
||||
primaryRemoteAccess: DeviceRemoteAccessEntry | null
|
||||
statusKey: string
|
||||
statusLabel: string
|
||||
hostname: string | null
|
||||
connect: () => void
|
||||
}
|
||||
|
||||
export function useTicketRemoteAccess(ticket: TicketWithDetails): RemoteAccessResult {
|
||||
const { isStaff } = useAuth()
|
||||
const machineId = ticket.machine?.id ?? null
|
||||
const canQueryDevice = isStaff && Boolean(machineId)
|
||||
|
||||
const deviceRecord = useQuery(
|
||||
api.devices.getById,
|
||||
canQueryDevice
|
||||
? ({
|
||||
id: machineId as Id<"machines">,
|
||||
includeMetadata: true,
|
||||
} as const)
|
||||
: "skip"
|
||||
) as Record<string, unknown> | null | undefined
|
||||
|
||||
const remoteAccessEntries = useMemo(() => {
|
||||
if (!deviceRecord) return []
|
||||
const source = (deviceRecord as { remoteAccess?: unknown }).remoteAccess
|
||||
return normalizeDeviceRemoteAccessList(source)
|
||||
}, [deviceRecord])
|
||||
|
||||
const primaryRemoteAccess = useMemo(
|
||||
() => remoteAccessEntries.find((entry) => isRustDeskAccess(entry)) ?? null,
|
||||
[remoteAccessEntries]
|
||||
)
|
||||
|
||||
const hostname =
|
||||
ticket.machine?.hostname ?? ((deviceRecord as { hostname?: string | null })?.hostname ?? null)
|
||||
|
||||
const statusKey = useMemo(() => {
|
||||
if (deviceRecord && typeof deviceRecord === "object") {
|
||||
return resolveDeviceStatus(
|
||||
deviceRecord as { status?: string | null; lastHeartbeatAt?: number | null; isActive?: boolean | null }
|
||||
)
|
||||
}
|
||||
const fallback = ticket.machine?.status
|
||||
return typeof fallback === "string" && fallback.length > 0 ? fallback.toLowerCase() : "unknown"
|
||||
}, [deviceRecord, ticket.machine?.status])
|
||||
|
||||
const handleConnect = useCallback(() => {
|
||||
if (!primaryRemoteAccess) {
|
||||
toast.error("Nenhum acesso remoto RustDesk cadastrado para esta máquina.")
|
||||
return
|
||||
}
|
||||
const link = buildRustDeskUri(primaryRemoteAccess)
|
||||
if (!link) {
|
||||
toast.error("Não foi possível montar o link do RustDesk (ID ou senha ausentes).")
|
||||
return
|
||||
}
|
||||
if (typeof window === "undefined") {
|
||||
toast.error("A conexão direta só funciona no navegador.")
|
||||
return
|
||||
}
|
||||
try {
|
||||
window.location.href = link
|
||||
toast.success("Abrindo o RustDesk...")
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
toast.error("Não foi possível acionar o RustDesk neste dispositivo.")
|
||||
}
|
||||
}, [primaryRemoteAccess])
|
||||
|
||||
return {
|
||||
canShowRemoteAccess: Boolean(canQueryDevice),
|
||||
primaryRemoteAccess,
|
||||
statusKey,
|
||||
statusLabel: DEVICE_STATUS_LABELS[statusKey] ?? statusKey,
|
||||
hostname,
|
||||
connect: handleConnect,
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue