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 | +}); |