File size: 4,334 Bytes
8059bf0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | import { defineStore } from 'pinia'
import { ref } from 'vue'
import { adminAPI } from '@/api'
import type { CustomMenuItem } from '@/types'
export const useAdminSettingsStore = defineStore('adminSettings', () => {
const loaded = ref(false)
const loading = ref(false)
const readCachedBool = (key: string, defaultValue: boolean): boolean => {
try {
const raw = localStorage.getItem(key)
if (raw === 'true') return true
if (raw === 'false') return false
} catch {
// ignore localStorage failures
}
return defaultValue
}
const writeCachedBool = (key: string, value: boolean) => {
try {
localStorage.setItem(key, value ? 'true' : 'false')
} catch {
// ignore localStorage failures
}
}
const readCachedString = (key: string, defaultValue: string): string => {
try {
const raw = localStorage.getItem(key)
if (typeof raw === 'string' && raw.length > 0) return raw
} catch {
// ignore localStorage failures
}
return defaultValue
}
const writeCachedString = (key: string, value: string) => {
try {
localStorage.setItem(key, value)
} catch {
// ignore localStorage failures
}
}
// Default open, but honor cached value to reduce UI flicker on first paint.
const opsMonitoringEnabled = ref(readCachedBool('ops_monitoring_enabled_cached', true))
const opsRealtimeMonitoringEnabled = ref(readCachedBool('ops_realtime_monitoring_enabled_cached', true))
const opsQueryModeDefault = ref(readCachedString('ops_query_mode_default_cached', 'auto'))
const customMenuItems = ref<CustomMenuItem[]>([])
async function fetch(force = false): Promise<void> {
if (loaded.value && !force) return
if (loading.value) return
loading.value = true
try {
const settings = await adminAPI.settings.getSettings()
opsMonitoringEnabled.value = settings.ops_monitoring_enabled ?? true
writeCachedBool('ops_monitoring_enabled_cached', opsMonitoringEnabled.value)
opsRealtimeMonitoringEnabled.value = settings.ops_realtime_monitoring_enabled ?? true
writeCachedBool('ops_realtime_monitoring_enabled_cached', opsRealtimeMonitoringEnabled.value)
opsQueryModeDefault.value = settings.ops_query_mode_default || 'auto'
writeCachedString('ops_query_mode_default_cached', opsQueryModeDefault.value)
customMenuItems.value = Array.isArray(settings.custom_menu_items) ? settings.custom_menu_items : []
loaded.value = true
} catch (err) {
// Keep cached/default value: do not "flip" the UI based on a transient fetch failure.
loaded.value = true
console.error('[adminSettings] Failed to fetch settings:', err)
} finally {
loading.value = false
}
}
function setOpsMonitoringEnabledLocal(value: boolean) {
opsMonitoringEnabled.value = value
writeCachedBool('ops_monitoring_enabled_cached', value)
loaded.value = true
}
function setOpsRealtimeMonitoringEnabledLocal(value: boolean) {
opsRealtimeMonitoringEnabled.value = value
writeCachedBool('ops_realtime_monitoring_enabled_cached', value)
loaded.value = true
}
function setOpsQueryModeDefaultLocal(value: string) {
opsQueryModeDefault.value = value || 'auto'
writeCachedString('ops_query_mode_default_cached', opsQueryModeDefault.value)
loaded.value = true
}
// Keep UI consistent if we learn that ops is disabled via feature-gated 404s.
// (event is dispatched from the axios interceptor)
let eventHandlerCleanup: (() => void) | null = null
function initializeEventListeners() {
if (eventHandlerCleanup) return
try {
const handler = () => {
setOpsMonitoringEnabledLocal(false)
}
window.addEventListener('ops-monitoring-disabled', handler)
eventHandlerCleanup = () => {
window.removeEventListener('ops-monitoring-disabled', handler)
}
} catch {
// ignore window access failures (SSR)
}
}
if (typeof window !== 'undefined') {
initializeEventListeners()
}
return {
loaded,
loading,
opsMonitoringEnabled,
opsRealtimeMonitoringEnabled,
opsQueryModeDefault,
customMenuItems,
fetch,
setOpsMonitoringEnabledLocal,
setOpsRealtimeMonitoringEnabledLocal,
setOpsQueryModeDefaultLocal
}
})
|