diff --git a/web/src/interfaces/database/knowledge.ts b/web/src/interfaces/database/knowledge.ts index 502c63c1b..36c55df9f 100644 --- a/web/src/interfaces/database/knowledge.ts +++ b/web/src/interfaces/database/knowledge.ts @@ -68,6 +68,8 @@ export interface ParserConfig { topn_tags?: number; graphrag?: { use_graphrag?: boolean }; enable_metadata?: boolean; + metadata?: any; + built_in_metadata?: Array<{ key: string; type: string }>; } export interface IKnowledgeFileParserConfig { 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 c9d54b1a5..5a56ad7a1 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 @@ -14,11 +14,14 @@ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router'; import { + IBuiltInMetadataItem, + IMetaDataJsonSchemaProperty, IMetaDataReturnJSONSettings, IMetaDataReturnJSONType, IMetaDataReturnType, IMetaDataTableData, MetadataOperations, + MetadataValueType, ShowManageMetadataModalProps, } from '../interface'; export enum MetadataType { @@ -71,6 +74,90 @@ export const MetadataDeleteMap = ( }, }; }; + +const DEFAULT_VALUE_TYPE: MetadataValueType = 'string'; +const VALUE_TYPES_WITH_ENUM = new Set(['enum']); +const VALUE_TYPE_LABELS: Record = { + string: 'String', + bool: 'Bool', + enum: 'Enum', + time: 'Time', + 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[] { return Object.entries(data).map(([key, value]) => { @@ -117,25 +204,58 @@ export const util = { tableDataToMetaDataSettingJSON( data: IMetaDataTableData[], ): IMetaDataReturnJSONSettings { - return data.map((item) => { - return { - key: item.field, - description: item.description, - enum: item.values, - }; - }); + const properties = data.reduce>( + (acc, item) => { + if (!item.field) { + return acc; + } + const valueType = item.valueType || DEFAULT_VALUE_TYPE; + const values = + isMetadataValueTypeWithEnum(valueType) && item.restrictDefinedValues + ? item.values + : []; + acc[item.field] = valueTypeToSchema( + valueType, + item.description, + values, + ); + return acc; + }, + {}, + ); + + return { + type: 'object', + properties, + additionalProperties: false, + }; }, metaDataSettingJSONToMetaDataTableData( data: IMetaDataReturnJSONSettings, ): IMetaDataTableData[] { - if (!Array.isArray(data)) return []; - return data.map((item) => { + if (!data) return []; + if (Array.isArray(data)) { + return data.map((item) => { + return { + field: item.key, + description: item.description, + values: item.enum || [], + restrictDefinedValues: !!item.enum?.length, + valueType: DEFAULT_VALUE_TYPE, + } as IMetaDataTableData; + }); + } + const properties = data.properties || {}; + return Object.entries(properties).map(([key, property]) => { + const valueType = schemaToValueType(property); + const values = property.enum || property.items?.enum || []; return { - field: item.key, - description: item.description, - values: item.enum, - restrictDefinedValues: !!item.enum?.length, + field: key, + description: property.description || '', + values, + restrictDefinedValues: !!values.length, + valueType, } as IMetaDataTableData; }); }, @@ -384,21 +504,15 @@ export const useManageMetaDataModal = ( ); const handleSaveSettings = useCallback( - async (callback: () => void) => { + async (callback: () => void, builtInMetadata?: IBuiltInMetadataItem[]) => { const data = util.tableDataToMetaDataSettingJSON(tableData); - const { data: res } = await kbService.kbUpdateMetaData({ - kb_id: id, + callback?.(); + return { metadata: data, - enable_metadata: true, - }); - if (res.code === 0) { - message.success(t('message.operated')); - callback?.(); - } - - return data; + builtInMetadata: builtInMetadata || [], + }; }, - [tableData, id, t], + [tableData], ); const handleSaveSingleFileSettings = useCallback( @@ -421,7 +535,13 @@ export const useManageMetaDataModal = ( ); const handleSave = useCallback( - async ({ callback }: { callback: () => void }) => { + async ({ + callback, + builtInMetadata, + }: { + callback: () => void; + builtInMetadata?: string[]; + }) => { switch (type) { case MetadataType.UpdateSingle: handleSaveUpdateSingle(callback); @@ -430,7 +550,7 @@ export const useManageMetaDataModal = ( handleSaveManage(callback); break; case MetadataType.Setting: - return handleSaveSettings(callback); + return handleSaveSettings(callback, builtInMetadata); case MetadataType.SingleFileSetting: return handleSaveSingleFileSettings(callback); default: 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 38608109d..9550f4aeb 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,13 +1,16 @@ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { MetadataDeleteMap, MetadataType } from '../hooks/use-manage-modal'; +import { + isMetadataValueTypeWithEnum, + MetadataDeleteMap, + MetadataType, +} from '../hooks/use-manage-modal'; import { IManageValuesProps, IMetaDataTableData } from '../interface'; export const useManageValues = (props: IManageValuesProps) => { const { data, - isShowValueSwitch, hideModal, onSave, addUpdateValue, @@ -16,7 +19,10 @@ export const useManageValues = (props: IManageValuesProps) => { type, } = props; const { t } = useTranslation(); - const [metaData, setMetaData] = useState(data); + const [metaData, setMetaData] = useState({ + ...data, + valueType: data.valueType || 'string', + }); const [valueError, setValueError] = useState>({ field: '', values: '', @@ -61,10 +67,28 @@ export const useManageValues = (props: IManageValuesProps) => { }; }); } - setMetaData((prev) => ({ - ...prev, - [field]: value, - })); + setMetaData((prev) => { + if (field === 'valueType') { + const nextValueType = (value || + 'string') as IMetaDataTableData['valueType']; + const supportsEnum = isMetadataValueTypeWithEnum(nextValueType); + if (!supportsEnum) { + setTempValues([]); + } + return { + ...prev, + valueType: nextValueType, + values: supportsEnum ? prev.values : [], + restrictDefinedValues: supportsEnum + ? prev.restrictDefinedValues || nextValueType === 'enum' + : false, + }; + } + return { + ...prev, + [field]: value, + }; + }); }, [existsKeys, type, t], ); @@ -74,7 +98,10 @@ export const useManageValues = (props: IManageValuesProps) => { useEffect(() => { setTempValues([...data.values]); - setMetaData(data); + setMetaData({ + ...data, + valueType: data.valueType || 'string', + }); }, [data]); const handleHideModal = useCallback(() => { @@ -86,14 +113,19 @@ export const useManageValues = (props: IManageValuesProps) => { if (type === MetadataType.Setting && valueError.field) { return; } - if (!metaData.restrictDefinedValues && isShowValueSwitch) { - const newMetaData = { ...metaData, values: [] }; - onSave(newMetaData); - } else { - onSave(metaData); + const supportsEnum = isMetadataValueTypeWithEnum(metaData.valueType); + if (!supportsEnum) { + onSave({ + ...metaData, + values: [], + restrictDefinedValues: false, + }); + handleHideModal(); + return; } + onSave(metaData); handleHideModal(); - }, [metaData, onSave, handleHideModal, isShowValueSwitch, type, valueError]); + }, [metaData, onSave, handleHideModal, type, valueError]); // Handle value changes, only update temporary state const handleValueChange = useCallback( diff --git a/web/src/pages/dataset/components/metedata/interface.ts b/web/src/pages/dataset/components/metedata/interface.ts index ef2990366..27f38d06f 100644 --- a/web/src/pages/dataset/components/metedata/interface.ts +++ b/web/src/pages/dataset/components/metedata/interface.ts @@ -11,13 +11,44 @@ export interface IMetaDataReturnJSONSettingItem { description?: string; enum?: string[]; } -export type IMetaDataReturnJSONSettings = Array; +export interface IMetaDataJsonSchemaProperty { + type?: string; + description?: string; + enum?: string[]; + items?: { + type?: string; + enum?: string[]; + }; + format?: string; +} +export interface IMetaDataJsonSchema { + type?: 'object'; + properties?: Record; + additionalProperties?: boolean; +} +export type IMetaDataReturnJSONSettings = + | IMetaDataJsonSchema + | Array; + +export type MetadataValueType = + | 'string' + | 'bool' + | 'enum' + | 'time' + | 'int' + | 'float'; export type IMetaDataTableData = { field: string; description: string; restrictDefinedValues?: boolean; values: string[]; + valueType?: MetadataValueType; +}; + +export type IBuiltInMetadataItem = { + key: string; + type: MetadataValueType; }; export type IManageModalProps = { @@ -34,6 +65,7 @@ export type IManageModalProps = { isAddValue?: boolean; isShowValueSwitch?: boolean; isVerticalShowValue?: boolean; + builtInMetadata?: IBuiltInMetadataItem[]; success?: (data: any) => void; }; @@ -45,6 +77,7 @@ export interface IManageValuesProps { isAddValue?: boolean; isShowDescription?: boolean; isShowValueSwitch?: boolean; + isShowType?: boolean; isVerticalShowValue?: boolean; data: IMetaDataTableData; type: MetadataType; @@ -81,6 +114,7 @@ export type ShowManageMetadataModalProps = Partial & { isCanAdd: boolean; type: MetadataType; record?: Record; + builtInMetadata?: IBuiltInMetadataItem[]; options?: ShowManageMetadataModalOptions; title?: ReactNode | string; isDeleteSingleValue?: boolean; diff --git a/web/src/pages/dataset/components/metedata/manage-modal.tsx b/web/src/pages/dataset/components/metedata/manage-modal.tsx index 790b2f1ea..68053b6bd 100644 --- a/web/src/pages/dataset/components/metedata/manage-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-modal.tsx @@ -7,6 +7,7 @@ import Empty from '@/components/empty/empty'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Modal } from '@/components/ui/modal/modal'; +import { Switch } from '@/components/ui/switch'; import { Table, TableBody, @@ -15,6 +16,7 @@ import { TableHeader, TableRow, } from '@/components/ui/table'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { useSetModalState } from '@/hooks/common-hooks'; import { Routes } from '@/routes'; import { @@ -39,11 +41,19 @@ import { useHandleMenuClick } from '../../sidebar/hooks'; import { MetadataDeleteMap, MetadataType, + getMetadataValueTypeLabel, + isMetadataValueTypeWithEnum, useManageMetaDataModal, } from './hooks/use-manage-modal'; -import { IManageModalProps, IMetaDataTableData } from './interface'; +import { + IBuiltInMetadataItem, + IManageModalProps, + IMetaDataTableData, +} from './interface'; import { ManageValuesModal } from './manage-values-modal'; +type MetadataSettingsTab = 'generation' | 'built-in'; + export const ManageMetadataModal = (props: IManageModalProps) => { const { title, @@ -59,6 +69,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { isShowDescription = false, isShowValueSwitch = false, isVerticalShowValue = true, + builtInMetadata, success, } = props; const { t } = useTranslation(); @@ -66,10 +77,15 @@ export const ManageMetadataModal = (props: IManageModalProps) => { field: '', description: '', values: [], + valueType: 'string', }); const [expanded, setExpanded] = useState(true); + const [activeTab, setActiveTab] = useState('generation'); const [currentValueIndex, setCurrentValueIndex] = useState(0); + const [builtInSelection, setBuiltInSelection] = useState< + IBuiltInMetadataItem[] + >([]); const [deleteDialogContent, setDeleteDialogContent] = useState({ visible: false, title: '', @@ -111,6 +127,62 @@ export const ManageMetadataModal = (props: IManageModalProps) => { }); }; + const isSettingsMode = + metadataType === MetadataType.Setting || + metadataType === MetadataType.SingleFileSetting; + const showTypeColumn = isSettingsMode; + const builtInRows = useMemo( + () => [ + { + field: 'update_time', + valueType: 'time', + description: t('knowledgeConfiguration.builtIn'), + }, + { + field: 'file_name', + valueType: 'string', + description: t('knowledgeConfiguration.builtIn'), + }, + ], + [t], + ); + const builtInTypeByKey = useMemo( + () => + new Map( + builtInRows.map((row) => [ + row.field, + row.valueType as IBuiltInMetadataItem['type'], + ]), + ), + [builtInRows], + ); + + useEffect(() => { + if (!visible) return; + setBuiltInSelection( + (builtInMetadata || []).map((item) => { + if (typeof item === 'string') { + return { + key: item, + type: builtInTypeByKey.get(item) || 'string', + }; + } + return { + key: item.key, + type: (item.type || + builtInTypeByKey.get(item.key) || + 'string') as IBuiltInMetadataItem['type'], + }; + }), + ); + setActiveTab('generation'); + }, [builtInMetadata, builtInTypeByKey, visible]); + + const builtInSelectionKeys = useMemo( + () => new Set(builtInSelection.map((item) => item.key)), + [builtInSelection], + ); + const handleEditValue = (field: string, value: string) => { setEditingValue({ field, value, newValue: value }); }; @@ -141,6 +213,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { field: '', description: '', values: [], + valueType: 'string', }); setCurrentValueIndex(tableData.length || 0); showManageValuesModal(); @@ -165,6 +238,21 @@ export const ManageMetadataModal = (props: IManageModalProps) => { ), }, + ...(showTypeColumn + ? ([ + { + accessorKey: 'valueType', + header: () => Type, + cell: ({ row }) => ( +
+ {getMetadataValueTypeLabel( + row.original.valueType as IMetaDataTableData['valueType'], + )} +
+ ), + }, + ] as ColumnDef[]) + : []), { accessorKey: 'description', header: () => {t('knowledgeDetails.metadata.description')}, @@ -196,8 +284,11 @@ export const ManageMetadataModal = (props: IManageModalProps) => { ), cell: ({ row }) => { const values = row.getValue('values') as Array; + const supportsEnum = isMetadataValueTypeWithEnum( + row.original.valueType, + ); - if (!Array.isArray(values) || values.length === 0) { + if (!supportsEnum || !Array.isArray(values) || values.length === 0) { return
; } @@ -342,7 +433,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { }, ]; if (!isShowDescription) { - cols.splice(1, 1); + return cols.filter((col) => col.accessorKey !== 'description'); } return cols; }, [ @@ -356,6 +447,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { expanded, editingValue, saveEditedValue, + showTypeColumn, ]); const table = useReactTable({ @@ -393,7 +485,11 @@ export const ManageMetadataModal = (props: IManageModalProps) => { const mergedValues = [ ...new Set([...existingItem.values, ...item.values]), ]; - fieldMap.set(item.field, { ...existingItem, values: mergedValues }); + fieldMap.set(item.field, { + ...existingItem, + ...item, + values: mergedValues, + }); } else { fieldMap.set(item.field, item); } @@ -407,13 +503,13 @@ export const ManageMetadataModal = (props: IManageModalProps) => { useEffect(() => { if (shouldSave) { const timer = setTimeout(() => { - handleSave({ callback: () => {} }); + handleSave({ callback: () => {}, builtInMetadata: builtInSelection }); setShouldSave(false); }, 0); return () => clearTimeout(timer); } - }, [tableData, shouldSave, handleSave]); + }, [tableData, shouldSave, handleSave, builtInSelection]); const existsKeys = useMemo(() => { return tableData.map((item) => item.field); @@ -428,7 +524,10 @@ export const ManageMetadataModal = (props: IManageModalProps) => { maskClosable={false} okText={t('common.save')} onOk={async () => { - const res = await handleSave({ callback: hideModal }); + const res = await handleSave({ + callback: hideModal, + builtInMetadata: builtInSelection, + }); console.log('data', res); success?.(res); }} @@ -449,7 +548,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { {t('knowledgeDetails.metadata.toMetadataSetting')} )} - {isCanAdd && ( + {isCanAdd && activeTab !== 'built-in' && ( )} - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ))} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - + {metadataType === MetadataType.Setting ? ( + setActiveTab(v as MetadataSettingsTab)} + > + + Generation + + {t('knowledgeConfiguration.builtIn')} + + + +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ))} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + + + + + )} + +
+ + + + + + + {t('knowledgeDetails.metadata.field')} + + Type + + {t('knowledgeDetails.metadata.description')} + + + {t('knowledgeDetails.metadata.action')} + + + + + {builtInRows.map((row) => ( + + +
+ {row.field} +
+
+ +
+ {getMetadataValueTypeLabel( + row.valueType as IMetaDataTableData['valueType'], + )} +
+
+ +
+ {row.description} +
+
+ + { + setBuiltInSelection((prev) => { + if (checked) { + const nextType = + row.valueType as IBuiltInMetadataItem['type']; + if ( + prev.some( + (item) => item.key === row.field, + ) + ) { + return prev.map((item) => + item.key === row.field + ? { ...item, type: nextType } + : item, + ); + } + return [ + ...prev, + { key: row.field, type: nextType }, + ]; + } + return prev.filter( + (item) => item.key !== row.field, + ); + }); + }} + /> + +
+ ))} +
+
+
+ + ) : ( + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + ))} - )) - ) : ( - - - - - - )} - -
+ ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + )) + ) : ( + + + + + + )} + + + )} {metadataType === MetadataType.Manage && (
@@ -537,6 +771,7 @@ export const ManageMetadataModal = (props: IManageModalProps) => { isAddValue={isAddValue || isCanAdd} isShowDescription={isShowDescription} isShowValueSwitch={isShowValueSwitch} + isShowType={isSettingsMode} isVerticalShowValue={isVerticalShowValue} // 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 f1c6343f6..2498dd887 100644 --- a/web/src/pages/dataset/components/metedata/manage-values-modal.tsx +++ b/web/src/pages/dataset/components/metedata/manage-values-modal.tsx @@ -7,11 +7,15 @@ import { Button } from '@/components/ui/button'; import { FormLabel } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Modal } from '@/components/ui/modal/modal'; -import { Switch } from '@/components/ui/switch'; +import { RAGFlowSelect } from '@/components/ui/select'; import { Textarea } from '@/components/ui/textarea'; import { Plus, Trash2 } from 'lucide-react'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; +import { + isMetadataValueTypeWithEnum, + metadataValueTypeOptions, +} from './hooks/use-manage-modal'; import { useManageValues } from './hooks/use-manage-values-modal'; import { IManageValuesProps } from './interface'; @@ -62,8 +66,8 @@ export const ManageValuesModal = (props: IManageValuesProps) => { visible, isAddValue, isShowDescription, - isShowValueSwitch, isVerticalShowValue, + isShowType, } = props; const { metaData, @@ -80,6 +84,7 @@ export const ManageValuesModal = (props: IManageValuesProps) => { handleHideModal, } = useManageValues(props); const { t } = useTranslation(); + const canShowValues = isMetadataValueTypeWithEnum(metaData.valueType); return ( {
)} + {isShowType && ( +
+
Type
+ handleChange('valueType', value)} + /> +
+ )} {isShowDescription && (
{
)} - {isShowValueSwitch && ( -
- - {t('knowledgeDetails.metadata.restrictDefinedValues')} - -
- - handleChange('restrictDefinedValues', checked) - } - /> -
-
- )} - {((metaData.restrictDefinedValues && isShowValueSwitch) || - !isShowValueSwitch) && ( + {canShowValues && (
{t('knowledgeDetails.metadata.values')}
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 39fef6c45..943c381cf 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx @@ -39,7 +39,10 @@ import { useManageMetadata, util, } from '../../components/metedata/hooks/use-manage-modal'; -import { IMetaDataReturnJSONSettings } from '../../components/metedata/interface'; +import { + IBuiltInMetadataItem, + IMetaDataReturnJSONSettings, +} from '../../components/metedata/interface'; import { ManageMetadataModal } from '../../components/metedata/manage-modal'; import { useHandleKbEmbedding, @@ -384,12 +387,14 @@ export function AutoMetadata({ const handleClickOpenMetadata = useCallback(() => { const metadata = form.getValues('parser_config.metadata'); + const builtInMetadata = form.getValues('parser_config.built_in_metadata'); const tableMetaData = util.metaDataSettingJSONToMetaDataTableData(metadata); showManageMetadataModal({ metadata: tableMetaData, isCanAdd: true, type: type, record: otherData, + builtInMetadata, }); }, [form, otherData, showManageMetadataModal, type]); @@ -429,8 +434,15 @@ export function AutoMetadata({ ), }; - const handleSaveMetadata = (data?: IMetaDataReturnJSONSettings) => { - form.setValue('parser_config.metadata', data || []); + const handleSaveMetadata = (data?: { + metadata?: IMetaDataReturnJSONSettings; + builtInMetadata?: IBuiltInMetadataItem[]; + }) => { + form.setValue('parser_config.metadata', data?.metadata || []); + form.setValue( + 'parser_config.built_in_metadata', + data?.builtInMetadata || [], + ); form.setValue('parser_config.enable_metadata', true); }; return ( @@ -461,7 +473,11 @@ export function AutoMetadata({ isShowDescription={true} isShowValueSwitch={true} isVerticalShowValue={false} - success={(data?: IMetaDataReturnJSONSettings) => { + builtInMetadata={metadataConfig.builtInMetadata} + success={(data?: { + metadata?: IMetaDataReturnJSONSettings; + builtInMetadata?: IBuiltInMetadataItem[]; + }) => { handleSaveMetadata(data); }} /> diff --git a/web/src/pages/dataset/dataset-setting/form-schema.ts b/web/src/pages/dataset/dataset-setting/form-schema.ts index 196fefe76..1884ff425 100644 --- a/web/src/pages/dataset/dataset-setting/form-schema.ts +++ b/web/src/pages/dataset/dataset-setting/form-schema.ts @@ -84,15 +84,13 @@ export const formSchema = z path: ['entity_types'], }, ), - metadata: z + metadata: z.any().optional(), + built_in_metadata: z .array( - z - .object({ - key: z.string().optional(), - description: z.string().optional(), - enum: z.array(z.string().optional()).optional(), - }) - .optional(), + z.object({ + key: z.string().optional(), + type: z.string().optional(), + }), ) .optional(), enable_metadata: z.boolean().optional(), diff --git a/web/src/pages/dataset/dataset-setting/index.tsx b/web/src/pages/dataset/dataset-setting/index.tsx index b3d9f87a2..b4a859053 100644 --- a/web/src/pages/dataset/dataset-setting/index.tsx +++ b/web/src/pages/dataset/dataset-setting/index.tsx @@ -95,7 +95,12 @@ export default function DatasetSettings() { entity_types: initialEntityTypes, method: MethodValue.Light, }, - metadata: [], + metadata: { + type: 'object', + properties: {}, + additionalProperties: false, + }, + built_in_metadata: [], enable_metadata: false, llm_id: '', },