feat: copy connection URL from connection card menu (#22)

Add 'Copy connection URL' (with password, fetched from the OS keychain on
demand) and 'Copy connection URL (no password)' to the connection card kebab
menu. Builds postgresql://, mysql://, sqlite://, redis:// strings with
percent-encoded credentials and the PG sslmode appended. Bump to v0.7.10.
This commit is contained in:
2026-08-13 14:33:54 +08:00
committed by GitHub
parent df3e3957a2
commit 6d1bbb0fa3
13 changed files with 254 additions and 36 deletions
@@ -5,6 +5,7 @@ import {
CircleCheck,
CircleX,
Copy,
EyeOff,
Loader2,
MoreVertical,
Pencil,
@@ -14,6 +15,7 @@ import {
import type { Connection } from "../../lib/types";
import { useConnectionStore } from "../../stores/connectionStore";
import { buildConfigFromConnection } from "./ConnectionCard";
import { buildConnectionUrl } from "../../lib/connectionString";
import { useConnectionStatus } from "./useConnectionStatus";
interface ConnectionCardMenuProps {
@@ -82,6 +84,19 @@ export function ConnectionCardMenu({
setManageOpen(false);
};
const copyUrl = async (withPassword: boolean) => {
let password: string | null = null;
if (withPassword) {
password = await useConnectionStore
.getState()
.getConnectionPassword(connection.id)
.catch(() => null);
}
const url = buildConnectionUrl(connection, password);
await navigator.clipboard.writeText(url).catch(() => {});
close();
};
const statusLabel =
state === "checking"
? "Testing…"
@@ -169,6 +184,28 @@ export function ConnectionCardMenu({
</span>
</button>
<button
type="button"
onClick={() => {
void copyUrl(true);
}}
className={menuItemClass}
>
<Copy size={14} className="text-text-muted" />
<span className="truncate">Copy connection URL</span>
</button>
<button
type="button"
onClick={() => {
void copyUrl(false);
}}
className={menuItemClass}
>
<EyeOff size={14} className="text-text-muted" />
<span className="truncate">Copy connection URL (no password)</span>
</button>
<button
type="button"
onClick={() => setManageOpen((m) => !m)}