文件
hyb-oa/client/src/components/navigation/NavLinks.tsx
T
wangsli fc50ffc808 feat(client): 用户管理页 + E2E 门禁(E15/E16/E18)
- 新增系统用户管理页(创建/禁用启用/重置密码/角色)

- 引入 Playwright E2E:覆盖登录-报销-待办-票据-OCR-支付-登出

- 新增 ci-e2e 工作流(PR + nightly)
2026-02-09 01:13:14 +08:00

80 行
1.8 KiB
TypeScript

import { NavLink } from "react-router-dom";
import { useAuth } from "../../auth/AuthContext";
import { hasAnyPermission } from "../../auth/permissions";
import { cn } from "../../lib/utils";
export type NavItem = {
to: string;
label: string;
anyOf?: string[];
};
export const NAV_ITEMS: NavItem[] = [
{ to: "/dashboard", label: "仪表盘" },
{
to: "/reimbursements",
label: "我的报销",
anyOf: ["expense.view_own", "expense.view_all"],
},
{
to: "/workflow/tasks",
label: "待我处理",
anyOf: ["expense.approve"],
},
{
to: "/invoice-pool",
label: "票据中心",
anyOf: ["invoice.upload", "invoice.view_own", "invoice.manage"],
},
{
to: "/audit-logs",
label: "审计工作台",
anyOf: ["system.audit.view"],
},
{
to: "/delegations",
label: "委派管理",
anyOf: ["expense.proxy_manage"],
},
{
to: "/system/users",
label: "用户管理",
anyOf: ["system.users"],
},
{ to: "/settings/profile", label: "个人设置" },
];
export function NavLinks({ onNavigate }: { onNavigate?: () => void }) {
const { permissions } = useAuth();
const visibleItems = NAV_ITEMS.filter((item) => {
if (!item.anyOf) {
return true;
}
return hasAnyPermission(permissions, item.anyOf);
});
return (
<nav className="space-y-1">
{visibleItems.map((item) => (
<NavLink
key={item.to}
to={item.to}
onClick={() => onNavigate?.()}
className={({ isActive }) =>
cn(
"block rounded-lg px-3 py-2.5 text-sm font-medium transition-colors",
isActive
? "bg-primary-50 text-primary"
: "text-slate-700 hover:bg-slate-50 hover:text-slate-900",
)
}
>
{item.label}
</NavLink>
))}
</nav>
);
}