index.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useCallback, useEffect, useState } from 'react'
  4. import { useTranslation } from 'react-i18next'
  5. import { useBoolean } from 'ahooks'
  6. import cn from 'classnames'
  7. import Panel from '../panel'
  8. import { DataSourceType } from '../panel/types'
  9. import ConfigFirecrawlModal from './config-firecrawl-modal'
  10. import { fetchDataSources, removeDataSourceApiKeyBinding } from '@/service/datasets'
  11. import type {
  12. DataSourceItem,
  13. } from '@/models/common'
  14. import { useAppContext } from '@/context/app-context'
  15. import {
  16. DataSourceProvider,
  17. } from '@/models/common'
  18. import Toast from '@/app/components/base/toast'
  19. type Props = {}
  20. const DataSourceWebsite: FC<Props> = () => {
  21. const { t } = useTranslation()
  22. const { isCurrentWorkspaceManager } = useAppContext()
  23. const [sources, setSources] = useState<DataSourceItem[]>([])
  24. const checkSetApiKey = useCallback(async () => {
  25. const res = await fetchDataSources() as any
  26. const list = res.sources
  27. setSources(list)
  28. }, [])
  29. useEffect(() => {
  30. checkSetApiKey()
  31. // eslint-disable-next-line react-hooks/exhaustive-deps
  32. }, [])
  33. const [isShowConfig, {
  34. setTrue: showConfig,
  35. setFalse: hideConfig,
  36. }] = useBoolean(false)
  37. const handleAdded = useCallback(() => {
  38. checkSetApiKey()
  39. hideConfig()
  40. }, [checkSetApiKey, hideConfig])
  41. const getIdByProvider = (provider: string): string | undefined => {
  42. const source = sources.find(item => item.provider === provider)
  43. return source?.id
  44. }
  45. const handleRemove = useCallback((provider: string) => {
  46. return async () => {
  47. const dataSourceId = getIdByProvider(provider)
  48. if (dataSourceId) {
  49. await removeDataSourceApiKeyBinding(dataSourceId)
  50. setSources(sources.filter(item => item.provider !== provider))
  51. Toast.notify({
  52. type: 'success',
  53. message: t('common.api.remove'),
  54. })
  55. }
  56. }
  57. }, [sources, t])
  58. return (
  59. <>
  60. <Panel
  61. type={DataSourceType.website}
  62. isConfigured={sources.length > 0}
  63. onConfigure={showConfig}
  64. readOnly={!isCurrentWorkspaceManager}
  65. configuredList={sources.map(item => ({
  66. id: item.id,
  67. logo: ({ className }: { className: string }) => (
  68. <div className={cn(className, 'flex items-center justify-center w-5 h-5 bg-white border border-gray-100 text-xs font-medium text-gray-500 rounded ml-3')}>🔥</div>
  69. ),
  70. name: 'Firecrawl',
  71. isActive: true,
  72. }))}
  73. onRemove={handleRemove(DataSourceProvider.fireCrawl)}
  74. />
  75. {isShowConfig && (
  76. <ConfigFirecrawlModal onSaved={handleAdded} onCancel={hideConfig} />
  77. )}
  78. </>
  79. )
  80. }
  81. export default React.memo(DataSourceWebsite)