show sync button for admin
Build and Push Containers / build-and-push-app (push) Successful in 1m38s
Build and Push Containers / build-and-push-db (push) Successful in 11s

This commit is contained in:
2026-08-28 23:24:23 -04:00
parent 3a404eb161
commit 6bf7f456d4
17 changed files with 368 additions and 284 deletions
+8 -5
View File
@@ -30,9 +30,11 @@ import { fetchIsAdmin, initSharedHeader } from "./header.js";
*
* The §7.4 never-stale lifecycle: idle → click → POST /api/sync
* → running (2 s poll of GET /api/sync/status) → success | failed.
* Admin-only: the button is hidden for anonymous users (initSharedHeader
* hides it). A failed run opens an error modal (same as the former
* header.js module — recreated here since the navbar button is gone).
* Admin-only: the button SHIPS hidden and the page boot below reveals it
* for the admin on the SAME cached whoami initSharedHeader() used (no
* extra fetch); the 403 branches stay as defense in depth. A failed run
* opens an error modal (same as the former header.js module — recreated
* here since the navbar button is gone).
*
* Elements: #sync-btn (the button), #sync-label (the text),
* #sync-icon (the spinner icon), #sync-result (aria-live result
@@ -165,7 +167,7 @@ function closeSyncModal() {
function applySyncSuccess(status) {
const time = fmtSyncTime(status.finished_at);
settleSyncButton(time ? `Synced ${time}` : "Synced");
if (syncResult) syncResult.textContent = fmtSyncResult(status);
if (syncResult) syncResult.textContent = fmtSyncResult(status.detail);
hideSyncError();
emitSyncStatus(status);
// Refresh the catalog live — the KB just changed.
@@ -411,7 +413,8 @@ function showEmpty() {
(async () => {
await initSharedHeader(); // phase 19: Sign in/out + Sources link in the shared bar
const admin = await initSharedHeader(); // phase 19: shared bar (cached whoami)
if (syncBtn) syncBtn.hidden = !admin; // admin-only: ship-hidden, revealed on the same whoami
if (!(await isAdmin())) {
// Anonymous: gate in, catalog out, and no /api/docs request at all.
if (statCards) statCards.hidden = true;