背景:A2 开卡前完成 H1 权限门,确认权限点目录、特殊权限、SoD 三对、六类数据范围与超管隐式全集口径(ADR-001)。 改动: - shared:30 权限点 / 10 模块目录与元数据、特殊权限 6 编码、SoD 三对、角色与权限树契约;/me 改 dataScopes 多角色并集。 - prisma:expand 迁移新增 permissions / data_scopes;种子按原型口径重写角色权限、数据范围与 8 项特殊授予。 - api:角色 CRUD / 复制 / 停用 / 删除、权限点启动同步、SoD 40304、系统角色保护、六类范围 ScopeContext 与 CustomerDirectory 端口、变更审计与 outbox。 - web:方案 B 主从分栏三角色页面(列表 / 编辑器 / 新建),权限树、范围选择、特殊权限二次确认、保存影响、SoD 冲突、只读态与模板预填。 - 测试:角色集成 13 条 + A2 e2e 1 条;A1 全量回归。 验证:format:check / lint / typecheck / test(306)/ test:int(27)/ A2 e2e(1,复跑通过)/ openapi:export 全绿。
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import { Link } from 'react-router';
|
|
|
|
import { getRoleSectionTrail, getUserSectionTrail } from '@/navigation/breadcrumbs';
|
|
import { getBreadcrumbs, NAV_MODULES } from '@/navigation/nav-config';
|
|
|
|
export interface PageBreadcrumbsProps {
|
|
pathname: string;
|
|
}
|
|
|
|
export function PageBreadcrumbs({ pathname }: PageBreadcrumbsProps): ReactNode {
|
|
const entries =
|
|
getUserSectionTrail(pathname) ??
|
|
getRoleSectionTrail(pathname) ??
|
|
getBreadcrumbs(NAV_MODULES, pathname);
|
|
return (
|
|
<nav className="lx-breadcrumbs" aria-label="面包屑">
|
|
{entries.map((entry, index) => {
|
|
const isLast = index === entries.length - 1;
|
|
return (
|
|
<span key={entry.key} className="lx-breadcrumbs__entry">
|
|
{index > 0 ? <span className="lx-breadcrumbs__sep">/</span> : null}
|
|
{entry.path !== undefined && !isLast ? (
|
|
<Link to={entry.path} className="lx-breadcrumbs__link">
|
|
{entry.label}
|
|
</Link>
|
|
) : (
|
|
<span className={isLast ? 'lx-breadcrumbs__current' : 'lx-breadcrumbs__label'}>
|
|
{entry.label}
|
|
</span>
|
|
)}
|
|
</span>
|
|
);
|
|
})}
|
|
</nav>
|
|
);
|
|
}
|