import React, { useCallback, useState } from 'react' import { useContext } from 'use-context-selector' import { ToastContext } from '../../base/toast' import { useTranslation } from 'react-i18next' import { useRouter } from 'next/navigation' import { useDocumentArchive, useDocumentDelete, useDocumentDisable, useDocumentEnable, useDocumentUnArchive, useSyncDocument, useSyncWebsite } from '@/service/knowledge/use-document' import type { OperationName } from './types' import { asyncRunSafe } from '@/utils' import type { CommonResponse } from '@/models/common' import { useBoolean, useDebounceFn } from 'ahooks' import Switch from '../../base/switch' import { noop } from 'lodash' import Tooltip from '../../base/tooltip' import Divider from '../../base/divider' import cn from '@/utils/classnames' import { RiArchive2Line, RiDeleteBinLine, RiEditLine, RiEqualizer2Line, RiLoopLeftLine, RiMoreFill } from '@remixicon/react' import CustomPopover from '../../base/popover' import s from './style.module.css' import { DataSourceType } from '@/models/datasets' import Confirm from '../../base/confirm' import RenameModal from './rename-modal' type OperationsProps = { embeddingAvailable: boolean detail: { name: string enabled: boolean archived: boolean id: string data_source_type: string doc_form: string } datasetId: string onUpdate: (operationName?: string) => void scene?: 'list' | 'detail' className?: string } const Operations = ({ embeddingAvailable, datasetId, detail, onUpdate, scene = 'list', className = '', }: OperationsProps) => { const { t } = useTranslation() const router = useRouter() const { id, enabled = false, archived = false, data_source_type } = detail || {} const [showModal, setShowModal] = useState(false) const [deleting, setDeleting] = useState(false) const { notify } = useContext(ToastContext) const { mutateAsync: archiveDocument } = useDocumentArchive() const { mutateAsync: unArchiveDocument } = useDocumentUnArchive() const { mutateAsync: enableDocument } = useDocumentEnable() const { mutateAsync: disableDocument } = useDocumentDisable() const { mutateAsync: deleteDocument } = useDocumentDelete() const { mutateAsync: syncDocument } = useSyncDocument() const { mutateAsync: syncWebsite } = useSyncWebsite() const isListScene = scene === 'list' const onOperate = async (operationName: OperationName) => { let opApi switch (operationName) { case 'archive': opApi = archiveDocument break case 'un_archive': opApi = unArchiveDocument break case 'enable': opApi = enableDocument break case 'disable': opApi = disableDocument break case 'sync': if (data_source_type === 'notion_import') opApi = syncDocument else opApi = syncWebsite break default: opApi = deleteDocument setDeleting(true) break } const [e] = await asyncRunSafe(opApi({ datasetId, documentId: id }) as Promise) if (!e) { notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) onUpdate(operationName) } else { notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) } if (operationName === 'delete') setDeleting(false) } const { run: handleSwitch } = useDebounceFn((operationName: OperationName) => { if (operationName === 'enable' && enabled) return if (operationName === 'disable' && !enabled) return onOperate(operationName) }, { wait: 500 }) const [currDocument, setCurrDocument] = useState<{ id: string name: string } | null>(null) const [isShowRenameModal, { setTrue: setShowRenameModalTrue, setFalse: setShowRenameModalFalse, }] = useBoolean(false) const handleShowRenameModal = useCallback((doc: { id: string name: string }) => { setCurrDocument(doc) setShowRenameModalTrue() }, [setShowRenameModalTrue]) const handleRenamed = useCallback(() => { onUpdate() }, [onUpdate]) return
e.stopPropagation()}> {isListScene && !embeddingAvailable && ( )} {isListScene && embeddingAvailable && ( <> {archived ?
: handleSwitch(v ? 'enable' : 'disable')} size='md' /> } )} {embeddingAvailable && ( <> {!archived && ( <>
{ handleShowRenameModal({ id: detail.id, name: detail.name, }) }}> {t('datasetDocuments.list.table.rename')}
{['notion_import', DataSourceType.WEB].includes(data_source_type) && (
onOperate('sync')}> {t('datasetDocuments.list.action.sync')}
)} )} {!archived &&
onOperate('archive')}> {t('datasetDocuments.list.action.archive')}
} {archived && (
onOperate('un_archive')}> {t('datasetDocuments.list.action.unarchive')}
)}
setShowModal(true)}> {t('datasetDocuments.list.action.delete')}
} trigger='click' position='br' btnElement={
} btnClassName={open => cn(isListScene ? s.actionIconWrapperList : s.actionIconWrapperDetail, open ? '!hover:bg-state-base-hover !shadow-none' : '!bg-transparent')} popupClassName='!w-full' className={`!z-20 flex h-fit !w-[200px] justify-end ${className}`} /> )} {showModal && onOperate('delete')} onCancel={() => setShowModal(false)} /> } {isShowRenameModal && currDocument && ( )} } export default React.memo(Operations)