mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-16 05:13:36 +00:00
207 lines
5.5 KiB
TypeScript
207 lines
5.5 KiB
TypeScript
import {
|
|
Box,
|
|
FolderSearch,
|
|
LayoutDashboard,
|
|
Monitor,
|
|
Network,
|
|
Server,
|
|
Settings,
|
|
Terminal,
|
|
User,
|
|
Activity,
|
|
TerminalSquare,
|
|
} from "lucide-react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { CommandHistoryProvider } from "@/features/terminal/command-history/CommandHistoryContext";
|
|
import { Terminal as TerminalFeature } from "@/features/terminal/Terminal";
|
|
import { FileManager } from "@/features/file-manager/FileManager";
|
|
import { DockerManager } from "@/features/docker/DockerManager";
|
|
import { ServerStats } from "@/features/server-stats/ServerStats";
|
|
import GuacamoleApp from "@/features/guacamole/GuacamoleApp";
|
|
import { DashboardTab } from "@/dashboard/DashboardTab";
|
|
import { TunnelTab } from "@/features/tunnel/TunnelTab";
|
|
import type { Tab, TabType, Host } from "@/types/ui-types";
|
|
import type { SSHHost } from "@/types";
|
|
|
|
function hostToSSHHost(h: Host): SSHHost {
|
|
return {
|
|
id: parseInt(h.id, 10),
|
|
name: h.name,
|
|
ip: h.ip,
|
|
port: h.port,
|
|
username: h.username,
|
|
folder: h.folder ?? "",
|
|
tags: h.tags ?? [],
|
|
pin: h.pin ?? false,
|
|
authType: h.authType,
|
|
password: h.password,
|
|
key: h.key,
|
|
keyPassword: h.keyPassword,
|
|
keyType: h.keyType,
|
|
credentialId: h.credentialId ? parseInt(h.credentialId, 10) : undefined,
|
|
terminalConfig: h.terminalConfig,
|
|
enableTerminal: h.enableTerminal ?? false,
|
|
enableTunnel: h.enableTunnel ?? false,
|
|
enableFileManager: h.enableFileManager ?? false,
|
|
enableDocker: h.enableDocker ?? false,
|
|
showTerminalInSidebar: true,
|
|
showFileManagerInSidebar: true,
|
|
showTunnelInSidebar: true,
|
|
showDockerInSidebar: true,
|
|
showServerStatsInSidebar: true,
|
|
defaultPath: h.defaultPath ?? "",
|
|
tunnelConnections: [],
|
|
connectionType: "ssh",
|
|
createdAt: "",
|
|
updatedAt: "",
|
|
} as SSHHost;
|
|
}
|
|
|
|
function EmptyState({
|
|
icon: Icon,
|
|
messageKey,
|
|
}: {
|
|
icon: React.ElementType;
|
|
messageKey: string;
|
|
}) {
|
|
const { t } = useTranslation();
|
|
return (
|
|
<div className="flex flex-col items-center justify-center flex-1 gap-3 p-6 text-center">
|
|
<div className="size-10 rounded-full bg-muted/40 flex items-center justify-center">
|
|
<Icon className="size-5 text-muted-foreground/30" />
|
|
</div>
|
|
<span className="text-sm font-semibold text-muted-foreground/60">
|
|
{t(messageKey)}
|
|
</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function tabIcon(type: TabType) {
|
|
switch (type) {
|
|
case "dashboard":
|
|
return <LayoutDashboard className="size-3.5" />;
|
|
case "terminal":
|
|
return <Terminal className="size-3.5" />;
|
|
case "rdp":
|
|
return <Monitor className="size-3.5" />;
|
|
case "vnc":
|
|
return <Monitor className="size-3.5" />;
|
|
case "telnet":
|
|
return <Terminal className="size-3.5" />;
|
|
case "stats":
|
|
return <Server className="size-3.5" />;
|
|
case "files":
|
|
return <FolderSearch className="size-3.5" />;
|
|
case "host-manager":
|
|
return <Server className="size-3.5" />;
|
|
case "user-profile":
|
|
return <User className="size-3.5" />;
|
|
case "admin-settings":
|
|
return <Settings className="size-3.5" />;
|
|
case "docker":
|
|
return <Box className="size-3.5" />;
|
|
case "tunnel":
|
|
return <Network className="size-3.5" />;
|
|
}
|
|
}
|
|
|
|
export function renderTabContent(
|
|
tab: Tab,
|
|
onOpenSingletonTab?: (type: TabType) => void,
|
|
onOpenTab?: (host: Host, type: TabType) => void,
|
|
) {
|
|
const { host, label } = tab;
|
|
|
|
switch (tab.type) {
|
|
case "dashboard":
|
|
return (
|
|
<DashboardTab
|
|
onOpenSingletonTab={onOpenSingletonTab!}
|
|
onOpenTab={onOpenTab!}
|
|
/>
|
|
);
|
|
|
|
case "terminal":
|
|
if (!host)
|
|
return (
|
|
<EmptyState
|
|
icon={TerminalSquare}
|
|
messageKey="terminal.noHostSelected"
|
|
/>
|
|
);
|
|
return (
|
|
<CommandHistoryProvider>
|
|
<TerminalFeature
|
|
hostConfig={
|
|
{
|
|
...hostToSSHHost(host),
|
|
sshPort: host.sshPort ?? host.port,
|
|
} as any
|
|
}
|
|
isVisible={true}
|
|
title={label}
|
|
showTitle={false}
|
|
splitScreen={false}
|
|
onClose={() => {}}
|
|
/>
|
|
</CommandHistoryProvider>
|
|
);
|
|
|
|
case "files":
|
|
if (!host)
|
|
return (
|
|
<EmptyState
|
|
icon={FolderSearch}
|
|
messageKey="fileManager.noHostSelected"
|
|
/>
|
|
);
|
|
return <FileManager initialHost={hostToSSHHost(host)} />;
|
|
|
|
case "docker":
|
|
if (!host)
|
|
return <EmptyState icon={Box} messageKey="docker.noHostSelected" />;
|
|
return (
|
|
<DockerManager
|
|
hostConfig={hostToSSHHost(host)}
|
|
title={label}
|
|
isVisible={true}
|
|
isTopbarOpen={false}
|
|
embedded={true}
|
|
/>
|
|
);
|
|
|
|
case "stats":
|
|
if (!host)
|
|
return (
|
|
<EmptyState icon={Activity} messageKey="serverStats.noHostSelected" />
|
|
);
|
|
return (
|
|
<ServerStats
|
|
hostConfig={hostToSSHHost(host) as any}
|
|
title={label}
|
|
isVisible={true}
|
|
isTopbarOpen={false}
|
|
embedded={true}
|
|
/>
|
|
);
|
|
|
|
case "tunnel":
|
|
return <TunnelTab label={label} host={host} />;
|
|
|
|
case "rdp":
|
|
case "vnc":
|
|
case "telnet":
|
|
if (!host)
|
|
return (
|
|
<EmptyState icon={Monitor} messageKey="guacamole.noHostSelected" />
|
|
);
|
|
return <GuacamoleApp hostId={host.id} />;
|
|
|
|
case "host-manager":
|
|
case "user-profile":
|
|
case "admin-settings":
|
|
return null;
|
|
}
|
|
}
|