mirror of
				https://github.com/langgenius/dify.git
				synced 2025-10-30 18:33:30 +00:00 
			
		
		
		
	 20376ca951
			
		
	
	
		20376ca951
		
			
		
	
	
	
	
		
			
			Support filter knowledge by metadata. Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: NFish <douxc512@gmail.com>
		
			
				
	
	
		
			160 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { useBatchUpdateDocMetadata, useDatasetMetaData, useDocumentMetaData } from '@/service/knowledge/use-metadata'
 | |
| import { useDatasetDetailContext } from '@/context/dataset-detail'
 | |
| import type { BuiltInMetadataItem } from '../types'
 | |
| import { DataType, type MetadataItemWithValue } from '../types'
 | |
| import { useCallback, useState } from 'react'
 | |
| import Toast from '@/app/components/base/toast'
 | |
| import type { FullDocumentDetail } from '@/models/datasets'
 | |
| import { useTranslation } from 'react-i18next'
 | |
| import { useLanguages, useMetadataMap } from '@/hooks/use-metadata'
 | |
| import { get } from 'lodash-es'
 | |
| import { useCreateMetaData } from '@/service/knowledge/use-metadata'
 | |
| import useCheckMetadataName from './use-check-metadata-name'
 | |
| 
 | |
| type Props = {
 | |
|   datasetId: string
 | |
|   documentId: string
 | |
|   docDetail: FullDocumentDetail
 | |
| }
 | |
| 
 | |
| const useMetadataDocument = ({
 | |
|   datasetId,
 | |
|   documentId,
 | |
|   docDetail,
 | |
| }: Props) => {
 | |
|   const { t } = useTranslation()
 | |
| 
 | |
|   const { dataset } = useDatasetDetailContext()
 | |
|   const embeddingAvailable = !!dataset?.embedding_available
 | |
| 
 | |
|   const { mutateAsync } = useBatchUpdateDocMetadata()
 | |
|   const { checkName } = useCheckMetadataName()
 | |
| 
 | |
|   const [isEdit, setIsEdit] = useState(false)
 | |
|   const { data: documentDetail } = useDocumentMetaData({
 | |
|     datasetId,
 | |
|     documentId,
 | |
|   })
 | |
| 
 | |
|   const allList = documentDetail?.doc_metadata || []
 | |
|   const list = allList.filter(item => item.id !== 'built-in')
 | |
|   const builtList = allList.filter(item => item.id === 'built-in')
 | |
|   const [tempList, setTempList] = useState<MetadataItemWithValue[]>(list)
 | |
|   const { mutateAsync: doAddMetaData } = useCreateMetaData(datasetId)
 | |
|   const handleSelectMetaData = useCallback((metaData: MetadataItemWithValue) => {
 | |
|     setTempList((prev) => {
 | |
|       const index = prev.findIndex(item => item.id === metaData.id)
 | |
|       if (index === -1)
 | |
|         return [...prev, metaData]
 | |
| 
 | |
|       return prev
 | |
|     })
 | |
|   }, [])
 | |
|   const handleAddMetaData = useCallback(async (payload: BuiltInMetadataItem) => {
 | |
|     const errorMsg = checkName(payload.name).errorMsg
 | |
|     if (errorMsg) {
 | |
|       Toast.notify({
 | |
|         message: errorMsg,
 | |
|         type: 'error',
 | |
|       })
 | |
|       return Promise.reject(new Error(errorMsg))
 | |
|     }
 | |
|     await doAddMetaData(payload)
 | |
|     Toast.notify({
 | |
|       type: 'success',
 | |
|       message: t('common.api.actionSuccess'),
 | |
|     })
 | |
|   }, [checkName, doAddMetaData, t])
 | |
| 
 | |
|   const hasData = list.length > 0
 | |
|   const handleSave = async () => {
 | |
|     await mutateAsync({
 | |
|       dataset_id: datasetId,
 | |
|       metadata_list: [{
 | |
|         document_id: documentId,
 | |
|         metadata_list: tempList,
 | |
|       }],
 | |
|     })
 | |
|     setIsEdit(false)
 | |
|     Toast.notify({
 | |
|       type: 'success',
 | |
|       message: t('common.api.actionSuccess'),
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   const handleCancel = () => {
 | |
|     setTempList(list)
 | |
|     setIsEdit(false)
 | |
|   }
 | |
| 
 | |
|   const startToEdit = () => {
 | |
|     setTempList(list)
 | |
|     setIsEdit(true)
 | |
|   }
 | |
| 
 | |
|   // built in enabled is set in dataset
 | |
|   const { data: datasetMetaData } = useDatasetMetaData(datasetId)
 | |
|   const builtInEnabled = datasetMetaData?.built_in_field_enabled
 | |
| 
 | |
|   // old metadata and technical params
 | |
|   const metadataMap = useMetadataMap()
 | |
|   const languageMap = useLanguages()
 | |
| 
 | |
|   const getReadOnlyMetaData = (mainField: 'originInfo' | 'technicalParameters') => {
 | |
|     const fieldMap = metadataMap[mainField]?.subFieldsMap
 | |
|     const sourceData = docDetail
 | |
|     const getTargetMap = (field: string) => {
 | |
|       if (field === 'language')
 | |
|         return languageMap
 | |
| 
 | |
|       return {} as any
 | |
|     }
 | |
| 
 | |
|     const getTargetValue = (field: string) => {
 | |
|       const val = get(sourceData, field, '')
 | |
|       if (!val && val !== 0)
 | |
|         return '-'
 | |
|       if (fieldMap[field]?.inputType === 'select')
 | |
|         return getTargetMap(field)[val]
 | |
|       if (fieldMap[field]?.render)
 | |
|         return fieldMap[field]?.render?.(val, field === 'hit_count' ? get(sourceData, 'segment_count', 0) as number : undefined)
 | |
|       return val
 | |
|     }
 | |
|     const fieldList = Object.keys(fieldMap).map((key) => {
 | |
|       const field = fieldMap[key]
 | |
|       return {
 | |
|         id: field?.label,
 | |
|         type: DataType.string,
 | |
|         name: field?.label,
 | |
|         value: getTargetValue(key),
 | |
|       }
 | |
|     })
 | |
| 
 | |
|     return fieldList
 | |
|   }
 | |
| 
 | |
|   const originInfo = getReadOnlyMetaData('originInfo')
 | |
|   const technicalParameters = getReadOnlyMetaData('technicalParameters')
 | |
| 
 | |
|   return {
 | |
|     embeddingAvailable,
 | |
|     isEdit,
 | |
|     setIsEdit,
 | |
|     list,
 | |
|     tempList,
 | |
|     setTempList,
 | |
|     handleSelectMetaData,
 | |
|     handleAddMetaData,
 | |
|     hasData,
 | |
|     builtList,
 | |
|     builtInEnabled,
 | |
|     startToEdit,
 | |
|     handleSave,
 | |
|     handleCancel,
 | |
|     originInfo,
 | |
|     technicalParameters,
 | |
|   }
 | |
| }
 | |
| 
 | |
| export default useMetadataDocument
 |