Spaces:
Build error
Build error
File size: 5,321 Bytes
a8b3f00 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
'use client'
import { useTranslation } from 'react-i18next'
import { Fragment, useMemo } from 'react'
import { useContext } from 'use-context-selector'
import { Menu, Transition } from '@headlessui/react'
import { CheckIcon, ChevronDownIcon } from '@heroicons/react/24/outline'
import s from './index.module.css'
import { useProviderContext } from '@/context/provider-context'
import cn from '@/utils/classnames'
import type { Member } from '@/models/common'
import { deleteMemberOrCancelInvitation, updateMemberRole } from '@/service/common'
import { ToastContext } from '@/app/components/base/toast'
const itemClassName = `
flex px-3 py-2 cursor-pointer hover:bg-gray-50 rounded-lg
`
const itemIconClassName = `
w-4 h-4 mt-[2px] mr-1 text-primary-600
`
const itemTitleClassName = `
leading-[20px] text-sm text-gray-700 whitespace-nowrap
`
const itemDescClassName = `
leading-[18px] text-xs text-gray-500 whitespace-nowrap
`
type IOperationProps = {
member: Member
onOperate: () => void
}
const Operation = ({
member,
onOperate,
}: IOperationProps) => {
const { t } = useTranslation()
const { datasetOperatorEnabled } = useProviderContext()
const RoleMap = {
owner: t('common.members.owner'),
admin: t('common.members.admin'),
editor: t('common.members.editor'),
normal: t('common.members.normal'),
dataset_operator: t('common.members.datasetOperator'),
}
const roleList = useMemo(() => {
return [
...['admin', 'editor', 'normal'],
...(datasetOperatorEnabled ? ['dataset_operator'] : []),
]
}, [datasetOperatorEnabled])
const { notify } = useContext(ToastContext)
const toHump = (name: string) => name.replace(/_(\w)/g, (all, letter) => letter.toUpperCase())
const handleDeleteMemberOrCancelInvitation = async () => {
try {
await deleteMemberOrCancelInvitation({ url: `/workspaces/current/members/${member.id}` })
onOperate()
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e) {
}
}
const handleUpdateMemberRole = async (role: string) => {
try {
await updateMemberRole({
url: `/workspaces/current/members/${member.id}/update-role`,
body: { role },
})
onOperate()
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
}
catch (e) {
}
}
return (
<Menu as="div" className="relative w-full h-full">
{
({ open }) => (
<>
<Menu.Button className={cn(
`
group flex items-center justify-between w-full h-full
hover:bg-gray-100 cursor-pointer ${open && 'bg-gray-100'}
text-[13px] text-gray-700 px-3
`,
)}>
{RoleMap[member.role] || RoleMap.normal}
<ChevronDownIcon className={`w-4 h-4 group-hover:block ${open ? 'block' : 'hidden'}`} />
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items
className={cn(
`
absolute right-0 top-[52px] z-10 bg-white border-[0.5px] border-gray-200
divide-y divide-gray-100 origin-top-right rounded-lg
`,
s.popup,
)}
>
<div className="px-1 py-1">
{
roleList.map(role => (
<Menu.Item key={role}>
<div className={itemClassName} onClick={() => handleUpdateMemberRole(role)}>
{
role === member.role
? <CheckIcon className={itemIconClassName} />
: <div className={itemIconClassName} />
}
<div>
<div className={itemTitleClassName}>{t(`common.members.${toHump(role)}`)}</div>
<div className={itemDescClassName}>{t(`common.members.${toHump(role)}Tip`)}</div>
</div>
</div>
</Menu.Item>
))
}
</div>
<Menu.Item>
<div className='px-1 py-1'>
<div className={itemClassName} onClick={handleDeleteMemberOrCancelInvitation}>
<div className={itemIconClassName} />
<div>
<div className={itemTitleClassName}>{t('common.members.removeFromTeam')}</div>
<div className={itemDescClassName}>{t('common.members.removeFromTeamTip')}</div>
</div>
</div>
</div>
</Menu.Item>
</Menu.Items>
</Transition>
</>
)
}
</Menu>
)
}
export default Operation
|