diff --git a/stash-web/src/AppNext.tsx b/stash-web/src/AppNext.tsx
index 7b05919..9e3a2df 100644
--- a/stash-web/src/AppNext.tsx
+++ b/stash-web/src/AppNext.tsx
@@ -710,6 +710,7 @@ export default function AppNext() {
live={live}
refreshing={refreshing}
onRefresh={refresh}
+ onOpenApi={() => navigate('/interface')}
/>
)}
{site.sidebar.show_nav !== false && (
diff --git a/stash-web/src/components/sidebar/CategoryNav.tsx b/stash-web/src/components/sidebar/CategoryNav.tsx
deleted file mode 100644
index 14c19fc..0000000
--- a/stash-web/src/components/sidebar/CategoryNav.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Card, Menu, type MenuItem } from '@stash/ui'
-import type { NavTarget } from '../../data/nav'
-import type { Category } from '../../data/types'
-
-/**
- * 分类导航树:由内容树派生。
- *
- * - 有分组的分类(apps)是折叠节点,子项是分组(分组可用 show_in_sidebar 单独隐藏);
- * - 没有分组、或分组全被隐藏的分类,就是一个普通菜单项。
- *
- * 折叠状态由组件库的 Menu 内部维护;这里只负责把内容树翻译成 items。
- */
-type CategoryNavProps = {
- /** 内容目录;顺序即侧栏顺序 */
- categories: Category[]
- /** 当前明细视图的分类 / 分组,用于高亮 */
- activeCategoryId?: string
- activeGroupId?: string
- /** 是否在首页(高亮「首页」项) */
- homeActive?: boolean
- onNavigate: (target: NavTarget) => void
- /** 点击「首页」 */
- onHome: () => void
-}
-
-const HOME_KEY = 'home'
-const categoryKey = (id: string) => `cat:${id}`
-const groupKey = (categoryId: string, groupId: string) => `group:${categoryId}:${groupId}`
-
-export function CategoryNav({
- categories,
- activeCategoryId,
- activeGroupId,
- homeActive = false,
- onNavigate,
- onHome,
-}: CategoryNavProps) {
- const items: MenuItem[] = [
- { key: HOME_KEY, label: '首页' },
- ...categories.map((category) => {
- // 「允许子分组」的分区才有 groups;空分组不出现在侧栏(后台仍保留)
- const groups = category.groups.filter((group) => group.items.length > 0)
-
- return {
- key: categoryKey(category.id),
- label: category.title,
- children:
- groups.length > 0
- ? groups.map((group) => ({
- key: groupKey(category.id, group.id),
- label: group.name,
- }))
- : undefined,
- }
- }),
- ]
-
- const activeKey = homeActive
- ? HOME_KEY
- : activeCategoryId === undefined
- ? undefined
- : activeGroupId !== undefined
- ? groupKey(activeCategoryId, activeGroupId)
- : categoryKey(activeCategoryId)
-
- const handleSelect = (key: string) => {
- if (key === HOME_KEY) {
- onHome()
- return
- }
-
- if (key.startsWith('group:')) {
- const [, categoryId, groupId] = key.split(':')
- onNavigate({ categoryId, groupId })
- return
- }
-
- onNavigate({ categoryId: key.slice('cat:'.length) })
- }
-
- return (
-