index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { PlusIcon } from '@heroicons/react/24/solid'
  6. import type { ConfigItemType } from './config-item'
  7. import ConfigItem from './config-item'
  8. import s from './style.module.css'
  9. import { DataSourceType } from './types'
  10. import { DataSourceProvider } from '@/models/common'
  11. import cn from '@/utils/classnames'
  12. type Props = {
  13. type: DataSourceType
  14. provider: DataSourceProvider
  15. isConfigured: boolean
  16. onConfigure: () => void
  17. readOnly: boolean
  18. isSupportList?: boolean
  19. configuredList: ConfigItemType[]
  20. onRemove: () => void
  21. notionActions?: {
  22. onChangeAuthorizedPage: () => void
  23. }
  24. }
  25. const Panel: FC<Props> = ({
  26. type,
  27. provider,
  28. isConfigured,
  29. onConfigure,
  30. readOnly,
  31. configuredList,
  32. isSupportList,
  33. onRemove,
  34. notionActions,
  35. }) => {
  36. const { t } = useTranslation()
  37. const isNotion = type === DataSourceType.notion
  38. const isWebsite = type === DataSourceType.website
  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[`${type}-icon`], 'w-8 h-8 mr-3 border border-gray-100 rounded-lg')} />
  43. <div className='grow'>
  44. <div className='flex items-center h-5'>
  45. <div className='text-sm font-medium text-gray-800'>{t(`common.dataSource.${type}.title`)}</div>
  46. {isWebsite && (
  47. <div className='ml-1 leading-[18px] px-1.5 rounded-md bg-white border border-gray-100 text-xs font-medium text-gray-700'>
  48. <span className='text-gray-500'>{t('common.dataSource.website.with')}</span> { provider === DataSourceProvider.fireCrawl ? '🔥 Firecrawl' : 'Jina Reader'}
  49. </div>
  50. )}
  51. </div>
  52. {
  53. !isConfigured && (
  54. <div className='leading-5 text-xs text-gray-500'>
  55. {t(`common.dataSource.${type}.description`)}
  56. </div>
  57. )
  58. }
  59. </div>
  60. {isNotion && (
  61. <>
  62. {
  63. isConfigured
  64. ? (
  65. <div
  66. className={
  67. `flex items-center ml-3 px-3 h-7 bg-white border border-gray-200
  68. rounded-md text-xs font-medium text-gray-700
  69. ${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
  70. }
  71. onClick={onConfigure}
  72. >
  73. {t('common.dataSource.configure')}
  74. </div>
  75. )
  76. : (
  77. <>
  78. {isSupportList && <div
  79. className={
  80. `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
  81. ${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
  82. }
  83. onClick={onConfigure}
  84. >
  85. <PlusIcon className='w-[14px] h-[14px] mr-[5px]' />
  86. {t('common.dataSource.notion.addWorkspace')}
  87. </div>}
  88. </>
  89. )
  90. }
  91. </>
  92. )}
  93. {isWebsite && !isConfigured && (
  94. <div
  95. className={
  96. `flex items-center ml-3 px-3 h-7 bg-white border border-gray-200
  97. rounded-md text-xs font-medium text-gray-700
  98. ${!readOnly ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
  99. }
  100. onClick={!readOnly ? onConfigure : undefined}
  101. >
  102. {t('common.dataSource.configure')}
  103. </div>
  104. )}
  105. </div>
  106. {
  107. isConfigured && (
  108. <>
  109. <div className='flex items-center px-3 h-[18px]'>
  110. <div className='text-xs font-medium text-gray-500'>
  111. {isNotion ? t('common.dataSource.notion.connectedWorkspace') : t('common.dataSource.website.configuredCrawlers')}
  112. </div>
  113. <div className='grow ml-3 border-t border-t-gray-100' />
  114. </div>
  115. <div className='px-3 pt-2 pb-3'>
  116. {
  117. configuredList.map(item => (
  118. <ConfigItem
  119. key={item.id}
  120. type={type}
  121. payload={item}
  122. onRemove={onRemove}
  123. notionActions={notionActions}
  124. readOnly={readOnly}
  125. />
  126. ))
  127. }
  128. </div>
  129. </>
  130. )
  131. }
  132. </div>
  133. )
  134. }
  135. export default React.memo(Panel)