feat(skill-addresses): 将「技能地址管理」并入管理员「技能管理」页的标签页
- SkillAddressesPage 主体抽成可复用的 SkillAddressesPanel(默认导出保留旧路由作直链回退) - AdminSkillsPage 顶部加 Tabs:技能列表 + 技能地址管理(嵌入 panel) - 移除 page-sidebar 左下角设置下拉里两处独立的「技能地址管理」入口 - 同步更新前后端 CLAUDE.md 文档 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f8228847ab
commit
26557b30a0
5 files changed
+64
-39
No files matched your search
@@ -9,7 +9,6 @@ import {
|
||||
FolderOpen,
|
||||
ListTree,
|
||||
MousePointerClick,
|
||||
Replace,
|
||||
Settings,
|
||||
ShieldAlert,
|
||||
User,
|
||||
@@ -223,14 +222,6 @@ function SecondaryNavSidebar() {
|
||||
按钮管理
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{isAdmin && (
|
||||
<DropdownMenuItem
|
||||
onClick={() => navigate("/page/strategy/admin/skill-addresses")}
|
||||
>
|
||||
<Replace className="size-4" />
|
||||
技能地址管理
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{canManageSensitiveWords() && (
|
||||
<DropdownMenuItem
|
||||
onClick={() => navigate("/page/strategy/admin/sensitive-words")}
|
||||
@@ -517,12 +508,6 @@ function LegacyAccordionSidebar({
|
||||
按钮管理
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{isAdmin && (
|
||||
<DropdownMenuItem onClick={() => navigate("/page/strategy/admin/skill-addresses")}>
|
||||
<Replace className="size-4" />
|
||||
技能地址管理
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{canManageSensitiveWords() && (
|
||||
<DropdownMenuItem onClick={() => navigate("/page/strategy/admin/sensitive-words")}>
|
||||
<ShieldAlert className="size-4" />
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import {
|
||||
ChevronLeftIcon,
|
||||
ChevronRightIcon,
|
||||
Replace,
|
||||
SearchIcon,
|
||||
SparklesIcon,
|
||||
} from "lucide-react";
|
||||
@@ -10,6 +11,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import {
|
||||
WorkspaceBody,
|
||||
WorkspaceContainer,
|
||||
@@ -19,6 +21,7 @@ import { SkillRow } from "@/components/workspace/settings/skill-settings-page";
|
||||
import { getStoredAuth } from "@/core/auth";
|
||||
import { useAllSkillsAdmin } from "@/core/skills/hooks";
|
||||
import { desensitize } from "@/lib/desensitize";
|
||||
import { SkillAddressesPanel } from "./SkillAddressesPage";
|
||||
|
||||
const PAGE_SIZE = 10;
|
||||
|
||||
@@ -52,27 +55,47 @@ export default function AdminSkillsPage() {
|
||||
<WorkspaceContainer>
|
||||
<WorkspaceHeader />
|
||||
<WorkspaceBody>
|
||||
<div className="flex size-full min-h-0 flex-col">
|
||||
<div className="flex items-start justify-between gap-4 border-b px-6 py-4">
|
||||
<div>
|
||||
<Tabs
|
||||
defaultValue="skills"
|
||||
className="flex size-full min-h-0 flex-col gap-0"
|
||||
>
|
||||
<div className="flex items-center justify-between gap-4 border-b px-6 pt-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<h1 className="text-xl font-semibold">技能管理</h1>
|
||||
<p className="text-muted-foreground mt-0.5 text-sm">
|
||||
管理员视图:查看、编辑、删除所有用户的技能(包括内置技能与未发布的自定义技能)。
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative w-64 shrink-0">
|
||||
<SearchIcon className="text-muted-foreground absolute left-2.5 top-1/2 size-4 -translate-y-1/2" />
|
||||
<Input
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder="按名称搜索"
|
||||
className="pl-8"
|
||||
/>
|
||||
<TabsList>
|
||||
<TabsTrigger value="skills">
|
||||
<SparklesIcon />
|
||||
技能列表
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="addresses">
|
||||
<Replace />
|
||||
技能地址管理
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col gap-4 overflow-y-auto p-6">
|
||||
{isLoading && (
|
||||
<TabsContent
|
||||
value="skills"
|
||||
className="mt-0 flex min-h-0 flex-1 flex-col overflow-hidden"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4 border-b px-6 py-4">
|
||||
<p className="text-muted-foreground text-sm">
|
||||
管理员视图:查看、编辑、删除所有用户的技能(包括内置技能与未发布的自定义技能)。
|
||||
</p>
|
||||
<div className="relative w-64 shrink-0">
|
||||
<SearchIcon className="text-muted-foreground absolute left-2.5 top-1/2 size-4 -translate-y-1/2" />
|
||||
<Input
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder="按名称搜索"
|
||||
className="pl-8"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col gap-4 overflow-y-auto p-6">
|
||||
{isLoading && (
|
||||
<div className="text-muted-foreground flex h-40 items-center justify-center text-sm">
|
||||
加载中…
|
||||
</div>
|
||||
@@ -132,8 +155,16 @@ export default function AdminSkillsPage() {
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent
|
||||
value="addresses"
|
||||
className="mt-0 min-h-0 flex-1 overflow-hidden"
|
||||
>
|
||||
<SkillAddressesPanel />
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</WorkspaceBody>
|
||||
</WorkspaceContainer>
|
||||
);
|
||||
|
||||
@@ -72,7 +72,7 @@ function KindBadge({ kind }: { kind: AddressKind }) {
|
||||
);
|
||||
}
|
||||
|
||||
export default function SkillAddressesPage() {
|
||||
export function SkillAddressesPanel() {
|
||||
const isAdmin = getStoredAuth()?.system_role === "admin";
|
||||
|
||||
const [kinds, setKinds] = useState<AddressKind[]>(ALL_KINDS);
|
||||
@@ -462,6 +462,10 @@ export default function SkillAddressesPage() {
|
||||
);
|
||||
}
|
||||
|
||||
export default function SkillAddressesPage() {
|
||||
return <SkillAddressesPanel />;
|
||||
}
|
||||
|
||||
function GroupRow({
|
||||
group,
|
||||
value,
|
||||
|
||||
Reference in new issue
Block a user