feat: add connection status indicator to settings UI

This commit is contained in:
Anish Sarkar 2026-04-22 06:13:01 +05:30
parent ae264290d0
commit a5e5f229d9
2 changed files with 82 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import {
Platform,
PluginSettingTab,
Setting,
setIcon,
} from "obsidian";
import { AuthError } from "./api-client";
import { normalizeFolder, parseExcludePatterns } from "./excludes";
@ -29,7 +30,7 @@ export class SurfSenseSettingTab extends PluginSettingTab {
const settings = this.plugin.settings;
new Setting(containerEl).setName("Connection").setHeading();
this.renderConnectionHeading(containerEl);
new Setting(containerEl)
.setName("Server URL")
@ -262,6 +263,53 @@ export class SurfSenseSettingTab extends PluginSettingTab {
);
}
private renderConnectionHeading(containerEl: HTMLElement): void {
const heading = new Setting(containerEl).setName("Connection").setHeading();
const indicator = heading.nameEl.createSpan({
cls: "surfsense-connection-indicator",
});
const visual = this.getConnectionVisual();
indicator.addClass(`surfsense-connection-indicator--${visual.tone}`);
setIcon(indicator, visual.icon);
indicator.setAttr("aria-label", visual.label);
indicator.setAttr("title", visual.label);
}
private getConnectionVisual(): {
icon: string;
label: string;
tone: "ok" | "syncing" | "warn" | "err" | "muted";
} {
const settings = this.plugin.settings;
const kind = this.plugin.lastStatus.kind;
if (kind === "auth-error") {
return { icon: "lock", label: "Token invalid or expired", tone: "err" };
}
if (kind === "error") {
return { icon: "alert-circle", label: "Connection error", tone: "err" };
}
if (kind === "offline") {
return { icon: "wifi-off", label: "Server unreachable", tone: "warn" };
}
if (!settings.apiToken) {
return { icon: "circle", label: "Missing API token", tone: "muted" };
}
if (!settings.searchSpaceId) {
return { icon: "circle", label: "Pick a search space", tone: "muted" };
}
if (!settings.connectorId) {
return { icon: "circle", label: "Not connected yet", tone: "muted" };
}
if (kind === "syncing" || kind === "queued") {
return { icon: "refresh-ccw", label: "Connected and syncing", tone: "syncing" };
}
return { icon: "check-circle", label: "Connected", tone: "ok" };
}
private async refreshSearchSpaces(): Promise<void> {
this.loadingSpaces = true;
try {

View file

@ -37,3 +37,36 @@
.surfsense-status--err .surfsense-status__icon {
color: var(--color-red);
}
.surfsense-connection-indicator {
display: inline-flex;
margin-left: 8px;
vertical-align: middle;
width: 14px;
height: 14px;
}
.surfsense-connection-indicator svg {
width: 14px;
height: 14px;
}
.surfsense-connection-indicator--ok {
color: var(--color-green);
}
.surfsense-connection-indicator--syncing {
color: var(--color-blue);
}
.surfsense-connection-indicator--warn {
color: var(--color-yellow);
}
.surfsense-connection-indicator--err {
color: var(--color-red);
}
.surfsense-connection-indicator--muted {
color: var(--text-muted);
}