index.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. 'use client'
  2. import { useCallback, useState } from 'react'
  3. import { useRouter } from 'next/navigation'
  4. import { RiArrowLeftLine, RiArrowRightLine } from '@remixicon/react'
  5. import { useTranslation } from 'react-i18next'
  6. import KnowledgeBaseInfo from './KnowledgeBaseInfo'
  7. import ExternalApiSelection from './ExternalApiSelection'
  8. import RetrievalSettings from './RetrievalSettings'
  9. import InfoPanel from './InfoPanel'
  10. import type { CreateKnowledgeBaseReq } from './declarations'
  11. import Divider from '@/app/components/base/divider'
  12. import Button from '@/app/components/base/button'
  13. type ExternalKnowledgeBaseCreateProps = {
  14. onConnect: (formValue: CreateKnowledgeBaseReq) => void
  15. loading: boolean
  16. }
  17. const ExternalKnowledgeBaseCreate: React.FC<ExternalKnowledgeBaseCreateProps> = ({ onConnect, loading }) => {
  18. const { t } = useTranslation()
  19. const router = useRouter()
  20. const [formData, setFormData] = useState<CreateKnowledgeBaseReq>({
  21. name: '',
  22. description: '',
  23. external_knowledge_api_id: '',
  24. external_knowledge_id: '',
  25. external_retrieval_model: {
  26. top_k: 2,
  27. score_threshold: 0.5,
  28. score_threshold_enabled: false,
  29. },
  30. provider: 'external',
  31. })
  32. const navBackHandle = useCallback(() => {
  33. router.replace('/datasets')
  34. }, [router])
  35. const handleFormChange = (newData: CreateKnowledgeBaseReq) => {
  36. setFormData(newData)
  37. }
  38. const isFormValid = formData.name.trim() !== ''
  39. && formData.external_knowledge_api_id !== ''
  40. && formData.external_knowledge_id !== ''
  41. && formData.external_retrieval_model.top_k !== undefined
  42. && formData.external_retrieval_model.score_threshold !== undefined
  43. return (
  44. <div className='flex flex-col flex-grow self-stretch rounded-t-2xl border-t border-effects-highlight bg-components-panel-bg'>
  45. <div className='flex justify-center flex-grow self-stretch'>
  46. <div className='flex w-full max-w-[960px] px-14 py-0 flex-col items-center'>
  47. <div className='flex w-full max-w-[640px] pt-6 pb-8 flex-col grow items-center gap-4'>
  48. <div className='relative flex flex-col py-2 items-center gap-[2px] self-stretch'>
  49. <div className='flex-grow text-text-primary system-xl-semibold self-stretch'>{t('dataset.connectDataset')}</div>
  50. <p className='text-text-tertiary system-sm-regular'>
  51. <span>{t('dataset.connectHelper.helper1')}</span>
  52. <span className='text-text-secondary system-sm-medium'>{t('dataset.connectHelper.helper2')}</span>
  53. <span>{t('dataset.connectHelper.helper3')}</span>
  54. <a className='self-stretch text-text-accent system-sm-regular' href='https://docs.dify.ai/guides/knowledge-base/connect-external-knowledge' target='_blank' rel="noopener noreferrer">
  55. {t('dataset.connectHelper.helper4')}
  56. </a>
  57. <span>{t('dataset.connectHelper.helper5')} </span>
  58. </p>
  59. <Button
  60. className='flex w-8 h-8 p-2 items-center justify-center absolute left-[-44px] top-1 rounded-full'
  61. variant='tertiary'
  62. onClick={navBackHandle}
  63. >
  64. <RiArrowLeftLine className='w-4 h-4 text-text-tertiary' />
  65. </Button>
  66. </div>
  67. <KnowledgeBaseInfo
  68. name={formData.name}
  69. description={formData.description ?? ''}
  70. onChange={data => handleFormChange({
  71. ...formData,
  72. ...data,
  73. })}
  74. />
  75. <Divider />
  76. <ExternalApiSelection
  77. external_knowledge_api_id={formData.external_knowledge_api_id}
  78. external_knowledge_id={formData.external_knowledge_id}
  79. onChange={data => handleFormChange({
  80. ...formData,
  81. ...data,
  82. })}
  83. />
  84. <RetrievalSettings
  85. topK={formData.external_retrieval_model.top_k}
  86. scoreThreshold={formData.external_retrieval_model.score_threshold}
  87. scoreThresholdEnabled={formData.external_retrieval_model.score_threshold_enabled}
  88. onChange={data => handleFormChange({
  89. ...formData,
  90. external_retrieval_model: {
  91. ...formData.external_retrieval_model,
  92. ...data,
  93. },
  94. })}
  95. />
  96. <div className='flex py-2 justify-end items-center gap-2 self-stretch'>
  97. <Button variant='secondary' onClick={navBackHandle}>
  98. <div className='text-components-button-secondary-text system-sm-medium'>{t('dataset.externalKnowledgeForm.cancel')}</div>
  99. </Button>
  100. <Button
  101. variant='primary'
  102. onClick={() => {
  103. onConnect(formData)
  104. }}
  105. disabled={!isFormValid}
  106. loading={loading}
  107. >
  108. <div className='text-components-button-primary-text system-sm-medium'>{t('dataset.externalKnowledgeForm.connect')}</div>
  109. <RiArrowRightLine className='w-4 h-4 text-components-button-primary-text' />
  110. </Button>
  111. </div>
  112. </div>
  113. </div>
  114. <InfoPanel />
  115. </div>
  116. </div>
  117. )
  118. }
  119. export default ExternalKnowledgeBaseCreate