Merge pull request #729 from touwaeriol/pr/fix-admin-menu-visibility
fix(frontend): admin custom menu items not showing in sidebar
This commit is contained in:
@@ -579,7 +579,7 @@ const customMenuItemsForUser = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const customMenuItemsForAdmin = computed(() => {
|
const customMenuItemsForAdmin = computed(() => {
|
||||||
const items = appStore.cachedPublicSettings?.custom_menu_items ?? []
|
const items = adminSettingsStore.customMenuItems ?? []
|
||||||
return items
|
return items
|
||||||
.filter((item) => item.visibility === 'admin')
|
.filter((item) => item.visibility === 'admin')
|
||||||
.sort((a, b) => a.sort_order - b.sort_order)
|
.sort((a, b) => a.sort_order - b.sort_order)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { adminAPI } from '@/api'
|
import { adminAPI } from '@/api'
|
||||||
|
import type { CustomMenuItem } from '@/types'
|
||||||
|
|
||||||
export const useAdminSettingsStore = defineStore('adminSettings', () => {
|
export const useAdminSettingsStore = defineStore('adminSettings', () => {
|
||||||
const loaded = ref(false)
|
const loaded = ref(false)
|
||||||
@@ -43,6 +44,9 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom menu items (all items including admin-only, loaded from admin settings API)
|
||||||
|
const customMenuItems = ref<CustomMenuItem[]>([])
|
||||||
|
|
||||||
// Default open, but honor cached value to reduce UI flicker on first paint.
|
// Default open, but honor cached value to reduce UI flicker on first paint.
|
||||||
const opsMonitoringEnabled = ref(readCachedBool('ops_monitoring_enabled_cached', true))
|
const opsMonitoringEnabled = ref(readCachedBool('ops_monitoring_enabled_cached', true))
|
||||||
const opsRealtimeMonitoringEnabled = ref(readCachedBool('ops_realtime_monitoring_enabled_cached', true))
|
const opsRealtimeMonitoringEnabled = ref(readCachedBool('ops_realtime_monitoring_enabled_cached', true))
|
||||||
@@ -64,6 +68,8 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => {
|
|||||||
opsQueryModeDefault.value = settings.ops_query_mode_default || 'auto'
|
opsQueryModeDefault.value = settings.ops_query_mode_default || 'auto'
|
||||||
writeCachedString('ops_query_mode_default_cached', opsQueryModeDefault.value)
|
writeCachedString('ops_query_mode_default_cached', opsQueryModeDefault.value)
|
||||||
|
|
||||||
|
customMenuItems.value = settings.custom_menu_items ?? []
|
||||||
|
|
||||||
loaded.value = true
|
loaded.value = true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Keep cached/default value: do not "flip" the UI based on a transient fetch failure.
|
// Keep cached/default value: do not "flip" the UI based on a transient fetch failure.
|
||||||
@@ -122,6 +128,7 @@ export const useAdminSettingsStore = defineStore('adminSettings', () => {
|
|||||||
opsMonitoringEnabled,
|
opsMonitoringEnabled,
|
||||||
opsRealtimeMonitoringEnabled,
|
opsRealtimeMonitoringEnabled,
|
||||||
opsQueryModeDefault,
|
opsQueryModeDefault,
|
||||||
|
customMenuItems,
|
||||||
fetch,
|
fetch,
|
||||||
setOpsMonitoringEnabledLocal,
|
setOpsMonitoringEnabledLocal,
|
||||||
setOpsRealtimeMonitoringEnabledLocal,
|
setOpsRealtimeMonitoringEnabledLocal,
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import { useRoute } from 'vue-router'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useAppStore } from '@/stores'
|
import { useAppStore } from '@/stores'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
import { useAdminSettingsStore } from '@/stores/adminSettings'
|
||||||
import AppLayout from '@/components/layout/AppLayout.vue'
|
import AppLayout from '@/components/layout/AppLayout.vue'
|
||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import { buildEmbeddedUrl, detectTheme } from '@/utils/embedded-url'
|
import { buildEmbeddedUrl, detectTheme } from '@/utils/embedded-url'
|
||||||
@@ -78,6 +79,7 @@ const { t } = useI18n()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
const adminSettingsStore = useAdminSettingsStore()
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const pageTheme = ref<'light' | 'dark'>('light')
|
const pageTheme = ref<'light' | 'dark'>('light')
|
||||||
@@ -86,8 +88,15 @@ let themeObserver: MutationObserver | null = null
|
|||||||
const menuItemId = computed(() => route.params.id as string)
|
const menuItemId = computed(() => route.params.id as string)
|
||||||
|
|
||||||
const menuItem = computed(() => {
|
const menuItem = computed(() => {
|
||||||
const items = appStore.cachedPublicSettings?.custom_menu_items ?? []
|
const publicItems = appStore.cachedPublicSettings?.custom_menu_items ?? []
|
||||||
const found = items.find((item) => item.id === menuItemId.value) ?? null
|
const adminItems = authStore.isAdmin ? (adminSettingsStore.customMenuItems ?? []) : []
|
||||||
|
const allItems = [...publicItems]
|
||||||
|
for (const item of adminItems) {
|
||||||
|
if (!allItems.some((existing) => existing.id === item.id)) {
|
||||||
|
allItems.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const found = allItems.find((item) => item.id === menuItemId.value) ?? null
|
||||||
if (found && found.visibility === 'admin' && !authStore.isAdmin) {
|
if (found && found.visibility === 'admin' && !authStore.isAdmin) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -122,12 +131,20 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appStore.publicSettingsLoaded) return
|
const promises: Promise<unknown>[] = []
|
||||||
loading.value = true
|
if (!appStore.publicSettingsLoaded) {
|
||||||
try {
|
promises.push(appStore.fetchPublicSettings())
|
||||||
await appStore.fetchPublicSettings()
|
}
|
||||||
} finally {
|
if (authStore.isAdmin) {
|
||||||
loading.value = false
|
promises.push(adminSettingsStore.fetch())
|
||||||
|
}
|
||||||
|
if (promises.length > 0) {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
await Promise.all(promises)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user