import React from "react"; import { Button } from "@/components/button.tsx"; import { useTranslation } from "react-i18next"; import { getHostPassword } from "@/main-axios.ts"; import { cn } from "@/lib/utils"; import { copyToClipboard } from "@/lib/clipboard"; import { Home, SeparatorVertical, X, Terminal as TerminalIcon, Server as ServerIcon, Folder as FolderIcon, FolderOpen, User as UserIcon, Monitor as MonitorIcon, Eye as EyeIcon, MessagesSquare as MessageSquareIcon, Network, ArrowDownUp as TunnelIcon, Container as DockerIcon, Layers as TmuxMonitorIcon, // --- tmux-monitor --- Key, } from "lucide-react"; import { toast } from "sonner"; import type { SSHHost } from "@/types"; interface TabProps { tabType: string; title?: string; isActive?: boolean; isSplit?: boolean; onActivate?: () => void; onClose?: () => void; onSplit?: () => void; canSplit?: boolean; canClose?: boolean; disableActivate?: boolean; disableSplit?: boolean; disableClose?: boolean; isDragging?: boolean; isDragOver?: boolean; isValidDropTarget?: boolean; isHoveredDropTarget?: boolean; hostConfig?: SSHHost; onOpenFileManager?: () => void; } export function Tab({ tabType, title, isActive, isSplit = false, onActivate, onClose, onSplit, canSplit = false, canClose = false, disableActivate = false, disableSplit = false, disableClose = false, isDragging = false, isDragOver = false, isValidDropTarget = false, isHoveredDropTarget = false, hostConfig, onOpenFileManager, }: TabProps): React.ReactElement { const { t } = useTranslation(); const handleCopyPassword = async (e: React.MouseEvent) => { e.stopPropagation(); if (!hostConfig) return; const hasSshPw = hostConfig.authType === "password" && (hostConfig.hasPassword || hostConfig.password); const hasSudoPw = hostConfig.hasSudoPassword || hostConfig.sudoPassword; if (!hasSshPw && !hasSudoPw) return; const field = hasSshPw ? "password" : "sudoPassword"; const passwordToCopy = await getHostPassword(hostConfig.id, field); if (!passwordToCopy) { toast.error(t("nav.failedToCopyPassword")); return; } const ok = await copyToClipboard(passwordToCopy); if (ok) toast.success(t("nav.passwordCopied")); else toast.error(t("nav.failedToCopyPassword")); }; const hasPassword = hostConfig && ((hostConfig.authType === "password" && (hostConfig.hasPassword || hostConfig.password)) || hostConfig.hasSudoPassword || hostConfig.sudoPassword); const getPasswordButtonTitle = () => { if (!hostConfig) return ""; const hasSshPw = hostConfig.authType === "password" && (hostConfig.hasPassword || hostConfig.password); const hasSudoPw = hostConfig.hasSudoPassword || hostConfig.sudoPassword; if (hasSshPw) { return t("nav.copyPassword"); } else if (hasSudoPw) { return t("nav.copySudoPassword"); } return t("nav.noPasswordAvailable"); }; const tabBaseClasses = cn( "relative flex items-center gap-1.5 px-3 w-full min-w-0", "rounded-t-lg border-t-2 border-l-2 border-r-2", "transition-all duration-150 h-[42px]", isDragOver && "bg-background/40 text-muted-foreground border-border opacity-60", isDragging && "opacity-70", isHoveredDropTarget && "bg-blue-500/20 border-blue-500 ring-2 ring-blue-500/50", !isHoveredDropTarget && isValidDropTarget && "border-blue-400/50 bg-background/90", !isDragOver && !isDragging && !isValidDropTarget && !isHoveredDropTarget && isActive && "bg-background text-foreground border-border z-10", !isDragOver && !isDragging && !isValidDropTarget && !isHoveredDropTarget && !isActive && "bg-background/80 text-muted-foreground border-border hover:bg-background/90", ); const splitTitle = (fullTitle: string): { base: string; suffix: string } => { const match = fullTitle.match(/^(.*?)(\s*\(\d+\))$/); if (match) { return { base: match[1], suffix: match[2] }; } return { base: fullTitle, suffix: "" }; }; if (tabType === "home") { return (