index.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import { useEffect, useState } from 'react'
  2. import useSWR from 'swr'
  3. import { useTranslation } from 'react-i18next'
  4. import { PlusIcon } from '@heroicons/react/24/solid'
  5. import cn from 'classnames'
  6. import Indicator from '../../../indicator'
  7. import Operate from './operate'
  8. import s from './style.module.css'
  9. import NotionIcon from '@/app/components/base/notion-icon'
  10. import type { DataSourceNotion as TDataSourceNotion } from '@/models/common'
  11. import { useAppContext } from '@/context/app-context'
  12. import { fetchNotionConnection } from '@/service/common'
  13. type DataSourceNotionProps = {
  14. workspaces: TDataSourceNotion[]
  15. }
  16. const DataSourceNotion = ({
  17. workspaces,
  18. }: DataSourceNotionProps) => {
  19. const { t } = useTranslation()
  20. const { isCurrentWorkspaceManager } = useAppContext()
  21. const [canConnectNotion, setCanConnectNotion] = useState(false)
  22. const { data } = useSWR(canConnectNotion ? '/oauth/data-source/notion' : null, fetchNotionConnection)
  23. const connected = !!workspaces.length
  24. const handleConnectNotion = () => {
  25. if (!isCurrentWorkspaceManager)
  26. return
  27. setCanConnectNotion(true)
  28. }
  29. const handleAuthAgain = () => {
  30. if (data?.data)
  31. window.location.href = data.data
  32. else
  33. setCanConnectNotion(true)
  34. }
  35. useEffect(() => {
  36. if (data?.data)
  37. window.location.href = data.data
  38. }, [data])
  39. return (
  40. <div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-xl'>
  41. <div className='flex items-center px-3 py-[9px]'>
  42. <div className={cn(s['notion-icon'], 'w-8 h-8 mr-3 border border-gray-100 rounded-lg')} />
  43. <div className='grow'>
  44. <div className='leading-5 text-sm font-medium text-gray-800'>
  45. {t('common.dataSource.notion.title')}
  46. </div>
  47. {
  48. !connected && (
  49. <div className='leading-5 text-xs text-gray-500'>
  50. {t('common.dataSource.notion.description')}
  51. </div>
  52. )
  53. }
  54. </div>
  55. {
  56. connected
  57. ? (
  58. <div
  59. className={
  60. `flex items-center ml-3 px-3 h-7 bg-white border border-gray-200
  61. rounded-md text-xs font-medium text-gray-700
  62. ${isCurrentWorkspaceManager ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
  63. }
  64. onClick={handleConnectNotion}
  65. >
  66. {t('common.dataSource.connect')}
  67. </div>
  68. )
  69. : (
  70. <div
  71. className={
  72. `flex items-center px-3 py-1 min-h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md
  73. ${isCurrentWorkspaceManager ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
  74. }
  75. onClick={handleConnectNotion}
  76. >
  77. <PlusIcon className='w-[14px] h-[14px] mr-[5px]' />
  78. {t('common.dataSource.notion.addWorkspace')}
  79. </div>
  80. )
  81. }
  82. </div>
  83. {
  84. connected && (
  85. <div className='flex items-center px-3 h-[18px]'>
  86. <div className='text-xs font-medium text-gray-500'>
  87. {t('common.dataSource.notion.connectedWorkspace')}
  88. </div>
  89. <div className='grow ml-3 border-t border-t-gray-100' />
  90. </div>
  91. )
  92. }
  93. {
  94. connected && (
  95. <div className='px-3 pt-2 pb-3'>
  96. {
  97. workspaces.map(workspace => (
  98. <div className={cn(s['workspace-item'], 'flex items-center mb-1 py-1 pr-1 bg-white rounded-lg')} key={workspace.id}>
  99. <NotionIcon
  100. className='ml-3 mr-[6px]'
  101. src={workspace.source_info.workspace_icon}
  102. name={workspace.source_info.workspace_name}
  103. />
  104. <div className='grow py-[7px] leading-[18px] text-[13px] font-medium text-gray-700 truncate' title={workspace.source_info.workspace_name}>{workspace.source_info.workspace_name}</div>
  105. {
  106. workspace.is_bound
  107. ? <Indicator className='shrink-0 mr-[6px]' />
  108. : <Indicator className='shrink-0 mr-[6px]' color='yellow' />
  109. }
  110. <div className='shrink-0 mr-3 text-xs font-medium'>
  111. {
  112. workspace.is_bound
  113. ? t('common.dataSource.notion.connected')
  114. : t('common.dataSource.notion.disconnected')
  115. }
  116. </div>
  117. <div className='mr-2 w-[1px] h-3 bg-gray-100' />
  118. <Operate workspace={workspace} onAuthAgain={handleAuthAgain} />
  119. </div>
  120. ))
  121. }
  122. </div>
  123. )
  124. }
  125. </div>
  126. )
  127. }
  128. export default DataSourceNotion