'use client';
import * as React from 'react';
import { useState, useRef } from 'react';
import { Button } from '@nice/ui/components/button';
import { Popover, PopoverContent, PopoverTrigger } from '@nice/ui/components/popover';
import {
Command,
CommandEmpty,
CommandGroup,
CommandItem,
CommandList,
} from '@nice/ui/components/command';
import { IconChevronDown, IconCheck, IconStarFilled, IconX } from '@tabler/icons-react';
import { cn } from '@nice/ui/lib/utils';
import { Badge } from '@nice/ui/components/badge';
import { DutyLevel } from '@fenghuo/common';
// 职务等级选项定义
const DUTY_LEVEL_OPTIONS = [
{ value: 3, label: DutyLevel.HIGH },
{ value: 2, label: DutyLevel.MIDDLE },
{ value: 1, label: DutyLevel.PRIMARY },
];
// 职务等级选择器属性
interface DutyLevelSelectorProps {
value?: number | number[]; // 支持单选和多选
onValueChange?: (value: number | number[]) => void;
placeholder?: string;
className?: string;
disabled?: boolean;
allowClear?: boolean;
multiple?: boolean; // 是否支持多选
modal?: boolean; // 是否为模态模式,用于在 Dialog 中解决滚轮问题
}
// 职务等级星星显示组件
function DutyLevelStars({ level }: { level: number }) {
const stars = Array.from({ length: level }, (_, index) => (
));
return
{stars}
;
}
// 职务等级选项组件
interface DutyLevelItemProps {
option: { value: number; label: string };
isSelected: boolean;
onSelect: () => void;
}
function DutyLevelItem({ option, isSelected, onSelect }: DutyLevelItemProps) {
return (
{/* 星星图标 */}
{/* 等级信息 */}
{option.label}
{/* 选中状态指示 */}
{isSelected && }
);
}
// 主组件
export function DutyLevelSelect({
value,
onValueChange,
placeholder = '选择职务等级',
className,
disabled = false,
allowClear = true,
multiple = false,
modal = false,
}: DutyLevelSelectorProps) {
const [open, setOpen] = useState(false);
const containerRef = useRef(null);
// 获取选中的职务等级
const selectedLevels = React.useMemo(() => {
if (!value) return [];
const selectedValues = Array.isArray(value) ? value : [value];
return DUTY_LEVEL_OPTIONS.filter((option) => selectedValues.includes(option.value));
}, [value]);
// 处理选择逻辑
const handleSelect = (levelValue: number) => {
if (!onValueChange) return;
if (multiple) {
const currentValues = Array.isArray(value) ? value : value ? [value] : [];
if (currentValues.includes(levelValue)) {
// 取消选择
const newValues = currentValues.filter((val) => val !== levelValue);
onValueChange(newValues);
} else {
// 添加选择
onValueChange([...currentValues, levelValue]);
}
} else {
// 单选模式
onValueChange(levelValue);
setOpen(false);
}
};
// 清除选择
const handleClear = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
onValueChange?.(multiple ? [] : 0);
};
// 处理单个职务等级移除(仅多选模式)
const handleRemoveLevel = (levelValue: number, e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
if (multiple) {
const currentValues = Array.isArray(value) ? value : value ? [value] : [];
const newValues = currentValues.filter((val) => val !== levelValue);
onValueChange?.(newValues);
}
};
// 渲染触发器内容
const renderTriggerContent = () => {
if (selectedLevels.length === 0) {
return placeholder;
}
if (multiple) {
if (selectedLevels.length === 1) {
return (
{selectedLevels[0]!.label}
);
} else {
return (
{selectedLevels.slice(0, 1).map((level) => (
{level.label}
handleRemoveLevel(level.value, e)}
className="ml-1 hover:bg-muted-foreground/20 rounded-sm p-0.5 cursor-pointer inline-flex items-center justify-center"
role="button"
tabIndex={0}
aria-label={`移除职务等级 ${level.label}`}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleRemoveLevel(level.value, e as any);
}
}}
>
))}
{selectedLevels.length > 1 && (
+{selectedLevels.length - 1}
)}
);
}
}
return (
{selectedLevels[0]!.label}
);
};
// 检查是否选中
const isSelected = (levelValue: number) => {
if (!value) return false;
return Array.isArray(value) ? value.includes(levelValue) : value === levelValue;
};
return (
{DUTY_LEVEL_OPTIONS.length === 0 ? (
未找到职务等级
) : (
{/* 多选模式下显示已选择数量 */}
{multiple && selectedLevels.length > 0 && (
已选择 {selectedLevels.length} 个职务等级
)}
{DUTY_LEVEL_OPTIONS.map((option) => (
handleSelect(option.value)}
/>
))}
)}
);
}
// 导出便捷的单选和多选组件
export function SingleDutyLevelSelector(
props: Omit & {
onValueChange?: (value: number) => void;
},
) {
const handleValueChange = (value: number | number[]) => {
if (props.onValueChange && typeof value === 'number') {
props.onValueChange(value);
}
};
return ;
}
export function MultipleDutyLevelSelector(
props: Omit & {
onValueChange?: (value: number[]) => void;
},
) {
const handleValueChange = (value: number | number[]) => {
if (props.onValueChange && Array.isArray(value)) {
props.onValueChange(value);
}
};
return ;
}