import { useMemo, useState } from "react"; import { AlertTriangle, CheckCircle2, Power, PowerOff, RotateCcw, ShieldBan, XCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useMachineNumber } from "@/hooks/useMachineNumber"; import { useExecuteSensitiveCommand, useGetSensitiveCommands } from "@/hooks/queries/useCommandQueries"; import { CommandType } from "@/types/command-registry"; import { toast } from "sonner"; interface DeviceActionBarProps { roomName: string; selectedDevices: any[]; onClearSelection: () => void; } const ACTIONS = [ { type: CommandType.RESTART, label: "Khởi động lại", icon: Power, variant: "outline" as const, }, { type: CommandType.SHUTDOWN, label: "Tắt máy", icon: PowerOff, variant: "destructive" as const, }, { type: CommandType.TASKKILL, label: "Kết thúc tác vụ", icon: XCircle, variant: "outline" as const, }, { type: CommandType.BLOCK, label: "Chặn", icon: ShieldBan, variant: "outline" as const, }, { type: CommandType.RESET, label: "Reset", icon: RotateCcw, variant: "destructive" as const, }, ]; const DANGER_TYPES = new Set([CommandType.SHUTDOWN, CommandType.RESET]); export function DeviceActionBar({ roomName, selectedDevices, onClearSelection, }: DeviceActionBarProps) { const [confirmOpen, setConfirmOpen] = useState(false); const [activeType, setActiveType] = useState(null); const [password, setPassword] = useState(""); const [isExecuting, setIsExecuting] = useState(false); const getMachineNumber = useMachineNumber(); const { data: sensitiveCommands = [] } = useGetSensitiveCommands(); const executeSensitiveMutation = useExecuteSensitiveCommand(); const commandsByType = useMemo(() => { return (Object.values(CommandType) as Array) .filter((value) => typeof value === "number") .reduce((acc: Record, type) => { acc[type as number] = (sensitiveCommands || []).filter( (command: any) => Number(command.command) === Number(type) ); return acc; }, {} as Record); }, [sensitiveCommands]); const selectedCount = selectedDevices.length; const activeCommand = activeType ? commandsByType[activeType]?.[0] : null; const buildDeviceLabel = (device: any) => { const number = getMachineNumber(device?.id || ""); const ipAddress = device?.networkInfos?.[0]?.ipAddress; if (number > 0) { return `#${number}${ipAddress ? ` (${ipAddress})` : ""}`; } return `${device?.id ?? ""}${ipAddress ? ` (${ipAddress})` : ""}`; }; const openConfirm = (type: CommandType) => { if (!commandsByType[type]?.length) { toast.error("Chưa có lệnh phù hợp cho thao tác này."); return; } setActiveType(type); setConfirmOpen(true); }; const handleClose = () => { if (isExecuting) return; setConfirmOpen(false); setActiveType(null); setPassword(""); }; const handleConfirm = async () => { if (!activeCommand || !activeType) return; if (!password.trim()) { toast.error("Vui lòng nhập mật khẩu xác nhận."); return; } setIsExecuting(true); try { await executeSensitiveMutation.mutateAsync({ roomName, command: activeCommand.commandName, password, }); toast.success(`Đã gửi lệnh: ${activeCommand.commandName}`); handleClose(); onClearSelection(); } catch (error) { console.error("Execute command error:", error); toast.error("Lỗi khi gửi lệnh!"); } finally { setIsExecuting(false); } }; if (selectedCount === 0) return null; return ( <>
Đã chọn {selectedCount} thiết bị
{ACTIONS.map((action) => { const Icon = action.icon; const isDisabled = !commandsByType[action.type]?.length; return ( ); })}
Xác nhận thực thi lệnh

Bạn có chắc chắn muốn thực thi lệnh{" "} {activeCommand?.commandName ?? ""}?

{DANGER_TYPES.has(activeType ?? CommandType.RESTART) && (

Hành động này không thể hoàn tác.

)}
Thiết bị được chọn
{selectedDevices.map((device) => (
{buildDeviceLabel(device)}
))}
setPassword(event.target.value)} placeholder="Nhập mật khẩu để xác nhận" />
); }