import type { FC } from 'react' import { useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { isEqual } from 'lodash-es' import cn from 'classnames' import { RiCloseLine } from '@remixicon/react' import { BookOpenIcon } from '@heroicons/react/24/outline' import IndexMethodRadio from '@/app/components/datasets/settings/index-method-radio' import Button from '@/app/components/base/button' import type { DataSet } from '@/models/datasets' import { useToastContext } from '@/app/components/base/toast' import { updateDatasetSetting } from '@/service/datasets' import { useModalContext } from '@/context/modal-context' import type { RetrievalConfig } from '@/types/app' import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config' import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config' import { ensureRerankModelSelected, isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import PermissionsRadio from '@/app/components/datasets/settings/permissions-radio' import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' import { useModelList, useModelListAndDefaultModelAndCurrentProviderAndModel, } from '@/app/components/header/account-setting/model-provider-page/hooks' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' type SettingsModalProps = { currentDataset: DataSet onCancel: () => void onSave: (newDataset: DataSet) => void } const rowClass = ` flex justify-between py-4 flex-wrap gap-y-2 ` const labelClass = ` flex w-[168px] shrink-0 ` const SettingsModal: FC = ({ currentDataset, onCancel, onSave, }) => { const { data: embeddingsModelList } = useModelList(ModelTypeEnum.textEmbedding) const { modelList: rerankModelList, defaultModel: rerankDefaultModel, currentModel: isRerankDefaultModelVaild, } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const { t } = useTranslation() const { notify } = useToastContext() const ref = useRef(null) const { setShowAccountSettingModal } = useModalContext() const [loading, setLoading] = useState(false) const [localeCurrentDataset, setLocaleCurrentDataset] = useState({ ...currentDataset }) const [indexMethod, setIndexMethod] = useState(currentDataset.indexing_technique) const [retrievalConfig, setRetrievalConfig] = useState(localeCurrentDataset?.retrieval_model_dict as RetrievalConfig) const handleValueChange = (type: string, value: string) => { setLocaleCurrentDataset({ ...localeCurrentDataset, [type]: value }) } const [isHideChangedTip, setIsHideChangedTip] = useState(false) const isRetrievalChanged = !isEqual(retrievalConfig, localeCurrentDataset?.retrieval_model_dict) || indexMethod !== localeCurrentDataset?.indexing_technique const handleSave = async () => { if (loading) return if (!localeCurrentDataset.name?.trim()) { notify({ type: 'error', message: t('datasetSettings.form.nameError') }) return } if ( !isReRankModelSelected({ rerankDefaultModel, isRerankDefaultModelVaild: !!isRerankDefaultModelVaild, rerankModelList, retrievalConfig, indexMethod, }) ) { notify({ type: 'error', message: t('appDebug.datasetConfig.rerankModelRequired') }) return } const postRetrievalConfig = ensureRerankModelSelected({ rerankDefaultModel: rerankDefaultModel!, retrievalConfig, indexMethod, }) try { setLoading(true) const { id, name, description, permission } = localeCurrentDataset await updateDatasetSetting({ datasetId: id, body: { name, description, permission, indexing_technique: indexMethod, retrieval_model: postRetrievalConfig, embedding_model: localeCurrentDataset.embedding_model, embedding_model_provider: localeCurrentDataset.embedding_model_provider, }, }) notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) onSave({ ...localeCurrentDataset, indexing_technique: indexMethod, retrieval_model_dict: postRetrievalConfig, }) } catch (e) { notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) } finally { setLoading(false) } } return (
{t('datasetSettings.title')}
{/* Body */}
{t('datasetSettings.form.name')}
handleValueChange('name', e.target.value)} className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none' placeholder={t('datasetSettings.form.namePlaceholder') || ''} />
{t('datasetSettings.form.desc')}