PermissionGroupList.tsx 1.8 KB
// REQ-USR-001 / REQ-USR-002: 权限分类勾选列表(表头全选 indeterminate + 逐项 Checkbox,BR10/BR11/D3)
import { Checkbox } from 'antd';
import type { PermissionItem } from '../../../api/types';
import { PERM_LIST_HEADER } from './constants';
import styles from './UserDetail.module.css';

export interface PermissionGroupListProps {
  permissions: PermissionItem[];
  checkedIds: number[];
  onToggle(id: number, checked: boolean): void;
  onToggleAll(checked: boolean): void;
  loading?: boolean;
}

export default function PermissionGroupList({
  permissions,
  checkedIds,
  onToggle,
  onToggleAll,
}: PermissionGroupListProps) {
  const total = permissions.length;
  const checkedCount = permissions.filter((p) => checkedIds.includes(p.id)).length;
  const allChecked = total > 0 && checkedCount === total;
  const indeterminate = checkedCount > 0 && checkedCount < total;

  return (
    <div className={styles.permList} data-testid="perm-list">
      <div className={styles.permHead}>
        <Checkbox
          checked={allChecked}
          indeterminate={indeterminate}
          onChange={(e) => onToggleAll(e.target.checked)}
          data-testid="perm-check-all"
        />
        <span>{PERM_LIST_HEADER}</span>
        <span className={styles.permHeadSort} aria-hidden="true">

        </span>
      </div>

      {total === 0 ? (
        <div className={styles.permEmpty} data-testid="perm-empty" />
      ) : (
        permissions.map((p) => (
          <label key={p.id} className={styles.permRow}>
            <Checkbox
              checked={checkedIds.includes(p.id)}
              onChange={(e) => onToggle(p.id, e.target.checked)}
              data-testid={'perm-check-' + p.id}
            />
            <span>{p.name}</span>
          </label>
        ))
      )}
    </div>
  );
}