3.1 KiB
Cross-Page Settings Desync: Missing initializeSettings
Diagnostic Signal
User toggles a setting (desktop notifications, sound alerts, dark mode) on page A, saves — it sticks. Navigates to page B — the same toggle shows its default/off state. Toggling+saving on page B works on page B but page A reverts. Each page "remembers" only its own saves.
Root Cause
A shared settings module (settings.js) exports initializeSettings(), which:
- Calls
loadSettings()— fetches saved settings from PocketBase/localStorage - Calls
populateSiteSettingsForm()— sets checkbox/select values from loaded settings - Calls
setupUnifiedSiteSettingsModalHandlers()— wires close/save/cancel buttons - Calls
subscribeToRealtimeSettings()— sets up change listeners
If any page in the app loads settings.js as a <script type="module"> but never calls initializeSettings(), that page runs with module defaults. The form controls show their raw HTML state (unchecked for input[type=checkbox] without a checked attribute).
Common Pattern
repair-orders.js: import { initializeSettings } from './settings.js'
await initializeSettings(...); // ✅ called
customers.js: import { initializeSettings } from './settings.js'
await initializeSettings(...); // ✅ called
main.js: import { initializeSettings } from './settings.js'
initializeSettings(...); // ✅ called
dashboard.js: settingsModule.initializeSettings(...); // ✅ called
appointments.js: // ❌ imports settings.js? Yes (loaded as module)
// ❌ calls initializeSettings()? NO
// → settings desync on appointments page
Fix
Add the import and call to every page that has a site settings modal:
// At top of page's JS file:
import { initializeSettings } from './settings.js';
// Inside the page's init function (after auth check):
initializeSettings();
Verification
# Check every page's JS for the initializeSettings call
for js in repair-orders.js appointments.js customers.js main.js dashboard.js; do
echo -n "$js: "
grep -c 'initializeSettings' "$js"
done
# Every result should be ≥ 2 (import + call site). A result of 0 or 1 = bug.
PocketBase Pitfall: onSnapshot is One-Shot
The onSnapshot function in PocketBase adapter (pocketbase.js) is a one-shot fetch, not a realtime listener. It fires once when called, then never again:
function onSnapshot(queryOrDocRef, callback) {
// Simple one-shot onSnapshot compatibility shim
getDoc(queryOrDocRef).then(doc => callback(doc));
return () => {}; // Unsubscribe is a no-op
}
This means subscribeToRealtimeSettings() does NOT provide realtime cross-page sync. Settings saved on page A are persisted to PocketBase, but page B won't see the change until it reloads (calling loadSettings() fresh). This is fine for navigation-based sync (each page loads settings on init), but means two open tabs won't stay in sync without a manual refresh.