Commit 06252b2c066ff256be4695625a44a362e1083d3b
1 parent
87c3d1f0
feat(usr): 用户单据权限页签条 PermissionTabs REQ-USR-001
Showing
2 changed files
with
75 additions
and
0 deletions
frontend/src/pages/usr/UserDetail/PermissionTabs.tsx
0 → 100644
| 1 | +// REQ-USR-001: 权限页签条(权限组 active 承载权限列表 + 5 占位查看权限页签 disabled,D9) | |
| 2 | +import type { ReactNode } from 'react'; | |
| 3 | +import { Tabs } from 'antd'; | |
| 4 | +import { TAB_PERM_GROUP, PLACEHOLDER_TABS } from './constants'; | |
| 5 | +import styles from './UserDetail.module.css'; | |
| 6 | + | |
| 7 | +export interface PermissionTabsProps { | |
| 8 | + activeKey?: string; | |
| 9 | + onChange?(key: string): void; | |
| 10 | + children: ReactNode; | |
| 11 | +} | |
| 12 | + | |
| 13 | +const GROUP_KEY = 'group'; | |
| 14 | + | |
| 15 | +export default function PermissionTabs({ activeKey, onChange, children }: PermissionTabsProps) { | |
| 16 | + const items = [ | |
| 17 | + { key: GROUP_KEY, label: TAB_PERM_GROUP, children }, | |
| 18 | + ...PLACEHOLDER_TABS.map((label, idx) => ({ | |
| 19 | + key: 'placeholder-' + idx, | |
| 20 | + label, | |
| 21 | + disabled: true, | |
| 22 | + children: null, | |
| 23 | + })), | |
| 24 | + ]; | |
| 25 | + | |
| 26 | + return ( | |
| 27 | + <Tabs | |
| 28 | + className={styles.permTabs} | |
| 29 | + defaultActiveKey={GROUP_KEY} | |
| 30 | + activeKey={activeKey} | |
| 31 | + onChange={onChange} | |
| 32 | + items={items} | |
| 33 | + /> | |
| 34 | + ); | |
| 35 | +} | ... | ... |
frontend/tests/unit/PermissionTabs.test.tsx
0 → 100644
| 1 | +// REQ-USR-001: PermissionTabs 权限页签条单测(权限组 active + 5 占位页签 disabled,D9) | |
| 2 | +import { describe, it, expect } from 'vitest'; | |
| 3 | +import { screen } from '@testing-library/react'; | |
| 4 | +import { renderShell } from './renderShell'; | |
| 5 | +import PermissionTabs from '../../src/pages/usr/UserDetail/PermissionTabs'; | |
| 6 | +import { PLACEHOLDER_TABS } from '../../src/pages/usr/UserDetail/constants'; | |
| 7 | + | |
| 8 | +function setup() { | |
| 9 | + renderShell( | |
| 10 | + <PermissionTabs> | |
| 11 | + <div data-testid="perm-children">权限列表内容</div> | |
| 12 | + </PermissionTabs>, | |
| 13 | + { preloadedAuth: { token: 't', user: { id: 1, sUserName: 'a', sUserType: 'x', sLanguage: '中文' } } }, | |
| 14 | + ); | |
| 15 | +} | |
| 16 | + | |
| 17 | +describe('PermissionTabs', () => { | |
| 18 | + it('renders 权限组 active with children', () => { | |
| 19 | + setup(); | |
| 20 | + const groupTab = screen.getByRole('tab', { name: '权限组' }); | |
| 21 | + expect(groupTab).toBeInTheDocument(); | |
| 22 | + expect(groupTab.getAttribute('aria-selected')).toBe('true'); | |
| 23 | + expect(screen.getByTestId('perm-children')).toBeInTheDocument(); | |
| 24 | + }); | |
| 25 | + | |
| 26 | + it('renders 5 placeholder tabs disabled', () => { | |
| 27 | + setup(); | |
| 28 | + for (const name of PLACEHOLDER_TABS) { | |
| 29 | + const tab = screen.getByRole('tab', { name }); | |
| 30 | + expect(tab).toBeInTheDocument(); | |
| 31 | + expect(tab.getAttribute('aria-disabled')).toBe('true'); | |
| 32 | + } | |
| 33 | + }); | |
| 34 | + | |
| 35 | + it('placeholder tabs do not render permission list content', () => { | |
| 36 | + setup(); | |
| 37 | + // 占位页签 disabled 无法切换,权限列表内容只在权限组面板内渲染(只 1 处) | |
| 38 | + expect(screen.getAllByTestId('perm-children')).toHaveLength(1); | |
| 39 | + }); | |
| 40 | +}); | ... | ... |