import React, { FC, useState, useMemo, ReactText, useCallback } from 'react'; import Popover from 'antd/es/popover'; import 'antd/es/popover/style/index'; import Tag from 'antd/es/tag'; import 'antd/es/tag/style/index'; import Tooltip from 'antd/es/tooltip'; import 'antd/es/tooltip/style/index'; import { XuiReactAngleThinRightIcon, XuiReactCheckMarkIcon } from '@jy-fe/icons'; import classnames from 'classnames'; import { XuiRoleMenuProps, RoleType, PositionType } from './xui-role-menu.d'; const classNameRoleMenu = 'xui-ant__role-menu'; const classNameRoleMenuPopover = `${classNameRoleMenu}--popover`; const classNameRoleMenuContainer = `${classNameRoleMenu}--container`; const classNameScrollContent = `${classNameRoleMenu}--scroll-content`; const classNameTitle = `${classNameRoleMenu}--title`; const classNamePosition = `${classNameRoleMenu}--position`; const classNamePositionItem = `${classNameRoleMenu}--position-item`; const classNamePositionSelected = `${classNameRoleMenu}--position-item-selected`; const classNamePositionItemInfo = `${classNameRoleMenu}--position-item-info`; const classNamePositionItemInfoName = `${classNameRoleMenu}--position-item-info-name`; const classNamePositionItemInfoDept = `${classNameRoleMenu}--position-item-info-dept`; const classNameRole = `${classNameRoleMenu}--role`; const classNameRoleBlank = `${classNameRoleMenu}--role-blank`; const classNameRoleItem = `${classNameRoleMenu}--role-item`; const classNameRoleItemSelected = `${classNameRoleMenu}--role-item-selected`; const classNameRoleItemName = `${classNameRoleMenu}--role-item-name`; const TooltipText: FC<{ max: number; children: any }> = ({ children, max }) => { let content; if (typeof children === 'string') { if (children.length > max) { content = {`${children.slice(0, max)}...`}; } else { content = children; } } return {content}; }; const Title: FC = ({ children }) => { return (
{children}
); }; const XuiRoleMenu: FC = ({ children, dataSource = [], visible, onChange, onVisibleChange, placement = 'bottom', trigger = 'hover', className, }) => { /** 根据登录数据初始化选中岗位角色 */ const setDefaultRoleList = useCallback(() => { dataSource.forEach(position => { if (position.defaultFlag) { setSelectedPosition(position.postId); setRoleList(formatRoleList(position)); } }); }, [dataSource]); const onPopoverVisibleChange = visible => { onVisibleChange?.(visible); if (visible) { setDefaultRoleList(); } }; const formatRoleList = (position: PositionType) => { if (position) { // 为角色增加岗位Id postId return position?.roleList.map(role => ({ ...role, postId: position.postId, orgId: position.orgId, })); } return []; }; const visibleProps = typeof visible === 'boolean' ? { visible, onVisibleChange: onPopoverVisibleChange, } : undefined; const [roleList, setRoleList] = useState([]); const [selectedPosition, setSelectedPosition] = useState(''); const idList = useMemo(() => { const result = [] as ReactText[]; dataSource?.forEach(position => { if (position.defaultFlag) { result.push(position.postId); position?.roleList?.forEach(role => { if (role.defaultFlag) { result.push(role.roleId); } }); } }); return result; }, [dataSource]); const triggerOperatorProp = useCallback( ({ orgId, postId, roleList }) => { const operator = { click: 'onClick', hover: 'onMouseEnter', }; return trigger && ['click', 'hover'] ? { [operator[trigger]]: () => { /** * trigger click 时,修改职位选中项为点击到的岗位 * trigger hover 时,不修改职位选中项,状态保存为进入时的默认选项 */ if (trigger === 'click') { setSelectedPosition(postId); } setRoleList(roleList?.map(item => ({ ...item, postId, orgId })) || []); }, } : undefined; }, [trigger], ); const content = (
选择岗位
{dataSource.map(({ postId, postTitle, orgId, orgTitle, orgKey, roleList }) => (
{postTitle}
{orgTitle}
))}
选择角色
{roleList.length ? ( roleList.map(({ postId, roleId, orgId, roleLabel }) => { /** 岗位角色 id 全部对应上,才能确认对应选项 */ const selected = postId === idList?.[0] && roleId === idList?.[1]; return (
onChange({ postId, roleId, orgId })} >
{roleLabel}
{selected && (
)}
); }) ) : (
暂无角色
)}
); return dataSource?.length > 0 ? ( {children} ) : ( <>{children} ); }; export default XuiRoleMenu;