Add database connection status indicator

This commit is contained in:
2026-08-05 18:53:11 +02:00
parent f2fa405008
commit f97d00ab7f
5 changed files with 16 additions and 2 deletions
+3
View File
@@ -44,6 +44,7 @@ const databaseModeInputs = document.querySelectorAll('input[name="databaseMode"]
const permissionInputs = document.querySelectorAll("#allowInsertToggle, #allowUpdateToggle, #allowDeleteToggle");
const transactionModeInputs = document.querySelectorAll('input[name="transactionMode"]');
const databaseStatus = document.querySelector("#databaseStatus");
const databaseStateDot = document.querySelector("#databaseStateDot");
const localDbFields = document.querySelector("#localDbFields");
const localDbInputs = document.querySelectorAll("#localDbFields input");
const testLocalDbButton = document.querySelector("#testLocalDbButton");
@@ -1036,6 +1037,8 @@ function refreshDatabaseStatusLabel() {
: (transactionMode === "dry-run" ? "dry-run" : "transaction");
databaseStatus.textContent = `${dbLabel} / ${connectionLabel} / ${accessLabel} / ${executionLabel}`;
databaseStatus.classList.toggle("database-error", connectionError);
databaseStateDot.className = `database-state-dot ${databaseConnectionState === "unknown" ? "is-pending" : connectionError ? "is-error" : "is-ready"}`;
databaseStateDot.setAttribute("aria-label", connectionError ? "Database disconnected" : databaseConnectionState === "unknown" ? "Database connection pending" : "Database connected");
}
function renderDatabaseModeNote(mode) {
databaseModeNote.textContent = mode === "live"
+3
View File
@@ -44,6 +44,7 @@ const databaseModeInputs = document.querySelectorAll('input[name="databaseMode"]
const permissionInputs = document.querySelectorAll("#allowInsertToggle, #allowUpdateToggle, #allowDeleteToggle");
const transactionModeInputs = document.querySelectorAll('input[name="transactionMode"]');
const databaseStatus = document.querySelector("#databaseStatus");
const databaseStateDot = document.querySelector("#databaseStateDot");
const localDbFields = document.querySelector("#localDbFields");
const localDbInputs = document.querySelectorAll("#localDbFields input");
const testLocalDbButton = document.querySelector("#testLocalDbButton");
@@ -1134,6 +1135,8 @@ function refreshDatabaseStatusLabel() {
: (transactionMode === "dry-run" ? "dry-run" : "transaction");
databaseStatus.textContent = `${dbLabel} / ${connectionLabel} / ${accessLabel} / ${executionLabel}`;
databaseStatus.classList.toggle("database-error", connectionError);
databaseStateDot.className = `database-state-dot ${databaseConnectionState === "unknown" ? "is-pending" : connectionError ? "is-error" : "is-ready"}`;
databaseStateDot.setAttribute("aria-label", connectionError ? "Database disconnected" : databaseConnectionState === "unknown" ? "Database connection pending" : "Database connected");
}
function renderDatabaseModeNote(mode) {
+4 -1
View File
@@ -98,7 +98,10 @@
<div class="sidebar-footer">
<button class="action-button primary" type="button"><svg class="sidebar-icon" aria-hidden="true"><use href="/icons.svg#menu"></use></svg><span>Show menu (20)</span></button>
<div class="app-status">
<span class="safe-mode" id="databaseStatus">DB read-only</span>
<span class="database-status-content">
<span class="database-state-dot is-pending" id="databaseStateDot" aria-hidden="true"></span>
<span class="safe-mode" id="databaseStatus">DB read-only</span>
</span>
</div>
<button class="action-button" id="themeToggle" type="button" aria-pressed="false"><svg class="sidebar-icon" aria-hidden="true"><use href="/icons.svg#moon"></use></svg><span>Dark theme</span></button>
<button class="action-button" id="settingsButton" type="button"><svg class="sidebar-icon" aria-hidden="true"><use href="/icons.svg#settings"></use></svg><span>Settings</span></button>
+1 -1
View File
File diff suppressed because one or more lines are too long
+5
View File
@@ -71,6 +71,11 @@
.action-button .sidebar-icon { @apply text-slate-400; }
.sidebar-footer { @apply mt-auto grid gap-1 border-t border-slate-700 pt-2; }
.app-status { @apply rounded border border-slate-700 bg-slate-950 p-1 text-[10px] leading-tight text-slate-100; }
.database-status-content { @apply flex items-center justify-center gap-1.5 text-center; }
.database-state-dot { @apply inline-block h-2.5 w-2.5 shrink-0 rounded-full border border-slate-500; }
.database-state-dot.is-ready { @apply border-emerald-300 bg-emerald-500; }
.database-state-dot.is-pending { @apply border-amber-300 bg-amber-400; }
.database-state-dot.is-error { @apply border-red-300 bg-red-500; }
.safe-mode, #modePill { @apply inline-block rounded bg-slate-100 px-1 py-0.5 text-[10px] font-semibold text-slate-800; }
#databaseStatus.database-error { @apply bg-red-100 text-red-700; }
.record-id { @apply flex h-10 items-center justify-center rounded border border-lime-700 bg-catalog-accent text-[26px] font-bold leading-none text-catalog-accent-text; }