diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 1926015a..756cd177 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -418,6 +418,7 @@
"mustSelectValidSshConfig": "Must select a valid SSH configuration from the list",
"addHost": "Add Host",
"editHost": "Edit Host",
+ "cloneHost": "Clone Host",
"updateHost": "Update Host",
"hostUpdatedSuccessfully": "Host \"{{name}}\" updated successfully!",
"hostAddedSuccessfully": "Host \"{{name}}\" added successfully!",
diff --git a/src/locales/zh/translation.json b/src/locales/zh/translation.json
index e9b168a6..a5456037 100644
--- a/src/locales/zh/translation.json
+++ b/src/locales/zh/translation.json
@@ -404,6 +404,7 @@
"mustSelectValidSshConfig": "必须从列表中选择有效的 SSH 配置",
"addHost": "添加主机",
"editHost": "编辑主机",
+ "cloneHost": "克隆主机",
"deleteHost": "删除主机",
"authType": "认证类型",
"passwordAuth": "密码",
diff --git a/src/ui/Desktop/Apps/Host Manager/HostManager.tsx b/src/ui/Desktop/Apps/Host Manager/HostManager.tsx
index 7d948d1d..34db6aa1 100644
--- a/src/ui/Desktop/Apps/Host Manager/HostManager.tsx
+++ b/src/ui/Desktop/Apps/Host Manager/HostManager.tsx
@@ -82,7 +82,11 @@ export function HostManager({
{t("hosts.hostViewer")}
- {editingHost ? t("hosts.editHost") : t("hosts.addHost")}
+ {editingHost
+ ? editingHost.id
+ ? t("hosts.editHost")
+ : t("hosts.cloneHost")
+ : t("hosts.addHost")}
diff --git a/src/ui/Desktop/Apps/Host Manager/HostManagerEditor.tsx b/src/ui/Desktop/Apps/Host Manager/HostManagerEditor.tsx
index a799c716..cad2565e 100644
--- a/src/ui/Desktop/Apps/Host Manager/HostManagerEditor.tsx
+++ b/src/ui/Desktop/Apps/Host Manager/HostManagerEditor.tsx
@@ -343,7 +343,7 @@ export function HostManagerEditor({
if (defaultAuthType === "password") {
formData.password = cleanedHost.password || "";
} else if (defaultAuthType === "key") {
- formData.key = "existing_key";
+ formData.key = editingHost.id ? "existing_key" : editingHost.key;
formData.keyPassword = cleanedHost.keyPassword || "";
formData.keyType = (cleanedHost.keyType as any) || "auto";
} else if (defaultAuthType === "credential") {
@@ -420,7 +420,7 @@ export function HostManagerEditor({
submitData.keyType = null;
if (data.authType === "credential") {
- if (data.credentialId === "existing_credential") {
+ if (data.credentialId === "existing_credential" && editingHost && editingHost.id) {
delete submitData.credentialId;
} else {
submitData.credentialId = data.credentialId;
@@ -440,7 +440,7 @@ export function HostManagerEditor({
submitData.keyType = data.keyType;
}
- if (editingHost) {
+ if (editingHost && editingHost.id) {
const updatedHost = await updateSSHHost(editingHost.id, submitData);
toast.success(t("hosts.hostUpdatedSuccessfully", { name: data.name }));
@@ -1497,7 +1497,7 @@ export function HostManagerEditor({
diff --git a/src/ui/Desktop/Apps/Host Manager/HostManagerViewer.tsx b/src/ui/Desktop/Apps/Host Manager/HostManagerViewer.tsx
index 9ca6ff7f..3e1e7abf 100644
--- a/src/ui/Desktop/Apps/Host Manager/HostManagerViewer.tsx
+++ b/src/ui/Desktop/Apps/Host Manager/HostManagerViewer.tsx
@@ -41,6 +41,7 @@ import {
Check,
Pencil,
FolderMinus,
+ Copy,
} from "lucide-react";
import type {
SSHHost,
@@ -206,6 +207,14 @@ export function HostManagerViewer({ onEditHost }: SSHManagerHostViewerProps) {
}
};
+ const handleClone = (host: SSHHost) => {
+ if(onEditHost) {
+ const clonedHost = {...host};
+ delete clonedHost.id;
+ onEditHost(clonedHost);
+ }
+ }
+
const handleRemoveFromFolder = async (host: SSHHost) => {
confirmWithToast(
t("hosts.confirmRemoveFromFolder", {
@@ -1009,6 +1018,24 @@ export function HostManagerViewer({ onEditHost }: SSHManagerHostViewerProps) {
Export host
+
+
+
+
+
+ Clone host
+
+