diff --git a/web/app/components/datasets/metadata/edit-metadat-batch/edit-row.tsx b/web/app/components/datasets/metadata/edit-metadat-batch/edit-row.tsx new file mode 100644 index 0000000000..bd713969d6 --- /dev/null +++ b/web/app/components/datasets/metadata/edit-metadat-batch/edit-row.tsx @@ -0,0 +1,65 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { type MetadataItemWithEdit, UpdateType } from '../types' +import Input from '../../create/website/base/input' +import Label from './label' +import { RiDeleteBinLine } from '@remixicon/react' +import cn from '@/utils/classnames' +import InputHasSetMultipleValue from './input-has-set-multiple-value' +import InputCombined from './input-combined' + +type Props = { + payload: MetadataItemWithEdit + onChange: (payload: MetadataItemWithEdit) => void + onRemove: (id: string) => void +} + +const labelClassName = '' + +export const AddedMetadataItem: FC = ({ + payload, + onChange, +}) => { + return ( +
+
{payload.name}
+ onChange({ ...payload, value: v as string }) + } /> +
+ ) +} + +const EditMetadatabatchItem: FC = ({ + payload, + onChange, + onRemove, +}) => { + const isDeleted = payload.updateType === UpdateType.delete + return ( +
+
+ ) +} +export default React.memo(EditMetadatabatchItem) diff --git a/web/app/components/datasets/metadata/edit-metadat-batch/input-combined.tsx b/web/app/components/datasets/metadata/edit-metadat-batch/input-combined.tsx new file mode 100644 index 0000000000..abbe4cb079 --- /dev/null +++ b/web/app/components/datasets/metadata/edit-metadat-batch/input-combined.tsx @@ -0,0 +1,30 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { DataType } from '../types' +import Input from '@/app/components/base/input' + +type Props = { + type: DataType + value: any + onChange: (value: any) => void +} + +const InputCombined: FC = ({ + type, + value, + onChange, +}) => { + if (type === DataType.time) + return
Datepicker placeholder
+ + return ( + onChange(e.target.value)} + > + + ) +} +export default React.memo(InputCombined) diff --git a/web/app/components/datasets/metadata/edit-metadat-batch/input-has-set-multiple-value.tsx b/web/app/components/datasets/metadata/edit-metadat-batch/input-has-set-multiple-value.tsx new file mode 100644 index 0000000000..6655cbe8fc --- /dev/null +++ b/web/app/components/datasets/metadata/edit-metadat-batch/input-has-set-multiple-value.tsx @@ -0,0 +1,27 @@ +'use client' +import { RiCloseLine } from '@remixicon/react' +import type { FC } from 'react' +import React from 'react' + +type Props = { + onClear: () => void +} + +const InputHasSetMultipleValue: FC = ({ + onClear, +}) => { + return ( +
+
+
Multiple Value
+
+ +
+
+
+ ) +} +export default React.memo(InputHasSetMultipleValue) diff --git a/web/app/components/datasets/metadata/edit-metadat-batch/label.tsx b/web/app/components/datasets/metadata/edit-metadat-batch/label.tsx new file mode 100644 index 0000000000..d48a4dbc72 --- /dev/null +++ b/web/app/components/datasets/metadata/edit-metadat-batch/label.tsx @@ -0,0 +1,27 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import cn from '@/utils/classnames' + +type Props = { + isDeleted: boolean, + className?: string, + text: string +} + +const Label: FC = ({ + isDeleted, + className, + text, +}) => { + return ( +
+ {text} +
+ ) +} +export default React.memo(Label) diff --git a/web/app/components/datasets/metadata/edit-metadat-batch/modal.tsx b/web/app/components/datasets/metadata/edit-metadat-batch/modal.tsx new file mode 100644 index 0000000000..719ca2b76e --- /dev/null +++ b/web/app/components/datasets/metadata/edit-metadat-batch/modal.tsx @@ -0,0 +1,103 @@ +'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-row' +import Button from '../../../base/button' +import { useTranslation } from 'react-i18next' +import Checkbox from '../../../base/checkbox' +import Tooltip from '../../../base/tooltip' + +type Props = { + documentNum: number + list: MetadataItemWithEdit[] + onChange: (list: MetadataItemWithEdit[], addedList: MetadataItemWithEdit[], isApplyToAllSelectDocument: boolean) => void + onHide: () => void +} + +const EditMetadataBatchModal: FC = ({ + documentNum, + 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 {documentNum} 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.
+ } /> +
+
+ + +
+ +
+ ) +} +export default React.memo(EditMetadataBatchModal)