import { type ButtonProps, Flex, Menu, MenuList, Box, Radio, useOutsideClick, HStack, MenuButton, Checkbox } from '@chakra-ui/react'; import React, { useMemo, useRef, useState } from 'react'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { type PermissionValueType } from '@fastgpt/global/support/permission/type'; import { useContextSelector } from 'use-context-selector'; import { Permission } from '@fastgpt/global/support/permission/controller'; import { CollaboratorContext } from './context'; import { useTranslation } from 'next-i18next'; import MyDivider from '@fastgpt/web/components/common/MyDivider'; export type PermissionSelectProps = { value?: PermissionValueType; onChange: (value: PermissionValueType) => void; trigger?: 'hover' | 'click'; offset?: [number, number]; Button: React.ReactNode; onDelete?: () => void; } & Omit; const MenuStyle = { py: 2, px: 3, _hover: { bg: 'myGray.50' }, borderRadius: 'md', cursor: 'pointer', fontSize: 'sm' }; function PermissionSelect({ value, onChange, trigger = 'click', offset = [0, 5], Button, width = 'auto', onDelete }: PermissionSelectProps) { const { t } = useTranslation(); const ref = useRef(null); const closeTimer = useRef(); const { permission, permissionList } = useContextSelector(CollaboratorContext, (v) => v); const [isOpen, setIsOpen] = useState(false); const permissionSelectList = useMemo(() => { if (!permissionList) return { singleCheckBoxList: [], multipleCheckBoxList: [] }; const list = Object.entries(permissionList).map(([_, value]) => { return { name: value.name, value: value.value, description: value.description, checkBoxType: value.checkBoxType }; }); return { singleCheckBoxList: list .filter((item) => item.checkBoxType === 'single') .filter((item) => { if (permission.isOwner) return true; if (item.value === permissionList['manage'].value) return false; return true; }), multipleCheckBoxList: list.filter((item) => item.checkBoxType === 'multiple') }; }, [permission.isOwner, permissionList]); const selectedSingleValue = useMemo(() => { if (!permissionList) return undefined; const per = new Permission({ per: value, permissionList }); if (per.hasManagePer) return permissionList['manage'].value; if (per.hasWritePer) return permissionList['write'].value; return permissionList['read'].value; }, [permissionList, value]); const selectedMultipleValues = useMemo(() => { const per = new Permission({ per: value, permissionList }); return permissionSelectList.multipleCheckBoxList .filter((item) => { return per.checkPer(item.value); }) .map((item) => item.value); }, [permissionList, permissionSelectList.multipleCheckBoxList, value]); const onSelectPer = (perValue: PermissionValueType) => { if (perValue === value) return; const per = new Permission({ per: perValue, permissionList }); per.addPer(...selectedMultipleValues); onChange(per.value); }; useOutsideClick({ ref: ref, handler: () => { setIsOpen(false); } }); return selectedSingleValue !== undefined ? ( { if (trigger === 'hover') { setIsOpen(true); } clearTimeout(closeTimer.current); }} onMouseLeave={() => { if (trigger === 'hover') { closeTimer.current = setTimeout(() => { setIsOpen(false); }, 100); } }} > { if (trigger === 'click') { setIsOpen(!isOpen); } }} > {Button} {/* The list of single select permissions */} {permissionSelectList.singleCheckBoxList.map((item) => { const change = () => { const per = new Permission({ per: value, permissionList }); per.removePer(selectedSingleValue); per.addPer(item.value); onSelectPer(per.value); }; return ( {t(item.name as any)} {t(item.description as any)} ); })} {permissionSelectList.multipleCheckBoxList.length > 0 && ( <> {permissionSelectList.multipleCheckBoxList.map((item) => { const isChecked = selectedMultipleValues.includes(item.value); const isDisabled = new Permission({ per: selectedSingleValue, permissionList }).checkPer(item.value); const change = () => { if (isDisabled) return; const per = new Permission({ per: value, permissionList }); if (isChecked) { per.removePer(item.value); } else { per.addPer(item.value); } onChange(per.value); }; return ( { // e.stopPropagation(); // e.preventDefault(); // }} isDisabled={isDisabled} /> {t(item.name as any)} {t(item.description as any)} ); })} )} {onDelete && ( <> { onDelete(); setIsOpen(false); }} > {t('common:Remove')} )} ) : null; } export default React.memo(PermissionSelect);