Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.tsx 4.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { Fragment } from 'react'
  2. import { useContext } from 'use-context-selector'
  3. import { useTranslation } from 'react-i18next'
  4. import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react'
  5. import { RiArrowDownSLine } from '@remixicon/react'
  6. import cn from '@/utils/classnames'
  7. import PlanBadge from '@/app/components/header/plan-badge'
  8. import { switchWorkspace } from '@/service/common'
  9. import { useWorkspacesContext } from '@/context/workspace-context'
  10. import { ToastContext } from '@/app/components/base/toast'
  11. import type { Plan } from '@/app/components/billing/type'
  12. const WorkplaceSelector = () => {
  13. const { t } = useTranslation()
  14. const { notify } = useContext(ToastContext)
  15. const { workspaces } = useWorkspacesContext()
  16. const currentWorkspace = workspaces.find(v => v.current)
  17. const handleSwitchWorkspace = async (tenant_id: string) => {
  18. try {
  19. if (currentWorkspace?.id === tenant_id)
  20. return
  21. await switchWorkspace({ url: '/workspaces/switch', body: { tenant_id } })
  22. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  23. location.assign(`${location.origin}`)
  24. }
  25. catch (e) {
  26. notify({ type: 'error', message: t('common.provider.saveFailed') })
  27. }
  28. }
  29. return (
  30. <Menu as="div" className="relative h-full w-full">
  31. {
  32. ({ open }) => (
  33. <>
  34. <MenuButton className={cn(
  35. `
  36. group flex w-full cursor-pointer items-center
  37. gap-1.5 p-0.5 hover:bg-state-base-hover ${open && 'bg-state-base-hover'} rounded-[10px]
  38. `,
  39. )}>
  40. <div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-blue-solid text-[13px]'>
  41. <span className='bg-gradient-to-r from-components-avatar-shape-fill-stop-0 to-components-avatar-shape-fill-stop-100 bg-clip-text font-semibold uppercase text-shadow-shadow-1 opacity-90'>{currentWorkspace?.name[0]?.toLocaleUpperCase()}</span>
  42. </div>
  43. <div className='flex flex-row'>
  44. <div className={'system-sm-medium max-w-[80px] truncate text-text-secondary'}>{currentWorkspace?.name}</div>
  45. <RiArrowDownSLine className='h-4 w-4 text-text-secondary' />
  46. </div>
  47. </MenuButton>
  48. <Transition
  49. as={Fragment}
  50. enter="transition ease-out duration-100"
  51. enterFrom="transform opacity-0 scale-95"
  52. enterTo="transform opacity-100 scale-100"
  53. leave="transition ease-in duration-75"
  54. leaveFrom="transform opacity-100 scale-100"
  55. leaveTo="transform opacity-0 scale-95"
  56. >
  57. <MenuItems
  58. className={cn(
  59. `
  60. shadows-shadow-lg absolute left-[-15px] mt-1 flex w-[280px] flex-col items-start rounded-xl bg-components-panel-bg-blur backdrop-blur-[5px]
  61. `,
  62. )}
  63. >
  64. <div className="flex w-full flex-col items-start self-stretch rounded-xl border-[0.5px] border-components-panel-border p-1 pb-2 shadow-lg ">
  65. <div className='flex items-start self-stretch px-3 pb-0.5 pt-1'>
  66. <span className='system-xs-medium-uppercase flex-1 text-text-tertiary'>{t('common.userProfile.workspace')}</span>
  67. </div>
  68. {
  69. workspaces.map(workspace => (
  70. <div className='flex items-center gap-2 self-stretch rounded-lg py-1 pl-3 pr-2 hover:bg-state-base-hover' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
  71. <div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-blue-solid text-[13px]'>
  72. <span className='bg-gradient-to-r from-components-avatar-shape-fill-stop-0 to-components-avatar-shape-fill-stop-100 bg-clip-text font-semibold uppercase text-shadow-shadow-1 opacity-90'>{workspace?.name[0]?.toLocaleUpperCase()}</span>
  73. </div>
  74. <div className='system-md-regular line-clamp-1 grow cursor-pointer overflow-hidden text-ellipsis text-text-secondary'>{workspace.name}</div>
  75. <PlanBadge plan={workspace.plan as Plan} />
  76. </div>
  77. ))
  78. }
  79. </div>
  80. </MenuItems>
  81. </Transition>
  82. </>
  83. )
  84. }
  85. </Menu>
  86. )
  87. }
  88. export default WorkplaceSelector