From 83e17d8c4a26a8a4290e704bb0909a48058c01ad Mon Sep 17 00:00:00 2001 From: chanx <1243304602@qq.com> Date: Wed, 21 Jan 2026 16:15:43 +0800 Subject: [PATCH] Fix: Optimize the metadata code structure to implement metadata list structure functionality. (#12741) ### What problem does this PR solve? Fix: Optimize the metadata code structure to implement metadata list structure functionality. #11564 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue) --- .../components/chunk-method-dialog/index.tsx | 2 +- web/src/locales/en.ts | 2 +- web/src/locales/zh.ts | 2 +- .../dataset/components/metedata/constant.ts | 80 +++++++ .../metedata/hooks/use-manage-modal.ts | 201 ++++-------------- .../metedata/hooks/use-manage-values-modal.ts | 83 ++++++-- .../dataset/components/metedata/interface.ts | 13 +- .../metedata/manage-modal-column.tsx | 8 +- .../components/metedata/manage-modal.tsx | 75 ++++--- .../metedata/manage-values-modal.tsx | 85 ++++++-- .../configuration/common-item.tsx | 3 +- web/src/pages/dataset/dataset/index.tsx | 8 +- .../dataset/use-dataset-table-columns.tsx | 4 +- 13 files changed, 315 insertions(+), 251 deletions(-) create mode 100644 web/src/pages/dataset/components/metedata/constant.ts diff --git a/web/src/components/chunk-method-dialog/index.tsx b/web/src/components/chunk-method-dialog/index.tsx index 9fd55016f..372e58fdc 100644 --- a/web/src/components/chunk-method-dialog/index.tsx +++ b/web/src/components/chunk-method-dialog/index.tsx @@ -18,7 +18,7 @@ import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-reques import { IModalProps } from '@/interfaces/common'; import { IParserConfig } from '@/interfaces/database/document'; import { IChangeParserConfigRequestBody } from '@/interfaces/request/document'; -import { MetadataType } from '@/pages/dataset/components/metedata/hooks/use-manage-modal'; +import { MetadataType } from '@/pages/dataset/components/metedata/constant'; import { AutoMetadata, ChunkMethodItem, diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 5d6bc96d4..4093ebde1 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -192,7 +192,7 @@ Example: A 1 KB message with 1024-dim embedding uses ~9 KB. The 5 MB default lim toMetadataSettingTip: 'Set auto-metadata in Configuration.', descriptionTip: 'Provide descriptions or examples to guide LLM extract values for this field. If left empty, it will rely on the field name.', - restrictTDefinedValuesTip: + restrictDefinedValuesTip: 'Enum Mode: Restricts LLM extraction to match preset values only. Define values below.', valueExists: 'Value already exists. Confirm to merge duplicates and combine all associated files.', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 02537e7f7..1ca477995 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -183,7 +183,7 @@ export default { toMetadataSetting: '生成设置', descriptionTip: '提供描述或示例来指导大语言模型为此字段提取值。如果留空,将依赖字段名称。', - restrictTDefinedValuesTip: + restrictDefinedValuesTip: '枚举模式:限制大语言模型提取的值只能匹配预设值。在下方定义值。', valueExists: '值已存在。确认合并重复项并组合所有关联文件。', fieldNameExists: '字段名已存在。确认合并重复项并组合所有关联文件。', diff --git a/web/src/pages/dataset/components/metedata/constant.ts b/web/src/pages/dataset/components/metedata/constant.ts new file mode 100644 index 000000000..426eaeef7 --- /dev/null +++ b/web/src/pages/dataset/components/metedata/constant.ts @@ -0,0 +1,80 @@ +import { TFunction } from 'i18next'; +import { MetadataValueType } from './interface'; + +export enum MetadataType { + Manage = 1, + UpdateSingle = 2, + Setting = 3, + SingleFileSetting = 4, +} + +export const MetadataDeleteMap = ( + t: TFunction<'translation', undefined>, +): Record< + MetadataType, + { + title: string; + warnFieldText: string; + warnValueText: string; + warnFieldName: string; + warnValueName: string; + } +> => { + return { + [MetadataType.Manage]: { + title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), + warnFieldText: t('knowledgeDetails.metadata.deleteManageFieldAllWarn'), + warnValueText: t('knowledgeDetails.metadata.deleteManageValueAllWarn'), + warnFieldName: t('knowledgeDetails.metadata.fieldNameExists'), + warnValueName: t('knowledgeDetails.metadata.valueExists'), + }, + [MetadataType.Setting]: { + title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), + warnFieldText: t('knowledgeDetails.metadata.deleteSettingFieldWarn'), + warnValueText: t('knowledgeDetails.metadata.deleteSettingValueWarn'), + warnFieldName: t('knowledgeDetails.metadata.fieldExists'), + warnValueName: t('knowledgeDetails.metadata.valueExists'), + }, + [MetadataType.UpdateSingle]: { + title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), + warnFieldText: t('knowledgeDetails.metadata.deleteManageFieldSingleWarn'), + warnValueText: t('knowledgeDetails.metadata.deleteManageValueSingleWarn'), + warnFieldName: t('knowledgeDetails.metadata.fieldSingleNameExists'), + warnValueName: t('knowledgeDetails.metadata.valueSingleExists'), + }, + [MetadataType.SingleFileSetting]: { + title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), + warnFieldText: t('knowledgeDetails.metadata.deleteSettingFieldWarn'), + warnValueText: t('knowledgeDetails.metadata.deleteSettingValueWarn'), + warnFieldName: t('knowledgeDetails.metadata.fieldExists'), + warnValueName: t('knowledgeDetails.metadata.valueSingleExists'), + }, + }; +}; + +export const DEFAULT_VALUE_TYPE: MetadataValueType = 'string'; +// const VALUE_TYPES_WITH_ENUM = new Set(['enum']); +export const VALUE_TYPE_LABELS: Record = { + string: 'String', + time: 'Time', + number: 'Number', + // bool: 'Bool', + // enum: 'Enum', + list: 'List', + // int: 'Int', + // float: 'Float', +}; + +export const metadataValueTypeEnum = Object.keys(VALUE_TYPE_LABELS).reduce( + (acc, item) => { + return { ...acc, [item]: item }; + }, + {} as Record, +); + +export const metadataValueTypeOptions = Object.entries(VALUE_TYPE_LABELS).map( + ([value, label]) => ({ label, value }), +); + +export const getMetadataValueTypeLabel = (value?: MetadataValueType) => + VALUE_TYPE_LABELS[value || DEFAULT_VALUE_TYPE] || VALUE_TYPE_LABELS.string; diff --git a/web/src/pages/dataset/components/metedata/hooks/use-manage-modal.ts b/web/src/pages/dataset/components/metedata/hooks/use-manage-modal.ts index 223794d57..cfd7ce81a 100644 --- a/web/src/pages/dataset/components/metedata/hooks/use-manage-modal.ts +++ b/web/src/pages/dataset/components/metedata/hooks/use-manage-modal.ts @@ -1,20 +1,17 @@ import message from '@/components/ui/message'; import { useSetModalState } from '@/hooks/common-hooks'; import { useSelectedIds } from '@/hooks/logic-hooks/use-row-selection'; -import { - DocumentApiAction, - useSetDocumentMeta, -} from '@/hooks/use-document-request'; +import { DocumentApiAction } from '@/hooks/use-document-request'; import kbService, { getMetaDataService, updateMetaData, } from '@/services/knowledge-service'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { RowSelectionState } from '@tanstack/react-table'; -import { TFunction } from 'i18next'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router'; +import { MetadataType, metadataValueTypeEnum } from '../constant'; import { IBuiltInMetadataItem, IMetaDataReturnJSONSettings, @@ -25,141 +22,6 @@ import { MetadataValueType, ShowManageMetadataModalProps, } from '../interface'; -export enum MetadataType { - Manage = 1, - UpdateSingle = 2, - Setting = 3, - SingleFileSetting = 4, -} - -export const MetadataDeleteMap = ( - t: TFunction<'translation', undefined>, -): Record< - MetadataType, - { - title: string; - warnFieldText: string; - warnValueText: string; - warnFieldName: string; - warnValueName: string; - } -> => { - return { - [MetadataType.Manage]: { - title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), - warnFieldText: t('knowledgeDetails.metadata.deleteManageFieldAllWarn'), - warnValueText: t('knowledgeDetails.metadata.deleteManageValueAllWarn'), - warnFieldName: t('knowledgeDetails.metadata.fieldNameExists'), - warnValueName: t('knowledgeDetails.metadata.valueExists'), - }, - [MetadataType.Setting]: { - title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), - warnFieldText: t('knowledgeDetails.metadata.deleteSettingFieldWarn'), - warnValueText: t('knowledgeDetails.metadata.deleteSettingValueWarn'), - warnFieldName: t('knowledgeDetails.metadata.fieldExists'), - warnValueName: t('knowledgeDetails.metadata.valueExists'), - }, - [MetadataType.UpdateSingle]: { - title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), - warnFieldText: t('knowledgeDetails.metadata.deleteManageFieldSingleWarn'), - warnValueText: t('knowledgeDetails.metadata.deleteManageValueSingleWarn'), - warnFieldName: t('knowledgeDetails.metadata.fieldSingleNameExists'), - warnValueName: t('knowledgeDetails.metadata.valueSingleExists'), - }, - [MetadataType.SingleFileSetting]: { - title: t('common.delete') + ' ' + t('knowledgeDetails.metadata.metadata'), - warnFieldText: t('knowledgeDetails.metadata.deleteSettingFieldWarn'), - warnValueText: t('knowledgeDetails.metadata.deleteSettingValueWarn'), - warnFieldName: t('knowledgeDetails.metadata.fieldExists'), - warnValueName: t('knowledgeDetails.metadata.valueSingleExists'), - }, - }; -}; - -const DEFAULT_VALUE_TYPE: MetadataValueType = 'string'; -// const VALUE_TYPES_WITH_ENUM = new Set(['enum']); -const VALUE_TYPE_LABELS: Record = { - string: 'String', - time: 'Time', - number: 'Number', - // bool: 'Bool', - // enum: 'Enum', - // 'list': 'List', - // int: 'Int', - // float: 'Float', -}; - -export const metadataValueTypeOptions = Object.entries(VALUE_TYPE_LABELS).map( - ([value, label]) => ({ label, value }), -); - -export const getMetadataValueTypeLabel = (value?: MetadataValueType) => - VALUE_TYPE_LABELS[value || DEFAULT_VALUE_TYPE] || VALUE_TYPE_LABELS.string; - -// export const isMetadataValueTypeWithEnum = (value?: MetadataValueType) => -// VALUE_TYPES_WITH_ENUM.has(value || DEFAULT_VALUE_TYPE); - -// const schemaToValueType = ( -// property?: IMetaDataJsonSchemaProperty, -// ): MetadataValueType => { -// if (!property) return DEFAULT_VALUE_TYPE; -// if ( -// property.type === 'array' && -// property.items?.type === 'string' && -// (property.items.enum?.length || 0) > 0 -// ) { -// return 'enum'; -// } -// if (property.type === 'boolean') return 'bool'; -// if (property.type === 'integer') return 'int'; -// if (property.type === 'number') return 'float'; -// if (property.type === 'string' && property.format) { -// return 'time'; -// } -// if (property.type === 'string' && property.enum?.length) { -// return 'enum'; -// } -// return DEFAULT_VALUE_TYPE; -// }; - -// const valueTypeToSchema = ( -// valueType: MetadataValueType, -// description: string, -// values: string[], -// ): IMetaDataJsonSchemaProperty => { -// const schema: IMetaDataJsonSchemaProperty = { -// description: description || '', -// }; - -// switch (valueType) { -// case 'bool': -// schema.type = 'boolean'; -// return schema; -// case 'int': -// schema.type = 'integer'; -// return schema; -// case 'float': -// schema.type = 'number'; -// return schema; -// case 'time': -// schema.type = 'string'; -// schema.format = 'date-time'; -// return schema; -// case 'enum': -// schema.type = 'string'; -// if (values?.length) { -// schema.enum = values; -// } -// return schema; -// case 'string': -// default: -// schema.type = 'string'; -// if (values?.length) { -// schema.enum = values; -// } -// return schema; -// } -// }; export const util = { changeToMetaDataTableData(data: IMetaDataReturnType): IMetaDataTableData[] { @@ -293,7 +155,22 @@ export const useMetadataOperations = () => { }, []); const addUpdateValue = useCallback( - (key: string, originalValue: string, newValue: string) => { + ( + key: string, + originalValue: string, + newValue: string | string[], + type?: MetadataValueType, + ) => { + let newValuesRes: string | string[]; + if (type !== metadataValueTypeEnum['list']) { + if (Array.isArray(newValue) && newValue.length > 0) { + newValuesRes = newValue[0]; + } else { + newValuesRes = newValue; + } + } else { + newValuesRes = newValue; + } setOperations((prev) => { const existsIndex = prev.updates.findIndex( (update) => update.key === key && update.match === originalValue, @@ -304,7 +181,8 @@ export const useMetadataOperations = () => { updatedUpdates[existsIndex] = { key, match: originalValue, - value: newValue, + value: newValuesRes, + type, }; return { ...prev, @@ -315,7 +193,7 @@ export const useMetadataOperations = () => { ...prev, updates: [ ...prev.updates, - { key, match: originalValue, value: newValue }, + { key, match: originalValue, value: newValuesRes, type }, ], }; }); @@ -398,7 +276,7 @@ export const useManageMetaDataModal = ( resetOperations, } = useMetadataOperations(); - const { setDocumentMeta } = useSetDocumentMeta(); + // const { setDocumentMeta } = useSetDocumentMeta(); useEffect(() => { if (fetchTypeList.includes(type)) { @@ -468,6 +346,7 @@ export const useManageMetaDataModal = ( const handleSaveManage = useCallback( async (callback: () => void) => { + console.log('handleSaveManage', tableData); const { data: res } = await updateMetaData({ kb_id: id as string, data: operations, @@ -482,25 +361,25 @@ export const useManageMetaDataModal = ( callback(); } }, - [operations, id, t, queryClient, resetOperations, documentIds], + [operations, id, t, queryClient, resetOperations, documentIds, tableData], ); - const handleSaveUpdateSingle = useCallback( - async (callback: () => void) => { - const reqData = util.tableDataToMetaDataJSON(tableData); - if (otherData?.id) { - const ret = await setDocumentMeta({ - documentId: otherData?.id, - meta: JSON.stringify(reqData), - }); - if (ret === 0) { - // message.success(t('message.success')); - callback(); - } - } - }, - [tableData, otherData, setDocumentMeta], - ); + // const handleSaveUpdateSingle = useCallback( + // async (callback: () => void) => { + // const reqData = util.tableDataToMetaDataJSON(tableData); + // if (otherData?.id) { + // const ret = await setDocumentMeta({ + // documentId: otherData?.id, + // meta: JSON.stringify(reqData), + // }); + // if (ret === 0) { + // // message.success(t('message.success')); + // callback(); + // } + // } + // }, + // [tableData, otherData, setDocumentMeta], + // ); const handleSaveSettings = useCallback( async (callback: () => void, builtInMetadata?: IBuiltInMetadataItem[]) => { diff --git a/web/src/pages/dataset/components/metedata/hooks/use-manage-values-modal.ts b/web/src/pages/dataset/components/metedata/hooks/use-manage-values-modal.ts index d819deb42..ccfd893d7 100644 --- a/web/src/pages/dataset/components/metedata/hooks/use-manage-values-modal.ts +++ b/web/src/pages/dataset/components/metedata/hooks/use-manage-values-modal.ts @@ -1,12 +1,16 @@ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { MetadataDeleteMap, MetadataType } from '../hooks/use-manage-modal'; +import { + MetadataDeleteMap, + MetadataType, + metadataValueTypeEnum, +} from '../constant'; import { IManageValuesProps, IMetaDataTableData } from '../interface'; export const useManageValues = (props: IManageValuesProps) => { const { data, - + isAddValueMode, hideModal, onSave, addUpdateValue, @@ -17,7 +21,8 @@ export const useManageValues = (props: IManageValuesProps) => { const { t } = useTranslation(); const [metaData, setMetaData] = useState({ ...data, - valueType: data.valueType || 'string', + valueType: data.valueType || metadataValueTypeEnum.string, + values: data.values || [''], }); const [valueError, setValueError] = useState>({ field: '', @@ -31,6 +36,8 @@ export const useManageValues = (props: IManageValuesProps) => { onOk: () => {}, onCancel: () => {}, }); + + const [shouldSave, setShouldSave] = useState(false); const hideDeleteModal = () => { setDeleteDialogContent({ visible: false, @@ -79,10 +86,11 @@ export const useManageValues = (props: IManageValuesProps) => { restrictDefinedValues: prev.restrictDefinedValues, }; } - return { + const newMetadata = { ...prev, [field]: value, }; + return newMetadata; }); return true; }, @@ -90,13 +98,13 @@ export const useManageValues = (props: IManageValuesProps) => { ); // Maintain separate state for each input box - const [tempValues, setTempValues] = useState([...data.values]); + const [tempValues, setTempValues] = useState(['']); useEffect(() => { setTempValues([...data.values]); setMetaData({ ...data, - valueType: data.valueType || 'string', + valueType: data.valueType || metadataValueTypeEnum.string, }); }, [data]); @@ -119,31 +127,63 @@ export const useManageValues = (props: IManageValuesProps) => { // handleHideModal(); // return; // } - onSave(metaData); - handleHideModal(); - }, [metaData, onSave, handleHideModal, type, valueError]); + if (isAddValueMode) { + addUpdateValue( + metaData.field, + undefined, + metaData.values, + metaData.valueType, + ); + } + // onSave(metaData); + setShouldSave(true); + }, [ + metaData, + // onSave, + // handleHideModal, + type, + valueError, + isAddValueMode, + addUpdateValue, + ]); + + useEffect(() => { + if (shouldSave) { + const timer = setTimeout(() => { + onSave(metaData); + setShouldSave(false); + clearTimeout(timer); + handleHideModal(); + }, 100); + } + }, [shouldSave, onSave, handleHideModal, metaData]); // Handle blur event, synchronize to main state const handleValueBlur = useCallback( (values?: string[]) => { const newValues = values || tempValues; - if (data.values.length > 0) { + if (data.values.length > 0 && !isAddValueMode) { newValues.forEach((newValue, index) => { if (index < data.values.length) { const originalValue = data.values[index]; if (originalValue !== newValue) { - addUpdateValue(metaData.field, originalValue, newValue); + addUpdateValue( + metaData.field, + originalValue, + newValue, + metaData.valueType, + ); } } else { if (newValue) { - addUpdateValue(metaData.field, '', newValue); + addUpdateValue(metaData.field, '', newValue, metaData.valueType); } } }); } handleChange('values', [...new Set([...newValues])]); }, - [handleChange, tempValues, metaData, data, addUpdateValue], + [handleChange, tempValues, metaData, data, addUpdateValue, isAddValueMode], ); // Handle value changes, only update temporary state @@ -200,13 +240,16 @@ export const useManageValues = (props: IManageValuesProps) => { [addDeleteValue, metaData], ); - const handleClearValues = useCallback(() => { - setTempValues([]); - setMetaData((prev) => ({ - ...prev, - values: [], - })); - }, [setTempValues, setMetaData]); + const handleClearValues = useCallback( + (isClearInitialValues = false) => { + setTempValues(isClearInitialValues ? [] : ['']); + setMetaData((prev) => ({ + ...prev, + values: isClearInitialValues ? [] : [''], + })); + }, + [setTempValues, setMetaData], + ); const showDeleteModal = (item: string, callback: () => void) => { setDeleteDialogContent({ diff --git a/web/src/pages/dataset/components/metedata/interface.ts b/web/src/pages/dataset/components/metedata/interface.ts index 9028984de..f725eaee2 100644 --- a/web/src/pages/dataset/components/metedata/interface.ts +++ b/web/src/pages/dataset/components/metedata/interface.ts @@ -1,5 +1,5 @@ import { ReactNode } from 'react'; -import { MetadataType } from './hooks/use-manage-modal'; +import { MetadataType } from './constant'; export type IMetaDataReturnType = Record< string, | { type: string; values: Array> } @@ -36,7 +36,7 @@ export type IMetaDataReturnJSONSettings = export type MetadataValueType = | 'string' - // | 'list' + | 'list' // | 'bool' // | 'enum' | 'time' @@ -84,14 +84,16 @@ export interface IManageValuesProps { isShowValueSwitch?: boolean; isShowType?: boolean; isVerticalShowValue?: boolean; + isAddValueMode?: boolean; data: IMetaDataTableData; type: MetadataType; hideModal: () => void; onSave: (data: IMetaDataTableData) => void; addUpdateValue: ( key: string, - originalValue: string, - newValue: string, + originalValue: string | undefined, + newValue: string | string[], + type?: MetadataValueType, ) => void; addDeleteValue: (key: string, value: string) => void; } @@ -104,7 +106,8 @@ interface DeleteOperation { interface UpdateOperation { key: string; match: string; - value: string; + value: string | string[]; + type?: MetadataValueType; } export interface MetadataOperations { diff --git a/web/src/pages/dataset/components/metedata/manage-modal-column.tsx b/web/src/pages/dataset/components/metedata/manage-modal-column.tsx index 110785fa9..4e8db74f9 100644 --- a/web/src/pages/dataset/components/metedata/manage-modal-column.tsx +++ b/web/src/pages/dataset/components/metedata/manage-modal-column.tsx @@ -1,7 +1,7 @@ import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Input } from '@/components/ui/input'; -import { ColumnDef } from '@tanstack/react-table'; +import { ColumnDef, Row, Table } from '@tanstack/react-table'; import { ListChevronsDownUp, ListChevronsUpDown, @@ -14,7 +14,7 @@ import { getMetadataValueTypeLabel, MetadataDeleteMap, MetadataType, -} from './hooks/use-manage-modal'; +} from './constant'; import { IMetaDataTableData } from './interface'; interface IUseMetadataColumns { @@ -102,7 +102,7 @@ export const useMetadataColumns = ({ ? [ { id: 'select', - header: ({ table }) => ( + header: ({ table }: { table: Table }) => ( ), - cell: ({ row }) => ( + cell: ({ row }: { row: Row }) => ( row.toggleSelected(!!value)} diff --git a/web/src/pages/dataset/components/metedata/manage-modal.tsx b/web/src/pages/dataset/components/metedata/manage-modal.tsx index 79ff390cb..e891cc7f0 100644 --- a/web/src/pages/dataset/components/metedata/manage-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-modal.tsx @@ -35,6 +35,9 @@ import { useHandleMenuClick } from '../../sidebar/hooks'; import { getMetadataValueTypeLabel, MetadataType, + metadataValueTypeEnum, +} from './constant'; +import { useManageMetaDataModal, useOperateData, } from './hooks/use-manage-modal'; @@ -72,7 +75,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { field: '', description: '', values: [], - valueType: 'string', + valueType: metadataValueTypeEnum.string, }); const [activeTab, setActiveTab] = useState('generation'); @@ -98,12 +101,18 @@ export const ManageMetadataModal = (props: IManageModalProps) => { ); const { handleMenuClick } = useHandleMenuClick(); const [shouldSave, setShouldSave] = useState(false); + const [isAddValueMode, setIsAddValueMode] = useState(false); const { visible: manageValuesVisible, showModal: showManageValuesModal, hideModal: hideManageValuesModal, } = useSetModalState(); + const hideManageValuesModalFunc = () => { + setIsAddValueMode(false); + hideManageValuesModal(); + }; + const isSettingsMode = metadataType === MetadataType.Setting || metadataType === MetadataType.SingleFileSetting || @@ -166,10 +175,15 @@ export const ManageMetadataModal = (props: IManageModalProps) => { setValueData({ field: '', description: '', - values: [], - valueType: 'string', + values: + metadataType === MetadataType.Setting || + metadataType === MetadataType.SingleFileSetting + ? [] + : [''], + valueType: metadataValueTypeEnum.string, }); setCurrentValueIndex(tableData.length || 0); + setIsAddValueMode(true); showManageValuesModal(); }; const handleEditValueRow = useCallback( @@ -246,6 +260,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { return Array.from(fieldMap.values()); }); setShouldSave(true); + setIsAddValueMode(false); }; useEffect(() => { @@ -254,7 +269,6 @@ export const ManageMetadataModal = (props: IManageModalProps) => { handleSave({ callback: () => {}, builtInMetadata: builtInSelection }); setShouldSave(false); }, 0); - console.log('shouldSave'); return () => clearTimeout(timer); } }, [tableData, shouldSave, handleSave, builtInSelection]); @@ -302,28 +316,30 @@ export const ManageMetadataModal = (props: IManageModalProps) => {
{t('knowledgeDetails.metadata.metadata')}
- {metadataType === MetadataType.Manage && ( - - )} - {isCanAdd && activeTab !== 'built-in' && ( - - )} +
+ {metadataType === MetadataType.Manage && ( + + )} + {isCanAdd && activeTab !== 'built-in' && ( + + )} +
{rowSelectionIsEmpty || ( @@ -538,17 +554,18 @@ export const ManageMetadataModal = (props: IManageModalProps) => { type={metadataType} existsKeys={existsKeys} visible={manageValuesVisible} - hideModal={hideManageValuesModal} + hideModal={hideManageValuesModalFunc} data={valueData} onSave={handleSaveValues} addUpdateValue={addUpdateValue} addDeleteValue={addDeleteValue} - isEditField={isEditField || isCanAdd} - isAddValue={isAddValue || isCanAdd} + isEditField={isEditField || isAddValueMode} + isAddValue={isAddValue || isAddValueMode} isShowDescription={isShowDescription} isShowValueSwitch={isShowValueSwitch} isShowType={isSettingsMode} isVerticalShowValue={isVerticalShowValue} + isAddValueMode={isAddValueMode} // handleDeleteSingleValue={handleDeleteSingleValue} // handleDeleteSingleRow={handleDeleteSingleRow} /> diff --git a/web/src/pages/dataset/components/metedata/manage-values-modal.tsx b/web/src/pages/dataset/components/metedata/manage-values-modal.tsx index 70be2b3ca..0b4a89933 100644 --- a/web/src/pages/dataset/components/metedata/manage-values-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-values-modal.tsx @@ -13,7 +13,11 @@ import dayjs from 'dayjs'; import { Plus, Trash2 } from 'lucide-react'; import { memo, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { metadataValueTypeOptions } from './hooks/use-manage-modal'; +import { + MetadataType, + metadataValueTypeEnum, + metadataValueTypeOptions, +} from './constant'; import { useManageValues } from './hooks/use-manage-values-modal'; import { IManageValuesProps, MetadataValueType } from './interface'; @@ -26,6 +30,7 @@ const ValueInputItem = memo( onValueChange, onDelete, onBlur, + isCanDelete = true, }: { item: string; index: number; @@ -33,6 +38,7 @@ const ValueInputItem = memo( onValueChange: (index: number, value: string, isUpdate?: boolean) => void; onDelete: (index: number) => void; onBlur: (index: number) => void; + isCanDelete?: boolean; }) => { const value = useMemo(() => { if (type === 'time') { @@ -84,14 +90,16 @@ const ValueInputItem = memo( /> )}
- + {isCanDelete && ( + + )} ); }, @@ -109,6 +117,7 @@ export const ManageValuesModal = (props: IManageValuesProps) => { isShowDescription, isVerticalShowValue, isShowType, + type: metadataType, } = props; const { metaData, @@ -158,11 +167,33 @@ export const ManageValuesModal = (props: IManageValuesProps) => { label: 'Type', type: FormFieldType.Select, options: metadataValueTypeOptions, - defaultValue: metaData.valueType || 'string', + defaultValue: metaData.valueType || metadataValueTypeEnum.string, onChange: (value: string) => { setValueType(value as MetadataValueType); handleChange('valueType', value); - handleClearValues(); + if ( + metadataType === MetadataType.Manage || + metadataType === MetadataType.UpdateSingle + ) { + handleClearValues(); + } + + if ( + metadataType === MetadataType.Setting || + metadataType === MetadataType.SingleFileSetting + ) { + if ( + value !== metadataValueTypeEnum.list && + value !== metadataValueTypeEnum.string + ) { + handleChange('restrictDefinedValues', false); + handleClearValues(true); + formRef.current?.form.setValue( + 'restrictDefinedValues', + false, + ); + } + } }, }, ] @@ -188,6 +219,11 @@ export const ManageValuesModal = (props: IManageValuesProps) => { tooltip: t('knowledgeDetails.metadata.restrictDefinedValuesTip'), type: FormFieldType.Switch, defaultValue: metaData.restrictDefinedValues || false, + shouldRender: (formData: any) => { + return ( + formData.valueType === 'list' || formData.valueType === 'string' + ); + }, onChange: (value: boolean) => handleChange('restrictDefinedValues', value), }, @@ -232,17 +268,19 @@ export const ManageValuesModal = (props: IManageValuesProps) => {
{t('knowledgeDetails.metadata.values')}
- {isAddValue && isVerticalShowValue && ( -
- -
- )} + {isAddValue && + isVerticalShowValue && + metaData.valueType === metadataValueTypeEnum['list'] && ( +
+ +
+ )}
{isVerticalShowValue && (
@@ -259,7 +297,8 @@ export const ManageValuesModal = (props: IManageValuesProps) => { handleDelete(idx); }); }} - onBlur={handleValueBlur} + isCanDelete={tempValues.length > 1} + onBlur={() => handleValueBlur()} /> ); })} diff --git a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx index 943c381cf..dc7185955 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx @@ -34,11 +34,12 @@ import { } from 'react-hook-form'; import { useLocation } from 'react-router'; import { DataSetContext } from '..'; +import { MetadataType } from '../../components/metedata/constant'; import { - MetadataType, useManageMetadata, util, } from '../../components/metedata/hooks/use-manage-modal'; + import { IBuiltInMetadataItem, IMetaDataReturnJSONSettings, diff --git a/web/src/pages/dataset/dataset/index.tsx b/web/src/pages/dataset/dataset/index.tsx index e5685502e..dbf19509c 100644 --- a/web/src/pages/dataset/dataset/index.tsx +++ b/web/src/pages/dataset/dataset/index.tsx @@ -19,10 +19,8 @@ import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-reques import { Upload } from 'lucide-react'; import { useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { - MetadataType, - useManageMetadata, -} from '../components/metedata/hooks/use-manage-modal'; +import { MetadataType } from '../components/metedata/constant'; +import { useManageMetadata } from '../components/metedata/hooks/use-manage-modal'; import { ManageMetadataModal } from '../components/metedata/manage-modal'; import { useKnowledgeBaseContext } from '../contexts/knowledge-base-context'; import { DatasetTable } from './dataset-table'; @@ -253,6 +251,8 @@ export default function Dataset() { // selectedRowKeys={selectedRowKeys} tableData={tableData} isCanAdd={metadataConfig.isCanAdd} + isAddValue={metadataConfig.isAddValue} + isVerticalShowValue={metadataConfig.isVerticalShowValue} isEditField={metadataConfig.isEditField} isDeleteSingleValue={metadataConfig.isDeleteSingleValue} type={metadataConfig.type} diff --git a/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx b/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx index aa3b59826..7e94fb1b4 100644 --- a/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx +++ b/web/src/pages/dataset/dataset/use-dataset-table-columns.tsx @@ -16,7 +16,7 @@ import { formatDate } from '@/utils/date'; import { ColumnDef } from '@tanstack/table-core'; import { ArrowUpDown, MonitorUp } from 'lucide-react'; import { useTranslation } from 'react-i18next'; -import { MetadataType } from '../components/metedata/hooks/use-manage-modal'; +import { MetadataType } from '../components/metedata/constant'; import { ShowManageMetadataModalProps } from '../components/metedata/interface'; import { DatasetActionCell } from './dataset-action-cell'; import { ParsingStatusCell } from './parsing-status-cell'; @@ -181,7 +181,9 @@ export function useDatasetTableColumns({ // metadata: util.JSONToMetaDataTableData( // row.original.meta_fields || {}, // ), + isEditField: false, isCanAdd: true, + isAddValue: true, type: MetadataType.UpdateSingle, record: row.original, title: (