mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-16 05:13:36 +00:00
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import React from "react";
|
|
import { TunnelObject } from "./TunnelObject.tsx";
|
|
import { useTranslation } from "react-i18next";
|
|
import type { SSHHost, TunnelStatus } from "@/types/index";
|
|
|
|
interface SSHTunnelViewerProps {
|
|
hosts: SSHHost[];
|
|
tunnelStatuses: Record<string, TunnelStatus>;
|
|
tunnelActions: Record<string, boolean>;
|
|
onTunnelAction: (
|
|
action: "connect" | "disconnect" | "cancel",
|
|
host: SSHHost,
|
|
tunnelIndex: number,
|
|
) => Promise<unknown>;
|
|
}
|
|
|
|
export function TunnelViewer({
|
|
hosts = [],
|
|
tunnelStatuses = {},
|
|
tunnelActions = {},
|
|
onTunnelAction,
|
|
}: SSHTunnelViewerProps): React.ReactElement {
|
|
const { t } = useTranslation();
|
|
const activeHost: SSHHost | undefined =
|
|
Array.isArray(hosts) && hosts.length > 0 ? hosts[0] : undefined;
|
|
|
|
if (
|
|
!activeHost ||
|
|
!activeHost.tunnelConnections ||
|
|
activeHost.tunnelConnections.length === 0
|
|
) {
|
|
return (
|
|
<div className="w-full h-full flex flex-col items-center justify-center text-center p-3">
|
|
<h3 className="text-lg font-semibold text-foreground mb-2">
|
|
{t("tunnels.noSshTunnels")}
|
|
</h3>
|
|
<p className="text-muted-foreground max-w-md">
|
|
{t("tunnels.createFirstTunnelMessage")}
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="w-full h-full flex flex-col overflow-hidden p-3 min-h-0">
|
|
<div className="min-h-0 flex-1 overflow-auto thin-scrollbar pr-1">
|
|
<div className="grid grid-cols-[repeat(auto-fit,minmax(320px,1fr))] gap-3 auto-rows-min content-start w-full">
|
|
{activeHost.tunnelConnections.map((t, idx) => (
|
|
<TunnelObject
|
|
key={`tunnel-${activeHost.id}-${idx}-${t.endpointHost}-${t.sourcePort}-${t.endpointPort}`}
|
|
host={activeHost}
|
|
tunnelIndex={idx}
|
|
tunnelStatuses={tunnelStatuses}
|
|
tunnelActions={tunnelActions}
|
|
onTunnelAction={onTunnelAction}
|
|
compact
|
|
bare
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|