mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: finish the remote-desktop plugin (B14)
This commit is contained in:
1 parent
0af2c94983
commit
14eb558b85
215 files changed
+30029
-3921
No files matched your search
@@ -2497,13 +2497,7 @@ export function AppShell({
|
||||
enableTerminalToolbar: false,
|
||||
enableAiAssistant: false,
|
||||
enableSsh: false,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: 22,
|
||||
rdpPort: 3389,
|
||||
vncPort: 5900,
|
||||
telnetPort: 23,
|
||||
serverTunnels: [],
|
||||
quickActions: [],
|
||||
};
|
||||
|
||||
@@ -112,7 +112,6 @@ export async function getAllServerStatuses(): Promise<
|
||||
try {
|
||||
const response = await sshHostApi.get<SSHHost[]>("/db/host");
|
||||
const defaultOrigin = await resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: null,
|
||||
});
|
||||
localHostIds = (response.data || [])
|
||||
|
||||
@@ -146,7 +146,6 @@ export interface UserPreferences {
|
||||
customThemes?: string | null;
|
||||
customKeybindings?: string | null;
|
||||
terminalDefaults?: string | null;
|
||||
rdpDefaults?: string | null;
|
||||
terminalMacros?: string | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ export interface PluginSettingsField {
|
||||
permission?: string;
|
||||
group?: string;
|
||||
component?: string;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
export interface PluginHostSettingsContribution {
|
||||
|
||||
@@ -106,33 +106,6 @@ export async function updateSessionTimeout(
|
||||
// Tailscale settings/device API wrappers moved to
|
||||
// plugins/tailscale/src/frontend/tailscale-api.ts.
|
||||
|
||||
// ============================================================================
|
||||
// GUACAMOLE SETTINGS
|
||||
// ============================================================================
|
||||
|
||||
export async function getGuacamoleSettings(): Promise<{
|
||||
enabled: boolean;
|
||||
url: string;
|
||||
}> {
|
||||
try {
|
||||
const response = await authApi.get("/users/guacamole-settings");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleApiError(error, "fetch guacamole settings");
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateGuacamoleSettings(settings: {
|
||||
enabled?: boolean;
|
||||
url?: string;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
await authApi.patch("/users/guacamole-settings", settings);
|
||||
} catch (error) {
|
||||
handleApiError(error, "update guacamole settings");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ANALYTICS SETTINGS
|
||||
// ============================================================================
|
||||
|
||||
@@ -10,27 +10,21 @@ import {
|
||||
} from "react";
|
||||
import { getUserPreferences, saveUserPreferences } from "@/api/open-tabs-api";
|
||||
import {
|
||||
parseRemoteDesktopDefaults,
|
||||
parseTerminalDefaults,
|
||||
type RemoteDesktopDefaults,
|
||||
type TerminalDefaults,
|
||||
} from "@/lib/connection-defaults";
|
||||
|
||||
interface ConnectionDefaultsContextValue {
|
||||
ready: boolean;
|
||||
terminal: TerminalDefaults;
|
||||
rdp: RemoteDesktopDefaults;
|
||||
saveTerminalDefaults: (value: TerminalDefaults) => Promise<void>;
|
||||
saveRdpDefaults: (value: RemoteDesktopDefaults) => Promise<void>;
|
||||
}
|
||||
|
||||
const ConnectionDefaultsContext = createContext<ConnectionDefaultsContextValue>(
|
||||
{
|
||||
ready: true,
|
||||
terminal: {},
|
||||
rdp: {},
|
||||
saveTerminalDefaults: async () => {},
|
||||
saveRdpDefaults: async () => {},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -41,7 +35,6 @@ export function ConnectionDefaultsProvider({
|
||||
}) {
|
||||
const [ready, setReady] = useState(false);
|
||||
const [terminal, setTerminal] = useState<TerminalDefaults>({});
|
||||
const [rdp, setRdp] = useState<RemoteDesktopDefaults>({});
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
@@ -49,7 +42,6 @@ export function ConnectionDefaultsProvider({
|
||||
.then((preferences) => {
|
||||
if (cancelled) return;
|
||||
setTerminal(parseTerminalDefaults(preferences.terminalDefaults));
|
||||
setRdp(parseRemoteDesktopDefaults(preferences.rdpDefaults));
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
@@ -64,14 +56,10 @@ export function ConnectionDefaultsProvider({
|
||||
await saveUserPreferences({ terminalDefaults: JSON.stringify(value) });
|
||||
setTerminal(value);
|
||||
}, []);
|
||||
const saveRdpDefaults = useCallback(async (value: RemoteDesktopDefaults) => {
|
||||
await saveUserPreferences({ rdpDefaults: JSON.stringify(value) });
|
||||
setRdp(value);
|
||||
}, []);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ ready, terminal, rdp, saveTerminalDefaults, saveRdpDefaults }),
|
||||
[ready, terminal, rdp, saveTerminalDefaults, saveRdpDefaults],
|
||||
() => ({ ready, terminal, saveTerminalDefaults }),
|
||||
[ready, terminal, saveTerminalDefaults],
|
||||
);
|
||||
return (
|
||||
<ConnectionDefaultsContext.Provider value={value}>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, useRef, useCallback, useEffect } from "react";
|
||||
import { enabledHostProtocols, protocolPort } from "@/sidebar/host-protocols";
|
||||
import { useSshAuthProviders } from "@/hooks/useSshAuthProviders";
|
||||
import { useIsMobile } from "@/hooks/use-mobile";
|
||||
import { Button } from "@/components/button";
|
||||
@@ -316,15 +317,12 @@ function QuickActionsCard({
|
||||
const { t } = useTranslation();
|
||||
const pinnedHosts = hosts.filter((h) => h.pin);
|
||||
const getConnectionEndpoint = (host: Host) => {
|
||||
const protocol = host.enableSsh ? undefined : enabledHostProtocols(host)[0];
|
||||
const port = host.enableSsh
|
||||
? host.sshPort
|
||||
: host.enableRdp
|
||||
? host.rdpPort
|
||||
: host.enableVnc
|
||||
? host.vncPort
|
||||
: host.enableTelnet
|
||||
? host.telnetPort
|
||||
: host.port;
|
||||
: protocol
|
||||
? protocolPort(host.pluginSettings, protocol)
|
||||
: host.port;
|
||||
return `${host.ip}:${port ?? host.port}`;
|
||||
};
|
||||
const renderConnectionIcon = (host: Host) => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { GuacamoleConfig } from "@/types/guacamole-config";
|
||||
import type { TerminalConfig } from "@/types";
|
||||
|
||||
export type TerminalDefaults = Partial<
|
||||
@@ -20,8 +19,6 @@ export type TerminalDefaults = Partial<
|
||||
>
|
||||
>;
|
||||
|
||||
export type RemoteDesktopDefaults = Partial<GuacamoleConfig>;
|
||||
|
||||
function parseObject<T extends object>(value?: string | null): Partial<T> {
|
||||
if (!value) return {};
|
||||
try {
|
||||
@@ -38,12 +35,6 @@ export function parseTerminalDefaults(value?: string | null): TerminalDefaults {
|
||||
return parseObject<TerminalDefaults>(value);
|
||||
}
|
||||
|
||||
export function parseRemoteDesktopDefaults(
|
||||
value?: string | null,
|
||||
): RemoteDesktopDefaults {
|
||||
return parseObject<RemoteDesktopDefaults>(value);
|
||||
}
|
||||
|
||||
// Booleans have three states in the defaults UI: unset means the host decides.
|
||||
export type TriState = "inherit" | "on" | "off";
|
||||
|
||||
|
||||
@@ -4,12 +4,9 @@ import { websocketAuthProtocols } from "@/lib/ws-auth";
|
||||
export type ConnectionOrigin = "local" | "remote";
|
||||
|
||||
interface OriginResolvableHost {
|
||||
connectionType?: string | null;
|
||||
connectionOrigin?: ConnectionOrigin | null;
|
||||
}
|
||||
|
||||
const GUACAMOLE_CONNECTION_TYPES = new Set(["rdp", "vnc", "telnet"]);
|
||||
|
||||
/**
|
||||
* Resolves which backend a given host's interactive connection (SSH, Docker
|
||||
* console, RDP/VNC/Telnet) should dial: the desktop app's embedded local
|
||||
@@ -21,16 +18,16 @@ const GUACAMOLE_CONNECTION_TYPES = new Set(["rdp", "vnc", "telnet"]);
|
||||
* Everything else follows the host's own override if set, falling back to
|
||||
* the desktop-wide default.
|
||||
*
|
||||
* RDP/VNC/Telnet are the exception to that fallback: left on Default they
|
||||
* resolve to "remote" rather than following the desktop-wide setting. They
|
||||
* need a guacd, which the desktop does not ship, so originating them here
|
||||
* only works once the user has pointed Termix at one of their own (the
|
||||
* global guacd URL setting, or a host's guacd Proxy override). Making that
|
||||
* opt-in per host keeps an upgrade from moving working connections onto a
|
||||
* guacd that isn't there -- see Termix-SSH/Support#1240.
|
||||
* `defaultRemote` makes a host left on Default resolve to "remote" instead of
|
||||
* following the desktop-wide setting. Remote desktop passes it: it needs a
|
||||
* guacd, which the desktop does not ship, so originating it here only works
|
||||
* once the user has pointed Termix at one of their own. Making that opt-in
|
||||
* per host keeps an upgrade from moving working connections onto a guacd
|
||||
* that isn't there -- see Termix-SSH/Support#1240.
|
||||
*/
|
||||
export async function resolveConnectionOrigin(
|
||||
host: OriginResolvableHost,
|
||||
options: { defaultRemote?: boolean } = {},
|
||||
): Promise<ConnectionOrigin> {
|
||||
if (!isElectron()) {
|
||||
return "local";
|
||||
@@ -38,7 +35,7 @@ export async function resolveConnectionOrigin(
|
||||
if (host.connectionOrigin === "local" || host.connectionOrigin === "remote") {
|
||||
return host.connectionOrigin;
|
||||
}
|
||||
if (GUACAMOLE_CONNECTION_TYPES.has(host.connectionType ?? "")) {
|
||||
if (options.defaultRemote) {
|
||||
return "remote";
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
import type { AxiosInstance } from "axios";
|
||||
import { authApi } from "@/main-axios";
|
||||
import { authApi, createRemoteOriginApiInstance } from "@/main-axios";
|
||||
import { getBasePath } from "@/lib/base-path";
|
||||
import { isElectron } from "@/lib/electron";
|
||||
import { websocketAuthProtocols } from "@/lib/ws-auth";
|
||||
@@ -75,6 +75,27 @@ export function createPluginApi(pluginId: string): AxiosInstance {
|
||||
}) as AxiosInstance;
|
||||
}
|
||||
|
||||
const remotePluginApis = new Map<string, AxiosInstance>();
|
||||
|
||||
/**
|
||||
* The same client pointed at the connected remote server, for a desktop app
|
||||
* host whose connection origin is "remote". Outside Electron, and for
|
||||
* "local", it is the ordinary client.
|
||||
*/
|
||||
export function pluginApiFor(
|
||||
pluginId: string,
|
||||
origin: ConnectionOrigin | undefined,
|
||||
local: AxiosInstance,
|
||||
): AxiosInstance {
|
||||
if (origin !== "remote" || !isElectron()) return local;
|
||||
let client = remotePluginApis.get(pluginId);
|
||||
if (!client) {
|
||||
client = createRemoteOriginApiInstance(pluginApiPath(pluginId));
|
||||
remotePluginApis.set(pluginId, client);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* pluginWsUrl for a path a backend handed out ("/plugin-ws/<id>/<path>?q"),
|
||||
* so a caller can dial a plugin's socket without naming the plugin.
|
||||
|
||||
+2
-26
@@ -725,7 +725,6 @@
|
||||
"connectionDetails": "Connection Details",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Remote Desktop",
|
||||
"port": "Port",
|
||||
"username": "Username",
|
||||
"folder": "Folder",
|
||||
@@ -752,10 +751,7 @@
|
||||
"tabGeneral": "General",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Host Metrics",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Sharing",
|
||||
"tabAuthentication": "Authentication",
|
||||
"terminal": "Terminal",
|
||||
@@ -829,8 +825,6 @@
|
||||
"deselectAll": "Deselect All",
|
||||
"protocols": "Protocols",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Virtual Network",
|
||||
"unencryptedShell": "Unencrypted shell",
|
||||
"addressIp": "Address / IP",
|
||||
"friendlyName": "Friendly Name",
|
||||
"macAddress": "MAC Address",
|
||||
@@ -853,7 +847,6 @@
|
||||
"useSocks5ProxyDesc": "Route connection through a proxy server",
|
||||
"connectionOrigin": "Connection Origin",
|
||||
"connectionOriginDesc": "Where this host's connection originates from. Overrides the desktop app's global default.",
|
||||
"connectionOriginRemoteDesktopNote": "RDP, VNC and Telnet use the remote server unless you pick \"This device\", which needs a guacd this machine can reach — set one in the guacd URL setting, or per host under guacd Proxy.",
|
||||
"connectionOriginDefault": "Use default",
|
||||
"connectionOriginLocal": "This device (local network)",
|
||||
"connectionOriginRemote": "Remote server",
|
||||
@@ -1378,9 +1371,6 @@
|
||||
"filterAuthStepca": "Step CA",
|
||||
"filterProtocolGroup": "Protocol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Features",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "File Manager",
|
||||
@@ -1478,8 +1468,6 @@
|
||||
"authTypeDirect": "Direct",
|
||||
"authTypeCredential": "Credential",
|
||||
"authTypeNone": "None",
|
||||
"colorDepth": "Color Depth",
|
||||
"resizeMethod": "Resize Method",
|
||||
"recordingPath": "Recording Path",
|
||||
"recordingName": "Recording Name",
|
||||
"saveHostFirst": "Save the host first.",
|
||||
@@ -2117,10 +2105,6 @@
|
||||
"metrics": "Metrics",
|
||||
"sec": "sec",
|
||||
"logLevel": "Log Level",
|
||||
"enableRemoteDesktop": "Enable Remote Desktop",
|
||||
"enableRemoteDesktopDesc": "RDP/VNC remote desktop",
|
||||
"enableRemoteDesktopDocsLink": "View docs",
|
||||
"guacdUrl": "guacd URL",
|
||||
"oidcDescription": "Configure OpenID Connect for SSO. Fields marked * are required.",
|
||||
"oidcDocsLink": "View docs",
|
||||
"oidcClientId": "Client ID",
|
||||
@@ -2266,9 +2250,6 @@
|
||||
"monitoringIntervalInvalid": "Invalid interval values",
|
||||
"monitoringSaved": "Monitoring settings saved",
|
||||
"monitoringSaveFailed": "Failed to save monitoring settings",
|
||||
"remoteDesktopSaved": "Remote Desktop settings saved",
|
||||
"remoteDesktopSaveFailed": "Failed to save Remote Desktop settings",
|
||||
"remoteDesktopUpdateFailed": "Failed to update Remote Desktop setting",
|
||||
"logLevelUpdateFailed": "Failed to update log level",
|
||||
"oidcSaved": "OIDC configuration saved",
|
||||
"oidcSaveFailed": "Failed to save OIDC config",
|
||||
@@ -2457,10 +2438,9 @@
|
||||
"protocolLabel": "Protocol",
|
||||
"domainLabel": "Domain",
|
||||
"domainPlaceholder": "optional",
|
||||
"connectToRdp": "Connect via RDP",
|
||||
"connectToVnc": "Connect via VNC",
|
||||
"connectToTerminal": "Connect to Terminal",
|
||||
"connectToFiles": "Connect to Files"
|
||||
"connectToFiles": "Connect to Files",
|
||||
"connectWith": "Connect via {{protocol}}"
|
||||
},
|
||||
"sshTools": {
|
||||
"keyRecordingTitle": "Key Recording",
|
||||
@@ -2667,13 +2647,9 @@
|
||||
"description": "Set values that every host inherits unless it overrides them.",
|
||||
"manage": "Manage",
|
||||
"dialogDescription": "These apply to hosts that leave a setting unset. Anything set on a host wins.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Remote Desktop",
|
||||
"inherit": "Inherit",
|
||||
"on": "On",
|
||||
"off": "Off",
|
||||
"resizeDisplayUpdate": "Display Update",
|
||||
"resizeReconnect": "Reconnect",
|
||||
"clearAll": "Clear All",
|
||||
"saved": "Connection defaults saved",
|
||||
"saveFailed": "Failed to save connection defaults",
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Verbindingsbesonderhede",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Afstandslessenaar",
|
||||
"port": "Hawe",
|
||||
"username": "Gebruikersnaam",
|
||||
"folder": "Vouer",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Algemeen",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminaal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Gasheermetrieke",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Deling",
|
||||
"tabAuthentication": "Verifikasie",
|
||||
"terminal": "Terminaal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Deselekteer alles",
|
||||
"protocols": "Protokolle",
|
||||
"secureShell": "Veilige Dop",
|
||||
"virtualNetwork": "Virtuele Netwerk",
|
||||
"unencryptedShell": "Ongeënkripteerde dop",
|
||||
"addressIp": "Adres / IP",
|
||||
"friendlyName": "Vriendelike Naam",
|
||||
"macAddress": "MAC-adres",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Stap CA",
|
||||
"filterProtocolGroup": "Protokol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Kenmerke",
|
||||
"filterFeatureTerminal": "Terminaal",
|
||||
"filterFeatureFileManager": "Lêerbestuurder",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direkte",
|
||||
"authTypeCredential": "Geloofsbrief",
|
||||
"authTypeNone": "Geen",
|
||||
"colorDepth": "Kleurdiepte",
|
||||
"resizeMethod": "Vergrootingsmetode",
|
||||
"recordingPath": "Opnamepad",
|
||||
"recordingName": "Opnamenaam",
|
||||
"saveHostFirst": "Stoor eers die gasheer.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Aktiveer Guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC-afstandlessenaar",
|
||||
"enableGuacamoleDocsLink": "Bekyk dokumente",
|
||||
"guacdUrl": "guacd-URL",
|
||||
"tailscaleApiKey": "Tailscale API-sleutel",
|
||||
"tailscaleApiKeyDescription": "Word gebruik vir toestelontdekking in die gasheerredigeerder. Ondersteun Tailscale (tskey-) en Headscale (hskey-) sleutels. Genereer 'n sleutel by tailscale.com/admin/settings/keys of vanaf jou Headscale-instansie.",
|
||||
"tailscaleApiKeyDocsLink": "Bekyk dokumente",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokol",
|
||||
"domainLabel": "Domein",
|
||||
"domainPlaceholder": "opsioneel",
|
||||
"connectToRdp": "Verbind via RDP",
|
||||
"connectToVnc": "Verbind via VNC",
|
||||
"connectToTerminal": "Koppel aan terminaal",
|
||||
"connectToFiles": "Koppel aan lêers"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Stel waardes wat elke gasheer erf tensy dit hulle oorskryf.",
|
||||
"manage": "Bestuur",
|
||||
"dialogDescription": "Dit geld vir gashere wat 'n instelling ongestel laat. Enigiets wat op 'n gasheer gestel word, wen.",
|
||||
"tabTerminal": "Terminaal",
|
||||
"tabRemoteDesktop": "Afstandslessenaar",
|
||||
"inherit": "Erf",
|
||||
"on": "Aan",
|
||||
"off": "Af",
|
||||
"resizeDisplayUpdate": "Skermopdatering",
|
||||
"resizeReconnect": "Herkoppel",
|
||||
"clearAll": "Vee alles uit",
|
||||
"saved": "Verbindingsverstekke gestoor",
|
||||
"saveFailed": "Kon nie verbindingsverstekinstellings stoor nie"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "تفاصيل الاتصال",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "سطح المكتب البعيد",
|
||||
"port": "المنفذ",
|
||||
"username": "اسم المستخدم",
|
||||
"folder": "المجلد",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "عام",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "الطرفية",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "مقاييس المضيف",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "المشاركة",
|
||||
"tabAuthentication": "المصادقة",
|
||||
"terminal": "الطرفية",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "إلغاء تحديد الكل",
|
||||
"protocols": "البروتوكولات",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "الشبكة الافتراضية",
|
||||
"unencryptedShell": "shell غير مشفر",
|
||||
"addressIp": "العنوان / IP",
|
||||
"friendlyName": "الاسم المألوف",
|
||||
"macAddress": "عنوان MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "الخطوة ج",
|
||||
"filterProtocolGroup": "البروتوكول",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "الميزات",
|
||||
"filterFeatureTerminal": "الطرفية",
|
||||
"filterFeatureFileManager": "مدير الملفات",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "مباشر",
|
||||
"authTypeCredential": "بيانات الاعتماد",
|
||||
"authTypeNone": "لا أحد",
|
||||
"colorDepth": "عمق اللون",
|
||||
"resizeMethod": "طريقة تغيير الحجم",
|
||||
"recordingPath": "مسار التسجيل",
|
||||
"recordingName": "اسم التسجيل",
|
||||
"saveHostFirst": "احفظ المضيف أولاً.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "تمكين Guacamole",
|
||||
"enableGuacamoleDesc": "سطح المكتب البعيد RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "عرض المستندات",
|
||||
"guacdUrl": "رابط guacd",
|
||||
"tailscaleApiKey": "مفتاح Tailscale API",
|
||||
"tailscaleApiKeyDescription": "يُستخدم لاكتشاف الأجهزة في محرر المضيف. يدعم مفاتيح Tailscale (tskey-) وHeadscale (hskey-). أنشئ مفتاحًا من خلال tailscale.com/admin/settings/keys أو من خلال حسابك في Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "عرض المستندات",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "بروتوكول",
|
||||
"domainLabel": "اِختِصاص",
|
||||
"domainPlaceholder": "خياري",
|
||||
"connectToRdp": "الاتصال عبر بروتوكول سطح المكتب البعيد (RDP)",
|
||||
"connectToVnc": "الاتصال عبر VNC",
|
||||
"connectToTerminal": "اتصل بالطرفية",
|
||||
"connectToFiles": "اتصل بالملفات"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "قم بتعيين القيم التي يرثها كل مضيف ما لم يقم بتجاوزها.",
|
||||
"manage": "يدير",
|
||||
"dialogDescription": "تنطبق هذه الشروط على الأجهزة المضيفة التي تترك إعدادًا غير مُحدد. أي إعداد مُحدد على الجهاز المضيف هو الذي يُعتمد.",
|
||||
"tabTerminal": "صالة",
|
||||
"tabRemoteDesktop": "سطح المكتب البعيد",
|
||||
"inherit": "يرث",
|
||||
"on": "على",
|
||||
"off": "عن",
|
||||
"resizeDisplayUpdate": "تحديث الشاشة",
|
||||
"resizeReconnect": "إعادة الاتصال",
|
||||
"clearAll": "مسح الكل",
|
||||
"saved": "تم حفظ إعدادات الاتصال الافتراضية",
|
||||
"saveFailed": "فشل حفظ إعدادات الاتصال الافتراضية"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Детайли за връзката",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Телнет",
|
||||
"remoteDesktop": "Отдалечен работен плот",
|
||||
"port": "Порт",
|
||||
"username": "Потребителско име",
|
||||
"folder": "Папка",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Общи",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRdp": "ПРСР",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Метрики на хоста",
|
||||
"tabTelnet": "Телнет",
|
||||
"tabSharing": "Споделяне",
|
||||
"tabAuthentication": "Удостоверяване",
|
||||
"terminal": "Терминал",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Премахване на избора от всички",
|
||||
"protocols": "Протоколи",
|
||||
"secureShell": "Защитена обвивка",
|
||||
"virtualNetwork": "Виртуална мрежа",
|
||||
"unencryptedShell": "Некриптирана обвивка",
|
||||
"addressIp": "Адрес / IP адрес",
|
||||
"friendlyName": "Приятелско име",
|
||||
"macAddress": "MAC адрес",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Стъпка CA",
|
||||
"filterProtocolGroup": "Протокол",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "ПРСР",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Телнет",
|
||||
"filterFeaturesGroup": "Характеристики",
|
||||
"filterFeatureTerminal": "Терминал",
|
||||
"filterFeatureFileManager": "Файлов мениджър",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Директно",
|
||||
"authTypeCredential": "Пълномощия",
|
||||
"authTypeNone": "Няма",
|
||||
"colorDepth": "Дълбочина на цвета",
|
||||
"resizeMethod": "Метод за преоразмеряване",
|
||||
"recordingPath": "Път на запис",
|
||||
"recordingName": "Име на записа",
|
||||
"saveHostFirst": "Първо запазете хоста.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Активиране на гуакамоле",
|
||||
"enableGuacamoleDesc": "RDP/VNC отдалечен работен плот",
|
||||
"enableGuacamoleDocsLink": "Преглед на документи",
|
||||
"guacdUrl": "URL адрес на GUACD",
|
||||
"tailscaleApiKey": "API ключ на Tailscale",
|
||||
"tailscaleApiKeyDescription": "Използва се за откриване на устройства в редактора на хостове. Поддържа ключове Tailscale (tkey-) и Headscale (hskey-). Генерирайте ключ на tailscale.com/admin/settings/keys или от вашия Headscale екземпляр.",
|
||||
"tailscaleApiKeyDocsLink": "Преглед на документи",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Протокол",
|
||||
"domainLabel": "Домейн",
|
||||
"domainPlaceholder": "по избор",
|
||||
"connectToRdp": "Свързване чрез RDP",
|
||||
"connectToVnc": "Свързване чрез VNC",
|
||||
"connectToTerminal": "Свързване с терминала",
|
||||
"connectToFiles": "Свързване с файлове"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Задайте стойности, които всеки хост наследява, освен ако не ги презапише.",
|
||||
"manage": "Управление",
|
||||
"dialogDescription": "Това се отнася за хостове, които оставят настройка незададена. Всичко, което е зададено на хост, печели.",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRemoteDesktop": "Отдалечен работен плот",
|
||||
"inherit": "Наследяване",
|
||||
"on": "Включено",
|
||||
"off": "Изключено",
|
||||
"resizeDisplayUpdate": "Актуализация на дисплея",
|
||||
"resizeReconnect": "Свържете се отново",
|
||||
"clearAll": "Изчисти всички",
|
||||
"saved": "Настройките по подразбиране на връзката са запазени",
|
||||
"saveFailed": "Запазването на настройките по подразбиране за връзка не бе успешно"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "সংযোগের বিবরণ",
|
||||
"ssh": "এসএসএইচ",
|
||||
"telnet": "টেলনেট",
|
||||
"remoteDesktop": "রিমোট ডেস্কটপ",
|
||||
"port": "বন্দর",
|
||||
"username": "ব্যবহারকারীর নাম",
|
||||
"folder": "ফোল্ডার",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "সাধারণ",
|
||||
"tabSsh": "এসএসএইচ",
|
||||
"tabTerminal": "টার্মিনাল",
|
||||
"tabRdp": "আরডিপি",
|
||||
"tabVnc": "ভিএনসি",
|
||||
"tabStats": "হোস্ট মেট্রিক্স",
|
||||
"tabTelnet": "টেলনেট",
|
||||
"tabSharing": "শেয়ারিং",
|
||||
"tabAuthentication": "প্রমাণীকরণ",
|
||||
"terminal": "টার্মিনাল",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "সবগুলো নির্বাচন বাতিল করুন",
|
||||
"protocols": "প্রোটোকল",
|
||||
"secureShell": "সুরক্ষিত খোলস",
|
||||
"virtualNetwork": "ভার্চুয়াল নেটওয়ার্ক",
|
||||
"unencryptedShell": "এনক্রিপ্টবিহীন শেল",
|
||||
"addressIp": "ঠিকানা / আইপি",
|
||||
"friendlyName": "বন্ধুত্বপূর্ণ নাম",
|
||||
"macAddress": "MAC ঠিকানা",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "স্টেপ সিএ",
|
||||
"filterProtocolGroup": "প্রোটোকল",
|
||||
"filterProtocolSsh": "এসএসএইচ",
|
||||
"filterProtocolRdp": "আরডিপি",
|
||||
"filterProtocolVnc": "ভিএনসি",
|
||||
"filterProtocolTelnet": "টেলনেট",
|
||||
"filterFeaturesGroup": "বৈশিষ্ট্য",
|
||||
"filterFeatureTerminal": "টার্মিনাল",
|
||||
"filterFeatureFileManager": "ফাইল ম্যানেজার",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "সরাসরি",
|
||||
"authTypeCredential": "শংসাপত্র",
|
||||
"authTypeNone": "কোনোটিই না",
|
||||
"colorDepth": "রঙের গভীরতা",
|
||||
"resizeMethod": "আকার পরিবর্তন পদ্ধতি",
|
||||
"recordingPath": "রেকর্ডিং পথ",
|
||||
"recordingName": "রেকর্ডিং নাম",
|
||||
"saveHostFirst": "প্রথমে হোস্টটি সংরক্ষণ করুন।",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "গুয়াকামোল সক্রিয় করুন",
|
||||
"enableGuacamoleDesc": "RDP/VNC রিমোট ডেস্কটপ",
|
||||
"enableGuacamoleDocsLink": "নথি দেখুন",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "টেইলস্কেল এপিআই কী",
|
||||
"tailscaleApiKeyDescription": "হোস্ট এডিটরে ডিভাইস শনাক্তকরণের জন্য ব্যবহৃত হয়। এটি টেইলস্কেল (tskey-) এবং হেডস্কেল (hskey-) কী সমর্থন করে। tailscale.com/admin/settings/keys থেকে অথবা আপনার হেডস্কেল ইনস্ট্যান্স থেকে একটি কী তৈরি করুন।",
|
||||
"tailscaleApiKeyDocsLink": "নথি দেখুন",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "প্রোটোকল",
|
||||
"domainLabel": "ডোমেইন",
|
||||
"domainPlaceholder": "ঐচ্ছিক",
|
||||
"connectToRdp": "RDP এর মাধ্যমে সংযোগ করুন",
|
||||
"connectToVnc": "VNC এর মাধ্যমে সংযোগ করুন",
|
||||
"connectToTerminal": "টার্মিনালের সাথে সংযোগ করুন",
|
||||
"connectToFiles": "ফাইলগুলির সাথে সংযোগ করুন"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "এমন মান নির্ধারণ করুন যা প্রতিটি হোস্ট উত্তরাধিকারসূত্রে পাবে, যদি না সে সেগুলোকে অগ্রাহ্য করে।",
|
||||
"manage": "পরিচালনা করুন",
|
||||
"dialogDescription": "এই নিয়মগুলো সেইসব হোস্টের ক্ষেত্রে প্রযোজ্য যারা কোনো সেটিং সেট করে না। হোস্টে যা কিছু সেট করা থাকে, তা-ই কার্যকর হয়।",
|
||||
"tabTerminal": "টার্মিনাল",
|
||||
"tabRemoteDesktop": "রিমোট ডেস্কটপ",
|
||||
"inherit": "উত্তরাধিকার সূত্রে",
|
||||
"on": "চালু",
|
||||
"off": "বন্ধ",
|
||||
"resizeDisplayUpdate": "ডিসপ্লে আপডেট",
|
||||
"resizeReconnect": "পুনরায় সংযোগ করুন",
|
||||
"clearAll": "সব পরিষ্কার করুন",
|
||||
"saved": "সংযোগের ডিফল্ট মান সংরক্ষিত আছে",
|
||||
"saveFailed": "সংযোগের ডিফল্ট মান সংরক্ষণ করতে ব্যর্থ হয়েছে"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detalls de la connexió",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Escriptori remot",
|
||||
"port": "Port",
|
||||
"username": "Nom d'usuari",
|
||||
"folder": "Carpeta",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "General",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Mètriques de l'amfitrió",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Compartir",
|
||||
"tabAuthentication": "Autenticació",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Desselecciona-ho tot",
|
||||
"protocols": "Protocols",
|
||||
"secureShell": "Shell segur",
|
||||
"virtualNetwork": "Xarxa virtual",
|
||||
"unencryptedShell": "Shell sense xifrar",
|
||||
"addressIp": "Adreça / IP",
|
||||
"friendlyName": "Nom amigable",
|
||||
"macAddress": "Adreça MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Pas CA",
|
||||
"filterProtocolGroup": "Protocol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Característiques",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Gestor de fitxers",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Directe",
|
||||
"authTypeCredential": "Credencial",
|
||||
"authTypeNone": "Cap",
|
||||
"colorDepth": "Profunditat de color",
|
||||
"resizeMethod": "Mètode de redimensionament",
|
||||
"recordingPath": "Ruta d'enregistrament",
|
||||
"recordingName": "Nom de l'enregistrament",
|
||||
"saveHostFirst": "Primer desa l'amfitrió.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Activa el guacamole",
|
||||
"enableGuacamoleDesc": "Escriptori remot RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Veure documents",
|
||||
"guacdUrl": "URL de guacd",
|
||||
"tailscaleApiKey": "Clau API de Tailscale",
|
||||
"tailscaleApiKeyDescription": "S'utilitza per a la detecció de dispositius a l'editor de l'amfitrió. Admet les claus Tailscale (tskey-) i Headscale (hskey-). Genereu una clau a tailscale.com/admin/settings/keys o des de la vostra instància de Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Veure documents",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocol",
|
||||
"domainLabel": "Domini",
|
||||
"domainPlaceholder": "opcional",
|
||||
"connectToRdp": "Connecta't via RDP",
|
||||
"connectToVnc": "Connecta't mitjançant VNC",
|
||||
"connectToTerminal": "Connecta't al terminal",
|
||||
"connectToFiles": "Connecta't a fitxers"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Defineix els valors que cada amfitrió hereta tret que els sobreescrigui.",
|
||||
"manage": "Gestiona",
|
||||
"dialogDescription": "Això s'aplica als amfitrions que deixen una configuració sense definir. Qualsevol cosa definida en un amfitrió guanya.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Escriptori remot",
|
||||
"inherit": "Heretar",
|
||||
"on": "Activat",
|
||||
"off": "Desactivat",
|
||||
"resizeDisplayUpdate": "Actualització de la pantalla",
|
||||
"resizeReconnect": "Reconnecta",
|
||||
"clearAll": "Esborra-ho tot",
|
||||
"saved": "Els valors predeterminats de connexió s'han desat",
|
||||
"saveFailed": "No s'han pogut desar els valors predeterminats de la connexió"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Podrobnosti o připojení",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Vzdálená plocha",
|
||||
"port": "Přístav",
|
||||
"username": "Uživatelské jméno",
|
||||
"folder": "Složka",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Generál",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminál",
|
||||
"tabRdp": "PRV",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Metriky hostitele",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Sdílení",
|
||||
"tabAuthentication": "Ověřování",
|
||||
"terminal": "Terminál",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Zrušit výběr všeho",
|
||||
"protocols": "Protokoly",
|
||||
"secureShell": "Bezpečné prostředí",
|
||||
"virtualNetwork": "Virtuální síť",
|
||||
"unencryptedShell": "Nešifrovaný shell",
|
||||
"addressIp": "Adresa / IP adresa",
|
||||
"friendlyName": "Přátelský název",
|
||||
"macAddress": "MAC adresa",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Krok CA",
|
||||
"filterProtocolGroup": "Protokol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "PRV",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funkce",
|
||||
"filterFeatureTerminal": "Terminál",
|
||||
"filterFeatureFileManager": "Správce souborů",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Řídit",
|
||||
"authTypeCredential": "Pověření",
|
||||
"authTypeNone": "Žádný",
|
||||
"colorDepth": "Barevná hloubka",
|
||||
"resizeMethod": "Metoda změny velikosti",
|
||||
"recordingPath": "Cesta záznamu",
|
||||
"recordingName": "Název nahrávky",
|
||||
"saveHostFirst": "Nejprve uložte hostitele.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Povolit guacamole",
|
||||
"enableGuacamoleDesc": "Vzdálená plocha RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Zobrazit dokumenty",
|
||||
"guacdUrl": "URL GUACD",
|
||||
"tailscaleApiKey": "Klíč API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Používá se pro vyhledávání zařízení v editoru hostitele. Podporuje klíče Tailscale (tkey-) a Headscale (hskey-). Klíč si můžete vygenerovat na adrese tailscale.com/admin/settings/keys nebo z vaší instance Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Zobrazit dokumenty",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokol",
|
||||
"domainLabel": "Doména",
|
||||
"domainPlaceholder": "volitelný",
|
||||
"connectToRdp": "Připojení přes RDP",
|
||||
"connectToVnc": "Připojení přes VNC",
|
||||
"connectToTerminal": "Připojení k terminálu",
|
||||
"connectToFiles": "Připojení k souborům"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Nastavte hodnoty, které zdědí každý hostitel, pokud je nepřepíše.",
|
||||
"manage": "Spravovat",
|
||||
"dialogDescription": "Toto platí pro hostitele, kteří nechají nastavení nenastavené. Cokoli, co je na hostiteli nastaveno, vyhrává.",
|
||||
"tabTerminal": "Terminál",
|
||||
"tabRemoteDesktop": "Vzdálená plocha",
|
||||
"inherit": "Zdědit",
|
||||
"on": "Na",
|
||||
"off": "Vypnuto",
|
||||
"resizeDisplayUpdate": "Aktualizace displeje",
|
||||
"resizeReconnect": "Znovu se připojte",
|
||||
"clearAll": "Vymazat vše",
|
||||
"saved": "Výchozí nastavení připojení uloženo",
|
||||
"saveFailed": "Nepodařilo se uložit výchozí nastavení připojení"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Forbindelsesdetaljer",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Fjernskrivebord",
|
||||
"port": "Havn",
|
||||
"username": "Brugernavn",
|
||||
"folder": "Folder",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Generel",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "Landdistriktsudviklingsplan",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Værtsmålinger",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Deling",
|
||||
"tabAuthentication": "Godkendelse",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Fravælg alle",
|
||||
"protocols": "Protokoller",
|
||||
"secureShell": "Sikker skal",
|
||||
"virtualNetwork": "Virtuelt netværk",
|
||||
"unencryptedShell": "Ukrypteret skal",
|
||||
"addressIp": "Adresse / IP",
|
||||
"friendlyName": "Venligt navn",
|
||||
"macAddress": "MAC-adresse",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Trin CA",
|
||||
"filterProtocolGroup": "Protokol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "Landdistriktsudviklingsplan",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funktioner",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Filhåndtering",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direkte",
|
||||
"authTypeCredential": "Legitimationsoplysninger",
|
||||
"authTypeNone": "Ingen",
|
||||
"colorDepth": "Farvedybde",
|
||||
"resizeMethod": "Ændre størrelse-metode",
|
||||
"recordingPath": "Optagelsessti",
|
||||
"recordingName": "Optagelsesnavn",
|
||||
"saveHostFirst": "Gem værten først.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Aktivér guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC fjernskrivebord",
|
||||
"enableGuacamoleDocsLink": "Se dokumenter",
|
||||
"guacdUrl": "guacd-URL",
|
||||
"tailscaleApiKey": "Tailscale API-nøgle",
|
||||
"tailscaleApiKeyDescription": "Bruges til enhedsregistrering i værtseditoren. Understøtter Tailscale (tskey-) og Headscale (hskey-) nøgler. Generer en nøgle på tailscale.com/admin/settings/keys eller fra din Headscale-instans.",
|
||||
"tailscaleApiKeyDocsLink": "Se dokumenter",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokol",
|
||||
"domainLabel": "Domæne",
|
||||
"domainPlaceholder": "valgfri",
|
||||
"connectToRdp": "Opret forbindelse via RDP",
|
||||
"connectToVnc": "Forbind via VNC",
|
||||
"connectToTerminal": "Opret forbindelse til terminalen",
|
||||
"connectToFiles": "Opret forbindelse til filer"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Angiv værdier, som hver vært arver, medmindre den tilsidesætter dem.",
|
||||
"manage": "Styre",
|
||||
"dialogDescription": "Disse gælder for værter, der ikke har angivet en indstilling. Alt, hvad der er angivet på en vært, vinder.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Fjernskrivebord",
|
||||
"inherit": "Arve",
|
||||
"on": "På",
|
||||
"off": "Slukket",
|
||||
"resizeDisplayUpdate": "Opdatering af display",
|
||||
"resizeReconnect": "Genopret forbindelse",
|
||||
"clearAll": "Ryd alt",
|
||||
"saved": "Standardindstillinger for forbindelser gemt",
|
||||
"saveFailed": "Kunne ikke gemme standardforbindelsesindstillinger"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Verbindungsdetails",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Remotedesktop",
|
||||
"port": "Port",
|
||||
"username": "Benutzername",
|
||||
"folder": "Ordner",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Allgemein",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Host-Metriken",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Freigabe",
|
||||
"tabAuthentication": "Authentifizierung",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Auswahl aufheben",
|
||||
"protocols": "Protokolle",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Virtuelles Netzwerk",
|
||||
"unencryptedShell": "Unverschlüsselte Shell",
|
||||
"addressIp": "Adresse / IP",
|
||||
"friendlyName": "Anzeigename",
|
||||
"macAddress": "MAC-Adresse",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Schritt CA",
|
||||
"filterProtocolGroup": "Protokoll",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funktionen",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Dateimanager",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direkt",
|
||||
"authTypeCredential": "Anmeldeinformation",
|
||||
"authTypeNone": "Keiner",
|
||||
"colorDepth": "Farbtiefe",
|
||||
"resizeMethod": "Skalierungsmethode",
|
||||
"recordingPath": "Aufzeichnungspfad",
|
||||
"recordingName": "Aufzeichnungsname",
|
||||
"saveHostFirst": "Host zuerst speichern.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamole aktivieren",
|
||||
"enableGuacamoleDesc": "RDP/VNC-Remotedesktop",
|
||||
"enableGuacamoleDocsLink": "Dokumentation anzeigen",
|
||||
"guacdUrl": "guacd-URL",
|
||||
"tailscaleApiKey": "Tailscale-API-Schlüssel",
|
||||
"tailscaleApiKeyDescription": "Wird zur Geräteerkennung im Host-Editor verwendet. Unterstützt Tailscale- (tskey-) und Headscale-Schlüssel (hskey-). Generieren Sie einen Schlüssel unter tailscale.com/admin/settings/keys oder in Ihrer Headscale-Instanz.",
|
||||
"tailscaleApiKeyDocsLink": "Dokumentation anzeigen",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokoll",
|
||||
"domainLabel": "Domain",
|
||||
"domainPlaceholder": "optional",
|
||||
"connectToRdp": "Verbindung über RDP herstellen",
|
||||
"connectToVnc": "Verbindung über VNC herstellen",
|
||||
"connectToTerminal": "Mit Terminal verbinden",
|
||||
"connectToFiles": "Mit Dateien verbinden"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Werte festlegen, die jeder Host erbt, sofern er sie nicht überschreibt.",
|
||||
"manage": "Verwalten",
|
||||
"dialogDescription": "Diese Regelungen gelten für Hosts, die keine Einstellung vorgenommen haben. Alle auf einem Host festgelegten Einstellungen haben Vorrang.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Remote-Desktop",
|
||||
"inherit": "Erben",
|
||||
"on": "An",
|
||||
"off": "Aus",
|
||||
"resizeDisplayUpdate": "Anzeigeaktualisierung",
|
||||
"resizeReconnect": "Wiederverbinden",
|
||||
"clearAll": "Alles löschen",
|
||||
"saved": "Standardeinstellungen für die Verbindung gespeichert",
|
||||
"saveFailed": "Die Standardverbindungseinstellungen konnten nicht gespeichert werden."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Λεπτομέρειες σύνδεσης",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Τέλνετ",
|
||||
"remoteDesktop": "Απομακρυσμένη επιφάνεια εργασίας",
|
||||
"port": "Λιμάνι",
|
||||
"username": "Όνομα χρήστη",
|
||||
"folder": "Ντοσιέ",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Γενικός",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Τερματικό",
|
||||
"tabRdp": "ΠΑΑ",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Μετρήσεις κεντρικού υπολογιστή",
|
||||
"tabTelnet": "Τέλνετ",
|
||||
"tabSharing": "Μοιρασιά",
|
||||
"tabAuthentication": "Πιστοποίηση",
|
||||
"terminal": "Τερματικό",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Αποεπιλογή όλων",
|
||||
"protocols": "Πρωτόκολλα",
|
||||
"secureShell": "Ασφαλές κέλυφος",
|
||||
"virtualNetwork": "Εικονικό Δίκτυο",
|
||||
"unencryptedShell": "Μη κρυπτογραφημένο κέλυφος",
|
||||
"addressIp": "Διεύθυνση / IP",
|
||||
"friendlyName": "Φιλικό όνομα",
|
||||
"macAddress": "Διεύθυνση MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Βήμα CA",
|
||||
"filterProtocolGroup": "Πρωτόκολλο",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "ΠΑΑ",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Τέλνετ",
|
||||
"filterFeaturesGroup": "Χαρακτηριστικά",
|
||||
"filterFeatureTerminal": "Τερματικό",
|
||||
"filterFeatureFileManager": "Διαχειριστής αρχείων",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Απευθείας",
|
||||
"authTypeCredential": "Πιστοποιητικό",
|
||||
"authTypeNone": "Κανένας",
|
||||
"colorDepth": "Βάθος χρώματος",
|
||||
"resizeMethod": "Μέθοδος αλλαγής μεγέθους",
|
||||
"recordingPath": "Διαδρομή εγγραφής",
|
||||
"recordingName": "Όνομα εγγραφής",
|
||||
"saveHostFirst": "Αποθηκεύστε πρώτα τον οικοδεσπότη.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Ενεργοποίηση Γουακαμόλε",
|
||||
"enableGuacamoleDesc": "Απομακρυσμένη επιφάνεια εργασίας RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Προβολή εγγράφων",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "Κλειδί API κλίμακας ουράς",
|
||||
"tailscaleApiKeyDescription": "Χρησιμοποιείται για την ανακάλυψη συσκευών στον επεξεργαστή κεντρικού υπολογιστή. Υποστηρίζει τα κλειδιά Tailscale (tskey-) και Headscale (hskey-). Δημιουργήστε ένα κλειδί στη διεύθυνση tailscale.com/admin/settings/keys ή από την παρουσία Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Προβολή εγγράφων",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Πρωτόκολλο",
|
||||
"domainLabel": "Πεδίο ορισμού",
|
||||
"domainPlaceholder": "προαιρετικός",
|
||||
"connectToRdp": "Σύνδεση μέσω RDP",
|
||||
"connectToVnc": "Σύνδεση μέσω VNC",
|
||||
"connectToTerminal": "Σύνδεση με τερματικό",
|
||||
"connectToFiles": "Σύνδεση με αρχεία"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Ορίστε τιμές που κληρονομεί κάθε κεντρικός υπολογιστής, εκτός εάν τις παρακάμπτει.",
|
||||
"manage": "Διαχειρίζομαι",
|
||||
"dialogDescription": "Αυτά ισχύουν για κεντρικούς υπολογιστές που αφήνουν μια ρύθμιση μη καθορισμένη. Οτιδήποτε οριστεί σε έναν κεντρικό υπολογιστή κερδίζει.",
|
||||
"tabTerminal": "Τερματικό",
|
||||
"tabRemoteDesktop": "Απομακρυσμένη επιφάνεια εργασίας",
|
||||
"inherit": "Κληρονομώ",
|
||||
"on": "Επί",
|
||||
"off": "Μακριά από",
|
||||
"resizeDisplayUpdate": "Ενημέρωση οθόνης",
|
||||
"resizeReconnect": "Επανασύνδεση",
|
||||
"clearAll": "Εκκαθάριση όλων",
|
||||
"saved": "Οι προεπιλογές σύνδεσης αποθηκεύτηκαν",
|
||||
"saveFailed": "Η αποθήκευση των προεπιλογών σύνδεσης απέτυχε"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detalles de la conexión",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Escritorio remoto",
|
||||
"port": "Puerto",
|
||||
"username": "Nombre de usuario",
|
||||
"folder": "Carpeta",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "General",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Métricas del host",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Compartir",
|
||||
"tabAuthentication": "Autenticación",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Deseleccionar todo",
|
||||
"protocols": "Protocolos",
|
||||
"secureShell": "Shell seguro",
|
||||
"virtualNetwork": "Red virtual",
|
||||
"unencryptedShell": "Shell sin cifrar",
|
||||
"addressIp": "Dirección / IP",
|
||||
"friendlyName": "Nombre descriptivo",
|
||||
"macAddress": "Dirección MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Paso CA",
|
||||
"filterProtocolGroup": "Protocolo",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Características",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Gestor de archivos",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Directa",
|
||||
"authTypeCredential": "Credencial",
|
||||
"authTypeNone": "Ninguno",
|
||||
"colorDepth": "Profundidad de color",
|
||||
"resizeMethod": "Método de redimensionamiento",
|
||||
"recordingPath": "Ruta de grabación",
|
||||
"recordingName": "Nombre de la grabación",
|
||||
"saveHostFirst": "Primero guarde el host.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Activar Guacamole",
|
||||
"enableGuacamoleDesc": "Escritorio remoto RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Ver documentación",
|
||||
"guacdUrl": "URL de guacd",
|
||||
"tailscaleApiKey": "Clave de API de Tailscale",
|
||||
"tailscaleApiKeyDescription": "Se utiliza para la detección de dispositivos en el editor del host. Admite claves de Tailscale (tskey-) y Headscale (hskey-). Genere una clave en tailscale.com/admin/settings/keys o desde su instancia de Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Ver documentación",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocolo",
|
||||
"domainLabel": "Dominio",
|
||||
"domainPlaceholder": "opcional",
|
||||
"connectToRdp": "Conéctese mediante RDP.",
|
||||
"connectToVnc": "Conéctese a través de VNC.",
|
||||
"connectToTerminal": "Conectar a Terminal",
|
||||
"connectToFiles": "Conectar a Archivos"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Establece valores que heredará cada host a menos que los sobrescriba.",
|
||||
"manage": "Administrar",
|
||||
"dialogDescription": "Esto se aplica a los hosts que dejan una configuración sin establecer. Cualquier configuración establecida en un host prevalecerá.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Escritorio remoto",
|
||||
"inherit": "Heredar",
|
||||
"on": "En",
|
||||
"off": "Apagado",
|
||||
"resizeDisplayUpdate": "Actualización de pantalla",
|
||||
"resizeReconnect": "Reconectar",
|
||||
"clearAll": "Borrar todo",
|
||||
"saved": "Se guardaron los valores predeterminados de conexión.",
|
||||
"saveFailed": "No se pudieron guardar los valores predeterminados de conexión."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Yhteystiedot",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Etätyöpöytä",
|
||||
"port": "Portti",
|
||||
"username": "Käyttäjätunnus",
|
||||
"folder": "Kansio",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Yleistä",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminaali",
|
||||
"tabRdp": "Maaseudun kehittämisohjelma",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Isännän mittarit",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Jakaminen",
|
||||
"tabAuthentication": "Todennus",
|
||||
"terminal": "Terminaali",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Poista kaikkien valinta",
|
||||
"protocols": "Protokollat",
|
||||
"secureShell": "Suojattu kuori",
|
||||
"virtualNetwork": "Virtuaaliverkko",
|
||||
"unencryptedShell": "Salaamaton kuori",
|
||||
"addressIp": "Osoite / IP-osoite",
|
||||
"friendlyName": "Ystävällinen nimi",
|
||||
"macAddress": "MAC-osoite",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Vaihe CA",
|
||||
"filterProtocolGroup": "Protokolla",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "Maaseudun kehittämisohjelma",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Ominaisuudet",
|
||||
"filterFeatureTerminal": "Terminaali",
|
||||
"filterFeatureFileManager": "Tiedostonhallinta",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Suoraan",
|
||||
"authTypeCredential": "Valtakirja",
|
||||
"authTypeNone": "Ei mitään",
|
||||
"colorDepth": "Värisyvyys",
|
||||
"resizeMethod": "Koon muuttamismenetelmä",
|
||||
"recordingPath": "Tallennuspolku",
|
||||
"recordingName": "Tallenteen nimi",
|
||||
"saveHostFirst": "Tallenna ensin isäntä.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Ota guacamole käyttöön",
|
||||
"enableGuacamoleDesc": "RDP/VNC-etätyöpöytä",
|
||||
"enableGuacamoleDocsLink": "Näytä dokumentit",
|
||||
"guacdUrl": "guacd-URL-osoite",
|
||||
"tailscaleApiKey": "Tailscale API-avain",
|
||||
"tailscaleApiKeyDescription": "Käytetään laitteiden etsimiseen isäntäeditorissa. Tukee Tailscale (tskey-) ja Headscale (hskey-) -avaimia. Luo avain osoitteessa tailscale.com/admin/settings/keys tai Headscale-instanssistasi.",
|
||||
"tailscaleApiKeyDocsLink": "Näytä dokumentit",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokolla",
|
||||
"domainLabel": "Verkkotunnus",
|
||||
"domainPlaceholder": "valinnainen",
|
||||
"connectToRdp": "Yhdistä RDP:n kautta",
|
||||
"connectToVnc": "Yhdistä VNC:n kautta",
|
||||
"connectToTerminal": "Yhdistä terminaaliin",
|
||||
"connectToFiles": "Yhdistä tiedostoihin"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Aseta arvot, jotka jokainen isäntä perii, ellei se korvaa niitä.",
|
||||
"manage": "Hallitse",
|
||||
"dialogDescription": "Nämä koskevat isäntiä, jotka jättävät asetuksen asettamatta. Mikä tahansa isännälle asetettu arvo voittaa.",
|
||||
"tabTerminal": "Terminaali",
|
||||
"tabRemoteDesktop": "Etätyöpöytä",
|
||||
"inherit": "Periä",
|
||||
"on": "Päällä",
|
||||
"off": "Pois",
|
||||
"resizeDisplayUpdate": "Näyttöpäivitys",
|
||||
"resizeReconnect": "Yhdistä uudelleen",
|
||||
"clearAll": "Tyhjennä kaikki",
|
||||
"saved": "Yhteysoletukset tallennettu",
|
||||
"saveFailed": "Yhteysasetusten tallentaminen epäonnistui"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Détails de la connexion",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Bureau à distance",
|
||||
"port": "Port",
|
||||
"username": "Nom d'utilisateur",
|
||||
"folder": "Dossier",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Général",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Métriques de l'hôte",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Partage",
|
||||
"tabAuthentication": "Authentification",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Tout désélectionner",
|
||||
"protocols": "Protocoles",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Réseau virtuel",
|
||||
"unencryptedShell": "Shell non chiffré",
|
||||
"addressIp": "Adresse / IP",
|
||||
"friendlyName": "Nom convivial",
|
||||
"macAddress": "Adresse MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Étape CA",
|
||||
"filterProtocolGroup": "Protocole",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Fonctionnalités",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Gestionnaire de fichiers",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direct",
|
||||
"authTypeCredential": "Identifiant",
|
||||
"authTypeNone": "Aucun",
|
||||
"colorDepth": "Profondeur de couleur",
|
||||
"resizeMethod": "Méthode de redimensionnement",
|
||||
"recordingPath": "Chemin d'enregistrement",
|
||||
"recordingName": "Nom de l'enregistrement",
|
||||
"saveHostFirst": "Enregistrez d'abord l'hôte.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Activer Guacamole",
|
||||
"enableGuacamoleDesc": "Bureau à distance RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Voir la documentation",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "Clé API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Utilisé pour la détection des périphériques dans l'éditeur d'hôtes. Compatible avec les clés Tailscale (tskey-) et Headscale (hskey-). Générez une clé sur tailscale.com/admin/settings/keys ou depuis votre instance Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Voir la documentation",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocole",
|
||||
"domainLabel": "Domaine",
|
||||
"domainPlaceholder": "facultatif",
|
||||
"connectToRdp": "Se connecter via RDP",
|
||||
"connectToVnc": "Connexion via VNC",
|
||||
"connectToTerminal": "Se connecter au terminal",
|
||||
"connectToFiles": "Se connecter aux fichiers"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Définissez des valeurs que chaque hôte hérite, sauf s'il les remplace.",
|
||||
"manage": "Gérer",
|
||||
"dialogDescription": "Ces règles s'appliquent aux hôtes qui n'ont pas défini ce paramètre. Tout paramètre défini sur l'hôte prévaut.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Bureau à distance",
|
||||
"inherit": "Hériter",
|
||||
"on": "Sur",
|
||||
"off": "Désactivé",
|
||||
"resizeDisplayUpdate": "Mise à jour de l'affichage",
|
||||
"resizeReconnect": "Reconnect",
|
||||
"clearAll": "Effacer tout",
|
||||
"saved": "Paramètres de connexion par défaut enregistrés",
|
||||
"saveFailed": "Impossible d'enregistrer les paramètres de connexion par défaut."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "פרטי חיבור",
|
||||
"ssh": "SSH",
|
||||
"telnet": "טלנט",
|
||||
"remoteDesktop": "שולחן עבודה מרוחק",
|
||||
"port": "נָמָל",
|
||||
"username": "שם משתמש",
|
||||
"folder": "תיקייה",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "כְּלָלִי",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "מָסוֹף",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "מדדי מארח",
|
||||
"tabTelnet": "טלנט",
|
||||
"tabSharing": "שיתוף",
|
||||
"tabAuthentication": "אימות",
|
||||
"terminal": "מָסוֹף",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "בטל את הבחירה של הכל",
|
||||
"protocols": "פרוטוקולים",
|
||||
"secureShell": "מעטפת מאובטחת",
|
||||
"virtualNetwork": "רשת וירטואלית",
|
||||
"unencryptedShell": "מעטפת לא מוצפנת",
|
||||
"addressIp": "כתובת / IP",
|
||||
"friendlyName": "שם ידידותי",
|
||||
"macAddress": "כתובת MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "שלב CA",
|
||||
"filterProtocolGroup": "פּרוֹטוֹקוֹל",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "טלנט",
|
||||
"filterFeaturesGroup": "תכונות",
|
||||
"filterFeatureTerminal": "מָסוֹף",
|
||||
"filterFeatureFileManager": "מנהל הקבצים",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "יָשִׁיר",
|
||||
"authTypeCredential": "תְעוּדָה",
|
||||
"authTypeNone": "אַף לֹא אֶחָד",
|
||||
"colorDepth": "עומק צבע",
|
||||
"resizeMethod": "שיטת שינוי גודל",
|
||||
"recordingPath": "נתיב ההקלטה",
|
||||
"recordingName": "שם ההקלטה",
|
||||
"saveHostFirst": "שמור את המארח קודם.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "הפעל גוואקמולי",
|
||||
"enableGuacamoleDesc": "שולחן עבודה מרוחק RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "הצג מסמכים",
|
||||
"guacdUrl": "כתובת אתר של guacd",
|
||||
"tailscaleApiKey": "מפתח ה-API של Tailscale",
|
||||
"tailscaleApiKeyDescription": "משמש לגילוי מכשירים בעורך המארח. תומך במפתחות Tailscale (tskey-) ו-Headscale (hskey-). צור מפתח בכתובת tailscale.com/admin/settings/keys או ממופע Headscale שלך.",
|
||||
"tailscaleApiKeyDocsLink": "הצג מסמכים",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "פּרוֹטוֹקוֹל",
|
||||
"domainLabel": "תְחוּם",
|
||||
"domainPlaceholder": "אופציונלי",
|
||||
"connectToRdp": "התחברות דרך RDP",
|
||||
"connectToVnc": "התחברות דרך VNC",
|
||||
"connectToTerminal": "התחברות לטרמינל",
|
||||
"connectToFiles": "התחברות לקבצים"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "הגדר ערכים שכל מארח יורש אלא אם כן הוא עוקף אותם.",
|
||||
"manage": "לְנַהֵל",
|
||||
"dialogDescription": "אלה חלים על מארחים שמשאירים הגדרה לא מוגדרת. כל דבר שמוגדר על מארח מנצח.",
|
||||
"tabTerminal": "מָסוֹף",
|
||||
"tabRemoteDesktop": "שולחן עבודה מרוחק",
|
||||
"inherit": "לָרֶשֶׁת",
|
||||
"on": "עַל",
|
||||
"off": "כבוי",
|
||||
"resizeDisplayUpdate": "עדכון תצוגה",
|
||||
"resizeReconnect": "התחבר מחדש",
|
||||
"clearAll": "נקה הכל",
|
||||
"saved": "ברירות מחדל של החיבור נשמרו",
|
||||
"saveFailed": "נכשלה שמירת ברירות המחדל של החיבור"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "कनेक्शन विवरण",
|
||||
"ssh": "SSH",
|
||||
"telnet": "टेलनेट",
|
||||
"remoteDesktop": "दूरस्थ डेस्कटॉप",
|
||||
"port": "पोर्ट",
|
||||
"username": "उपयोगकर्ता नाम",
|
||||
"folder": "फ़ोल्डर",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "सामान्य",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "टर्मिनल",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "होस्ट मेट्रिक्स",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "साझाकरण",
|
||||
"tabAuthentication": "प्रमाणीकरण",
|
||||
"terminal": "टर्मिनल",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "सभी अचयनित करें",
|
||||
"protocols": "प्रोटोकॉल",
|
||||
"secureShell": "सुरक्षित शेल",
|
||||
"virtualNetwork": "वर्चुअल नेटवर्क",
|
||||
"unencryptedShell": "अनएन्क्रिप्टेड शेल",
|
||||
"addressIp": "पता / IP",
|
||||
"friendlyName": "अनुकूल नाम",
|
||||
"macAddress": "MAC पता",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "स्टेप सीए",
|
||||
"filterProtocolGroup": "प्रोटोकॉल",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "विशेषताएं",
|
||||
"filterFeatureTerminal": "टर्मिनल",
|
||||
"filterFeatureFileManager": "फ़ाइल प्रबंधक",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "सीधा",
|
||||
"authTypeCredential": "क्रेडेंशियल",
|
||||
"authTypeNone": "कोई नहीं",
|
||||
"colorDepth": "रंग गहराई",
|
||||
"resizeMethod": "रीसाइज़ विधि",
|
||||
"recordingPath": "रिकॉर्डिंग पथ",
|
||||
"recordingName": "रिकॉर्डिंग नाम",
|
||||
"saveHostFirst": "पहले होस्ट सहेजें।",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamole सक्षम करें",
|
||||
"enableGuacamoleDesc": "RDP/VNC रिमोट डेस्कटॉप",
|
||||
"enableGuacamoleDocsLink": "दस्तावेज़ देखें",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API कुंजी",
|
||||
"tailscaleApiKeyDescription": "होस्ट एडिटर में डिवाइस की पहचान के लिए उपयोग किया जाता है। यह टेलस्केल (tskey-) और हेडस्केल (hskey-) कुंजियों का समर्थन करता है। आप tailscale.com/admin/settings/keys पर जाकर या अपने हेडस्केल इंस्टेंस से कुंजी जनरेट कर सकते हैं।",
|
||||
"tailscaleApiKeyDocsLink": "दस्तावेज़ देखें",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "शिष्टाचार",
|
||||
"domainLabel": "कार्यक्षेत्र",
|
||||
"domainPlaceholder": "वैकल्पिक",
|
||||
"connectToRdp": "आरडीपी के माध्यम से कनेक्ट करें",
|
||||
"connectToVnc": "VNC के माध्यम से कनेक्ट करें",
|
||||
"connectToTerminal": "टर्मिनल से कनेक्ट करें",
|
||||
"connectToFiles": "फ़ाइलों से कनेक्ट करें"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "ऐसे मान निर्धारित करें जिन्हें प्रत्येक होस्ट विरासत में प्राप्त करेगा, जब तक कि वह उन्हें ओवरराइड न कर दे।",
|
||||
"manage": "प्रबंधित करना",
|
||||
"dialogDescription": "ये नियम उन होस्ट पर लागू होते हैं जो कोई सेटिंग नहीं छोड़ते हैं। होस्ट पर जो भी सेटिंग सेट होती है, वही मान्य होती है।",
|
||||
"tabTerminal": "टर्मिनल",
|
||||
"tabRemoteDesktop": "दूरवर्ती डेस्कटॉप",
|
||||
"inherit": "इनहेरिट",
|
||||
"on": "पर",
|
||||
"off": "बंद",
|
||||
"resizeDisplayUpdate": "डिस्प्ले अपडेट",
|
||||
"resizeReconnect": "रिकनेक्ट",
|
||||
"clearAll": "सभी साफ करें",
|
||||
"saved": "कनेक्शन डिफ़ॉल्ट सहेजे गए",
|
||||
"saveFailed": "कनेक्शन डिफ़ॉल्ट सहेजने में विफल"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Kapcsolat részletei",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Távoli asztal",
|
||||
"port": "Kikötő",
|
||||
"username": "Felhasználónév",
|
||||
"folder": "Mappa",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Általános",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminál",
|
||||
"tabRdp": "Vidékfejlesztési Program",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Gazdagép-metrikák",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Megosztás",
|
||||
"tabAuthentication": "Hitelesítés",
|
||||
"terminal": "Terminál",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Összes kijelölés törlése",
|
||||
"protocols": "Protokollok",
|
||||
"secureShell": "Biztonságos shell",
|
||||
"virtualNetwork": "Virtuális hálózat",
|
||||
"unencryptedShell": "Titkosítatlan shell",
|
||||
"addressIp": "Cím / IP-cím",
|
||||
"friendlyName": "Barátságos név",
|
||||
"macAddress": "MAC-cím",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "CA lépés",
|
||||
"filterProtocolGroup": "Jegyzőkönyv",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "Vidékfejlesztési Program",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Jellemzők",
|
||||
"filterFeatureTerminal": "Terminál",
|
||||
"filterFeatureFileManager": "Fájlkezelő",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Közvetlen",
|
||||
"authTypeCredential": "Hitelesítő adat",
|
||||
"authTypeNone": "Egyik sem",
|
||||
"colorDepth": "Színmélység",
|
||||
"resizeMethod": "Átméretezési módszer",
|
||||
"recordingPath": "Felvételi útvonal",
|
||||
"recordingName": "Felvétel neve",
|
||||
"saveHostFirst": "Először mentsd el a gazdagépet.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamole engedélyezése",
|
||||
"enableGuacamoleDesc": "RDP/VNC távoli asztal",
|
||||
"enableGuacamoleDocsLink": "Dokumentumok megtekintése",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API-kulcs",
|
||||
"tailscaleApiKeyDescription": "Eszközfelderítésre használatos a gazdagép-szerkesztőben. Támogatja a Tailscale (tskey-) és Headscale (hskey-) kulcsokat. Kulcsot generálhat a tailscale.com/admin/settings/keys oldalon vagy a Headscale-példányából.",
|
||||
"tailscaleApiKeyDocsLink": "Dokumentumok megtekintése",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Jegyzőkönyv",
|
||||
"domainLabel": "Domain",
|
||||
"domainPlaceholder": "választható",
|
||||
"connectToRdp": "Csatlakozás RDP-n keresztül",
|
||||
"connectToVnc": "Csatlakozás VNC-n keresztül",
|
||||
"connectToTerminal": "Csatlakozás a terminálhoz",
|
||||
"connectToFiles": "Kapcsolódás fájlokhoz"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Olyan értékeket állítson be, amelyeket minden host örököl, kivéve, ha felülírja őket.",
|
||||
"manage": "Kezelés",
|
||||
"dialogDescription": "Ezek azokra a hosztokra vonatkoznak, amelyek üresen hagynak egy beállítást. Bármi, ami be van állítva egy hoszton, nyer.",
|
||||
"tabTerminal": "Terminál",
|
||||
"tabRemoteDesktop": "Távoli asztal",
|
||||
"inherit": "Örököl",
|
||||
"on": "On",
|
||||
"off": "Le",
|
||||
"resizeDisplayUpdate": "Kijelzőfrissítés",
|
||||
"resizeReconnect": "Újracsatlakozás",
|
||||
"clearAll": "Összes törlése",
|
||||
"saved": "A kapcsolat alapértelmezett beállításai mentve",
|
||||
"saveFailed": "Nem sikerült menteni a kapcsolat alapértelmezett beállításait"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detail Koneksi",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Desktop Jarak Jauh",
|
||||
"port": "Pelabuhan",
|
||||
"username": "Nama belakang",
|
||||
"folder": "Map",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Umum",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Metrik Host",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Membagikan",
|
||||
"tabAuthentication": "Autentikasi",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Batalkan Pilihan Semua",
|
||||
"protocols": "Protokol",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Jaringan Virtual",
|
||||
"unencryptedShell": "Shell yang tidak terenkripsi",
|
||||
"addressIp": "Alamat / IP",
|
||||
"friendlyName": "Nama yang Ramah",
|
||||
"macAddress": "Alamat MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Langkah CA",
|
||||
"filterProtocolGroup": "Protokol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Fitur",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Pengelola File",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Langsung",
|
||||
"authTypeCredential": "Mandat",
|
||||
"authTypeNone": "Tidak ada",
|
||||
"colorDepth": "Kedalaman Warna",
|
||||
"resizeMethod": "Metode Pengubahan Ukuran",
|
||||
"recordingPath": "Jalur Perekaman",
|
||||
"recordingName": "Nama Rekaman",
|
||||
"saveHostFirst": "Selamatkan tuan rumah terlebih dahulu.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Aktifkan Guacamole",
|
||||
"enableGuacamoleDesc": "Desktop jarak jauh RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Lihat dokumen",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "Kunci API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Digunakan untuk pendeteksian perangkat di editor host. Mendukung kunci Tailscale (tskey-) dan Headscale (hskey-). Hasilkan kunci di tailscale.com/admin/settings/keys atau dari instance Headscale Anda.",
|
||||
"tailscaleApiKeyDocsLink": "Lihat dokumen",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokol",
|
||||
"domainLabel": "Domain",
|
||||
"domainPlaceholder": "opsional",
|
||||
"connectToRdp": "Terhubung melalui RDP",
|
||||
"connectToVnc": "Terhubung melalui VNC",
|
||||
"connectToTerminal": "Hubungkan ke Terminal",
|
||||
"connectToFiles": "Menghubungkan ke File"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Tetapkan nilai-nilai yang akan diwarisi oleh setiap host kecuali jika host tersebut menimpanya.",
|
||||
"manage": "Mengelola",
|
||||
"dialogDescription": "Ketentuan ini berlaku untuk host yang tidak mengatur apa pun. Apa pun yang diatur pada host akan berlaku.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Desktop Jarak Jauh",
|
||||
"inherit": "Mewarisi",
|
||||
"on": "Pada",
|
||||
"off": "Mati",
|
||||
"resizeDisplayUpdate": "Pembaruan Tampilan",
|
||||
"resizeReconnect": "Terhubung kembali",
|
||||
"clearAll": "Hapus Semua",
|
||||
"saved": "Pengaturan koneksi default tersimpan.",
|
||||
"saveFailed": "Gagal menyimpan pengaturan default koneksi."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Dettagli connessione",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Desktop remoto",
|
||||
"port": "Porta",
|
||||
"username": "Nome utente",
|
||||
"folder": "Cartella",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Generale",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminale",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Metriche host",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Condivisione",
|
||||
"tabAuthentication": "Autenticazione",
|
||||
"terminal": "Terminale",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Deseleziona tutto",
|
||||
"protocols": "Protocolli",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Rete virtuale",
|
||||
"unencryptedShell": "Shell non crittografata",
|
||||
"addressIp": "Indirizzo / IP",
|
||||
"friendlyName": "Nome descrittivo",
|
||||
"macAddress": "Indirizzo MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Passo CA",
|
||||
"filterProtocolGroup": "Protocollo",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funzionalità",
|
||||
"filterFeatureTerminal": "Terminale",
|
||||
"filterFeatureFileManager": "Gestione file",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Diretta",
|
||||
"authTypeCredential": "Credenziale",
|
||||
"authTypeNone": "Nessuno",
|
||||
"colorDepth": "Profondità colore",
|
||||
"resizeMethod": "Metodo di ridimensionamento",
|
||||
"recordingPath": "Percorso registrazione",
|
||||
"recordingName": "Nome registrazione",
|
||||
"saveHostFirst": "Salva prima l'host",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Abilita Guacamole",
|
||||
"enableGuacamoleDesc": "Desktop remoto RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Visualizza documentazione",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "Chiave API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Utilizzata per il rilevamento dei dispositivi nell'editor host. Supporta le chiavi Tailscale (tskey-) e Headscale (hskey-). Genera una chiave su tailscale.com/admin/settings/keys o dalla tua istanza Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Visualizza documentazione",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocollo",
|
||||
"domainLabel": "Dominio",
|
||||
"domainPlaceholder": "opzionale",
|
||||
"connectToRdp": "Connettiti tramite RDP",
|
||||
"connectToVnc": "Connessione tramite VNC",
|
||||
"connectToTerminal": "Connetti al terminale",
|
||||
"connectToFiles": "Connetti ai file"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Imposta valori che ogni host eredita a meno che non li sovrascriva.",
|
||||
"manage": "Maneggio",
|
||||
"dialogDescription": "Queste impostazioni si applicano agli host che non specificano alcuna impostazione. Qualsiasi impostazione configurata su un host ha la precedenza.",
|
||||
"tabTerminal": "terminale",
|
||||
"tabRemoteDesktop": "Desktop remoto",
|
||||
"inherit": "Ereditare",
|
||||
"on": "SU",
|
||||
"off": "Spento",
|
||||
"resizeDisplayUpdate": "Aggiornamento della visualizzazione",
|
||||
"resizeReconnect": "Ricollega",
|
||||
"clearAll": "Cancella tutto",
|
||||
"saved": "Impostazioni di connessione salvate",
|
||||
"saveFailed": "Impossibile salvare le impostazioni di connessione predefinite."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "接続の詳細",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "リモートデスクトップ",
|
||||
"port": "ポート",
|
||||
"username": "ユーザー名",
|
||||
"folder": "フォルダー",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "一般",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "ターミナル",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "ホストメトリクス",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "共有",
|
||||
"tabAuthentication": "認証",
|
||||
"terminal": "ターミナル",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "すべて選択解除",
|
||||
"protocols": "プロトコル",
|
||||
"secureShell": "セキュアシェル",
|
||||
"virtualNetwork": "仮想ネットワーク",
|
||||
"unencryptedShell": "暗号化されていないシェル",
|
||||
"addressIp": "アドレス / IP",
|
||||
"friendlyName": "表示名",
|
||||
"macAddress": "MAC アドレス",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "ステップCA",
|
||||
"filterProtocolGroup": "プロトコル",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "機能",
|
||||
"filterFeatureTerminal": "ターミナル",
|
||||
"filterFeatureFileManager": "ファイルマネージャー",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "直接",
|
||||
"authTypeCredential": "認証情報",
|
||||
"authTypeNone": "なし",
|
||||
"colorDepth": "色深度",
|
||||
"resizeMethod": "リサイズ方法",
|
||||
"recordingPath": "録画パス",
|
||||
"recordingName": "録画名",
|
||||
"saveHostFirst": "最初にホストを保存してください。",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamoleを有効にする",
|
||||
"enableGuacamoleDesc": "RDP/VNCリモートデスクトップ",
|
||||
"enableGuacamoleDocsLink": "ドキュメントを見る",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale APIキー",
|
||||
"tailscaleApiKeyDescription": "ホストエディタでのデバイス検出に使用されます。Tailscale (tskey-) および Headscale (hskey-) キーをサポートしています。キーは tailscale.com/admin/settings/keys または Headscale インスタンスから生成できます。",
|
||||
"tailscaleApiKeyDocsLink": "ドキュメントを見る",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "プロトコル",
|
||||
"domainLabel": "ドメイン",
|
||||
"domainPlaceholder": "オプション",
|
||||
"connectToRdp": "RDP経由で接続する",
|
||||
"connectToVnc": "VN経由で接続",
|
||||
"connectToTerminal": "ターミナルに接続",
|
||||
"connectToFiles": "ファイルに接続"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "すべてのホストが継承する値を設定します。ただし、ホストが上書きする場合は除きます。",
|
||||
"manage": "管理",
|
||||
"dialogDescription": "これは、設定が未設定のホストに適用されます。ホストで設定されている内容が優先されます。",
|
||||
"tabTerminal": "ターミナル",
|
||||
"tabRemoteDesktop": "リモートデスクトップ",
|
||||
"inherit": "継承する",
|
||||
"on": "の上",
|
||||
"off": "オフ",
|
||||
"resizeDisplayUpdate": "ディスプレイの更新",
|
||||
"resizeReconnect": "再接続",
|
||||
"clearAll": "すべてクリア",
|
||||
"saved": "接続のデフォルト設定が保存されました",
|
||||
"saveFailed": "接続設定の保存に失敗しました"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "연결 세부 정보",
|
||||
"ssh": "SSH",
|
||||
"telnet": "텔넷",
|
||||
"remoteDesktop": "원격 데스크톱",
|
||||
"port": "포트",
|
||||
"username": "사용자 이름",
|
||||
"folder": "폴더",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "일반",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "터미널",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "호스트 메트릭",
|
||||
"tabTelnet": "텔넷",
|
||||
"tabSharing": "공유",
|
||||
"tabAuthentication": "인증",
|
||||
"terminal": "터미널",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "전체 선택 해제",
|
||||
"protocols": "프로토콜",
|
||||
"secureShell": "보안 셸",
|
||||
"virtualNetwork": "가상 네트워크",
|
||||
"unencryptedShell": "암호화되지 않은 셸",
|
||||
"addressIp": "주소 / IP",
|
||||
"friendlyName": "친숙한 이름",
|
||||
"macAddress": "MAC 주소",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "스텝 CA",
|
||||
"filterProtocolGroup": "프로토콜",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "텔넷",
|
||||
"filterFeaturesGroup": "기능",
|
||||
"filterFeatureTerminal": "터미널",
|
||||
"filterFeatureFileManager": "파일 관리자",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "직접",
|
||||
"authTypeCredential": "자격 증명",
|
||||
"authTypeNone": "없음",
|
||||
"colorDepth": "색 농도",
|
||||
"resizeMethod": "크기 조정 방법",
|
||||
"recordingPath": "녹화 경로",
|
||||
"recordingName": "녹화 이름",
|
||||
"saveHostFirst": "호스트를 먼저 저장하세요.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamole 활성화",
|
||||
"enableGuacamoleDesc": "RDP/VNC 원격 데스크톱",
|
||||
"enableGuacamoleDocsLink": "문서 보기",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API 키",
|
||||
"tailscaleApiKeyDescription": "호스트 편집기에서 장치 검색에 사용됩니다. Tailscale(tskey-) 및 Headscale(hskey-) 키를 지원합니다. 키는 tailscale.com/admin/settings/keys 또는 Headscale 인스턴스에서 생성할 수 있습니다.",
|
||||
"tailscaleApiKeyDocsLink": "문서 보기",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "규약",
|
||||
"domainLabel": "도메인",
|
||||
"domainPlaceholder": "선택 과목",
|
||||
"connectToRdp": "RDP를 통해 연결",
|
||||
"connectToVnc": "VNC를 통해 연결",
|
||||
"connectToTerminal": "터미널에 연결",
|
||||
"connectToFiles": "파일에 연결"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "호스트가 재정의하지 않는 한 모든 호스트가 상속받는 값을 설정합니다.",
|
||||
"manage": "관리하다",
|
||||
"dialogDescription": "이 설정은 호스트에서 설정을 지정하지 않은 경우에 적용됩니다. 호스트에 설정된 값이 우선 적용됩니다.",
|
||||
"tabTerminal": "단말기",
|
||||
"tabRemoteDesktop": "원격 데스크톱",
|
||||
"inherit": "상속하다",
|
||||
"on": "~에",
|
||||
"off": "끄다",
|
||||
"resizeDisplayUpdate": "디스플레이 업데이트",
|
||||
"resizeReconnect": "다시 연결",
|
||||
"clearAll": "모두 지우기",
|
||||
"saved": "연결 기본 설정이 저장되었습니다.",
|
||||
"saveFailed": "연결 기본 설정을 저장하는 데 실패했습니다."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Verbindingsgegevens",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Extern bureaublad",
|
||||
"port": "Haven",
|
||||
"username": "Gebruikersnaam",
|
||||
"folder": "Map",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Algemeen",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Hoststatistieken",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Delen",
|
||||
"tabAuthentication": "Authenticatie",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Alles deselecteren",
|
||||
"protocols": "Protocollen",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Virtueel netwerk",
|
||||
"unencryptedShell": "Niet-versleutelde shell",
|
||||
"addressIp": "Adres / IP-adres",
|
||||
"friendlyName": "Vriendelijke naam",
|
||||
"macAddress": "MAC-adres",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Stap CA",
|
||||
"filterProtocolGroup": "Protocol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Functies",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Bestandsbeheerder",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direct",
|
||||
"authTypeCredential": "Referentie",
|
||||
"authTypeNone": "Geen",
|
||||
"colorDepth": "Kleurdiepte",
|
||||
"resizeMethod": "Formaatwijzigingsmethode",
|
||||
"recordingPath": "Opnamepad",
|
||||
"recordingName": "Opnamenaam",
|
||||
"saveHostFirst": "Sla eerst de host op.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Schakel Guacamole in",
|
||||
"enableGuacamoleDesc": "RDP/VNC-extern bureaublad",
|
||||
"enableGuacamoleDocsLink": "Documenten bekijken",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API-sleutel",
|
||||
"tailscaleApiKeyDescription": "Wordt gebruikt voor apparaatdetectie in de hosteditor. Ondersteunt Tailscale (tskey-) en Headscale (hskey-) sleutels. Genereer een sleutel op tailscale.com/admin/settings/keys of vanuit uw Headscale-instantie.",
|
||||
"tailscaleApiKeyDocsLink": "Documenten bekijken",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocol",
|
||||
"domainLabel": "Domein",
|
||||
"domainPlaceholder": "optioneel",
|
||||
"connectToRdp": "Verbinden via RDP",
|
||||
"connectToVnc": "Verbinden via VNC",
|
||||
"connectToTerminal": "Verbinden met de terminal",
|
||||
"connectToFiles": "Verbinding maken met bestanden"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Stel waarden in die elke host overneemt, tenzij deze ze overschrijft.",
|
||||
"manage": "Beheren",
|
||||
"dialogDescription": "Dit geldt voor hosts die een instelling niet hebben ingesteld. Alles wat op een host is ingesteld, heeft voorrang.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Extern bureaublad",
|
||||
"inherit": "Erven",
|
||||
"on": "Op",
|
||||
"off": "Uit",
|
||||
"resizeDisplayUpdate": "Weergave bijwerken",
|
||||
"resizeReconnect": "Opnieuw verbinding maken",
|
||||
"clearAll": "Alles wissen",
|
||||
"saved": "Verbindingsstandaarden opgeslagen",
|
||||
"saveFailed": "Het opslaan van de verbindingsinstellingen is mislukt."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Tilkoblingsdetaljer",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Eksternt skrivebord",
|
||||
"port": "Havn",
|
||||
"username": "Brukernavn",
|
||||
"folder": "Mappe",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "General",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Vertsmålinger",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Deling",
|
||||
"tabAuthentication": "Autentisering",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Fjern merkingen av alle",
|
||||
"protocols": "Protokoller",
|
||||
"secureShell": "Sikkert skall",
|
||||
"virtualNetwork": "Virtuelt nettverk",
|
||||
"unencryptedShell": "Ukryptert skall",
|
||||
"addressIp": "Adresse / IP",
|
||||
"friendlyName": "Vennlig navn",
|
||||
"macAddress": "MAC-adresse",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Trinn CA",
|
||||
"filterProtocolGroup": "Protokoll",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funksjoner",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Filbehandler",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direkte",
|
||||
"authTypeCredential": "Legitimasjon",
|
||||
"authTypeNone": "Ingen",
|
||||
"colorDepth": "Fargedybde",
|
||||
"resizeMethod": "Endre størrelse-metoden",
|
||||
"recordingPath": "Opptakssti",
|
||||
"recordingName": "Opptaksnavn",
|
||||
"saveHostFirst": "Lagre verten først.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Aktiver guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC eksternt skrivebord",
|
||||
"enableGuacamoleDocsLink": "Vis dokumenter",
|
||||
"guacdUrl": "guacd-URL",
|
||||
"tailscaleApiKey": "Tailscale API-nøkkel",
|
||||
"tailscaleApiKeyDescription": "Brukes for enhetsoppdagelse i vertredigeringsprogrammet. Støtter Tailscale- (tskey-) og Headscale- (hskey-) nøkler. Generer en nøkkel på tailscale.com/admin/settings/keys eller fra Headscale-instansen din.",
|
||||
"tailscaleApiKeyDocsLink": "Vis dokumenter",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokoll",
|
||||
"domainLabel": "Domene",
|
||||
"domainPlaceholder": "valgfri",
|
||||
"connectToRdp": "Koble til via RDP",
|
||||
"connectToVnc": "Koble til via VNC",
|
||||
"connectToTerminal": "Koble til terminalen",
|
||||
"connectToFiles": "Koble til filer"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Angi verdier som hver vert arver med mindre den overstyrer dem.",
|
||||
"manage": "Administrer",
|
||||
"dialogDescription": "Disse gjelder for verter som ikke angir en innstilling. Alt som er angitt på en vert vinner.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Eksternt skrivebord",
|
||||
"inherit": "Arve",
|
||||
"on": "På",
|
||||
"off": "Av",
|
||||
"resizeDisplayUpdate": "Oppdatering av skjerm",
|
||||
"resizeReconnect": "Koble til igjen",
|
||||
"clearAll": "Fjern alt",
|
||||
"saved": "Standardinnstillinger for tilkobling lagret",
|
||||
"saveFailed": "Kunne ikke lagre standardinnstillinger for tilkobling"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Szczegóły połączenia",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Pulpit zdalny",
|
||||
"port": "Port",
|
||||
"username": "Nazwa użytkownika",
|
||||
"folder": "Folder",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Ogólne",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Metryki hosta",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Udostępnianie",
|
||||
"tabAuthentication": "Uwierzytelnianie",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Odznacz wszystko",
|
||||
"protocols": "Protokoły",
|
||||
"secureShell": "Bezpieczna powłoka",
|
||||
"virtualNetwork": "Sieć wirtualna",
|
||||
"unencryptedShell": "Niezaszyfrowana powłoka",
|
||||
"addressIp": "Adres / IP",
|
||||
"friendlyName": "Przyjazna nazwa",
|
||||
"macAddress": "Adres MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Krok CA",
|
||||
"filterProtocolGroup": "Protokół",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funkcje",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Menedżer plików",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Bezpośredni",
|
||||
"authTypeCredential": "Poświadczenie",
|
||||
"authTypeNone": "Brak",
|
||||
"colorDepth": "Głębia koloru",
|
||||
"resizeMethod": "Metoda zmiany rozmiaru",
|
||||
"recordingPath": "Ścieżka nagrywania",
|
||||
"recordingName": "Nazwa nagrania",
|
||||
"saveHostFirst": "Najpierw zapisz hosta.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Włącz Guacamole",
|
||||
"enableGuacamoleDesc": "Zdalny pulpit RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Zobacz dokumentację",
|
||||
"guacdUrl": "Adres URL guacd",
|
||||
"tailscaleApiKey": "Klucz API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Służy do wykrywania urządzeń w edytorze hostów. Obsługuje klucze Tailscale (tskey-) i Headscale (hskey-). Wygeneruj klucz na tailscale.com/admin/settings/keys lub w swojej instancji Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Zobacz dokumentację",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokół",
|
||||
"domainLabel": "Domena",
|
||||
"domainPlaceholder": "fakultatywny",
|
||||
"connectToRdp": "Połącz przez RDP",
|
||||
"connectToVnc": "Połącz przez VNC",
|
||||
"connectToTerminal": "Połącz z terminalem",
|
||||
"connectToFiles": "Połącz z plikami"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Ustaw wartości, które dziedziczy każdy host, chyba że je nadpisze.",
|
||||
"manage": "Zarządzaj",
|
||||
"dialogDescription": "Dotyczą hostów, które nie mają ustawionej danej opcji. Ustawienie na hoście ma pierwszeństwo.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Pulpit zdalny",
|
||||
"inherit": "Dziedzicz",
|
||||
"on": "Wł.",
|
||||
"off": "Wył.",
|
||||
"resizeDisplayUpdate": "Aktualizacja ekranu",
|
||||
"resizeReconnect": "Połącz ponownie",
|
||||
"clearAll": "Wyczyść wszystko",
|
||||
"saved": "Zapisano domyślne ustawienia połączenia",
|
||||
"saveFailed": "Nie udało się zapisać domyślnych ustawień połączenia"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detalhes da conexão",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Área de Trabalho Remota",
|
||||
"port": "Porta",
|
||||
"username": "Nome de usuário",
|
||||
"folder": "Pasta",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Em geral",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Métricas do host",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Compartilhamento",
|
||||
"tabAuthentication": "Autenticação",
|
||||
"terminal": "terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Desmarcar tudo",
|
||||
"protocols": "Protocolos",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Rede Virtual",
|
||||
"unencryptedShell": "Shell não criptografado",
|
||||
"addressIp": "Endereço IP /",
|
||||
"friendlyName": "Nome amigável",
|
||||
"macAddress": "Endereço MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Etapa CA",
|
||||
"filterProtocolGroup": "Protocolo",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Características",
|
||||
"filterFeatureTerminal": "terminal",
|
||||
"filterFeatureFileManager": "Gerenciador de arquivos",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direto",
|
||||
"authTypeCredential": "Credencial",
|
||||
"authTypeNone": "Nenhum",
|
||||
"colorDepth": "Profundidade de cor",
|
||||
"resizeMethod": "Método de redimensionamento",
|
||||
"recordingPath": "Caminho de gravação",
|
||||
"recordingName": "Nome da gravação",
|
||||
"saveHostFirst": "Primeiro, salve o host.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Ativar Guacamole",
|
||||
"enableGuacamoleDesc": "Área de trabalho remota RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Ver documentos",
|
||||
"guacdUrl": "URL do guacd",
|
||||
"tailscaleApiKey": "Chave da API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Utilizado para descoberta de dispositivos no editor de hosts. Compatível com chaves Tailscale (tskey-) e Headscale (hskey-). Gere uma chave em tailscale.com/admin/settings/keys ou a partir da sua instância Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Ver documentos",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocolo",
|
||||
"domainLabel": "Domínio",
|
||||
"domainPlaceholder": "opcional",
|
||||
"connectToRdp": "Conectar via RDP",
|
||||
"connectToVnc": "Conecte-se via VNC",
|
||||
"connectToTerminal": "Conectar ao terminal",
|
||||
"connectToFiles": "Conectar aos arquivos"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Defina valores que todos os hosts herdarão, a menos que os substituam.",
|
||||
"manage": "Gerenciar",
|
||||
"dialogDescription": "Essas configurações se aplicam a hosts que deixam alguma configuração indefinida. Qualquer configuração definida no host prevalece.",
|
||||
"tabTerminal": "terminal",
|
||||
"tabRemoteDesktop": "Área de Trabalho Remota",
|
||||
"inherit": "Herdar",
|
||||
"on": "Sobre",
|
||||
"off": "Desligado",
|
||||
"resizeDisplayUpdate": "Atualização de exibição",
|
||||
"resizeReconnect": "Reconectar",
|
||||
"clearAll": "Limpar tudo",
|
||||
"saved": "Configurações de conexão salvas",
|
||||
"saveFailed": "Falha ao salvar as configurações padrão de conexão."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detalhes da ligação",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Ambiente de trabalho remoto",
|
||||
"port": "Porta",
|
||||
"username": "Nome de utilizador",
|
||||
"folder": "Pasta",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Geral",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Métricas do Host",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Partilha",
|
||||
"tabAuthentication": "Autenticação",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Desmarcar Todos",
|
||||
"protocols": "Protocolos",
|
||||
"secureShell": "Shell Seguro",
|
||||
"virtualNetwork": "Rede Virtual",
|
||||
"unencryptedShell": "Shell não encriptado",
|
||||
"addressIp": "Endereço / IP",
|
||||
"friendlyName": "Nome Amigável",
|
||||
"macAddress": "Endereço MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Etapa CA",
|
||||
"filterProtocolGroup": "Protocolo",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Funcionalidades",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Gestor de Ficheiros",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direta",
|
||||
"authTypeCredential": "Credencial",
|
||||
"authTypeNone": "Nenhum",
|
||||
"colorDepth": "Profundidade de cor",
|
||||
"resizeMethod": "Método de redimensionamento",
|
||||
"recordingPath": "Caminho da gravação",
|
||||
"recordingName": "Nome da gravação",
|
||||
"saveHostFirst": "Guarde o host primeiro.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Ativar Guacamole",
|
||||
"enableGuacamoleDesc": "Ambiente de trabalho remoto RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Ver documentação",
|
||||
"guacdUrl": "URL do guacd",
|
||||
"tailscaleApiKey": "Chave de API do Tailscale",
|
||||
"tailscaleApiKeyDescription": "Utilizado para a descoberta de dispositivos no editor de hosts. Compatível com as chaves Tailscale (tskey-) e Headscale (hskey-). Gere uma chave em tailscale.com/admin/settings/keys ou a partir da sua instância Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Ver documentação",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocolo",
|
||||
"domainLabel": "Domínio",
|
||||
"domainPlaceholder": "opcional",
|
||||
"connectToRdp": "Ligar via RDP",
|
||||
"connectToVnc": "Ligue-se via VNC",
|
||||
"connectToTerminal": "Ligar ao Terminal",
|
||||
"connectToFiles": "Ligar aos Ficheiros"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Defina valores que todos os hosts herdarão, a menos que os substituam.",
|
||||
"manage": "Gerir",
|
||||
"dialogDescription": "Estas definições aplicam-se a hosts que deixam alguma configuração indefinida. Qualquer configuração definida no host prevalece.",
|
||||
"tabTerminal": "terminal",
|
||||
"tabRemoteDesktop": "Área de Trabalho Remota",
|
||||
"inherit": "Herdar",
|
||||
"on": "Em",
|
||||
"off": "Desligado",
|
||||
"resizeDisplayUpdate": "Atualização de visualização",
|
||||
"resizeReconnect": "Reconectar",
|
||||
"clearAll": "Limpar tudo",
|
||||
"saved": "Configurações de ligação guardadas",
|
||||
"saveFailed": "Falha ao guardar as definições padrão de ligação."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Detalii conexiune",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Desktop la distanță",
|
||||
"port": "Port",
|
||||
"username": "Nume de utilizator",
|
||||
"folder": "Pliant",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "General",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Metrici ale gazdei",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Partajare",
|
||||
"tabAuthentication": "Autentificare",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Deselectați tot",
|
||||
"protocols": "Protocoale",
|
||||
"secureShell": "Shell securizat",
|
||||
"virtualNetwork": "Rețea virtuală",
|
||||
"unencryptedShell": "Shell necriptat",
|
||||
"addressIp": "Adresă / IP",
|
||||
"friendlyName": "Nume prietenos",
|
||||
"macAddress": "Adresă MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Pasul CA",
|
||||
"filterProtocolGroup": "Protocol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Caracteristici",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Manager de fișiere",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direct",
|
||||
"authTypeCredential": "Acreditare",
|
||||
"authTypeNone": "Nici unul",
|
||||
"colorDepth": "Adâncimea culorii",
|
||||
"resizeMethod": "Metodă de redimensionare",
|
||||
"recordingPath": "Calea de înregistrare",
|
||||
"recordingName": "Nume înregistrare",
|
||||
"saveHostFirst": "Salvează mai întâi gazda.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Activează Guacamole",
|
||||
"enableGuacamoleDesc": "Desktop la distanță RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Vizualizați documentele",
|
||||
"guacdUrl": "URL-ul guacd",
|
||||
"tailscaleApiKey": "Cheie API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Folosit pentru descoperirea dispozitivelor în editorul gazdă. Acceptă cheile Tailscale (tskey-) și Headscale (hskey-). Generați o cheie la tailscale.com/admin/settings/keys sau din instanța Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Vizualizați documentele",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protocol",
|
||||
"domainLabel": "Domeniu",
|
||||
"domainPlaceholder": "opțional",
|
||||
"connectToRdp": "Conectați-vă prin RDP",
|
||||
"connectToVnc": "Conectați-vă prin VNC",
|
||||
"connectToTerminal": "Conectați-vă la terminal",
|
||||
"connectToFiles": "Conectare la fișiere"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Setați valorile pe care fiecare gazdă le moștenește, cu excepția cazului în care le suprascrie.",
|
||||
"manage": "Gestionează",
|
||||
"dialogDescription": "Acestea se aplică gazdelor care lasă o setare neconfigurată. Orice setare este setată pe o gazdă este câștigătoare.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Desktop la distanță",
|
||||
"inherit": "Moşteni",
|
||||
"on": "Pe",
|
||||
"off": "Dezactivat",
|
||||
"resizeDisplayUpdate": "Actualizare afișare",
|
||||
"resizeReconnect": "Reconectați-vă",
|
||||
"clearAll": "Ștergeți tot",
|
||||
"saved": "Setările implicite ale conexiunii au fost salvate",
|
||||
"saveFailed": "Nu s-au putut salva setările implicite ale conexiunii"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Детали подключения",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Удаленный рабочий стол",
|
||||
"port": "Порт",
|
||||
"username": "Имя пользователя",
|
||||
"folder": "Папка",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Общие",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Метрики хоста",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Общий доступ",
|
||||
"tabAuthentication": "Аутентификация",
|
||||
"terminal": "Терминал",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Снять выделение со всех",
|
||||
"protocols": "Протоколы",
|
||||
"secureShell": "SSH",
|
||||
"virtualNetwork": "Виртуальная сеть",
|
||||
"unencryptedShell": "Незашифрованная оболочка",
|
||||
"addressIp": "Адрес / IP",
|
||||
"friendlyName": "Понятное имя",
|
||||
"macAddress": "MAC-адрес",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Шаг CA",
|
||||
"filterProtocolGroup": "Протокол",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Функции",
|
||||
"filterFeatureTerminal": "Терминал",
|
||||
"filterFeatureFileManager": "Файловый менеджер",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Прямой",
|
||||
"authTypeCredential": "Учетные данные",
|
||||
"authTypeNone": "Никто",
|
||||
"colorDepth": "Глубина цвета",
|
||||
"resizeMethod": "Метод изменения размера",
|
||||
"recordingPath": "Путь записи",
|
||||
"recordingName": "Имя записи",
|
||||
"saveHostFirst": "Сначала сохраните хост.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Включить Guacamole",
|
||||
"enableGuacamoleDesc": "Удаленный рабочий стол RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Документация",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "API-ключ Tailscale",
|
||||
"tailscaleApiKeyDescription": "Используется для обнаружения устройств в редакторе хоста. Поддерживает ключи Tailscale (tskey-) и Headscale (hskey-). Сгенерируйте ключ на сайте tailscale.com/admin/settings/keys или в вашем экземпляре Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Документация",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Протокол",
|
||||
"domainLabel": "Домен",
|
||||
"domainPlaceholder": "необязательный",
|
||||
"connectToRdp": "Подключение через RDP",
|
||||
"connectToVnc": "Подключение через VNC",
|
||||
"connectToTerminal": "Подключиться к терминалу",
|
||||
"connectToFiles": "Подключиться к файлам"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Установите значения, которые будут наследоваться каждым хостом, если он их не переопределит.",
|
||||
"manage": "Управлять",
|
||||
"dialogDescription": "Эти правила применяются к хостам, которые не задают какой-либо параметр. Любой параметр, заданный на хосте, имеет приоритет.",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRemoteDesktop": "Удаленный рабочий стол",
|
||||
"inherit": "Наследовать",
|
||||
"on": "На",
|
||||
"off": "Выключенный",
|
||||
"resizeDisplayUpdate": "Обновление дисплея",
|
||||
"resizeReconnect": "Переподключитесь",
|
||||
"clearAll": "Очистить все",
|
||||
"saved": "Сохранены параметры подключения по умолчанию.",
|
||||
"saveFailed": "Не удалось сохранить параметры подключения по умолчанию."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Детаљи везе",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Телнет",
|
||||
"remoteDesktop": "Удаљена радна површина",
|
||||
"port": "Лука",
|
||||
"username": "Корисничко име",
|
||||
"folder": "Фасцикла",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Опште",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRdp": "РДП",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Метрике хоста",
|
||||
"tabTelnet": "Телнет",
|
||||
"tabSharing": "Дељење",
|
||||
"tabAuthentication": "Аутентификација",
|
||||
"terminal": "Терминал",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Поништи избор свих",
|
||||
"protocols": "Протоколи",
|
||||
"secureShell": "Безбедна шкољка",
|
||||
"virtualNetwork": "Виртуелна мрежа",
|
||||
"unencryptedShell": "Нешифрована љуска",
|
||||
"addressIp": "Адреса / ИП",
|
||||
"friendlyName": "Пријатељско име",
|
||||
"macAddress": "MAC адреса",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Корак CA",
|
||||
"filterProtocolGroup": "Протокол",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "РДП",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Телнет",
|
||||
"filterFeaturesGroup": "Карактеристике",
|
||||
"filterFeatureTerminal": "Терминал",
|
||||
"filterFeatureFileManager": "Менаџер датотека",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Директно",
|
||||
"authTypeCredential": "Акредитив",
|
||||
"authTypeNone": "Ниједан",
|
||||
"colorDepth": "Дубина боје",
|
||||
"resizeMethod": "Метод промене величине",
|
||||
"recordingPath": "Путања снимања",
|
||||
"recordingName": "Назив снимка",
|
||||
"saveHostFirst": "Прво сачувајте домаћина.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Омогући гуакамоле",
|
||||
"enableGuacamoleDesc": "RDP/VNC удаљена радна површина",
|
||||
"enableGuacamoleDocsLink": "Прикажи документе",
|
||||
"guacdUrl": "URL адреса guacd-а",
|
||||
"tailscaleApiKey": "API кључ Tailscale-а",
|
||||
"tailscaleApiKeyDescription": "Користи се за откривање уређаја у уређивачу хоста. Подржава кључеве Tailscale (tkey-) и Headscale (hskey-). Генеришите кључ на tailscale.com/admin/settings/keys или из ваше Headscale инстанце.",
|
||||
"tailscaleApiKeyDocsLink": "Прикажи документе",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Протокол",
|
||||
"domainLabel": "Домен",
|
||||
"domainPlaceholder": "опционо",
|
||||
"connectToRdp": "Повежите се путем RDP-а",
|
||||
"connectToVnc": "Повежите се преко VNC-а",
|
||||
"connectToTerminal": "Повежи се са терминалом",
|
||||
"connectToFiles": "Повежи се са датотекама"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Поставите вредности које сваки хост наслеђује, осим ако их не препише.",
|
||||
"manage": "Управљај",
|
||||
"dialogDescription": "Ово се односи на хостове који не подешавају подешавање. Све што је подешено на хосту побеђује.",
|
||||
"tabTerminal": "Терминал",
|
||||
"tabRemoteDesktop": "Удаљена радна површина",
|
||||
"inherit": "Наследи",
|
||||
"on": "Укључено",
|
||||
"off": "Искључено",
|
||||
"resizeDisplayUpdate": "Ажурирање екрана",
|
||||
"resizeReconnect": "Поново се повежите",
|
||||
"clearAll": "Обриши све",
|
||||
"saved": "Подразумевана подешавања везе су сачувана",
|
||||
"saveFailed": "Чување подразумеваних подешавања везе није успело"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Anslutningsdetaljer",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Fjärrskrivbord",
|
||||
"port": "Hamn",
|
||||
"username": "Användarnamn",
|
||||
"folder": "Mapp",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Allmän",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "Landsbygdsutveckling",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Värdstatistik",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Delning",
|
||||
"tabAuthentication": "Autentisering",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Avmarkera alla",
|
||||
"protocols": "Protokoll",
|
||||
"secureShell": "Säkert skal",
|
||||
"virtualNetwork": "Virtuellt nätverk",
|
||||
"unencryptedShell": "Okrypterat skal",
|
||||
"addressIp": "Adress / IP-adress",
|
||||
"friendlyName": "Vänligt namn",
|
||||
"macAddress": "MAC-adress",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Steg CA",
|
||||
"filterProtocolGroup": "Protokoll",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "Landsbygdsutveckling",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Drag",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Filhanteraren",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Direkt",
|
||||
"authTypeCredential": "Referenser",
|
||||
"authTypeNone": "Ingen",
|
||||
"colorDepth": "Färgdjup",
|
||||
"resizeMethod": "Ändra storleksmetod",
|
||||
"recordingPath": "Inspelningsväg",
|
||||
"recordingName": "Inspelningsnamn",
|
||||
"saveHostFirst": "Spara värden först.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Aktivera guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC-fjärrskrivbord",
|
||||
"enableGuacamoleDocsLink": "Visa dokument",
|
||||
"guacdUrl": "guacd-URL",
|
||||
"tailscaleApiKey": "Tailscale API-nyckel",
|
||||
"tailscaleApiKeyDescription": "Används för enhetsidentifiering i värdredigeraren. Stöder Tailscale- (tskey-) och Headscale- (hskey-) nycklar. Generera en nyckel på tailscale.com/admin/settings/keys eller från din Headscale-instans.",
|
||||
"tailscaleApiKeyDocsLink": "Visa dokument",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokoll",
|
||||
"domainLabel": "Domän",
|
||||
"domainPlaceholder": "frivillig",
|
||||
"connectToRdp": "Anslut via RDP",
|
||||
"connectToVnc": "Anslut via VNC",
|
||||
"connectToTerminal": "Anslut till terminalen",
|
||||
"connectToFiles": "Anslut till filer"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Ange värden som varje värd ärver om den inte åsidosätter dem.",
|
||||
"manage": "Hantera",
|
||||
"dialogDescription": "Dessa gäller för värdar som lämnar en inställning oaktiverad. Allt som ställs in på en värd vinner.",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRemoteDesktop": "Fjärrskrivbord",
|
||||
"inherit": "Ärva",
|
||||
"on": "På",
|
||||
"off": "Av",
|
||||
"resizeDisplayUpdate": "Uppdatering av displayen",
|
||||
"resizeReconnect": "Återanslut",
|
||||
"clearAll": "Rensa alla",
|
||||
"saved": "Standardinställningar för anslutning sparade",
|
||||
"saveFailed": "Kunde inte spara standardinställningarna för anslutningen"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "รายละเอียดการเชื่อมต่อ",
|
||||
"ssh": "เอสเอช",
|
||||
"telnet": "เทลเน็ต",
|
||||
"remoteDesktop": "รีโมทเดสก์ท็อป",
|
||||
"port": "ท่าเรือ",
|
||||
"username": "ชื่อผู้ใช้",
|
||||
"folder": "โฟลเดอร์",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "ทั่วไป",
|
||||
"tabSsh": "เอสเอช",
|
||||
"tabTerminal": "เทอร์มินัล",
|
||||
"tabRdp": "อาร์ดีพี",
|
||||
"tabVnc": "วีเอ็นซี",
|
||||
"tabStats": "เมตริกโฮสต์",
|
||||
"tabTelnet": "เทลเน็ต",
|
||||
"tabSharing": "การแบ่งปัน",
|
||||
"tabAuthentication": "การตรวจสอบสิทธิ์",
|
||||
"terminal": "เทอร์มินัล",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "ยกเลิกการเลือกทั้งหมด",
|
||||
"protocols": "โปรโตคอล",
|
||||
"secureShell": "เปลือกหุ้มที่ปลอดภัย",
|
||||
"virtualNetwork": "เครือข่ายเสมือน",
|
||||
"unencryptedShell": "เชลล์ที่ไม่ได้เข้ารหัส",
|
||||
"addressIp": "ที่อยู่ / IP",
|
||||
"friendlyName": "ชื่อที่เป็นมิตร",
|
||||
"macAddress": "ที่อยู่ MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "ขั้นตอน CA",
|
||||
"filterProtocolGroup": "โปรโตคอล",
|
||||
"filterProtocolSsh": "เอสเอช",
|
||||
"filterProtocolRdp": "อาร์ดีพี",
|
||||
"filterProtocolVnc": "วีเอ็นซี",
|
||||
"filterProtocolTelnet": "เทลเน็ต",
|
||||
"filterFeaturesGroup": "คุณสมบัติ",
|
||||
"filterFeatureTerminal": "เทอร์มินัล",
|
||||
"filterFeatureFileManager": "ตัวจัดการไฟล์",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "โดยตรง",
|
||||
"authTypeCredential": "ใบรับรอง",
|
||||
"authTypeNone": "ไม่มี",
|
||||
"colorDepth": "ความลึกของสี",
|
||||
"resizeMethod": "วิธีการปรับขนาด",
|
||||
"recordingPath": "เส้นทางการบันทึก",
|
||||
"recordingName": "ชื่อการบันทึก",
|
||||
"saveHostFirst": "บันทึกข้อมูลโฮสต์ก่อน",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "เปิดใช้งาน Guacamole",
|
||||
"enableGuacamoleDesc": "การเข้าถึงเดสก์ท็อประยะไกลผ่าน RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "ดูเอกสาร",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "คีย์ API ของ Tailscale",
|
||||
"tailscaleApiKeyDescription": "ใช้สำหรับการค้นหาอุปกรณ์ในตัวแก้ไขโฮสต์ รองรับคีย์ Tailscale (tskey-) และ Headscale (hskey-) สร้างคีย์ได้ที่ tailscale.com/admin/settings/keys หรือจากอินสแตนซ์ Headscale ของคุณ",
|
||||
"tailscaleApiKeyDocsLink": "ดูเอกสาร",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "โปรโตคอล",
|
||||
"domainLabel": "โดเมน",
|
||||
"domainPlaceholder": "ไม่จำเป็น",
|
||||
"connectToRdp": "เชื่อมต่อผ่าน RDP",
|
||||
"connectToVnc": "เชื่อมต่อผ่าน VNC",
|
||||
"connectToTerminal": "เชื่อมต่อกับเทอร์มินัล",
|
||||
"connectToFiles": "เชื่อมต่อกับไฟล์"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "กำหนดค่าต่างๆ ที่โฮสต์ทุกตัวจะได้รับสืบทอด เว้นแต่ว่าโฮสต์นั้นจะกำหนดค่าใหม่เอง",
|
||||
"manage": "จัดการ",
|
||||
"dialogDescription": "ข้อกำหนดเหล่านี้ใช้กับโฮสต์ที่ไม่ได้ตั้งค่าใดๆ ไว้ การตั้งค่าใดๆ บนโฮสต์จะมีผลเหนือกว่า",
|
||||
"tabTerminal": "เทอร์มินัล",
|
||||
"tabRemoteDesktop": "รีโมทเดสก์ท็อป",
|
||||
"inherit": "สืบทอด",
|
||||
"on": "บน",
|
||||
"off": "ปิด",
|
||||
"resizeDisplayUpdate": "อัปเดตการแสดงผล",
|
||||
"resizeReconnect": "เชื่อมต่อใหม่",
|
||||
"clearAll": "ล้างทั้งหมด",
|
||||
"saved": "บันทึกการตั้งค่าการเชื่อมต่อเริ่มต้นแล้ว",
|
||||
"saveFailed": "ไม่สามารถบันทึกการตั้งค่าการเชื่อมต่อเริ่มต้นได้"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Bağlantı Ayrıntıları",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Uzak Masaüstü",
|
||||
"port": "Bağlantı Noktası",
|
||||
"username": "Kullanıcı Adı",
|
||||
"folder": "Klasör",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Genel",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Sunucu Metrikleri",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Paylaşım",
|
||||
"tabAuthentication": "Kimlik Doğrulama",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Tüm Seçimi Kaldır",
|
||||
"protocols": "Protokoller",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Sanal Ağ",
|
||||
"unencryptedShell": "Şifrelenmemiş Shell",
|
||||
"addressIp": "Adres / IP",
|
||||
"friendlyName": "Kolay Ad",
|
||||
"macAddress": "MAC Adresi",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Adım CA",
|
||||
"filterProtocolGroup": "Protokol",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Özellikler",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Dosya Yöneticisi",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Doğrudan",
|
||||
"authTypeCredential": "Kimlik bilgisi",
|
||||
"authTypeNone": "Hiçbiri",
|
||||
"colorDepth": "Renk Derinliği",
|
||||
"resizeMethod": "Yeniden Boyutlandırma Yöntemi",
|
||||
"recordingPath": "Kayıt Yolu",
|
||||
"recordingName": "Kayıt Adı",
|
||||
"saveHostFirst": "Önce ana makineyi kaydedin.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Guacamole'yi Etkinleştir",
|
||||
"enableGuacamoleDesc": "RDP/VNC uzak masaüstü",
|
||||
"enableGuacamoleDocsLink": "Belgeleri görüntüle",
|
||||
"guacdUrl": "guacd URL'si",
|
||||
"tailscaleApiKey": "Tailscale API Anahtarı",
|
||||
"tailscaleApiKeyDescription": "Ana bilgisayar düzenleyicisinde cihaz keşfi için kullanılır. Tailscale (tskey-) ve Headscale (hskey-) anahtarlarını destekler. Anahtarınızı tailscale.com/admin/settings/keys adresinden veya Headscale örneğinizden oluşturabilirsiniz.",
|
||||
"tailscaleApiKeyDocsLink": "Belgeleri görüntüle",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Protokol",
|
||||
"domainLabel": "İhtisas",
|
||||
"domainPlaceholder": "isteğe bağlı",
|
||||
"connectToRdp": "RDP üzerinden bağlanın",
|
||||
"connectToVnc": "VNC üzerinden bağlantı kurun",
|
||||
"connectToTerminal": "Terminale Bağlan",
|
||||
"connectToFiles": "Dosyalara Bağlan"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Sunucunun kendisi tarafından geçersiz kılınmadığı sürece her sunucunun devralacağı değerler belirleyin.",
|
||||
"manage": "Üstesinden gelmek",
|
||||
"dialogDescription": "Bu kurallar, ayarlarını değiştirmeyen sunucular için geçerlidir. Sunucuda yapılan herhangi bir ayar geçerlidir.",
|
||||
"tabTerminal": "terminal",
|
||||
"tabRemoteDesktop": "Uzaktan Masaüstü",
|
||||
"inherit": "Miras almak",
|
||||
"on": "Açık",
|
||||
"off": "Kapalı",
|
||||
"resizeDisplayUpdate": "Ekran Güncellemesi",
|
||||
"resizeReconnect": "Yeniden bağlan",
|
||||
"clearAll": "Tümünü Temizle",
|
||||
"saved": "Bağlantı varsayılan ayarları kaydedildi.",
|
||||
"saveFailed": "Bağlantı varsayılan ayarları kaydedilemedi."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Деталі підключення",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Телнет",
|
||||
"remoteDesktop": "Віддалений робочий стіл",
|
||||
"port": "Порт",
|
||||
"username": "Ім'я користувача",
|
||||
"folder": "Папка",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Загальне",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Термінал",
|
||||
"tabRdp": "ПРП",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Метрики хоста",
|
||||
"tabTelnet": "Телнет",
|
||||
"tabSharing": "Спільне використання",
|
||||
"tabAuthentication": "Автентифікація",
|
||||
"terminal": "Термінал",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Зняти вибір усіх",
|
||||
"protocols": "Протоколи",
|
||||
"secureShell": "Безпечна оболонка",
|
||||
"virtualNetwork": "Віртуальна мережа",
|
||||
"unencryptedShell": "Незашифрована оболонка",
|
||||
"addressIp": "Адреса / IP-адреса",
|
||||
"friendlyName": "Зрозуміле ім'я",
|
||||
"macAddress": "MAC-адреса",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Крок CA",
|
||||
"filterProtocolGroup": "Протокол",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "ПРП",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Телнет",
|
||||
"filterFeaturesGroup": "Особливості",
|
||||
"filterFeatureTerminal": "Термінал",
|
||||
"filterFeatureFileManager": "Файловий менеджер",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Прямий",
|
||||
"authTypeCredential": "Посвідчення",
|
||||
"authTypeNone": "Жоден",
|
||||
"colorDepth": "Глибина кольору",
|
||||
"resizeMethod": "Метод зміни розміру",
|
||||
"recordingPath": "Шлях запису",
|
||||
"recordingName": "Назва запису",
|
||||
"saveHostFirst": "Спочатку збережіть хост.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Увімкнути гуакамоле",
|
||||
"enableGuacamoleDesc": "Віддалений робочий стіл RDP/VNC",
|
||||
"enableGuacamoleDocsLink": "Переглянути документи",
|
||||
"guacdUrl": "URL-адреса GUACD",
|
||||
"tailscaleApiKey": "Ключ API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Використовується для виявлення пристроїв у редакторі хоста. Підтримує ключі Tailscale (tkey-) та Headscale (hskey-). Згенеруйте ключ на tailscale.com/admin/settings/keys або з вашого екземпляра Headscale.",
|
||||
"tailscaleApiKeyDocsLink": "Переглянути документи",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Протокол",
|
||||
"domainLabel": "Домен",
|
||||
"domainPlaceholder": "необов'язково",
|
||||
"connectToRdp": "Підключення через RDP",
|
||||
"connectToVnc": "Підключення через VNC",
|
||||
"connectToTerminal": "Підключення до терміналу",
|
||||
"connectToFiles": "Підключення до файлів"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Встановіть значення, які успадковує кожен хост, якщо він їх не перевизначить.",
|
||||
"manage": "Керувати",
|
||||
"dialogDescription": "Це стосується хостів, які залишають налаштування невизначеними. Будь-яке налаштування, встановлене на хості, виграє.",
|
||||
"tabTerminal": "Термінал",
|
||||
"tabRemoteDesktop": "Віддалений робочий стіл",
|
||||
"inherit": "Успадкувати",
|
||||
"on": "Увімкнено",
|
||||
"off": "Вимкнено",
|
||||
"resizeDisplayUpdate": "Оновлення дисплея",
|
||||
"resizeReconnect": "Знову підключитися",
|
||||
"clearAll": "Очистити все",
|
||||
"saved": "Налаштування з'єднання за замовчуванням збережено",
|
||||
"saveFailed": "Не вдалося зберегти налаштування з’єднання за замовчуванням"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "Chi tiết kết nối",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "Máy tính từ xa",
|
||||
"port": "Cổng",
|
||||
"username": "Tên đăng nhập",
|
||||
"folder": "Thư mục",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "Chung",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "Terminal",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "Số liệu máy chủ",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "Chia sẻ",
|
||||
"tabAuthentication": "Xác thực",
|
||||
"terminal": "Terminal",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "Bỏ chọn tất cả",
|
||||
"protocols": "Giao thức",
|
||||
"secureShell": "Secure Shell",
|
||||
"virtualNetwork": "Mạng ảo",
|
||||
"unencryptedShell": "Shell không mã hóa",
|
||||
"addressIp": "Địa chỉ / IP",
|
||||
"friendlyName": "Tên hiển thị",
|
||||
"macAddress": "Địa chỉ MAC",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "Bước CA",
|
||||
"filterProtocolGroup": "Giao thức",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "Tính năng",
|
||||
"filterFeatureTerminal": "Terminal",
|
||||
"filterFeatureFileManager": "Trình quản lý file",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "Trực tiếp",
|
||||
"authTypeCredential": "Thông tin xác thực",
|
||||
"authTypeNone": "Không có",
|
||||
"colorDepth": "Độ sâu màu",
|
||||
"resizeMethod": "Phương thức thay đổi kích thước",
|
||||
"recordingPath": "Đường dẫn ghi",
|
||||
"recordingName": "Tên bản ghi",
|
||||
"saveHostFirst": "Lưu máy chủ trước.",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "Bật Guacamole",
|
||||
"enableGuacamoleDesc": "Kết nối RDP/VNC từ xa",
|
||||
"enableGuacamoleDocsLink": "Xem tài liệu",
|
||||
"guacdUrl": "URL guacd",
|
||||
"tailscaleApiKey": "Khóa API Tailscale",
|
||||
"tailscaleApiKeyDescription": "Được sử dụng để phát hiện thiết bị trong trình chỉnh sửa máy chủ. Hỗ trợ khóa Tailscale (tskey-) và Headscale (hskey-). Tạo khóa tại tailscale.com/admin/settings/keys hoặc từ phiên bản Headscale của bạn.",
|
||||
"tailscaleApiKeyDocsLink": "Xem tài liệu",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "Giao thức",
|
||||
"domainLabel": "Lãnh địa",
|
||||
"domainPlaceholder": "không bắt buộc",
|
||||
"connectToRdp": "Kết nối qua RDP",
|
||||
"connectToVnc": "Kết nối qua VNC",
|
||||
"connectToTerminal": "Kết nối đến Terminal",
|
||||
"connectToFiles": "Kết nối đến Files"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "Đặt các giá trị mà mọi máy chủ đều kế thừa trừ khi nó ghi đè lên các giá trị đó.",
|
||||
"manage": "Quản lý",
|
||||
"dialogDescription": "Các quy định này áp dụng cho các máy chủ không thiết lập bất kỳ cài đặt nào. Bất kỳ cài đặt nào được thiết lập trên máy chủ đều sẽ được ưu tiên.",
|
||||
"tabTerminal": "Phần cuối",
|
||||
"tabRemoteDesktop": "Máy tính từ xa",
|
||||
"inherit": "Kế thừa",
|
||||
"on": "TRÊN",
|
||||
"off": "Tắt",
|
||||
"resizeDisplayUpdate": "Cập nhật hiển thị",
|
||||
"resizeReconnect": "Kết nối lại",
|
||||
"clearAll": "Xóa tất cả",
|
||||
"saved": "Cài đặt kết nối mặc định đã được lưu",
|
||||
"saveFailed": "Không thể lưu cài đặt kết nối mặc định."
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "连接详情",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "远程桌面",
|
||||
"port": "端口",
|
||||
"username": "用户名",
|
||||
"folder": "文件夹",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "常规",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "终端",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "主机指标",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "共享",
|
||||
"tabAuthentication": "认证",
|
||||
"terminal": "终端",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "取消全选",
|
||||
"protocols": "协议",
|
||||
"secureShell": "SSH",
|
||||
"virtualNetwork": "虚拟网络",
|
||||
"unencryptedShell": "未加密 Shell",
|
||||
"addressIp": "地址 / IP",
|
||||
"friendlyName": "友好名称",
|
||||
"macAddress": "MAC 地址",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "步骤 CA",
|
||||
"filterProtocolGroup": "协议",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "功能",
|
||||
"filterFeatureTerminal": "终端",
|
||||
"filterFeatureFileManager": "文件管理器",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "直接",
|
||||
"authTypeCredential": "凭据",
|
||||
"authTypeNone": "无",
|
||||
"colorDepth": "颜色深度",
|
||||
"resizeMethod": "调整大小方法",
|
||||
"recordingPath": "录制路径",
|
||||
"recordingName": "录制名称",
|
||||
"saveHostFirst": "请先保存主机。",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "启用 Guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC 远程桌面",
|
||||
"enableGuacamoleDocsLink": "查看文档",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API 密钥",
|
||||
"tailscaleApiKeyDescription": "用于主机编辑器中的设备发现。支持 Tailscale (tskey-) 和 Headscale (hskey-) 密钥。您可以在 tailscale.com/admin/settings/keys 或从您的 Headscale 实例生成密钥。",
|
||||
"tailscaleApiKeyDocsLink": "查看文档",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "协议",
|
||||
"domainLabel": "领域",
|
||||
"domainPlaceholder": "选修的",
|
||||
"connectToRdp": "通过 RDP 连接",
|
||||
"connectToVnc": "通过 VNC 连接",
|
||||
"connectToTerminal": "连接到终端",
|
||||
"connectToFiles": "连接到文件管理器"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "设置所有主机都将继承的值,除非主机覆盖这些值。",
|
||||
"manage": "管理",
|
||||
"dialogDescription": "这些规则适用于未设置相关设置的主机。主机上已设置的任何内容均会生效。",
|
||||
"tabTerminal": "终端",
|
||||
"tabRemoteDesktop": "远程桌面",
|
||||
"inherit": "继承",
|
||||
"on": "开启",
|
||||
"off": "关闭",
|
||||
"resizeDisplayUpdate": "显示更新",
|
||||
"resizeReconnect": "重新连接",
|
||||
"clearAll": "全部清除",
|
||||
"saved": "已保存连接默认设置",
|
||||
"saveFailed": "保存连接默认设置失败"
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"connectionDetails": "連線詳細資料",
|
||||
"ssh": "SSH",
|
||||
"telnet": "Telnet",
|
||||
"remoteDesktop": "遠端桌面",
|
||||
"port": "連接埠",
|
||||
"username": "使用者名稱",
|
||||
"folder": "資料夾",
|
||||
@@ -756,10 +755,7 @@
|
||||
"tabGeneral": "一般",
|
||||
"tabSsh": "SSH",
|
||||
"tabTerminal": "終端機",
|
||||
"tabRdp": "RDP",
|
||||
"tabVnc": "VNC",
|
||||
"tabStats": "主機指標",
|
||||
"tabTelnet": "Telnet",
|
||||
"tabSharing": "分享",
|
||||
"tabAuthentication": "驗證",
|
||||
"terminal": "終端機",
|
||||
@@ -833,8 +829,6 @@
|
||||
"deselectAll": "取消全選",
|
||||
"protocols": "通訊協定",
|
||||
"secureShell": "安全殼層",
|
||||
"virtualNetwork": "虛擬網路",
|
||||
"unencryptedShell": "未加密殼層",
|
||||
"addressIp": "位址 / IP",
|
||||
"friendlyName": "易記名稱",
|
||||
"macAddress": "MAC 位址",
|
||||
@@ -1381,9 +1375,6 @@
|
||||
"filterAuthStepca": "步驟 CA",
|
||||
"filterProtocolGroup": "通訊協定",
|
||||
"filterProtocolSsh": "SSH",
|
||||
"filterProtocolRdp": "RDP",
|
||||
"filterProtocolVnc": "VNC",
|
||||
"filterProtocolTelnet": "Telnet",
|
||||
"filterFeaturesGroup": "功能",
|
||||
"filterFeatureTerminal": "終端機",
|
||||
"filterFeatureFileManager": "檔案管理員",
|
||||
@@ -1482,8 +1473,6 @@
|
||||
"authTypeDirect": "直接",
|
||||
"authTypeCredential": "憑證",
|
||||
"authTypeNone": "沒有任何",
|
||||
"colorDepth": "色彩深度",
|
||||
"resizeMethod": "調整尺寸方法",
|
||||
"recordingPath": "錄製路徑",
|
||||
"recordingName": "錄製名稱",
|
||||
"saveHostFirst": "請先儲存主機。",
|
||||
@@ -2108,7 +2097,6 @@
|
||||
"enableGuacamole": "啟用 Guacamole",
|
||||
"enableGuacamoleDesc": "RDP/VNC 遠端桌面",
|
||||
"enableGuacamoleDocsLink": "檢視文件",
|
||||
"guacdUrl": "guacd URL",
|
||||
"tailscaleApiKey": "Tailscale API 金鑰",
|
||||
"tailscaleApiKeyDescription": "用於主機編輯器中的設備發現。支援 Tailscale (tskey-) 和 Headscale (hskey-) 金鑰。您可以在 tailscale.com/admin/settings/keys 或從您的 Headscale 實例產生金鑰。",
|
||||
"tailscaleApiKeyDocsLink": "檢視文件",
|
||||
@@ -2424,8 +2412,6 @@
|
||||
"protocolLabel": "協定",
|
||||
"domainLabel": "領域",
|
||||
"domainPlaceholder": "選修的",
|
||||
"connectToRdp": "透過 RDP 連接",
|
||||
"connectToVnc": "透過 VNC 連接",
|
||||
"connectToTerminal": "連線至終端機",
|
||||
"connectToFiles": "連線至檔案管理員"
|
||||
},
|
||||
@@ -2633,13 +2619,9 @@
|
||||
"description": "設定所有主機都將繼承的值,除非主機覆寫這些值。",
|
||||
"manage": "管理",
|
||||
"dialogDescription": "這些規則適用於未設定相關設定的主機。主機上已設定的任何內容均會生效。",
|
||||
"tabTerminal": "終端",
|
||||
"tabRemoteDesktop": "遠端桌面",
|
||||
"inherit": "繼承",
|
||||
"on": "在",
|
||||
"off": "離開",
|
||||
"resizeDisplayUpdate": "顯示更新",
|
||||
"resizeReconnect": "重新連接",
|
||||
"clearAll": "全部清除",
|
||||
"saved": "已儲存連線預設設定",
|
||||
"saveFailed": "儲存連線預設設定失敗"
|
||||
|
||||
+1
-11
@@ -794,7 +794,7 @@ function getApiUrl(path: string, defaultPort: number): string {
|
||||
// JWT fresh on every request (cheap, and correct even if the user
|
||||
// connects/disconnects remote sync without an app reload).
|
||||
|
||||
function createRemoteOriginApiInstance(path: string): AxiosInstance {
|
||||
export function createRemoteOriginApiInstance(path: string): AxiosInstance {
|
||||
const instance = axios.create({
|
||||
headers: { "Content-Type": "application/json" },
|
||||
timeout: 30000,
|
||||
@@ -835,7 +835,6 @@ function createRemoteOriginApiInstance(path: string): AxiosInstance {
|
||||
let remoteFileManagerApi: AxiosInstance | null = null;
|
||||
let remoteStatsApi: AxiosInstance | null = null;
|
||||
let remoteCoreApi: AxiosInstance | null = null;
|
||||
let remoteGuacamoleApi: AxiosInstance | null = null;
|
||||
|
||||
export function getRemoteFileManagerApi(): AxiosInstance {
|
||||
if (!remoteFileManagerApi) {
|
||||
@@ -867,13 +866,6 @@ export function getRemoteCoreApi(): AxiosInstance {
|
||||
return remoteCoreApi;
|
||||
}
|
||||
|
||||
export function getRemoteGuacamoleApi(): AxiosInstance {
|
||||
if (!remoteGuacamoleApi) {
|
||||
remoteGuacamoleApi = createRemoteOriginApiInstance("");
|
||||
}
|
||||
return remoteGuacamoleApi;
|
||||
}
|
||||
|
||||
// Maps a live SSH session (keyed by sessionId, which today is the host's
|
||||
// numeric id as a string -- see ensureSSHSessionForHost) to the resolved
|
||||
// origin it was connected through, so every subsequent file-manager call
|
||||
@@ -1582,8 +1574,6 @@ export {
|
||||
updateLogLevel,
|
||||
getSessionTimeout,
|
||||
updateSessionTimeout,
|
||||
getGuacamoleSettings,
|
||||
updateGuacamoleSettings,
|
||||
} from "@/api/settings-api";
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
registerHostContextMenuItem,
|
||||
} from "@/sidebar/host-contributions";
|
||||
import { registerPaletteEntry } from "@/shell/palette-registry";
|
||||
import { registerHostProtocol } from "@/sidebar/host-protocols";
|
||||
import {
|
||||
registerDashboardCard,
|
||||
type DashboardCardRenderProps,
|
||||
@@ -30,7 +31,7 @@ import {
|
||||
registerAction,
|
||||
registerSlotContribution,
|
||||
} from "@/shell/action-registry";
|
||||
import { pluginWsUrl } from "@/lib/plugin-transport";
|
||||
import { pluginApiFor, pluginWsUrl } from "@/lib/plugin-transport";
|
||||
import { registerPluginComponent } from "./component-registry";
|
||||
import type { WidgetTypeDefinition } from "@/types/homepage-types";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
@@ -208,6 +209,19 @@ export function createPluginApp(
|
||||
);
|
||||
},
|
||||
|
||||
registerHostProtocol(protocol) {
|
||||
return track(
|
||||
registerHostProtocol({
|
||||
...protocol,
|
||||
pluginId,
|
||||
titleKey: key(protocol.titleKey),
|
||||
descriptionKey: protocol.descriptionKey
|
||||
? key(protocol.descriptionKey)
|
||||
: undefined,
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
registerHostBadge(badge) {
|
||||
return track(
|
||||
registerHostBadge({
|
||||
@@ -367,6 +381,12 @@ export function createPluginApp(
|
||||
}
|
||||
},
|
||||
api: pluginHostBridge.getApi(pluginId),
|
||||
apiFor: (origin) =>
|
||||
pluginApiFor(
|
||||
pluginId,
|
||||
origin as never,
|
||||
pluginHostBridge.getApi(pluginId) as never,
|
||||
) as unknown as TermixApp["api"],
|
||||
wsUrl: (path, options) =>
|
||||
pluginWsUrl(pluginId, path, options as never) as ReturnType<
|
||||
TermixApp["wsUrl"]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { enabledHostProtocols } from "@/sidebar/host-protocols";
|
||||
import { useTranslation as useI18nTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
@@ -275,6 +276,13 @@ export const pluginHostBridge: PluginHostBridge = {
|
||||
|
||||
useSlotContributions: (slotId, context) => useActionSlot(slotId, context),
|
||||
|
||||
hostProtocols: (record) => [
|
||||
...(record.enableSsh !== false ? ["ssh"] : []),
|
||||
...enabledHostProtocols(
|
||||
record as { pluginSettings?: Record<string, Record<string, unknown>> },
|
||||
).map((protocol) => protocol.id),
|
||||
],
|
||||
|
||||
usePluginComponent: (id) => usePluginComponent(id),
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +112,16 @@ export {
|
||||
type ConnectionOrigin,
|
||||
} from "@/lib/connection-origin";
|
||||
export { pluginWsUrl } from "@/lib/plugin-transport";
|
||||
export { hydrateLocalSharedHostAuth } from "@/lib/remote-server-api";
|
||||
export {
|
||||
buildOriginWsUrl,
|
||||
type WebSocketConnectionTarget,
|
||||
} from "@/lib/connection-origin";
|
||||
export { getBasePath } from "@/lib/base-path";
|
||||
export type { ConnectionStage } from "@/types/connection-log";
|
||||
export {
|
||||
hydrateLocalSharedHostAuth,
|
||||
resolveRemoteHostId,
|
||||
} from "@/lib/remote-server-api";
|
||||
export { useConnectionDefaults } from "@/contexts/ConnectionDefaultsContext";
|
||||
|
||||
// Core APIs a terminal-like surface calls: recent activity, the host's stored
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { getPanel, listPanels } from "@/shell/panel-registry";
|
||||
import { listRegisteredRailItems } from "@/sidebar/rail-items";
|
||||
import { listHostActions } from "@/sidebar/host-contributions";
|
||||
import { listHostProtocols } from "@/sidebar/host-protocols";
|
||||
import {
|
||||
getHostEditorSection,
|
||||
hostEditorSectionList,
|
||||
@@ -207,6 +208,8 @@ export async function renderPlugin(
|
||||
id: action.id,
|
||||
tabType: action.tabType,
|
||||
})),
|
||||
hostProtocols: () =>
|
||||
mine(listHostProtocols()).map((protocol) => protocol.id),
|
||||
hostEditorSections: () =>
|
||||
mine(hostEditorSectionList()).map((section) => section.id),
|
||||
dashboardCards: () =>
|
||||
|
||||
@@ -17,7 +17,7 @@ import { SectionCard } from "@/components/section-card";
|
||||
import { PluginIcon } from "@/lib/plugin-icon";
|
||||
import { getPlugins, type PluginSummary } from "@/api/plugins-api";
|
||||
import { SettingsFieldRow } from "./SettingsFields";
|
||||
import { isFieldActive } from "./settings-fields-util";
|
||||
import { hasVisibleFields, isFieldActive } from "./settings-fields-util";
|
||||
|
||||
/** Values for every plugin on one host: { [pluginId]: { [key]: value } }. */
|
||||
export type HostPluginSettings = Record<string, Record<string, unknown>>;
|
||||
@@ -45,7 +45,7 @@ export function usePluginHostSections(): PluginSummary[] {
|
||||
plugins.filter((plugin) => {
|
||||
if (!plugin.enabled) return false;
|
||||
const host = plugin.contributes?.settings?.host;
|
||||
return !!host && (host.fields.length > 0 || !!host.enableKey);
|
||||
return !!host && (hasVisibleFields(host.fields) || !!host.enableKey);
|
||||
}),
|
||||
[plugins],
|
||||
);
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
HostPluginSections,
|
||||
type HostPluginSettings,
|
||||
} from "./HostPluginSections";
|
||||
import { hasVisibleFields } from "./settings-fields-util";
|
||||
|
||||
export const HOST_PLUGINS_TAB_ID = "plugins";
|
||||
|
||||
@@ -38,7 +39,7 @@ export function syncHostPluginsTab(plugins: PluginSummary[]): boolean {
|
||||
const contributors = plugins.filter((plugin) => {
|
||||
if (!plugin.enabled) return false;
|
||||
const host = plugin.contributes?.settings?.host;
|
||||
return !!host && (host.fields.length > 0 || !!host.enableKey);
|
||||
return !!host && (hasVisibleFields(host.fields) || !!host.enableKey);
|
||||
});
|
||||
|
||||
if (contributors.length === 0) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { PluginSettingsField } from "@/api/plugins-api";
|
||||
|
||||
/**
|
||||
* Whether a field's `requires` gate is satisfied.
|
||||
* Whether the generic form draws a field: not hidden (the plugin edits it in
|
||||
* its own UI) and its `requires` gate satisfied.
|
||||
*
|
||||
* Kept out of the component file so both the settings page and the host editor
|
||||
* section can import it without dragging a component along.
|
||||
@@ -10,6 +11,12 @@ export function isFieldActive(
|
||||
field: PluginSettingsField,
|
||||
values: Record<string, unknown>,
|
||||
): boolean {
|
||||
if (field.hidden) return false;
|
||||
if (!field.requires) return true;
|
||||
return values[field.requires] === true;
|
||||
}
|
||||
|
||||
/** Whether a plugin has any field the generic form would ever draw. */
|
||||
export function hasVisibleFields(fields: PluginSettingsField[]): boolean {
|
||||
return fields.some((field) => !field.hidden);
|
||||
}
|
||||
@@ -33,8 +33,6 @@ import {
|
||||
updateGlobalMonitoringSettings,
|
||||
getLogLevel,
|
||||
updateLogLevel,
|
||||
getGuacamoleSettings,
|
||||
updateGuacamoleSettings,
|
||||
getOidcAutoProvision,
|
||||
updateOidcAutoProvision,
|
||||
getSecondFactorAfterExternalLogin,
|
||||
@@ -137,8 +135,6 @@ export function AdminSettingsPanel({
|
||||
const [sessionTimeout, setSessionTimeout] = useState("24");
|
||||
const [statusInterval, setStatusInterval] = useState("60");
|
||||
const [metricsInterval, setMetricsInterval] = useState("30");
|
||||
const [guacEnabled, setGuacEnabled] = useState(false);
|
||||
const [guacUrl, setGuacUrl] = useState("guacd:4822");
|
||||
const [logLevel, setLogLevel] = useState("info");
|
||||
const [analyticsEnabled, setAnalyticsEnabled] = useState(true);
|
||||
const [analyticsLocked, setAnalyticsLocked] = useState(false);
|
||||
@@ -350,7 +346,6 @@ export function AdminSettingsPanel({
|
||||
timeout,
|
||||
monitoring,
|
||||
level,
|
||||
guac,
|
||||
oidcProv,
|
||||
secondFactorExternal,
|
||||
oidcSilent,
|
||||
@@ -366,7 +361,6 @@ export function AdminSettingsPanel({
|
||||
getSessionTimeout(),
|
||||
getGlobalMonitoringSettings(),
|
||||
getLogLevel(),
|
||||
getGuacamoleSettings(),
|
||||
getOidcAutoProvision(),
|
||||
getSecondFactorAfterExternalLogin(),
|
||||
getOidcSilentLoginDefault(),
|
||||
@@ -402,10 +396,6 @@ export function AdminSettingsPanel({
|
||||
}
|
||||
|
||||
if (level.status === "fulfilled") setLogLevel(level.value.level);
|
||||
if (guac.status === "fulfilled") {
|
||||
setGuacEnabled(guac.value.enabled);
|
||||
setGuacUrl(guac.value.url || "guacd:4822");
|
||||
}
|
||||
if (analytics.status === "fulfilled") {
|
||||
setAnalyticsEnabled(analytics.value.enabled);
|
||||
setAnalyticsLocked(analytics.value.locked ?? false);
|
||||
@@ -656,26 +646,6 @@ export function AdminSettingsPanel({
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveGuacamole() {
|
||||
try {
|
||||
await updateGuacamoleSettings({ enabled: guacEnabled, url: guacUrl });
|
||||
toast.success(t("admin.remoteDesktopSaved"));
|
||||
} catch {
|
||||
toast.error(t("admin.remoteDesktopSaveFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
async function handleToggleGuacamole() {
|
||||
const newVal = !guacEnabled;
|
||||
setGuacEnabled(newVal);
|
||||
try {
|
||||
await updateGuacamoleSettings({ enabled: newVal, url: guacUrl });
|
||||
} catch {
|
||||
setGuacEnabled(!newVal);
|
||||
toast.error(t("admin.remoteDesktopUpdateFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSaveLogLevel(level: string) {
|
||||
setLogLevel(level);
|
||||
try {
|
||||
@@ -1103,11 +1073,6 @@ export function AdminSettingsPanel({
|
||||
metricsInterval={metricsInterval}
|
||||
setMetricsInterval={setMetricsInterval}
|
||||
handleSaveMonitoring={handleSaveMonitoring}
|
||||
guacEnabled={guacEnabled}
|
||||
handleToggleGuacamole={handleToggleGuacamole}
|
||||
guacUrl={guacUrl}
|
||||
setGuacUrl={setGuacUrl}
|
||||
handleSaveGuacamole={handleSaveGuacamole}
|
||||
logLevel={logLevel}
|
||||
handleSaveLogLevel={handleSaveLogLevel}
|
||||
/>
|
||||
|
||||
@@ -60,11 +60,6 @@ type GeneralSettingsSectionProps = {
|
||||
metricsInterval: string;
|
||||
setMetricsInterval: Dispatch<SetStateAction<string>>;
|
||||
handleSaveMonitoring: () => void;
|
||||
guacEnabled: boolean;
|
||||
handleToggleGuacamole: () => void;
|
||||
guacUrl: string;
|
||||
setGuacUrl: Dispatch<SetStateAction<string>>;
|
||||
handleSaveGuacamole: () => void;
|
||||
logLevel: string;
|
||||
handleSaveLogLevel: (level: string) => void;
|
||||
};
|
||||
@@ -106,11 +101,6 @@ export function AdminGeneralSettingsSection({
|
||||
metricsInterval,
|
||||
setMetricsInterval,
|
||||
handleSaveMonitoring,
|
||||
guacEnabled,
|
||||
handleToggleGuacamole,
|
||||
guacUrl,
|
||||
setGuacUrl,
|
||||
handleSaveGuacamole,
|
||||
logLevel,
|
||||
handleSaveLogLevel,
|
||||
}: GeneralSettingsSectionProps) {
|
||||
@@ -390,50 +380,6 @@ export function AdminGeneralSettingsSection({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 border-t border-border pt-3 mt-2">
|
||||
<SettingRow
|
||||
label={t("admin.enableRemoteDesktop")}
|
||||
description={
|
||||
<>
|
||||
{t("admin.enableRemoteDesktopDesc")}{" "}
|
||||
<a
|
||||
href="https://docs.termix.site/setup/remote-desktop"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-accent-brand hover:underline"
|
||||
>
|
||||
{t("admin.enableRemoteDesktopDocsLink")}
|
||||
</a>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<AdminToggle on={guacEnabled} onToggle={handleToggleGuacamole} />
|
||||
</SettingRow>
|
||||
{guacEnabled && (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<label className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
|
||||
{t("admin.guacdUrl")}
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
value={guacUrl}
|
||||
onChange={(e) => setGuacUrl(e.target.value)}
|
||||
placeholder="guacd:4822"
|
||||
className="text-sm"
|
||||
/>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="text-xs border-accent-brand/40 text-accent-brand hover:bg-accent-brand/10 hover:text-accent-brand h-7 shrink-0"
|
||||
onClick={handleSaveGuacamole}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 border-t border-border pt-3 mt-2">
|
||||
<span className="text-[10px] font-bold uppercase tracking-widest text-muted-foreground">
|
||||
{t("admin.logLevel")}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { hostProtocolFlags, type HostProtocols } from "./host-protocols";
|
||||
import { getUserList } from "@/main-axios";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
@@ -141,12 +142,9 @@ export function AdminUserManagePanel({
|
||||
}, [user.id]);
|
||||
const [editor, setEditor] = useState<EditorState>(null);
|
||||
const [editorTab, setEditorTab] = useState("general");
|
||||
const [editorProtocols, setEditorProtocols] = useState({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
const [editorProtocols, setEditorProtocols] = useState<HostProtocols>(() =>
|
||||
hostProtocolFlags(null),
|
||||
);
|
||||
const [confirmDialog, setConfirmDialog] = useState<{
|
||||
message: string;
|
||||
onConfirm: () => void;
|
||||
@@ -791,12 +789,7 @@ export function AdminUserManagePanel({
|
||||
size="sm"
|
||||
className="h-6 text-[10px] border-accent-brand/40 text-accent-brand hover:bg-accent-brand/10 hover:text-accent-brand"
|
||||
onClick={() => {
|
||||
setEditorProtocols({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
setEditorProtocols(hostProtocolFlags(null));
|
||||
setEditorTab("general");
|
||||
setEditor({ kind: "host", host: null });
|
||||
}}
|
||||
@@ -842,12 +835,7 @@ export function AdminUserManagePanel({
|
||||
size="icon"
|
||||
className="size-6 text-muted-foreground hover:text-foreground"
|
||||
onClick={() => {
|
||||
setEditorProtocols({
|
||||
enableSsh: host.enableSsh,
|
||||
enableRdp: host.enableRdp,
|
||||
enableVnc: host.enableVnc,
|
||||
enableTelnet: host.enableTelnet,
|
||||
});
|
||||
setEditorProtocols(hostProtocolFlags(host));
|
||||
setEditorTab("general");
|
||||
setEditor({ kind: "host", host });
|
||||
}}
|
||||
|
||||
@@ -20,7 +20,6 @@ import {
|
||||
import {
|
||||
fromTriState,
|
||||
toTriState,
|
||||
type RemoteDesktopDefaults,
|
||||
type TerminalDefaults,
|
||||
type TriState,
|
||||
} from "@/lib/connection-defaults";
|
||||
@@ -35,34 +34,6 @@ const inputClass =
|
||||
const labelClass =
|
||||
"text-[10px] font-bold uppercase tracking-widest text-muted-foreground";
|
||||
|
||||
const RDP_TOGGLES = [
|
||||
["forceLossless", "hosts.guac.forceLossless", "hosts.guac.forceLosslessDesc"],
|
||||
["enableWallpaper", "hosts.guac.wallpaper", "hosts.guac.wallpaperDesc"],
|
||||
[
|
||||
"enableFontSmoothing",
|
||||
"hosts.guac.fontSmoothing",
|
||||
"hosts.guac.fontSmoothingDesc",
|
||||
],
|
||||
[
|
||||
"enableDesktopComposition",
|
||||
"hosts.guac.desktopComposition",
|
||||
"hosts.guac.desktopCompositionDesc",
|
||||
],
|
||||
["disableAudio", "hosts.guac.disableAudio", "hosts.guac.disableAudioDesc"],
|
||||
[
|
||||
"enablePrinting",
|
||||
"hosts.guac.enablePrinting",
|
||||
"hosts.guac.enablePrintingDesc",
|
||||
],
|
||||
[
|
||||
"enableDrive",
|
||||
"hosts.guac.enableDriveRedirection",
|
||||
"hosts.guac.enableDriveRedirectionDesc",
|
||||
],
|
||||
["disableCopy", "hosts.guac.disableCopy", "hosts.guac.disableCopyDesc"],
|
||||
["disablePaste", "hosts.guac.disablePaste", "hosts.guac.disablePasteDesc"],
|
||||
] as const;
|
||||
|
||||
function Field({
|
||||
label,
|
||||
children,
|
||||
@@ -105,17 +76,14 @@ export function ConnectionDefaultsSettings() {
|
||||
const { t } = useTranslation();
|
||||
const defaults = useConnectionDefaults();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [tab, setTab] = useState<"shell" | "desktop">("shell");
|
||||
const [terminal, setTerminal] = useState<TerminalDefaults>({});
|
||||
const [rdp, setRdp] = useState<RemoteDesktopDefaults>({});
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [savedThemes, setSavedThemes] = useState<SavedCustomTheme[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!defaults.ready) return;
|
||||
setTerminal(defaults.terminal);
|
||||
setRdp(defaults.rdp);
|
||||
}, [defaults.ready, defaults.terminal, defaults.rdp]);
|
||||
}, [defaults.ready, defaults.terminal]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
@@ -127,17 +95,13 @@ export function ConnectionDefaultsSettings() {
|
||||
const configuredCount = useMemo(() => {
|
||||
const count = (source: Record<string, unknown>) =>
|
||||
Object.values(source).filter((value) => value !== undefined).length;
|
||||
return count(defaults.terminal) + count(defaults.rdp);
|
||||
}, [defaults.terminal, defaults.rdp]);
|
||||
return count(defaults.terminal);
|
||||
}, [defaults.terminal]);
|
||||
|
||||
const updateTerminal = <K extends keyof TerminalDefaults>(
|
||||
key: K,
|
||||
value: TerminalDefaults[K],
|
||||
) => setTerminal((current) => ({ ...current, [key]: value }));
|
||||
const updateRdp = <K extends keyof RemoteDesktopDefaults>(
|
||||
key: K,
|
||||
value: RemoteDesktopDefaults[K],
|
||||
) => setRdp((current) => ({ ...current, [key]: value }));
|
||||
|
||||
const applySavedTheme = (id: string) => {
|
||||
if (!id) return;
|
||||
@@ -153,10 +117,7 @@ export function ConnectionDefaultsSettings() {
|
||||
async function save() {
|
||||
setSaving(true);
|
||||
try {
|
||||
await Promise.all([
|
||||
defaults.saveTerminalDefaults(terminal),
|
||||
defaults.saveRdpDefaults(rdp),
|
||||
]);
|
||||
await defaults.saveTerminalDefaults(terminal);
|
||||
toast.success(t("newUi.sidebar.connectionDefaults.saved"));
|
||||
setOpen(false);
|
||||
} catch {
|
||||
@@ -204,241 +165,155 @@ export function ConnectionDefaultsSettings() {
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="flex border-b border-border">
|
||||
{(
|
||||
[
|
||||
["shell", "newUi.sidebar.connectionDefaults.tabTerminal"],
|
||||
[
|
||||
"desktop",
|
||||
"newUi.sidebar.connectionDefaults.tabRemoteDesktop",
|
||||
],
|
||||
] as const
|
||||
).map(([id, labelKey]) => (
|
||||
<button
|
||||
key={id}
|
||||
onClick={() => setTab(id)}
|
||||
className={`px-3 py-2 text-xs font-medium border-b-2 -mb-px transition-colors ${
|
||||
tab === id
|
||||
? "border-accent-brand text-foreground"
|
||||
: "border-transparent text-muted-foreground hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
{t(labelKey)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="max-h-[55vh] overflow-y-auto pr-1">
|
||||
{tab === "shell" ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<Field label={t("hosts.fontFamilyLabel")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.fontFamily ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal("fontFamily", e.target.value || undefined)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{TERMINAL_FONTS.map((font) => (
|
||||
<option key={font.value} value={font.value}>
|
||||
{font.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.colorTheme")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.theme ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal("theme", e.target.value || undefined)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{Object.entries(TERMINAL_THEMES)
|
||||
.filter(
|
||||
([key]) =>
|
||||
key !== "termixDark" && key !== "termixLight",
|
||||
)
|
||||
.map(([key, theme]) => (
|
||||
<option key={key} value={key}>
|
||||
{theme.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
{savedThemes.length > 0 && (
|
||||
<Field
|
||||
label={t(
|
||||
"newUi.sidebar.connectionDefaults.savedThemeLabel",
|
||||
)}
|
||||
>
|
||||
<select
|
||||
className={inputClass}
|
||||
value=""
|
||||
onChange={(e) => applySavedTheme(e.target.value)}
|
||||
>
|
||||
<option value="">
|
||||
{t(
|
||||
"newUi.sidebar.connectionDefaults.savedThemePlaceholder",
|
||||
)}
|
||||
</option>
|
||||
{savedThemes.map((theme) => (
|
||||
<option key={theme.id} value={theme.id}>
|
||||
{theme.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
)}
|
||||
|
||||
<Field label={t("hosts.fontSizeLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={8}
|
||||
max={32}
|
||||
value={terminal.fontSize ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"fontSize",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.lineHeightLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={0.8}
|
||||
max={2}
|
||||
step={0.05}
|
||||
value={terminal.lineHeight ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"lineHeight",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.cursorStyleLabel")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.cursorStyle ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"cursorStyle",
|
||||
(e.target.value || undefined) as
|
||||
TerminalDefaults["cursorStyle"] | undefined,
|
||||
)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{CURSOR_STYLES.map((style) => (
|
||||
<option key={style.value} value={style.value}>
|
||||
{style.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.scrollbackBufferLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={1000}
|
||||
max={100000}
|
||||
step={1000}
|
||||
value={terminal.scrollback ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"scrollback",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<div className="sm:col-span-2">
|
||||
<SettingRow
|
||||
label={t("hosts.cursorBlinking")}
|
||||
description={t("hosts.cursorBlinkingDesc")}
|
||||
>
|
||||
<TriStateSelect
|
||||
value={terminal.cursorBlink}
|
||||
onChange={(value) => updateTerminal("cursorBlink", value)}
|
||||
/>
|
||||
</SettingRow>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<Field label={t("hosts.guac.colorDepth")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={rdp.colorDepth ?? ""}
|
||||
onChange={(e) =>
|
||||
updateRdp(
|
||||
"colorDepth",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
<option value="16">16-bit</option>
|
||||
<option value="24">24-bit</option>
|
||||
<option value="32">32-bit</option>
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.guac.resizeMethod")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={rdp.resizeMethod ?? ""}
|
||||
onChange={(e) =>
|
||||
updateRdp("resizeMethod", e.target.value || undefined)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
<option value="display-update">
|
||||
{t(
|
||||
"newUi.sidebar.connectionDefaults.resizeDisplayUpdate",
|
||||
)}
|
||||
</option>
|
||||
<option value="reconnect">
|
||||
{t("newUi.sidebar.connectionDefaults.resizeReconnect")}
|
||||
</option>
|
||||
</select>
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{RDP_TOGGLES.map(([key, labelKey, descriptionKey]) => (
|
||||
<SettingRow
|
||||
key={key}
|
||||
label={t(labelKey)}
|
||||
description={t(descriptionKey)}
|
||||
>
|
||||
<TriStateSelect
|
||||
value={rdp[key] as boolean | undefined}
|
||||
onChange={(value) => updateRdp(key, value)}
|
||||
/>
|
||||
</SettingRow>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<Field label={t("hosts.fontFamilyLabel")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.fontFamily ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal("fontFamily", e.target.value || undefined)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{TERMINAL_FONTS.map((font) => (
|
||||
<option key={font.value} value={font.value}>
|
||||
{font.label}
|
||||
</option>
|
||||
))}
|
||||
</div>
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.colorTheme")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.theme ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal("theme", e.target.value || undefined)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{Object.entries(TERMINAL_THEMES)
|
||||
.filter(
|
||||
([key]) => key !== "termixDark" && key !== "termixLight",
|
||||
)
|
||||
.map(([key, theme]) => (
|
||||
<option key={key} value={key}>
|
||||
{theme.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
{savedThemes.length > 0 && (
|
||||
<Field
|
||||
label={t("newUi.sidebar.connectionDefaults.savedThemeLabel")}
|
||||
>
|
||||
<select
|
||||
className={inputClass}
|
||||
value=""
|
||||
onChange={(e) => applySavedTheme(e.target.value)}
|
||||
>
|
||||
<option value="">
|
||||
{t(
|
||||
"newUi.sidebar.connectionDefaults.savedThemePlaceholder",
|
||||
)}
|
||||
</option>
|
||||
{savedThemes.map((theme) => (
|
||||
<option key={theme.id} value={theme.id}>
|
||||
{theme.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
)}
|
||||
|
||||
<Field label={t("hosts.fontSizeLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={8}
|
||||
max={32}
|
||||
value={terminal.fontSize ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"fontSize",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.lineHeightLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={0.8}
|
||||
max={2}
|
||||
step={0.05}
|
||||
value={terminal.lineHeight ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"lineHeight",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.cursorStyleLabel")}>
|
||||
<select
|
||||
className={inputClass}
|
||||
value={terminal.cursorStyle ?? ""}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"cursorStyle",
|
||||
(e.target.value || undefined) as
|
||||
TerminalDefaults["cursorStyle"] | undefined,
|
||||
)
|
||||
}
|
||||
>
|
||||
<option value="">{inheritLabel}</option>
|
||||
{CURSOR_STYLES.map((style) => (
|
||||
<option key={style.value} value={style.value}>
|
||||
{style.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</Field>
|
||||
|
||||
<Field label={t("hosts.scrollbackBufferLabel")}>
|
||||
<input
|
||||
className={inputClass}
|
||||
type="number"
|
||||
min={1000}
|
||||
max={100000}
|
||||
step={1000}
|
||||
value={terminal.scrollback ?? ""}
|
||||
placeholder={inheritLabel}
|
||||
onChange={(e) =>
|
||||
updateTerminal(
|
||||
"scrollback",
|
||||
e.target.value ? Number(e.target.value) : undefined,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<div className="sm:col-span-2">
|
||||
<SettingRow
|
||||
label={t("hosts.cursorBlinking")}
|
||||
description={t("hosts.cursorBlinkingDesc")}
|
||||
>
|
||||
<TriStateSelect
|
||||
value={terminal.cursorBlink}
|
||||
onChange={(value) => updateTerminal("cursorBlink", value)}
|
||||
/>
|
||||
</SettingRow>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between gap-2 pt-3 border-t border-border">
|
||||
@@ -447,7 +322,6 @@ export function ConnectionDefaultsSettings() {
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
setTerminal({});
|
||||
setRdp({});
|
||||
}}
|
||||
>
|
||||
{t("newUi.sidebar.connectionDefaults.clearAll")}
|
||||
|
||||
@@ -76,6 +76,7 @@ import {
|
||||
} from "./HostEditorData";
|
||||
import { useConnectionDefaults } from "@/contexts/ConnectionDefaultsContext";
|
||||
import { HostEditorGeneralTab } from "./HostEditorGeneralTab";
|
||||
import { withProtocolSettings } from "./host-protocols";
|
||||
import { canEditHost } from "./host-permissions";
|
||||
import { VaultProfileManager } from "./VaultProfileManager";
|
||||
import {
|
||||
@@ -331,7 +332,10 @@ export function HostEditor({
|
||||
}
|
||||
// After the host: a new one has no id to scope settings to until it
|
||||
// exists. A failure here must not claim the host itself failed to save.
|
||||
await savePluginHostSettings(Number(saved.id), form.pluginSettings);
|
||||
await savePluginHostSettings(
|
||||
Number(saved.id),
|
||||
withProtocolSettings(form.pluginSettings, protocols),
|
||||
);
|
||||
|
||||
toast.success(host ? t("hosts.hostUpdated") : t("hosts.hostCreated"));
|
||||
setPreviewTerminalTheme(null);
|
||||
|
||||
@@ -2,19 +2,16 @@ import { TERMINAL_THEMES } from "@/lib/terminal-themes";
|
||||
import type { Host } from "@/types/ui-types";
|
||||
import type { SSHHostData } from "@/types";
|
||||
import type { HostDefaults } from "@/api/settings-api";
|
||||
import type {
|
||||
RemoteDesktopDefaults,
|
||||
TerminalDefaults,
|
||||
} from "@/lib/connection-defaults";
|
||||
import type { TerminalDefaults } from "@/lib/connection-defaults";
|
||||
import {
|
||||
listHostProtocols,
|
||||
protocolPort,
|
||||
type HostProtocols,
|
||||
} from "./host-protocols";
|
||||
|
||||
type HostSocks5ProxyNode = NonNullable<Host["socks5ProxyChain"]>[number];
|
||||
|
||||
export type HostProtocols = {
|
||||
enableSsh: boolean;
|
||||
enableRdp: boolean;
|
||||
enableVnc: boolean;
|
||||
enableTelnet: boolean;
|
||||
};
|
||||
export type { HostProtocols };
|
||||
|
||||
export type HostAuthType = Host["authType"];
|
||||
export type HostCursorStyle = NonNullable<
|
||||
@@ -44,23 +41,8 @@ export const terminalAppearanceKeys = [
|
||||
"customThemeColors",
|
||||
] as const satisfies readonly (keyof TerminalDefaults)[];
|
||||
|
||||
export const remoteDesktopDefaultKeys = [
|
||||
"colorDepth",
|
||||
"resizeMethod",
|
||||
"forceLossless",
|
||||
"disableAudio",
|
||||
"enableWallpaper",
|
||||
"enableFontSmoothing",
|
||||
"enableDesktopComposition",
|
||||
"enablePrinting",
|
||||
"enableDrive",
|
||||
"disableCopy",
|
||||
"disablePaste",
|
||||
] as const satisfies readonly (keyof RemoteDesktopDefaults)[];
|
||||
|
||||
export interface UserConnectionDefaults {
|
||||
terminal: TerminalDefaults;
|
||||
rdp: RemoteDesktopDefaults;
|
||||
}
|
||||
|
||||
function hasOwn(value: object | undefined, key: PropertyKey): boolean {
|
||||
@@ -86,18 +68,13 @@ type SnippetResponse = SnippetListItem[] | { snippets?: SnippetListItem[] };
|
||||
/**
|
||||
* Whether the Connection Origin control is meaningful for a host.
|
||||
*
|
||||
* Every protocol Termix can dial from either backend belongs here. RDP, VNC
|
||||
* and Telnet were added once they could originate from the desktop
|
||||
* (Termix-SSH/Support#1240); before that the control was gated on SSH alone,
|
||||
* so a host enabling only those protocols could never reach the setting.
|
||||
* Every protocol Termix can dial from either backend belongs here, plugin
|
||||
* protocols included (Termix-SSH/Support#1240); before that the control was
|
||||
* gated on SSH alone, so a host enabling only remote desktop could never
|
||||
* reach the setting.
|
||||
*/
|
||||
export function connectionOriginAppliesTo(protocols: HostProtocols): boolean {
|
||||
return (
|
||||
protocols.enableSsh ||
|
||||
protocols.enableRdp ||
|
||||
protocols.enableVnc ||
|
||||
protocols.enableTelnet
|
||||
);
|
||||
return Object.values(protocols).some(Boolean);
|
||||
}
|
||||
|
||||
export function mapSnippetResponse(
|
||||
@@ -122,11 +99,6 @@ export function createHostEditorForm(
|
||||
...(connectionDefaults?.terminal ?? {}),
|
||||
...(host?.terminalConfig ?? {}),
|
||||
};
|
||||
const remoteDefaults = host?.enableRdp ? connectionDefaults?.rdp : undefined;
|
||||
const guacamoleConfig = {
|
||||
...(remoteDefaults ?? {}),
|
||||
...(host?.guacamoleConfig ?? {}),
|
||||
};
|
||||
const proxmoxSettings = (host?.pluginSettings?.proxmox ?? {}) as Record<
|
||||
string,
|
||||
unknown
|
||||
@@ -147,9 +119,6 @@ export function createHostEditorForm(
|
||||
ip: host?.ip ?? "",
|
||||
username: host?.username ?? (host ? "" : "root"),
|
||||
sshPort: host?.sshPort ?? host?.port ?? 22,
|
||||
rdpPort: host?.rdpPort ?? 3389,
|
||||
vncPort: host?.vncPort ?? 5900,
|
||||
telnetPort: host?.telnetPort ?? 23,
|
||||
authType: host?.authType ?? "password",
|
||||
useWarpgate: host?.useWarpgate ?? false,
|
||||
shareSshAuth: host?.shareSshAuth ?? false,
|
||||
@@ -223,11 +192,6 @@ export function createHostEditorForm(
|
||||
inheritTerminalAppearance:
|
||||
!host ||
|
||||
terminalAppearanceKeys.every((key) => !hasOwn(host.terminalConfig, key)),
|
||||
inheritRemoteDesktopDefaults:
|
||||
!host ||
|
||||
remoteDesktopDefaultKeys.every(
|
||||
(key) => !hasOwn(host.guacamoleConfig, key),
|
||||
),
|
||||
localEcho: host?.terminalConfig?.localEcho ?? "default",
|
||||
fontSize: terminalConfig.fontSize ?? d?.fontSize ?? 14,
|
||||
fontFamily:
|
||||
@@ -298,8 +262,6 @@ export function createHostEditorForm(
|
||||
? "existing_rdp_password"
|
||||
: (host?.rdpPassword ?? ""),
|
||||
domain: host?.domain ?? "",
|
||||
security: host?.security ?? "",
|
||||
ignoreCert: host?.ignoreCert ?? false,
|
||||
vncCredentialId: host?.vncCredentialId ?? "",
|
||||
vncPassword: host?.hasVncPassword
|
||||
? "existing_vnc_password"
|
||||
@@ -320,7 +282,6 @@ export function createHostEditorForm(
|
||||
telnetAuthType: (host?.telnetAuthType ??
|
||||
(host?.telnetCredentialId ? "credential" : "direct")) as
|
||||
"direct" | "credential",
|
||||
guacamoleConfig,
|
||||
statsConfig: host?.statsConfig ?? {
|
||||
statusCheckEnabled: d?.statusCheckEnabled ?? true,
|
||||
statusCheckInterval: 60,
|
||||
@@ -399,9 +360,11 @@ export function buildHostEditorPayload(
|
||||
const usesPassword = form.authType === "password";
|
||||
const usesAgent = form.authType === "agent";
|
||||
const usesVault = form.authType === "vault";
|
||||
const guacamoleConfig = form.inheritRemoteDesktopDefaults
|
||||
? stripKeys(form.guacamoleConfig, remoteDesktopDefaultKeys)
|
||||
: form.guacamoleConfig;
|
||||
// With SSH off, the host's primary protocol is the first plugin protocol
|
||||
// switched on, and its port stands in for the host port.
|
||||
const primaryProtocol = protocols.enableSsh
|
||||
? undefined
|
||||
: listHostProtocols().find((protocol) => protocols[protocol.settingKey]);
|
||||
const terminalConfig = {
|
||||
theme: form.theme,
|
||||
cursorBlink: form.cursorBlink,
|
||||
@@ -449,22 +412,12 @@ export function buildHostEditorPayload(
|
||||
: terminalConfig;
|
||||
|
||||
return {
|
||||
connectionType: protocols.enableSsh
|
||||
? "ssh"
|
||||
: protocols.enableRdp
|
||||
? "rdp"
|
||||
: protocols.enableVnc
|
||||
? "vnc"
|
||||
: "telnet",
|
||||
connectionType: primaryProtocol?.id ?? "ssh",
|
||||
name: form.name,
|
||||
ip: form.ip,
|
||||
port: protocols.enableSsh
|
||||
? Number(form.sshPort)
|
||||
: protocols.enableRdp
|
||||
? Number(form.rdpPort)
|
||||
: protocols.enableVnc
|
||||
? Number(form.vncPort)
|
||||
: Number(form.telnetPort),
|
||||
port: primaryProtocol
|
||||
? protocolPort(form.pluginSettings, primaryProtocol)
|
||||
: Number(form.sshPort),
|
||||
username: form.username,
|
||||
folder: form.folder,
|
||||
parentHostId: form.parentHostId ? Number(form.parentHostId) : null,
|
||||
@@ -531,13 +484,7 @@ export function buildHostEditorPayload(
|
||||
form.socks5ProxyMode === "chain" ? form.socks5ProxyChain : null,
|
||||
connectionOrigin: form.connectionOrigin,
|
||||
enableSsh: protocols.enableSsh,
|
||||
enableRdp: protocols.enableRdp,
|
||||
enableVnc: protocols.enableVnc,
|
||||
enableTelnet: protocols.enableTelnet,
|
||||
sshPort: Number(form.sshPort),
|
||||
rdpPort: Number(form.rdpPort),
|
||||
vncPort: Number(form.vncPort),
|
||||
telnetPort: Number(form.telnetPort),
|
||||
forceKeyboardInteractive: form.forceKeyboardInteractive,
|
||||
rdpAuthType: protocols.enableRdp ? form.rdpAuthType : null,
|
||||
rdpCredentialId:
|
||||
@@ -557,8 +504,6 @@ export function buildHostEditorPayload(
|
||||
? form.rdpPassword || null
|
||||
: null,
|
||||
rdpDomain: form.domain || null,
|
||||
rdpSecurity: form.security || null,
|
||||
rdpIgnoreCert: form.ignoreCert,
|
||||
vncAuthType: protocols.enableVnc ? form.vncAuthType : null,
|
||||
vncCredentialId:
|
||||
protocols.enableVnc &&
|
||||
@@ -602,11 +547,6 @@ export function buildHostEditorPayload(
|
||||
snippetId: Number(a.snippetId),
|
||||
})),
|
||||
statsConfig: form.statsConfig,
|
||||
guacamoleConfig:
|
||||
(protocols.enableRdp || protocols.enableVnc || protocols.enableTelnet) &&
|
||||
Object.keys(guacamoleConfig).length > 0
|
||||
? guacamoleConfig
|
||||
: null,
|
||||
terminalConfig: protocols.enableSsh ? terminalOverrides : null,
|
||||
};
|
||||
}
|
||||
@@ -9,8 +9,6 @@ import type { Host } from "@/types/ui-types";
|
||||
import {
|
||||
Globe,
|
||||
LayoutGrid,
|
||||
Monitor,
|
||||
MousePointerClick,
|
||||
Plus,
|
||||
Tag,
|
||||
Terminal,
|
||||
@@ -23,6 +21,7 @@ import { getSSHFolders, isElectron } from "@/main-axios";
|
||||
import { connectionOriginAppliesTo } from "./HostEditorData";
|
||||
import type { HostEditorForm, HostProtocols } from "./HostEditorData";
|
||||
import { Select2 } from "@/components/select2";
|
||||
import { useHostProtocols } from "./host-protocols";
|
||||
|
||||
type HostEditorSetField = <K extends keyof HostEditorForm>(
|
||||
key: K,
|
||||
@@ -48,6 +47,7 @@ export function HostEditorGeneralTab({
|
||||
simpleMode?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const pluginProtocols = useHostProtocols();
|
||||
|
||||
// Tracks which picker is shown, independent of whether a value is set yet
|
||||
// -- switching to "parent host" mode with nothing picked shouldn't bounce
|
||||
@@ -116,35 +116,22 @@ export function HostEditorGeneralTab({
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 py-3">
|
||||
{[
|
||||
{
|
||||
proto: "enableSsh" as const,
|
||||
proto: "enableSsh",
|
||||
label: t("hosts.tabSsh"),
|
||||
desc: t("hosts.secureShell"),
|
||||
icon: <Terminal className="size-4" />,
|
||||
portField: "sshPort" as const,
|
||||
},
|
||||
{
|
||||
proto: "enableRdp" as const,
|
||||
label: t("hosts.tabRdp"),
|
||||
desc: t("hosts.remoteDesktop"),
|
||||
icon: <Monitor className="size-4" />,
|
||||
portField: "rdpPort" as const,
|
||||
},
|
||||
{
|
||||
proto: "enableVnc" as const,
|
||||
label: t("hosts.tabVnc"),
|
||||
desc: t("hosts.virtualNetwork"),
|
||||
icon: <MousePointerClick className="size-4" />,
|
||||
portField: "vncPort" as const,
|
||||
},
|
||||
{
|
||||
proto: "enableTelnet" as const,
|
||||
label: t("hosts.tabTelnet"),
|
||||
desc: t("hosts.unencryptedShell"),
|
||||
icon: <Terminal className="size-4" />,
|
||||
portField: "telnetPort" as const,
|
||||
},
|
||||
...pluginProtocols.map((protocol) => {
|
||||
const Icon = protocol.icon;
|
||||
return {
|
||||
proto: protocol.settingKey,
|
||||
label: t(protocol.titleKey),
|
||||
desc: protocol.descriptionKey ? t(protocol.descriptionKey) : "",
|
||||
icon: <Icon className="size-4" />,
|
||||
};
|
||||
}),
|
||||
].map(({ proto, label, desc, icon }) => {
|
||||
const enabled = protocols[proto];
|
||||
const enabled = !!protocols[proto];
|
||||
return (
|
||||
<div
|
||||
key={proto}
|
||||
@@ -245,15 +232,12 @@ export function HostEditorGeneralTab({
|
||||
</div>
|
||||
</SectionCard>
|
||||
|
||||
{!protocols.enableSsh &&
|
||||
!protocols.enableRdp &&
|
||||
!protocols.enableVnc &&
|
||||
!protocols.enableTelnet && (
|
||||
<div className="flex items-center gap-3 p-3 border border-border bg-muted/20 text-xs text-muted-foreground">
|
||||
<Globe className="size-4 shrink-0 text-muted-foreground/40" />
|
||||
<span>{t("hosts.enableAtLeastOneProtocol")}</span>
|
||||
</div>
|
||||
)}
|
||||
{!Object.values(protocols).some(Boolean) && (
|
||||
<div className="flex items-center gap-3 p-3 border border-border bg-muted/20 text-xs text-muted-foreground">
|
||||
<Globe className="size-4 shrink-0 text-muted-foreground/40" />
|
||||
<span>{t("hosts.enableAtLeastOneProtocol")}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<SectionCard
|
||||
title={t("hosts.folderAndAdvanced")}
|
||||
@@ -769,13 +753,7 @@ export function HostEditorGeneralTab({
|
||||
{isElectron() && connectionOriginAppliesTo(protocols) && (
|
||||
<SettingRow
|
||||
label={t("hosts.connectionOrigin")}
|
||||
description={
|
||||
protocols.enableRdp ||
|
||||
protocols.enableVnc ||
|
||||
protocols.enableTelnet
|
||||
? `${t("hosts.connectionOriginDesc")} ${t("hosts.connectionOriginRemoteDesktopNote")}`
|
||||
: t("hosts.connectionOriginDesc")
|
||||
}
|
||||
description={t("hosts.connectionOriginDesc")}
|
||||
>
|
||||
<select
|
||||
className="flex h-7 border border-border bg-background px-2 py-0 text-xs outline-none focus:ring-1 focus:ring-ring"
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
enabledHostProtocols,
|
||||
hostProtocolFlags,
|
||||
type HostProtocols,
|
||||
} from "./host-protocols";
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
@@ -102,12 +107,9 @@ export function HostManager({
|
||||
} | null>(null);
|
||||
const [hostEditorDirty, setHostEditorDirty] = useState(false);
|
||||
const [showUnsavedHostDialog, setShowUnsavedHostDialog] = useState(false);
|
||||
const [editingProtocols, setEditingProtocols] = useState({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
const [editingProtocols, setEditingProtocols] = useState<HostProtocols>(() =>
|
||||
hostProtocolFlags(null),
|
||||
);
|
||||
const simpleEditor = useUiPreference("hostEditor", "mode") === "simple";
|
||||
// Expanding advanced is a per-session choice; fixing one host's SSH options
|
||||
// shouldn't quietly move the whole app off the Simple preset.
|
||||
@@ -142,12 +144,7 @@ export function HostManager({
|
||||
setEditingHost(host);
|
||||
setEditingCredential(null);
|
||||
setActiveHostTab("general");
|
||||
setEditingProtocols({
|
||||
enableSsh: host.enableSsh,
|
||||
enableRdp: host.enableRdp,
|
||||
enableVnc: host.enableVnc,
|
||||
enableTelnet: host.enableTelnet,
|
||||
});
|
||||
setEditingProtocols(hostProtocolFlags(host));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -204,12 +201,7 @@ export function HostManager({
|
||||
if (action === "add-host") {
|
||||
setEditingHost("new");
|
||||
setEditingCredential(null);
|
||||
setEditingProtocols({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
setEditingProtocols(hostProtocolFlags(null));
|
||||
setActiveHostTab("general");
|
||||
} else if (action === "add-credential") {
|
||||
setEditingCredential("new");
|
||||
@@ -224,12 +216,7 @@ export function HostManager({
|
||||
const handleAddHost = () => {
|
||||
setEditingHost("new");
|
||||
setEditingCredential(null);
|
||||
setEditingProtocols({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
setEditingProtocols(hostProtocolFlags(null));
|
||||
setActiveHostTab("general");
|
||||
};
|
||||
const handleAddCredential = () => {
|
||||
@@ -244,12 +231,7 @@ export function HostManager({
|
||||
setEditingHost(host);
|
||||
setEditingCredential(null);
|
||||
setActiveHostTab("general");
|
||||
setEditingProtocols({
|
||||
enableSsh: host.enableSsh,
|
||||
enableRdp: host.enableRdp,
|
||||
enableVnc: host.enableVnc,
|
||||
enableTelnet: host.enableTelnet,
|
||||
});
|
||||
setEditingProtocols(hostProtocolFlags(host));
|
||||
}
|
||||
};
|
||||
window.addEventListener("host-manager:add-host", handleAddHost);
|
||||
@@ -848,9 +830,7 @@ export function HostManager({
|
||||
<option value="">{t("credentials.selectHostOption")}</option>
|
||||
{allHosts
|
||||
.filter(
|
||||
(h) =>
|
||||
h.enableSsh ||
|
||||
(!h.enableRdp && !h.enableVnc && !h.enableTelnet),
|
||||
(h) => h.enableSsh || enabledHostProtocols(h).length === 0,
|
||||
)
|
||||
.map((h) => (
|
||||
<option key={h.id} value={h.id}>
|
||||
|
||||
@@ -109,16 +109,9 @@ export function sshHostToHost(h: SSHHostWithStatus): Host {
|
||||
proxmoxStatsConfig:
|
||||
(proxmoxSettings.proxmoxStatsConfig as Host["proxmoxStatsConfig"]) ??
|
||||
null,
|
||||
enableRdp: h.enableRdp != null ? h.enableRdp : h.connectionType === "rdp",
|
||||
enableVnc: h.enableVnc != null ? h.enableVnc : h.connectionType === "vnc",
|
||||
enableTelnet:
|
||||
h.enableTelnet != null ? h.enableTelnet : h.connectionType === "telnet",
|
||||
sshPort:
|
||||
h.sshPort ??
|
||||
(h.connectionType === "ssh" || !h.connectionType ? h.port : 22),
|
||||
rdpPort: h.rdpPort ?? (h.connectionType === "rdp" ? h.port : 3389),
|
||||
vncPort: h.vncPort ?? (h.connectionType === "vnc" ? h.port : 5900),
|
||||
telnetPort: h.telnetPort ?? (h.connectionType === "telnet" ? h.port : 23),
|
||||
rdpAuthType:
|
||||
(h.rdpAuthType as "direct" | "credential") ??
|
||||
(h.rdpCredentialId ? "credential" : "direct"),
|
||||
@@ -128,8 +121,6 @@ export function sshHostToHost(h: SSHHostWithStatus): Host {
|
||||
rdpPassword: h.rdpPassword ?? "",
|
||||
hasRdpPassword: !!host.hasRdpPassword || !!h.rdpPassword,
|
||||
domain: h.rdpDomain,
|
||||
security: h.rdpSecurity,
|
||||
ignoreCert: h.rdpIgnoreCert ?? false,
|
||||
vncAuthType:
|
||||
(h.vncAuthType as "direct" | "credential") ??
|
||||
(h.vncCredentialId ? "credential" : "direct"),
|
||||
@@ -160,7 +151,6 @@ export function sshHostToHost(h: SSHHostWithStatus): Host {
|
||||
hasSudoPassword:
|
||||
!!host.hasSudoPassword || !!parsedTerminalConfig?.sudoPassword,
|
||||
statsConfig: parseJson(h.statsConfig) as Host["statsConfig"],
|
||||
guacamoleConfig: parseJson(h.guacamoleConfig),
|
||||
forceKeyboardInteractive: h.forceKeyboardInteractive ?? false,
|
||||
useSocks5: h.useSocks5,
|
||||
socks5Host: h.socks5Host,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getErrorMessage } from "../lib/error-message.js";
|
||||
import { enabledHostProtocols, useHostProtocols } from "./host-protocols";
|
||||
import { useSshAuthProviders } from "@/hooks/useSshAuthProviders";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import type { HostData } from "@/types/index";
|
||||
@@ -87,9 +88,9 @@ function hostGroupNames(host: Host, key: GroupKey): string[] {
|
||||
case "protocol": {
|
||||
const protos: string[] = [];
|
||||
if (host.enableSsh) protos.push("ssh");
|
||||
if (host.enableRdp) protos.push("rdp");
|
||||
if (host.enableVnc) protos.push("vnc");
|
||||
if (host.enableTelnet) protos.push("telnet");
|
||||
for (const protocol of enabledHostProtocols(host)) {
|
||||
protos.push(protocol.id);
|
||||
}
|
||||
return protos.length > 0 ? protos : ["__none__"];
|
||||
}
|
||||
case "auth":
|
||||
@@ -144,9 +145,9 @@ function hostPassesFilters(host: Host, filters: FilterState): boolean {
|
||||
if (filters.protocol.length > 0) {
|
||||
const ok =
|
||||
(filters.protocol.includes("ssh") && host.enableSsh) ||
|
||||
(filters.protocol.includes("rdp") && host.enableRdp) ||
|
||||
(filters.protocol.includes("vnc") && host.enableVnc) ||
|
||||
(filters.protocol.includes("telnet") && host.enableTelnet);
|
||||
enabledHostProtocols(host).some((protocol) =>
|
||||
filters.protocol.includes(protocol.id),
|
||||
);
|
||||
if (!ok) return false;
|
||||
}
|
||||
if (filters.features.length > 0) {
|
||||
@@ -203,6 +204,7 @@ export function HostsPanel({
|
||||
active?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const hostProtocols = useHostProtocols();
|
||||
const sshAuthProviders = useSshAuthProviders();
|
||||
const [hostSearch, setHostSearch] = useState("");
|
||||
const [managerEditing, setManagerEditing] = useState(false);
|
||||
@@ -349,9 +351,6 @@ export function HostsPanel({
|
||||
pin: true,
|
||||
notes: "Main production web server running Nginx",
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: 22,
|
||||
enableTerminal: true,
|
||||
enableTunnel: false,
|
||||
@@ -370,9 +369,6 @@ export function HostsPanel({
|
||||
folder: "Production",
|
||||
tags: ["database", "production", "postgresql"],
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: 22,
|
||||
enableTerminal: true,
|
||||
enableTunnel: true,
|
||||
@@ -449,10 +445,6 @@ export function HostsPanel({
|
||||
...h,
|
||||
port: h.port ?? h.sshPort ?? 22,
|
||||
enableSsh: h.enableSsh ?? h.connectionType === "ssh",
|
||||
enableRdp: h.enableRdp ?? h.connectionType === "rdp",
|
||||
enableVnc: h.enableVnc ?? h.connectionType === "vnc",
|
||||
enableTelnet:
|
||||
h.enableTelnet ?? h.connectionType === "telnet",
|
||||
}),
|
||||
);
|
||||
const result = await bulkImportSSHHosts(
|
||||
@@ -768,23 +760,20 @@ export function HostsPanel({
|
||||
<DropdownMenuLabel>
|
||||
{t("hosts.filterProtocolGroup")}
|
||||
</DropdownMenuLabel>
|
||||
{(
|
||||
[
|
||||
["ssh", "Ssh"],
|
||||
["rdp", "Rdp"],
|
||||
["vnc", "Vnc"],
|
||||
["telnet", "Telnet"],
|
||||
] as const
|
||||
).map(([val, key]) => (
|
||||
{[
|
||||
{ id: "ssh", label: t("hosts.filterProtocolSsh") },
|
||||
...hostProtocols.map((protocol) => ({
|
||||
id: protocol.id,
|
||||
label: t(protocol.titleKey),
|
||||
})),
|
||||
].map(({ id, label }) => (
|
||||
<DropdownMenuCheckboxItem
|
||||
key={val}
|
||||
checked={filterState.protocol.includes(val)}
|
||||
onCheckedChange={() =>
|
||||
handleFilterToggle("protocol", val)
|
||||
}
|
||||
key={id}
|
||||
checked={filterState.protocol.includes(id)}
|
||||
onCheckedChange={() => handleFilterToggle("protocol", id)}
|
||||
onSelect={(e) => e.preventDefault()}
|
||||
>
|
||||
{t(`hosts.filterProtocol${key}`)}
|
||||
{label}
|
||||
</DropdownMenuCheckboxItem>
|
||||
))}
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Eye,
|
||||
EyeOff,
|
||||
FolderSearch,
|
||||
Monitor,
|
||||
MousePointerClick,
|
||||
Terminal,
|
||||
} from "lucide-react";
|
||||
import { Eye, EyeOff, FolderSearch, Terminal } from "lucide-react";
|
||||
import { Input } from "@/components/input";
|
||||
import type { Host } from "@/types/ui-types";
|
||||
import { getCredentials } from "@/api/credentials-api";
|
||||
import { mapCredentials } from "./HostManagerData";
|
||||
import {
|
||||
createQuickConnectHost,
|
||||
type QuickConnectProtocol,
|
||||
} from "./quick-connect-host";
|
||||
|
||||
const DEFAULT_PORTS: Record<QuickConnectProtocol, string> = {
|
||||
ssh: "22",
|
||||
rdp: "3389",
|
||||
vnc: "5900",
|
||||
};
|
||||
import { createQuickConnectHost } from "./quick-connect-host";
|
||||
import { useHostProtocols } from "./host-protocols";
|
||||
import { Select2 } from "@/components/select2";
|
||||
import { resolveHostTabType } from "@/lib/host-connection-tabs";
|
||||
|
||||
@@ -32,7 +17,8 @@ interface QuickConnectPanelProps {
|
||||
export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
const { t } = useTranslation();
|
||||
const [host, setHost] = useState("");
|
||||
const [protocol, setProtocol] = useState<QuickConnectProtocol>("ssh");
|
||||
// "ssh", or the id of a plugin protocol offered in Quick Connect.
|
||||
const [protocol, setProtocol] = useState("ssh");
|
||||
const [port, setPort] = useState("22");
|
||||
const [domain, setDomain] = useState("");
|
||||
const [username, setUsername] = useState("root");
|
||||
@@ -53,11 +39,17 @@ export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
.catch(() => {});
|
||||
}, []);
|
||||
|
||||
const isDesktop = protocol !== "ssh";
|
||||
const pluginProtocols = useHostProtocols().filter(
|
||||
(entry) => entry.quickConnect,
|
||||
);
|
||||
const selected = pluginProtocols.find((entry) => entry.id === protocol);
|
||||
const isDesktop = !!selected;
|
||||
const defaultPort = (id: string) =>
|
||||
String(pluginProtocols.find((entry) => entry.id === id)?.defaultPort ?? 22);
|
||||
|
||||
const switchProtocol = (next: QuickConnectProtocol) => {
|
||||
const switchProtocol = (next: string) => {
|
||||
// Keep a port the user typed; only swap the protocol default.
|
||||
if (port === DEFAULT_PORTS[protocol]) setPort(DEFAULT_PORTS[next]);
|
||||
if (port === defaultPort(protocol)) setPort(defaultPort(next));
|
||||
setProtocol(next);
|
||||
};
|
||||
|
||||
@@ -67,13 +59,13 @@ export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
if (!isDesktop && !username) return;
|
||||
const hostConfig = createQuickConnectHost({
|
||||
ip: host,
|
||||
port: parseInt(port) || parseInt(DEFAULT_PORTS[protocol]),
|
||||
port: parseInt(port) || parseInt(defaultPort(protocol)),
|
||||
username,
|
||||
authType: isDesktop ? "password" : authType,
|
||||
password,
|
||||
key: privateKey,
|
||||
credentialId,
|
||||
protocol,
|
||||
protocol: selected,
|
||||
domain: domain || undefined,
|
||||
});
|
||||
const target = type ?? resolveHostTabType(hostConfig);
|
||||
@@ -90,19 +82,21 @@ export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
{t("newUi.sidebar.quickConnect.protocolLabel")}
|
||||
</label>
|
||||
<div className="flex gap-1">
|
||||
{(["ssh", "rdp", "vnc"] as const).map((type) => (
|
||||
<button
|
||||
key={type}
|
||||
onClick={() => switchProtocol(type)}
|
||||
className={`flex-1 py-1 text-[10px] font-semibold border transition-colors uppercase ${
|
||||
protocol === type
|
||||
? "border-accent-brand/40 bg-accent-brand/10 text-accent-brand"
|
||||
: "border-border text-muted-foreground hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
{type}
|
||||
</button>
|
||||
))}
|
||||
{["ssh", ...pluginProtocols.map((entry) => entry.id)].map(
|
||||
(type) => (
|
||||
<button
|
||||
key={type}
|
||||
onClick={() => switchProtocol(type)}
|
||||
className={`flex-1 py-1 text-[10px] font-semibold border transition-colors uppercase ${
|
||||
protocol === type
|
||||
? "border-accent-brand/40 bg-accent-brand/10 text-accent-brand"
|
||||
: "border-border text-muted-foreground hover:text-foreground"
|
||||
}`}
|
||||
>
|
||||
{type}
|
||||
</button>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
@@ -206,7 +200,7 @@ export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isDesktop && protocol === "rdp" && (
|
||||
{selected?.quickConnect?.showDomain && (
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-[10px] font-semibold uppercase tracking-widest text-muted-foreground">
|
||||
{t("newUi.sidebar.quickConnect.domainLabel")}
|
||||
@@ -264,21 +258,15 @@ export function QuickConnectPanel({ onConnect }: QuickConnectPanelProps) {
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-1.5 pt-1">
|
||||
{isDesktop ? (
|
||||
{selected ? (
|
||||
<button
|
||||
onClick={() => connect(protocol)}
|
||||
onClick={() => connect()}
|
||||
className="flex items-center justify-center gap-1.5 h-7 w-full border border-accent-brand/40 bg-accent-brand/10 text-accent-brand text-xs font-semibold hover:bg-accent-brand/20 transition-colors"
|
||||
>
|
||||
{protocol === "rdp" ? (
|
||||
<Monitor className="size-3.5" />
|
||||
) : (
|
||||
<MousePointerClick className="size-3.5" />
|
||||
)}
|
||||
{t(
|
||||
protocol === "rdp"
|
||||
? "newUi.sidebar.quickConnect.connectToRdp"
|
||||
: "newUi.sidebar.quickConnect.connectToVnc",
|
||||
)}
|
||||
<selected.icon className="size-3.5" />
|
||||
{t("newUi.sidebar.quickConnect.connectWith", {
|
||||
protocol: t(selected.titleKey),
|
||||
})}
|
||||
</button>
|
||||
) : (
|
||||
<>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Host, SharePermissionLevel } from "@/types/ui-types";
|
||||
import {
|
||||
AUTH_PROTOCOL_METADATA,
|
||||
isSupportedAuthOverrideProtocol,
|
||||
type AuthOverrideProtocol,
|
||||
} from "@/types/auth-protocols";
|
||||
import { listHostProtocols, protocolEnabled } from "./host-protocols";
|
||||
|
||||
const LEVEL_RANK: Record<SharePermissionLevel, number> = {
|
||||
connect: 1,
|
||||
@@ -36,10 +36,11 @@ export function canOverrideHostAuth(
|
||||
host: Host,
|
||||
protocol: AuthOverrideProtocol,
|
||||
): boolean {
|
||||
const enableField = AUTH_PROTOCOL_METADATA[protocol].enableField;
|
||||
return (
|
||||
!!host.isShared &&
|
||||
isSupportedAuthOverrideProtocol(protocol) &&
|
||||
!!host[enableField]
|
||||
);
|
||||
if (!host.isShared || !isSupportedAuthOverrideProtocol(protocol)) {
|
||||
return false;
|
||||
}
|
||||
if (protocol === "ssh") return !!host.enableSsh;
|
||||
// Other protocols are switched on in their plugin's host settings.
|
||||
const plugin = listHostProtocols().find((entry) => entry.id === protocol);
|
||||
return !!plugin && protocolEnabled(host.pluginSettings, plugin);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import type { ComponentType } from "react";
|
||||
import { byOrderThenId, createRegistry } from "@/lib/registry";
|
||||
|
||||
type Icon = ComponentType<{ className?: string; size?: number | string }>;
|
||||
|
||||
/**
|
||||
* A connection protocol a plugin adds next to SSH (RDP, VNC). Its on/off
|
||||
* switch and port are the plugin's own host settings, so core reads them
|
||||
* from host.pluginSettings[pluginId] and never knows the protocol by name.
|
||||
*/
|
||||
export interface HostProtocolDef {
|
||||
id: string;
|
||||
pluginId: string;
|
||||
/** The plugin's boolean host setting that switches the protocol on. */
|
||||
settingKey: string;
|
||||
/** The plugin's number host setting holding the port, if it has one. */
|
||||
portKey?: string;
|
||||
defaultPort: number;
|
||||
titleKey: string;
|
||||
descriptionKey?: string;
|
||||
icon: Icon;
|
||||
order?: number;
|
||||
/** Offer it in Quick Connect, optionally with a domain field. */
|
||||
quickConnect?: { showDomain?: boolean };
|
||||
}
|
||||
|
||||
const protocols = createRegistry<HostProtocolDef>(byOrderThenId);
|
||||
|
||||
export const registerHostProtocol = protocols.register;
|
||||
export const useHostProtocols = protocols.useList;
|
||||
export const listHostProtocols = protocols.list;
|
||||
|
||||
/** Which protocols are on, keyed by setting key, with SSH as enableSsh. */
|
||||
export type HostProtocols = { enableSsh: boolean } & Record<string, boolean>;
|
||||
|
||||
type PluginSettingsBag = Record<string, Record<string, unknown>> | undefined;
|
||||
|
||||
function settingsOf(
|
||||
pluginSettings: PluginSettingsBag,
|
||||
protocol: HostProtocolDef,
|
||||
): Record<string, unknown> {
|
||||
return pluginSettings?.[protocol.pluginId] ?? {};
|
||||
}
|
||||
|
||||
export function protocolEnabled(
|
||||
pluginSettings: PluginSettingsBag,
|
||||
protocol: HostProtocolDef,
|
||||
): boolean {
|
||||
return settingsOf(pluginSettings, protocol)[protocol.settingKey] === true;
|
||||
}
|
||||
|
||||
export function protocolPort(
|
||||
pluginSettings: PluginSettingsBag,
|
||||
protocol: HostProtocolDef,
|
||||
): number {
|
||||
const raw = protocol.portKey
|
||||
? Number(settingsOf(pluginSettings, protocol)[protocol.portKey])
|
||||
: NaN;
|
||||
return Number.isInteger(raw) && raw > 0 ? raw : protocol.defaultPort;
|
||||
}
|
||||
|
||||
export function hostProtocolFlags(
|
||||
host: { enableSsh?: boolean; pluginSettings?: PluginSettingsBag } | null,
|
||||
list: HostProtocolDef[] = listHostProtocols(),
|
||||
): HostProtocols {
|
||||
const flags: HostProtocols = {
|
||||
enableSsh: host ? host.enableSsh !== false : true,
|
||||
};
|
||||
for (const protocol of list) {
|
||||
flags[protocol.settingKey] = host
|
||||
? protocolEnabled(host.pluginSettings, protocol)
|
||||
: false;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/** The protocols a host has switched on, in registration order. */
|
||||
export function enabledHostProtocols(
|
||||
host: { pluginSettings?: PluginSettingsBag },
|
||||
list: HostProtocolDef[] = listHostProtocols(),
|
||||
): HostProtocolDef[] {
|
||||
return list.filter((protocol) =>
|
||||
protocolEnabled(host.pluginSettings, protocol),
|
||||
);
|
||||
}
|
||||
|
||||
/** Writes the editor's protocol switches into each owner's host settings. */
|
||||
export function withProtocolSettings(
|
||||
pluginSettings: Record<string, Record<string, unknown>>,
|
||||
flags: HostProtocols,
|
||||
list: HostProtocolDef[] = listHostProtocols(),
|
||||
): Record<string, Record<string, unknown>> {
|
||||
const next = { ...pluginSettings };
|
||||
for (const protocol of list) {
|
||||
if (!(protocol.settingKey in flags)) continue;
|
||||
next[protocol.pluginId] = {
|
||||
...(next[protocol.pluginId] ?? {}),
|
||||
[protocol.settingKey]: flags[protocol.settingKey] === true,
|
||||
};
|
||||
}
|
||||
return next;
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
import type { SSHHostData } from "@/types";
|
||||
import type { Host } from "@/types/ui-types";
|
||||
|
||||
export type QuickConnectProtocol = "ssh" | "rdp" | "vnc";
|
||||
import type { HostProtocolDef } from "./host-protocols";
|
||||
|
||||
type QuickConnectInput = Pick<
|
||||
Host,
|
||||
"ip" | "port" | "username" | "authType" | "password" | "key" | "credentialId"
|
||||
> & { protocol?: QuickConnectProtocol; domain?: string };
|
||||
> & {
|
||||
/** A plugin protocol; SSH when omitted. */
|
||||
protocol?: HostProtocolDef;
|
||||
domain?: string;
|
||||
};
|
||||
|
||||
export const QUICK_CONNECT_ID_PREFIX = "quick-connect-";
|
||||
|
||||
@@ -15,10 +18,17 @@ export function isQuickConnectHost(host: Pick<Host, "id">): boolean {
|
||||
}
|
||||
|
||||
export function createQuickConnectHost(input: QuickConnectInput): Host {
|
||||
const protocol = input.protocol ?? "ssh";
|
||||
if (protocol !== "ssh") {
|
||||
const protocol = input.protocol;
|
||||
if (protocol) {
|
||||
// Protocol logins are core host fields named after the protocol.
|
||||
const login = {
|
||||
[`${protocol.id}AuthType`]: "direct",
|
||||
[`${protocol.id}User`]: input.username,
|
||||
[`${protocol.id}Password`]: input.password,
|
||||
};
|
||||
return {
|
||||
...createQuickConnectHost({ ...input, protocol: "ssh", port: 22 }),
|
||||
...createQuickConnectHost({ ...input, protocol: undefined, port: 22 }),
|
||||
...login,
|
||||
port: input.port,
|
||||
enableTerminal: false,
|
||||
enableCommandHistory: false,
|
||||
@@ -28,16 +38,13 @@ export function createQuickConnectHost(input: QuickConnectInput): Host {
|
||||
enableTerminalToolbar: false,
|
||||
enableAiAssistant: false,
|
||||
enableSsh: false,
|
||||
enableRdp: protocol === "rdp",
|
||||
enableVnc: protocol === "vnc",
|
||||
rdpPort: protocol === "rdp" ? input.port : 3389,
|
||||
vncPort: protocol === "vnc" ? input.port : 5900,
|
||||
rdpAuthType: "direct",
|
||||
rdpUser: protocol === "rdp" ? input.username : undefined,
|
||||
rdpPassword: protocol === "rdp" ? input.password : undefined,
|
||||
domain: protocol === "rdp" ? input.domain : undefined,
|
||||
vncUser: protocol === "vnc" ? input.username : undefined,
|
||||
vncPassword: protocol === "vnc" ? input.password : undefined,
|
||||
domain: input.domain,
|
||||
pluginSettings: {
|
||||
[protocol.pluginId]: {
|
||||
[protocol.settingKey]: true,
|
||||
...(protocol.portKey ? { [protocol.portKey]: input.port } : {}),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -71,13 +78,7 @@ export function createQuickConnectHost(input: QuickConnectInput): Host {
|
||||
enableTerminalToolbar: true,
|
||||
enableAiAssistant: false,
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: input.port,
|
||||
rdpPort: 3389,
|
||||
vncPort: 5900,
|
||||
telnetPort: 23,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,12 +114,6 @@ export function quickConnectHostToPayload(host: Host): SSHHostData {
|
||||
showServerStatsInSidebar: true,
|
||||
connectionType: "ssh",
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: host.sshPort,
|
||||
rdpPort: host.rdpPort,
|
||||
vncPort: host.vncPort,
|
||||
telnetPort: host.telnetPort,
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { registerHostProtocol } from "@/sidebar/host-protocols";
|
||||
import type { Host } from "@/types/ui-types";
|
||||
import {
|
||||
buildStatusTooltip,
|
||||
@@ -69,25 +70,27 @@ describe("buildStatusTooltip", () => {
|
||||
});
|
||||
|
||||
it("includes protocol names in the tooltip when protocols are enabled", () => {
|
||||
const dispose = registerHostProtocol({
|
||||
id: "demo-desktop",
|
||||
pluginId: "demo",
|
||||
settingKey: "enableDemo",
|
||||
defaultPort: 3389,
|
||||
titleKey: "Demo Desktop",
|
||||
icon: () => null,
|
||||
});
|
||||
const host = makeHost({
|
||||
enableSsh: true,
|
||||
enableRdp: true,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
pluginSettings: { demo: { enableDemo: true } },
|
||||
});
|
||||
const tooltip = buildStatusTooltip(host, "online", t);
|
||||
dispose();
|
||||
expect(tooltip).toContain("SSH");
|
||||
expect(tooltip).toContain("RDP");
|
||||
expect(tooltip).toContain("Demo Desktop");
|
||||
expect(tooltip).toContain("Available");
|
||||
});
|
||||
|
||||
it("returns just the status label when no protocols are enabled", () => {
|
||||
const host = makeHost({
|
||||
enableSsh: false,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
});
|
||||
const host = makeHost({ enableSsh: false });
|
||||
const tooltip = buildStatusTooltip(host, "online", t);
|
||||
expect(tooltip).toBe("Available");
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* eslint-disable react-refresh/only-export-components */
|
||||
import { enabledHostProtocols } from "@/sidebar/host-protocols";
|
||||
import { useEffect, useRef, useState, type MouseEvent } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -105,9 +106,9 @@ export function buildStatusTooltip(
|
||||
if (!statusCheckEnabled(host)) return t("hosts.status.monitoringDisabled");
|
||||
const protocols: string[] = [];
|
||||
if (host.enableSsh) protocols.push("SSH");
|
||||
if (host.enableRdp) protocols.push("RDP");
|
||||
if (host.enableVnc) protocols.push("VNC");
|
||||
if (host.enableTelnet) protocols.push("Telnet");
|
||||
for (const protocol of enabledHostProtocols(host)) {
|
||||
protocols.push(t(protocol.titleKey));
|
||||
}
|
||||
if (protocols.length === 0) return statusLabel;
|
||||
return `${protocols.join(", ")}: ${statusLabel}`;
|
||||
}
|
||||
@@ -958,11 +959,7 @@ export function HostItem({
|
||||
// reachable. If the host only exposes a single action, just launch it.
|
||||
if (isTouchOnly) {
|
||||
e.stopPropagation();
|
||||
const otherProtocols = [
|
||||
host.enableRdp,
|
||||
host.enableVnc,
|
||||
host.enableTelnet,
|
||||
].filter(Boolean).length;
|
||||
const otherProtocols = enabledHostProtocols(host).length;
|
||||
if (otherProtocols <= 1) {
|
||||
openHostTab(defaultAction);
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
useLayoutEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import { updatePluginHostSettings } from "@/api/plugins-api";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useVirtualizer } from "@tanstack/react-virtual";
|
||||
import { useAreaPreferences } from "@/contexts/UiPreferencesContext";
|
||||
@@ -608,22 +609,14 @@ export function SidebarTree({
|
||||
credentialId: host.credentialId ? Number(host.credentialId) : null,
|
||||
overrideCredentialUsername: host.overrideCredentialUsername ?? false,
|
||||
enableSsh: host.enableSsh,
|
||||
enableRdp: host.enableRdp,
|
||||
enableVnc: host.enableVnc,
|
||||
enableTelnet: host.enableTelnet,
|
||||
enableTerminal: host.enableTerminal,
|
||||
enableTunnel: host.enableTunnel,
|
||||
enableFileManager: host.enableFileManager,
|
||||
enableDocker: host.enableDocker,
|
||||
sshPort: host.sshPort,
|
||||
rdpPort: host.rdpPort,
|
||||
vncPort: host.vncPort,
|
||||
telnetPort: host.telnetPort,
|
||||
rdpUser: host.rdpUser ?? null,
|
||||
rdpPassword: host.rdpPassword ?? null,
|
||||
rdpDomain: host.domain ?? null,
|
||||
rdpSecurity: host.security ?? null,
|
||||
rdpIgnoreCert: host.ignoreCert ?? false,
|
||||
vncAuthType: host.vncAuthType ?? null,
|
||||
vncCredentialId: host.vncCredentialId
|
||||
? Number(host.vncCredentialId)
|
||||
@@ -650,10 +643,21 @@ export function SidebarTree({
|
||||
snippetId: Number(a.snippetId),
|
||||
})),
|
||||
statsConfig: host.statsConfig,
|
||||
guacamoleConfig: host.guacamoleConfig ?? null,
|
||||
terminalConfig: host.terminalConfig ?? null,
|
||||
};
|
||||
await createSSHHost(duplicateHost);
|
||||
const created = await createSSHHost(duplicateHost);
|
||||
// Plugin host settings live outside the host row. Secrets come back
|
||||
// redacted, and sending the marker back is a no-op, so they stay unset.
|
||||
for (const [pluginId, fields] of Object.entries(
|
||||
host.pluginSettings ?? {},
|
||||
)) {
|
||||
if (!fields || Object.keys(fields).length === 0) continue;
|
||||
await updatePluginHostSettings(
|
||||
pluginId,
|
||||
Number(created.id),
|
||||
fields,
|
||||
).catch(() => {});
|
||||
}
|
||||
window.dispatchEvent(new CustomEvent("termix:hosts-changed"));
|
||||
toast.success(t("hosts.duplicatedHost", { name: host.name }));
|
||||
} catch {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
fromTriState,
|
||||
parseRemoteDesktopDefaults,
|
||||
parseTerminalDefaults,
|
||||
resolveConnectionDefaults,
|
||||
toTriState,
|
||||
@@ -10,7 +9,7 @@ import {
|
||||
describe("connection defaults", () => {
|
||||
it("ignores malformed persisted defaults", () => {
|
||||
expect(parseTerminalDefaults("not-json")).toEqual({});
|
||||
expect(parseRemoteDesktopDefaults("[]")).toEqual({});
|
||||
expect(parseTerminalDefaults("[]")).toEqual({});
|
||||
});
|
||||
|
||||
it("lets host values override user defaults", () => {
|
||||
|
||||
@@ -15,7 +15,7 @@ describe("resolveConnectionOrigin", () => {
|
||||
// Support#1240: these can now originate from the desktop, but only when a
|
||||
// host opts in. Left on Default they stay remote, so an upgrade never moves
|
||||
// an existing host onto a local guacd the user has not set up.
|
||||
it("resolves rdp/vnc/telnet to remote when the host has no override", async () => {
|
||||
it("resolves to remote with defaultRemote when the host has no override", async () => {
|
||||
win.IS_ELECTRON = true;
|
||||
win.electronAPI = {
|
||||
invoke: async (channel: string) =>
|
||||
@@ -23,44 +23,42 @@ describe("resolveConnectionOrigin", () => {
|
||||
? { defaultConnectionOrigin: "local" }
|
||||
: null,
|
||||
};
|
||||
for (const connectionType of ["rdp", "vnc", "telnet"]) {
|
||||
await expect(
|
||||
resolveConnectionOrigin({ connectionType, connectionOrigin: null }),
|
||||
).resolves.toBe("remote");
|
||||
}
|
||||
});
|
||||
|
||||
it("honors an explicit local override for rdp/vnc/telnet", async () => {
|
||||
win.IS_ELECTRON = true;
|
||||
for (const connectionType of ["rdp", "vnc", "telnet"]) {
|
||||
await expect(
|
||||
resolveConnectionOrigin({ connectionType, connectionOrigin: "local" }),
|
||||
).resolves.toBe("local");
|
||||
}
|
||||
});
|
||||
|
||||
it("honors an explicit remote override for rdp/vnc/telnet", async () => {
|
||||
win.IS_ELECTRON = true;
|
||||
for (const connectionType of ["rdp", "vnc", "telnet"]) {
|
||||
await expect(
|
||||
resolveConnectionOrigin({ connectionType, connectionOrigin: "remote" }),
|
||||
).resolves.toBe("remote");
|
||||
}
|
||||
});
|
||||
|
||||
it("resolves rdp to local outside Electron, where there is only one backend", async () => {
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "rdp",
|
||||
connectionOrigin: null,
|
||||
}),
|
||||
resolveConnectionOrigin(
|
||||
{ connectionOrigin: null },
|
||||
{ defaultRemote: true },
|
||||
),
|
||||
).resolves.toBe("remote");
|
||||
});
|
||||
|
||||
it("honors an explicit override over defaultRemote", async () => {
|
||||
win.IS_ELECTRON = true;
|
||||
await expect(
|
||||
resolveConnectionOrigin(
|
||||
{ connectionOrigin: "local" },
|
||||
{ defaultRemote: true },
|
||||
),
|
||||
).resolves.toBe("local");
|
||||
await expect(
|
||||
resolveConnectionOrigin(
|
||||
{ connectionOrigin: "remote" },
|
||||
{ defaultRemote: true },
|
||||
),
|
||||
).resolves.toBe("remote");
|
||||
});
|
||||
|
||||
it("resolves to local outside Electron even with defaultRemote", async () => {
|
||||
await expect(
|
||||
resolveConnectionOrigin(
|
||||
{ connectionOrigin: null },
|
||||
{ defaultRemote: true },
|
||||
),
|
||||
).resolves.toBe("local");
|
||||
});
|
||||
|
||||
it("resolves to local outside Electron regardless of connectionType", async () => {
|
||||
it("resolves to local outside Electron regardless of the host override", async () => {
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: "remote",
|
||||
}),
|
||||
).resolves.toBe("local");
|
||||
@@ -70,13 +68,11 @@ describe("resolveConnectionOrigin", () => {
|
||||
win.IS_ELECTRON = true;
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: "remote",
|
||||
}),
|
||||
).resolves.toBe("remote");
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: "local",
|
||||
}),
|
||||
).resolves.toBe("local");
|
||||
@@ -94,7 +90,6 @@ describe("resolveConnectionOrigin", () => {
|
||||
};
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: null,
|
||||
}),
|
||||
).resolves.toBe("remote");
|
||||
@@ -109,7 +104,6 @@ describe("resolveConnectionOrigin", () => {
|
||||
};
|
||||
await expect(
|
||||
resolveConnectionOrigin({
|
||||
connectionType: "ssh",
|
||||
connectionOrigin: null,
|
||||
}),
|
||||
).resolves.toBe("local");
|
||||
|
||||
@@ -61,6 +61,21 @@ describe("syncHostPluginsTab", () => {
|
||||
expect(getHostEditorSection(HOST_PLUGINS_TAB_ID)).toBeDefined();
|
||||
});
|
||||
|
||||
it("registers nothing for a plugin whose host fields are all hidden", () => {
|
||||
const own = plugin({
|
||||
contributes: {
|
||||
settings: {
|
||||
host: {
|
||||
fields: [
|
||||
{ key: "port", type: "number", labelKey: "p", hidden: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Partial<PluginSummary>);
|
||||
expect(syncHostPluginsTab([own])).toBe(false);
|
||||
});
|
||||
|
||||
it("registers nothing when no plugin contributes", () => {
|
||||
expect(syncHostPluginsTab([])).toBe(false);
|
||||
expect(getHostEditorSection(HOST_PLUGINS_TAB_ID)).toBeUndefined();
|
||||
@@ -101,6 +116,32 @@ describe("syncHostPluginsTab", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("HostPluginSections hidden fields", () => {
|
||||
it("does not draw a field the plugin edits itself", () => {
|
||||
const own = plugin({
|
||||
contributes: {
|
||||
settings: {
|
||||
host: {
|
||||
fields: [
|
||||
{ key: "shown", type: "string", labelKey: "shown.label" },
|
||||
{
|
||||
key: "secretish",
|
||||
type: "string",
|
||||
labelKey: "hidden.label",
|
||||
hidden: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as Partial<PluginSummary>);
|
||||
render(
|
||||
<HostPluginSections plugins={[own]} values={{}} setValue={() => {}} />,
|
||||
);
|
||||
expect(screen.queryByText("hidden.label")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("HostPluginSections", () => {
|
||||
it("shows the enable switch and hides the fields until it is on", () => {
|
||||
const setValue = vi.fn();
|
||||
|
||||
@@ -36,6 +36,7 @@ vi.mock("react-i18next", () => ({
|
||||
|
||||
import { HostAuthOverrideModal } from "../../sidebar/HostAuthOverrideModal";
|
||||
import { canOverrideHostAuth } from "../../sidebar/host-permissions";
|
||||
import { registerHostProtocol } from "../../sidebar/host-protocols";
|
||||
|
||||
const host = {
|
||||
id: "42",
|
||||
@@ -238,9 +239,27 @@ describe("canOverrideHostAuth", () => {
|
||||
expect(
|
||||
canOverrideHostAuth({ ...host, enableSsh: false } as Host, "ssh"),
|
||||
).toBe(false);
|
||||
const dispose = registerHostProtocol({
|
||||
id: "rdp",
|
||||
pluginId: "demo",
|
||||
settingKey: "enableRdp",
|
||||
defaultPort: 3389,
|
||||
titleKey: "rdp",
|
||||
icon: () => null,
|
||||
});
|
||||
expect(
|
||||
canOverrideHostAuth({ ...host, enableRdp: true } as Host, "rdp"),
|
||||
canOverrideHostAuth(
|
||||
{ ...host, pluginSettings: { demo: { enableRdp: true } } } as Host,
|
||||
"rdp",
|
||||
),
|
||||
).toBe(true);
|
||||
expect(canOverrideHostAuth(host, "rdp")).toBe(false);
|
||||
dispose();
|
||||
expect(
|
||||
canOverrideHostAuth(
|
||||
{ ...host, pluginSettings: { demo: { enableRdp: true } } } as Host,
|
||||
"rdp",
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -55,13 +55,7 @@ function makeHost(overrides: Partial<Host>): Host {
|
||||
enableTmuxMonitor: false,
|
||||
quickActions: [],
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
sshPort: 22,
|
||||
rdpPort: 3389,
|
||||
vncPort: 5900,
|
||||
telnetPort: 23,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
@@ -136,7 +130,6 @@ describe("HostCredentialList credential usage", () => {
|
||||
credentialId: undefined,
|
||||
rdpCredentialId: "1",
|
||||
enableSsh: false,
|
||||
enableRdp: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { registerHostProtocol } from "../../sidebar/host-protocols";
|
||||
import {
|
||||
createHostEditorForm,
|
||||
buildHostEditorPayload,
|
||||
@@ -568,53 +569,36 @@ describe("RDP/VNC/Telnet password persistence indicator", () => {
|
||||
describe("user connection defaults", () => {
|
||||
const defaults = {
|
||||
terminal: { fontSize: 18, cursorBlink: false },
|
||||
rdp: { colorDepth: 24, disableCopy: true },
|
||||
};
|
||||
|
||||
it("shows inherited values without persisting them as host overrides", () => {
|
||||
const host = {
|
||||
enableSsh: true,
|
||||
enableRdp: true,
|
||||
terminalConfig: { autoTmux: true },
|
||||
guacamoleConfig: { enableAudioInput: true },
|
||||
} as Host;
|
||||
} as unknown as Host;
|
||||
const form = createHostEditorForm(host, undefined, defaults);
|
||||
|
||||
expect(form).toMatchObject({
|
||||
fontSize: 18,
|
||||
cursorBlink: false,
|
||||
inheritTerminalAppearance: true,
|
||||
inheritRemoteDesktopDefaults: true,
|
||||
guacamoleConfig: {
|
||||
colorDepth: 24,
|
||||
disableCopy: true,
|
||||
enableAudioInput: true,
|
||||
},
|
||||
});
|
||||
|
||||
const payload = buildHostEditorPayload(form, {
|
||||
...sshOnly,
|
||||
enableRdp: true,
|
||||
});
|
||||
const payload = buildHostEditorPayload(form, sshOnly);
|
||||
expect(payload.terminalConfig).toMatchObject({ autoTmux: true });
|
||||
expect(payload.terminalConfig).not.toHaveProperty("fontSize");
|
||||
expect(payload.guacamoleConfig).toEqual({ enableAudioInput: true });
|
||||
});
|
||||
|
||||
it("keeps explicit host overrides above user defaults", () => {
|
||||
const host = {
|
||||
enableSsh: true,
|
||||
enableRdp: true,
|
||||
terminalConfig: { fontSize: 12 },
|
||||
guacamoleConfig: { colorDepth: 32 },
|
||||
} as Host;
|
||||
} as unknown as Host;
|
||||
const form = createHostEditorForm(host, undefined, defaults);
|
||||
|
||||
expect(form).toMatchObject({
|
||||
fontSize: 12,
|
||||
inheritTerminalAppearance: false,
|
||||
inheritRemoteDesktopDefaults: false,
|
||||
guacamoleConfig: { colorDepth: 32, disableCopy: true },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -694,3 +678,29 @@ describe("macOS Option character defaults", () => {
|
||||
expect(createHostEditorForm(host).macOptionIsMeta).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("plugin protocols", () => {
|
||||
it("uses the first protocol switched on as the host's type and port without SSH", () => {
|
||||
const dispose = registerHostProtocol({
|
||||
id: "demo-desktop",
|
||||
pluginId: "demo",
|
||||
settingKey: "enableDemo",
|
||||
portKey: "demoPort",
|
||||
defaultPort: 3389,
|
||||
titleKey: "demo",
|
||||
icon: () => null,
|
||||
});
|
||||
const form = {
|
||||
...createHostEditorForm(null),
|
||||
pluginSettings: { demo: { demoPort: 3390 } },
|
||||
};
|
||||
const payload = buildHostEditorPayload(form, {
|
||||
enableSsh: false,
|
||||
enableDemo: true,
|
||||
});
|
||||
dispose();
|
||||
expect(payload.connectionType).toBe("demo-desktop");
|
||||
expect(payload.port).toBe(3390);
|
||||
expect(payload.enableSsh).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
enabledHostProtocols,
|
||||
hostProtocolFlags,
|
||||
protocolPort,
|
||||
registerHostProtocol,
|
||||
withProtocolSettings,
|
||||
type HostProtocolDef,
|
||||
} from "../../sidebar/host-protocols";
|
||||
|
||||
const desktop: HostProtocolDef = {
|
||||
id: "demo-desktop",
|
||||
pluginId: "demo",
|
||||
settingKey: "enableDemo",
|
||||
portKey: "demoPort",
|
||||
defaultPort: 3389,
|
||||
titleKey: "demo:title",
|
||||
icon: () => null,
|
||||
};
|
||||
|
||||
let dispose: (() => void) | null = null;
|
||||
|
||||
afterEach(() => {
|
||||
dispose?.();
|
||||
dispose = null;
|
||||
});
|
||||
|
||||
describe("host protocols", () => {
|
||||
it("reads a protocol's switch from its plugin's host settings", () => {
|
||||
dispose = registerHostProtocol(desktop);
|
||||
const host = {
|
||||
enableSsh: false,
|
||||
pluginSettings: { demo: { enableDemo: true } },
|
||||
};
|
||||
expect(hostProtocolFlags(host)).toEqual({
|
||||
enableSsh: false,
|
||||
enableDemo: true,
|
||||
});
|
||||
expect(enabledHostProtocols(host).map((p) => p.id)).toEqual([
|
||||
"demo-desktop",
|
||||
]);
|
||||
expect(hostProtocolFlags(null)).toEqual({
|
||||
enableSsh: true,
|
||||
enableDemo: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to the default port", () => {
|
||||
expect(protocolPort({ demo: { demoPort: 3390 } }, desktop)).toBe(3390);
|
||||
expect(protocolPort({ demo: { demoPort: "x" } }, desktop)).toBe(3389);
|
||||
expect(protocolPort(undefined, desktop)).toBe(3389);
|
||||
});
|
||||
|
||||
it("writes the editor's switches into each owner's settings", () => {
|
||||
dispose = registerHostProtocol(desktop);
|
||||
expect(
|
||||
withProtocolSettings(
|
||||
{ demo: { demoPort: 3390 }, other: { a: 1 } },
|
||||
{ enableSsh: true, enableDemo: true },
|
||||
),
|
||||
).toEqual({
|
||||
demo: { demoPort: 3390, enableDemo: true },
|
||||
other: { a: 1 },
|
||||
});
|
||||
});
|
||||
|
||||
it("forgets a protocol once its plugin unregisters it", () => {
|
||||
dispose = registerHostProtocol(desktop);
|
||||
dispose();
|
||||
dispose = null;
|
||||
expect(
|
||||
enabledHostProtocols({ pluginSettings: { demo: { enableDemo: true } } }),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -61,46 +61,40 @@ describe("createQuickConnectHost for remote desktop protocols", () => {
|
||||
expect(isQuickConnectHost(host)).toBe(true);
|
||||
expect(host).toMatchObject({
|
||||
enableSsh: true,
|
||||
enableRdp: false,
|
||||
sshPort: 2222,
|
||||
password: "pw",
|
||||
});
|
||||
});
|
||||
|
||||
it("builds an RDP host that GuacamoleApp can mint a token from", () => {
|
||||
const desktop = {
|
||||
id: "demo-desktop",
|
||||
pluginId: "demo",
|
||||
settingKey: "enableDemo",
|
||||
portKey: "demoPort",
|
||||
defaultPort: 3389,
|
||||
titleKey: "demo",
|
||||
icon: () => null,
|
||||
};
|
||||
|
||||
it("builds a plugin protocol host with its switch and port in plugin settings", () => {
|
||||
const host = createQuickConnectHost({
|
||||
ip: "10.0.0.2",
|
||||
port: 3390,
|
||||
username: "admin",
|
||||
authType: "password",
|
||||
password: "pw",
|
||||
protocol: "rdp",
|
||||
protocol: desktop,
|
||||
domain: "CORP",
|
||||
});
|
||||
expect(host).toMatchObject({
|
||||
enableSsh: false,
|
||||
enableRdp: true,
|
||||
enableVnc: false,
|
||||
rdpPort: 3390,
|
||||
rdpUser: "admin",
|
||||
rdpPassword: "pw",
|
||||
pluginSettings: { demo: { enableDemo: true, demoPort: 3390 } },
|
||||
domain: "CORP",
|
||||
});
|
||||
});
|
||||
|
||||
it("builds a VNC host with the password on the VNC fields", () => {
|
||||
const host = createQuickConnectHost({
|
||||
ip: "10.0.0.3",
|
||||
port: 5901,
|
||||
username: "",
|
||||
authType: "password",
|
||||
password: "vncpw",
|
||||
protocol: "vnc",
|
||||
});
|
||||
// The login sits on the core fields named after the protocol.
|
||||
expect(host).toMatchObject({
|
||||
enableVnc: true,
|
||||
vncPort: 5901,
|
||||
vncPassword: "vncpw",
|
||||
"demo-desktopUser": "admin",
|
||||
"demo-desktopPassword": "pw",
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -29,9 +29,6 @@ function host(id: string, name: string): Host {
|
||||
enableTunnel: false,
|
||||
enableFileManager: true,
|
||||
enableDocker: false,
|
||||
enableRdp: false,
|
||||
enableVnc: false,
|
||||
enableTelnet: false,
|
||||
quickActions: [],
|
||||
} as Host;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user