diff --git a/web/app/components/datasets/metadata/edit-metadata-batch-item.tsx b/web/app/components/datasets/metadata/edit-metadata-batch-item.tsx
new file mode 100644
index 0000000000..9ac55cba05
--- /dev/null
+++ b/web/app/components/datasets/metadata/edit-metadata-batch-item.tsx
@@ -0,0 +1,45 @@
+'use client'
+import type { FC } from 'react'
+import React from 'react'
+import type { MetadataItemWithEdit } from './types'
+import Input from '../create/website/base/input'
+
+type Props = {
+ payload: MetadataItemWithEdit
+ onChange: (payload: MetadataItemWithEdit) => void
+ onRemove: (id: string) => void
+}
+
+const labelClassName = 'w-[136px] system-xs-medium text-text-tertiary'
+
+export const AddedMetadataItem: FC
= ({
+ payload,
+ onChange,
+}) => {
+ return (
+
+
{payload.name}
+
onChange({ ...payload, value: v as string })
+ } />
+
+ )
+}
+
+const EditMetadatabatchItem: FC = ({
+ payload,
+ onChange,
+ onRemove,
+}) => {
+ return (
+
+
{payload.name}
+
onChange({ ...payload, value: v as string })
+ } />
+
+ )
+}
+export default React.memo(EditMetadatabatchItem)
diff --git a/web/app/components/datasets/metadata/edit-metadata-batch-modal.tsx b/web/app/components/datasets/metadata/edit-metadata-batch-modal.tsx
new file mode 100644
index 0000000000..ce385c8557
--- /dev/null
+++ b/web/app/components/datasets/metadata/edit-metadata-batch-modal.tsx
@@ -0,0 +1,100 @@
+'use client'
+import type { FC } from 'react'
+import React, { useCallback, useState } from 'react'
+import Modal from '../../base/modal'
+import type { MetadataItemWithEdit } from './types'
+import EditMetadataBatchItem, { AddedMetadataItem } from './edit-metadata-batch-item'
+import Button from '../../base/button'
+import { useTranslation } from 'react-i18next'
+import Checkbox from '../../base/checkbox'
+import Tooltip from '../../base/tooltip'
+
+type Props = {
+ list: MetadataItemWithEdit[]
+ onChange: (list: MetadataItemWithEdit[], addedList: MetadataItemWithEdit[], isApplyToAllSelectDocument: boolean) => void
+ onHide: () => void
+}
+
+const EditMetadataBatchModal: FC = ({
+ list,
+ onChange,
+ onHide,
+}) => {
+ const { t } = useTranslation()
+ const [templeList, setTempleList] = useState(list)
+ const handleTemplesChange = useCallback((payload: MetadataItemWithEdit) => {
+ const newTempleList = templeList.map(i => i.id === payload.id ? payload : i)
+ setTempleList(newTempleList)
+ }, [templeList])
+ const handleTempleItemRemove = useCallback((id: string) => {
+ const newTempleList = templeList.filter(i => i.id !== id)
+ setTempleList(newTempleList)
+ }, [templeList])
+
+ const [addedList, setAddedList] = useState([])
+ const handleAddedListChange = useCallback((payload: MetadataItemWithEdit) => {
+ const newAddedList = addedList.map(i => i.id === payload.id ? payload : i)
+ setAddedList(newAddedList)
+ }, [addedList])
+ const handleAddedItemRemove = useCallback((id: string) => {
+ const newAddedList = addedList.filter(i => i.id !== id)
+ setAddedList(newAddedList)
+ }, [addedList])
+
+ const [isApplyToAllSelectDocument, setIsApplyToAllSelectDocument] = useState(false)
+
+ const handleSave = useCallback(() => {
+ onChange(templeList, addedList, isApplyToAllSelectDocument)
+ }, [templeList, addedList, isApplyToAllSelectDocument, onChange])
+ return (
+
+ Editing 5 documents
+ {/* TODO handle list scroll. There is two list. */}
+
+ {templeList.map(item => (
+
+ ))}
+
+
+
+ {addedList.map(item => (
+
+ ))}
+
+
+
+
+
setIsApplyToAllSelectDocument(!isApplyToAllSelectDocument)} />
+ Apply to all selected documents
+ Automatically create all the above edited and new metadata for all selected documents, otherwise editing metadata will only apply to documents with it.
+ } />
+
+
+ {t('common.operation.cancel')}
+ {t('common.operation.save')}
+
+
+
+ )
+}
+export default React.memo(EditMetadataBatchModal)
diff --git a/web/app/components/datasets/metadata/types.ts b/web/app/components/datasets/metadata/types.ts
index ee44a1ce91..ee4d62b90a 100644
--- a/web/app/components/datasets/metadata/types.ts
+++ b/web/app/components/datasets/metadata/types.ts
@@ -13,3 +13,10 @@ export type MetadataItem = {
export type MetadataItemWithValueLength = MetadataItem & {
valueLength: number
}
+
+export type MetadataItemWithEdit = MetadataItem & {
+ value: string
+ isMultipleValue?: boolean
+ isRemoved?: boolean
+ isUpdated?: boolean
+}