import { useEffect, useRef, useState } from 'react' // import { useTranslation } from 'react-i18next' import { debounce } from 'lodash-es' import Textarea from '@/app/components/base/textarea' import SchemaEditor from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/schema-editor' import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader' import ErrorMessage from '@/app/components/workflow/nodes/llm/components/json-schema-config-modal/error-message' import { checkJsonSchemaDepth, getValidationErrorMessage, validateSchemaAgainstDraft7, } from '@/app/components/workflow/nodes/llm/utils' import { validateJSONSchema, } from '@/app/components/workflow/variable-inspect/utils' import { useFeatures } from '@/app/components/base/features/hooks' import { getProcessedFiles } from '@/app/components/base/file-uploader/utils' import { JSON_SCHEMA_MAX_DEPTH } from '@/config' import { TransferMethod } from '@/types/app' import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import type { VarInInspect } from '@/types/workflow' import { VarInInspectType } from '@/types/workflow' import cn from '@/utils/classnames' export const MOCK_DATA = { id: 'var-jfkldjjfkldaf-dfhekdfj', type: 'node', // type: 'conversation', // type: 'environment', name: 'out_put', // value_type: 'string', // value_type: 'number', // value_type: 'object', // value_type: 'array[string]', // value_type: 'array[number]', // value_type: 'array[object]', // value_type: 'file', value_type: 'array[file]', // value: 'tuituitui', // value: ['aaa', 'bbb', 'ccc'], // value: { // abc: '123', // def: 456, // fff: true, // }, value: [], edited: true, } type Props = { currentVar: VarInInspect } const ValueContent = ({ // currentVar = MOCK_DATA as any, // TODO remove this line currentVar, }: Props) => { const contentContainerRef = useRef(null) const errorMessageRef = useRef(null) const [editorHeight, setEditorHeight] = useState(0) const showTextEditor = currentVar.value_type === 'secret' || currentVar.value_type === 'string' || currentVar.value_type === 'number' const showJSONEditor = currentVar.value_type === 'object' || currentVar.value_type === 'array[string]' || currentVar.value_type === 'array[number]' || currentVar.value_type === 'array[object]' const showFileEditor = currentVar.value_type === 'file' || currentVar.value_type === 'array[file]' const [value, setValue] = useState() const [jsonSchema, setJsonSchema] = useState() const [json, setJson] = useState('') const [parseError, setParseError] = useState(null) const [validationError, setValidationError] = useState('') const fileFeature = useFeatures(s => s.features.file) const [fileValue, setFileValue] = useState( currentVar.value_type === 'array[file]' ? currentVar.value || [] : currentVar.value ? [currentVar.value] : [], ) // update default value when id changed useEffect(() => { if (showTextEditor) { if (!currentVar.value) return setValue('') if (currentVar.value_type === 'number') return setValue(JSON.stringify(currentVar.value)) setValue(currentVar.value) } if (showJSONEditor) { setJsonSchema(currentVar.value || null) setJson(currentVar.value ? JSON.stringify(currentVar.value, null, 2) : '') } if (showFileEditor) { setFileValue(currentVar.value_type === 'array[file]' ? currentVar.value || [] : currentVar.value ? [currentVar.value] : []) } }, [currentVar, showTextEditor, showJSONEditor, showFileEditor]) const handleTextChange = (value: string) => { if (currentVar.value_type === 'string') setValue(value) if (currentVar.value_type === 'number') { if (/^-?\d+(\.)?(\d+)?$/.test(value)) setValue(value) } // TODO call api of value update } const jsonValueValidate = (value: string, type: string) => { try { const newJSONSchema = JSON.parse(value) setParseError(null) const result = validateJSONSchema(newJSONSchema, type) if (!result.success) { setValidationError(result.error.message) return false } if (type === 'object' || type === 'array[object]') { const schemaDepth = checkJsonSchemaDepth(newJSONSchema) if (schemaDepth > JSON_SCHEMA_MAX_DEPTH) { setValidationError(`Schema exceeds maximum depth of ${JSON_SCHEMA_MAX_DEPTH}.`) return false } const validationErrors = validateSchemaAgainstDraft7(newJSONSchema) if (validationErrors.length > 0) { setValidationError(getValidationErrorMessage(validationErrors)) return false } } setValidationError('') return true } catch (error) { setValidationError('') if (error instanceof Error) { setParseError(error) return false } else { setParseError(new Error('Invalid JSON')) return false } } } const handleEditorChange = (value: string) => { setJson(value) if (jsonValueValidate(value, currentVar.value_type)) { const parsed = JSON.parse(value) setJsonSchema(parsed) // TODO call api of value update } } const handleFileChange = (value: any) => { console.log('value', value) setFileValue(value) // TODO check every file upload progress // invoke update api after every file uploaded if (currentVar.value_type === 'file') { // TODO call api of value update } if (currentVar.value_type === 'array[file]') { // TODO call api of value update } } // get editor height useEffect(() => { if (contentContainerRef.current && errorMessageRef.current) { const errorMessageObserver = new ResizeObserver((entries) => { for (const entry of entries) { const { inlineSize } = entry.borderBoxSize[0] const height = (contentContainerRef.current as any).clientHeight - inlineSize setEditorHeight(height) } }) errorMessageObserver.observe(errorMessageRef.current) return () => { errorMessageObserver.disconnect() } } }, [errorMessageRef.current, setEditorHeight]) return (
{showTextEditor && (