Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

use-batch-edit-document-metadata.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import { useBoolean } from 'ahooks'
  2. import { type MetadataBatchEditToServer, type MetadataItemInBatchEdit, type MetadataItemWithEdit, type MetadataItemWithValue, UpdateType } from '../types'
  3. import type { SimpleDocumentDetail } from '@/models/datasets'
  4. import { useMemo } from 'react'
  5. import { useBatchUpdateDocMetadata } from '@/service/knowledge/use-metadata'
  6. import Toast from '@/app/components/base/toast'
  7. import { t } from 'i18next'
  8. type Props = {
  9. datasetId: string
  10. docList: SimpleDocumentDetail[]
  11. selectedDocumentIds?: string[]
  12. onUpdate: () => void
  13. }
  14. const useBatchEditDocumentMetadata = ({
  15. datasetId,
  16. docList,
  17. selectedDocumentIds,
  18. onUpdate,
  19. }: Props) => {
  20. const [isShowEditModal, {
  21. setTrue: showEditModal,
  22. setFalse: hideEditModal,
  23. }] = useBoolean(false)
  24. const metaDataList: MetadataItemWithValue[][] = (() => {
  25. const res: MetadataItemWithValue[][] = []
  26. docList.forEach((item) => {
  27. if (item.doc_metadata) {
  28. res.push(item.doc_metadata.filter(item => item.id !== 'built-in'))
  29. return
  30. }
  31. res.push([])
  32. })
  33. return res
  34. })()
  35. // To check is key has multiple value
  36. const originalList: MetadataItemInBatchEdit[] = useMemo(() => {
  37. const idNameValue: Record<string, { value: string | number | null, isMultipleValue: boolean }> = {}
  38. const res: MetadataItemInBatchEdit[] = []
  39. metaDataList.forEach((metaData) => {
  40. metaData.forEach((item) => {
  41. if (idNameValue[item.id]?.isMultipleValue)
  42. return
  43. const itemInRes = res.find(i => i.id === item.id)
  44. if (!idNameValue[item.id]) {
  45. idNameValue[item.id] = {
  46. value: item.value,
  47. isMultipleValue: false,
  48. }
  49. }
  50. if (itemInRes && itemInRes.value !== item.value) {
  51. idNameValue[item.id].isMultipleValue = true
  52. itemInRes.isMultipleValue = true
  53. itemInRes.value = null
  54. return
  55. }
  56. if (!itemInRes) {
  57. res.push({
  58. ...item,
  59. isMultipleValue: false,
  60. })
  61. }
  62. })
  63. })
  64. return res
  65. }, [metaDataList])
  66. const formateToBackendList = (editedList: MetadataItemWithEdit[], addedList: MetadataItemInBatchEdit[], isApplyToAllSelectDocument: boolean) => {
  67. const updatedList = editedList.filter((editedItem) => {
  68. return editedItem.updateType === UpdateType.changeValue
  69. })
  70. const removedList = originalList.filter((originalItem) => {
  71. const editedItem = editedList.find(i => i.id === originalItem.id)
  72. if (!editedItem) // removed item
  73. return true
  74. return false
  75. })
  76. // Use selectedDocumentIds if available, otherwise fall back to docList
  77. const documentIds = selectedDocumentIds || docList.map(doc => doc.id)
  78. const res: MetadataBatchEditToServer = documentIds.map((documentId) => {
  79. // Find the document in docList to get its metadata
  80. const docIndex = docList.findIndex(doc => doc.id === documentId)
  81. const oldMetadataList = docIndex >= 0 ? metaDataList[docIndex] : []
  82. let newMetadataList: MetadataItemWithValue[] = [...oldMetadataList, ...addedList]
  83. .filter((item) => {
  84. return !removedList.find(removedItem => removedItem.id === item.id)
  85. })
  86. .map(item => ({
  87. id: item.id,
  88. name: item.name,
  89. type: item.type,
  90. value: item.value,
  91. }))
  92. if (isApplyToAllSelectDocument) {
  93. // add missing metadata item
  94. updatedList.forEach((editedItem) => {
  95. if (!newMetadataList.find(i => i.id === editedItem.id) && !editedItem.isMultipleValue)
  96. newMetadataList.push(editedItem)
  97. })
  98. }
  99. newMetadataList = newMetadataList.map((item) => {
  100. const editedItem = updatedList.find(i => i.id === item.id)
  101. if (editedItem)
  102. return editedItem
  103. return item
  104. })
  105. return {
  106. document_id: documentId,
  107. metadata_list: newMetadataList,
  108. }
  109. })
  110. return res
  111. }
  112. const { mutateAsync } = useBatchUpdateDocMetadata()
  113. const handleSave = async (editedList: MetadataItemInBatchEdit[], addedList: MetadataItemInBatchEdit[], isApplyToAllSelectDocument: boolean) => {
  114. const backendList = formateToBackendList(editedList, addedList, isApplyToAllSelectDocument)
  115. await mutateAsync({
  116. dataset_id: datasetId,
  117. metadata_list: backendList,
  118. })
  119. onUpdate()
  120. hideEditModal()
  121. Toast.notify({
  122. type: 'success',
  123. message: t('common.actionMsg.modifiedSuccessfully'),
  124. })
  125. }
  126. return {
  127. isShowEditModal,
  128. showEditModal,
  129. hideEditModal,
  130. originalList,
  131. handleSave,
  132. }
  133. }
  134. export default useBatchEditDocumentMetadata