Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
9792b175
Unverified
Commit
9792b175
authored
Mar 03, 2026
by
Wesley Liddick
Committed by
GitHub
Mar 03, 2026
Browse files
Merge pull request #729 from touwaeriol/pr/fix-admin-menu-visibility
fix(frontend): admin custom menu items not showing in sidebar
parents
b7df7ce5
5ba71cd2
Changes
3
Hide whitespace changes
Inline
Side-by-side
frontend/src/components/layout/AppSidebar.vue
View file @
9792b175
...
...
@@ -579,7 +579,7 @@ const customMenuItemsForUser = computed(() => {
})
const
customMenuItemsForAdmin
=
computed
(()
=>
{
const
items
=
a
ppStore
.
cachedPublic
Settings
?
.
custom
_m
enu
_i
tems
??
[]
const
items
=
a
dmin
Settings
Store
.
custom
M
enu
I
tems
??
[]
return
items
.
filter
((
item
)
=>
item
.
visibility
===
'
admin
'
)
.
sort
((
a
,
b
)
=>
a
.
sort_order
-
b
.
sort_order
)
...
...
frontend/src/stores/adminSettings.ts
View file @
9792b175
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
)
...
...
@@ -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.
const
opsMonitoringEnabled
=
ref
(
readCachedBool
(
'
ops_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
'
writeCachedString
(
'
ops_query_mode_default_cached
'
,
opsQueryModeDefault
.
value
)
customMenuItems
.
value
=
settings
.
custom_menu_items
??
[]
loaded
.
value
=
true
}
catch
(
err
)
{
// 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
,
opsRealtimeMonitoringEnabled
,
opsQueryModeDefault
,
customMenuItems
,
fetch
,
setOpsMonitoringEnabledLocal
,
setOpsRealtimeMonitoringEnabledLocal
,
...
...
frontend/src/views/user/CustomPageView.vue
View file @
9792b175
...
...
@@ -70,6 +70,7 @@ import { useRoute } from 'vue-router'
import
{
useI18n
}
from
'
vue-i18n
'
import
{
useAppStore
}
from
'
@/stores
'
import
{
useAuthStore
}
from
'
@/stores/auth
'
import
{
useAdminSettingsStore
}
from
'
@/stores/adminSettings
'
import
AppLayout
from
'
@/components/layout/AppLayout.vue
'
import
Icon
from
'
@/components/icons/Icon.vue
'
import
{
buildEmbeddedUrl
,
detectTheme
}
from
'
@/utils/embedded-url
'
...
...
@@ -78,6 +79,7 @@ const { t } = useI18n()
const
route
=
useRoute
()
const
appStore
=
useAppStore
()
const
authStore
=
useAuthStore
()
const
adminSettingsStore
=
useAdminSettingsStore
()
const
loading
=
ref
(
false
)
const
pageTheme
=
ref
<
'
light
'
|
'
dark
'
>
(
'
light
'
)
...
...
@@ -86,8 +88,15 @@ let themeObserver: MutationObserver | null = null
const
menuItemId
=
computed
(()
=>
route
.
params
.
id
as
string
)
const
menuItem
=
computed
(()
=>
{
const
items
=
appStore
.
cachedPublicSettings
?.
custom_menu_items
??
[]
const
found
=
items
.
find
((
item
)
=>
item
.
id
===
menuItemId
.
value
)
??
null
const
publicItems
=
appStore
.
cachedPublicSettings
?.
custom_menu_items
??
[]
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
)
{
return
null
}
...
...
@@ -122,12 +131,20 @@ onMounted(async () => {
})
}
if
(
appStore
.
publicSettingsLoaded
)
return
loading
.
value
=
true
try
{
await
appStore
.
fetchPublicSettings
()
}
finally
{
loading
.
value
=
false
const
promises
:
Promise
<
unknown
>
[]
=
[]
if
(
!
appStore
.
publicSettingsLoaded
)
{
promises
.
push
(
appStore
.
fetchPublicSettings
())
}
if
(
authStore
.
isAdmin
)
{
promises
.
push
(
adminSettingsStore
.
fetch
())
}
if
(
promises
.
length
>
0
)
{
loading
.
value
=
true
try
{
await
Promise
.
all
(
promises
)
}
finally
{
loading
.
value
=
false
}
}
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment