feat: role CRUD page
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { Home, Code, Calendar, Settings, Users, Folder } from "lucide-react";
|
||||
import { Home, Code, Calendar, Settings, Users, Folder, ShieldCheck } from "lucide-react";
|
||||
import type { ComponentType } from "react";
|
||||
|
||||
export type ActivePage = "home" | "scripts" | "schedules" | "system";
|
||||
export type SubPage = "users" | "projects";
|
||||
export type SubPage = "users" | "projects" | "roles";
|
||||
|
||||
export type NavigationItem = {
|
||||
/** 菜单显示名 */
|
||||
@@ -33,6 +33,7 @@ export const navigation: NavigationItem[] = [
|
||||
children: [
|
||||
{ label: "用户管理", icon: Users, page: "system", sub: "users", permission: "system:user:view" },
|
||||
{ label: "项目管理", icon: Folder, page: "system", sub: "projects", permission: "system:project:view" },
|
||||
{ label: "角色管理", icon: ShieldCheck, page: "system", sub: "roles", permission: "system:role:view" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Outlet, useLocation, useNavigate } from "react-router";
|
||||
|
||||
import { PanelLeft, ChevronRight } from "lucide-react";
|
||||
import { navigation } from "./platform.navigation";
|
||||
import type { ActivePage, NavigationItem } from "./platform.navigation";
|
||||
import type { ActivePage, NavigationItem, SubPage } from "./platform.navigation";
|
||||
import { Collapsible } from "@base-ui/react/collapsible";
|
||||
|
||||
import type { Route } from "./+types/platform";
|
||||
@@ -70,7 +70,7 @@ function NavRow({
|
||||
can: (code: string) => boolean;
|
||||
activePage: ActivePage;
|
||||
pathname: string;
|
||||
onNavigate: (sub?: "users" | "projects") => void;
|
||||
onNavigate: (sub?: SubPage) => void;
|
||||
}) {
|
||||
const itemIcon = <item.icon />;
|
||||
const childActivePath = (child: NavigationItem) =>
|
||||
@@ -208,7 +208,7 @@ function AuthenticatedLayout() {
|
||||
|
||||
// 原 common/Sidebar 的编辑会话守卫上移到这里:切出 /scripts 时有活动编辑
|
||||
// 会话先 endEditing,回工作台时清空选中脚本;再按当前激活页导航。
|
||||
function guardedNavigate(page: ActivePage, sub?: "users" | "projects") {
|
||||
function guardedNavigate(page: ActivePage, sub?: SubPage) {
|
||||
if (page !== "scripts" && editSessionHandle.current) {
|
||||
void endEditing(true);
|
||||
} else if (page === "home") {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useAuth } from "~/context/AuthContext";
|
||||
import { useScriptWorkspaceStore } from "~/features/platform/state/scriptWorkspaceStore";
|
||||
import { useUiStore } from "~/features/platform/state/uiStore";
|
||||
import { RoleManagementPage } from "~/features/admin/RoleManagementPage";
|
||||
|
||||
/**
|
||||
* /system/roles 路由页。RoleManagementPage 内部有 useState,
|
||||
* 在 user / workspace 切换时必须重挂载以重置本地状态
|
||||
* (见 CLAUDE.md「Route components with their own internal state」)。
|
||||
*/
|
||||
export default function RoleManagementRoute() {
|
||||
const { user, currentWorkspace } = useAuth();
|
||||
const setApiOnline = useScriptWorkspaceStore((s) => s.setApiOnline);
|
||||
const pushToast = useUiStore((s) => s.pushToast);
|
||||
|
||||
return (
|
||||
<RoleManagementPage
|
||||
key={`${user?.user_id ?? "anon"}-${currentWorkspace?.workspace_id ?? "none"}`}
|
||||
onNotify={pushToast}
|
||||
onConnectionChange={setApiOnline}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user