fix: load and save plugin host settings in the editor and tighten settings row spacing

This commit is contained in:
LukeGus committed 2026-09-29 22:40:01 -05:00
1 parent 1a6f9ffad6
commit 3028ab1176
6 files changed
+66 -10

No files matched your search

+3 -1
View File
@@ -42,7 +42,9 @@ export function SettingRow({
children: React.ReactNode;
}) {
return (
<div className="flex items-center justify-between gap-3 py-3 border-b border-border last:border-0">
// In a gap-4 form stack the gap already spaces the row, so its own padding
// and divider would double up.
<div className="flex items-center justify-between gap-3 py-3 border-b border-border last:border-0 [.gap-4>&]:py-0 [.gap-4>&]:border-0">
<div className="flex flex-col gap-0.5 min-w-0 flex-1">
<div className="flex items-center gap-1.5 flex-wrap">
<span className="text-sm font-medium leading-snug">{label}</span>
+18 -4
View File
@@ -153,17 +153,23 @@ export function HostEditor({
const savePluginHostSettings = async (
hostId: number,
values: Record<string, Record<string, unknown>> | undefined,
) => {
if (!values || !Number.isInteger(hostId)) return;
): Promise<Record<string, Record<string, unknown>>> => {
const saved: Record<string, Record<string, unknown>> = {};
if (!values || !Number.isInteger(hostId)) return saved;
for (const [pluginId, fields] of Object.entries(values)) {
if (!fields || Object.keys(fields).length === 0) continue;
try {
await updatePluginHostSettings(pluginId, hostId, fields);
saved[pluginId] = await updatePluginHostSettings(
pluginId,
hostId,
fields,
);
} catch {
toast.error(t("settings.pluginSettingsSaveFailed"));
}
}
return saved;
};
const handleSave = async () => {
@@ -186,12 +192,20 @@ 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.
const pluginValues = withProtocolSettings(form.pluginSettings, protocols);
await savePluginHostSettings(
const savedPluginValues = await savePluginHostSettings(
Number(saved.id),
host
? pluginValues
: withNewHostDefaults(pluginValues ?? {}, hostSettingPlugins),
);
// The host was read back before these were written.
saved = {
...saved,
pluginSettings: {
...(saved.pluginSettings ?? {}),
...savedPluginValues,
},
};
toast.success(host ? t("hosts.hostUpdated") : t("hosts.hostCreated"));
onSave(saved);
+1
View File
@@ -79,6 +79,7 @@ export function sshHostToHost(h: SSHHostWithStatus): Host {
h.sshPort ??
(h.connectionType === "ssh" || !h.connectionType ? h.port : 22),
protocolAuth: h.protocolAuth ?? {},
pluginSettings: h.pluginSettings ?? {},
jumpHosts: (parseJson<HostJumpHost[]>(h.jumpHosts) ?? []).map((j) => ({
hostId: String(j.hostId ?? j.hostid ?? j),
})),
@@ -32,4 +32,33 @@ describe("sshHostToHost", () => {
expect(host.id).toBe("-12");
expect(host.isShared).toBe(true);
});
it("keeps every plugin's host settings so the editor can load them", () => {
const pluginSettings = {
docker: { enableDocker: true, containerRuntime: "podman" },
"tmux-monitor": { enableTmuxMonitor: true },
};
const host = sshHostToHost({
id: 3,
name: "box",
ip: "10.0.0.3",
port: 22,
username: "root",
pluginSettings,
} as unknown as SSHHostWithStatus);
expect(host.pluginSettings).toEqual(pluginSettings);
});
it("defaults plugin settings to an empty map", () => {
const host = sshHostToHost({
id: 4,
name: "bare",
ip: "10.0.0.4",
port: 22,
username: "root",
} as SSHHostWithStatus);
expect(host.pluginSettings).toEqual({});
});
});