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