feat(web): form add rules
This commit is contained in:
@@ -41,6 +41,8 @@ interface SearchInputProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
/** Input size */
|
/** Input size */
|
||||||
size?: InputProps['size']
|
size?: InputProps['size']
|
||||||
|
/** Maximum length of the input value */
|
||||||
|
maxLength?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Search input component with debounce and throttle support */
|
/** Search input component with debounce and throttle support */
|
||||||
|
|||||||
@@ -453,6 +453,8 @@ export const en = {
|
|||||||
prevStep: 'Previous Step',
|
prevStep: 'Previous Step',
|
||||||
exportSuccess: 'Export successful',
|
exportSuccess: 'Export successful',
|
||||||
recommend: 'Recommend',
|
recommend: 'Recommend',
|
||||||
|
logoTip: `Supported image formats: JPG, PNG \n Suggested size: square ratio \n Maximum size: ≤ 2MB`,
|
||||||
|
imageSquareRequired: 'Please upload a square image',
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
searchPlaceholder: 'search model…',
|
searchPlaceholder: 'search model…',
|
||||||
@@ -542,7 +544,8 @@ export const en = {
|
|||||||
ollama: "Ollama",
|
ollama: "Ollama",
|
||||||
xinference: "Xinference",
|
xinference: "Xinference",
|
||||||
gpustack: "Gpustack",
|
gpustack: "Gpustack",
|
||||||
bedrock: "Bedrock"
|
bedrock: "Bedrock",
|
||||||
|
nameInvalid: 'Model name can only contain letters, numbers, underscores and spaces, cannot be empty or pure whitespace',
|
||||||
},
|
},
|
||||||
modelNew: {
|
modelNew: {
|
||||||
group: 'Model Group',
|
group: 'Model Group',
|
||||||
|
|||||||
@@ -1029,6 +1029,8 @@ export const zh = {
|
|||||||
prevStep: '上一步',
|
prevStep: '上一步',
|
||||||
exportSuccess: '导出成功',
|
exportSuccess: '导出成功',
|
||||||
recommend: '推荐',
|
recommend: '推荐',
|
||||||
|
logoTip: `支持图片格式(JPG、PNG)\n 尺寸:正方形比例 \n 文件大小限制:≤ 2MB`,
|
||||||
|
imageSquareRequired: '请上传正方形比例图片',
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
searchPlaceholder: '搜索模型…',
|
searchPlaceholder: '搜索模型…',
|
||||||
@@ -1176,7 +1178,8 @@ export const zh = {
|
|||||||
ollama: "Ollama",
|
ollama: "Ollama",
|
||||||
xinference: "Xinference",
|
xinference: "Xinference",
|
||||||
gpustack: "Gpustack",
|
gpustack: "Gpustack",
|
||||||
bedrock: "Bedrock"
|
bedrock: "Bedrock",
|
||||||
|
nameInvalid: '模型名称只能包含字母、数字、下划线和空格, 不能为空或纯空格',
|
||||||
},
|
},
|
||||||
timezones: {
|
timezones: {
|
||||||
'Asia/Shanghai': '中国标准时间 (UTC+8)',
|
'Asia/Shanghai': '中国标准时间 (UTC+8)',
|
||||||
|
|||||||
50
web/src/utils/validator.ts
Normal file
50
web/src/utils/validator.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* @Author: ZhaoYing
|
||||||
|
* @Date: 2026-03-02 13:46:53
|
||||||
|
* @Last Modified by: ZhaoYing
|
||||||
|
* @Last Modified time: 2026-03-02 14:38:33
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Form validation utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface UploadFile {
|
||||||
|
originFileObj: Blob;
|
||||||
|
[key: string]: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate if uploaded image is square (width === height)
|
||||||
|
* @param errorMessage - Error message to display when validation fails
|
||||||
|
* @returns Ant Design form validator
|
||||||
|
*/
|
||||||
|
export const validateSquareImage = (errorMessage: string = 'Image must be square') => {
|
||||||
|
return (_: unknown, value: UploadFile | UploadFile[] | undefined) => {
|
||||||
|
if (!value || (Array.isArray(value) && value.length === 0)) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = Array.isArray(value) ? value[0] : value;
|
||||||
|
|
||||||
|
if (file?.originFileObj) {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
if (img.width === img.height) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error(errorMessage));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
img.onerror = () => reject(new Error('Failed to load image'));
|
||||||
|
img.src = URL.createObjectURL(file.originFileObj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// - Cannot be empty or pure whitespace
|
||||||
|
// - Cannot start with a space
|
||||||
|
export const stringRegExp = /^[a-zA-Z0-9\u4e00-\u9fa5][a-zA-Z0-9\u4e00-\u9fa5\s]*$/
|
||||||
@@ -12,6 +12,7 @@ import dayjs from 'dayjs'
|
|||||||
import type { ApiKey, ApiKeyModalRef } from '../types';
|
import type { ApiKey, ApiKeyModalRef } from '../types';
|
||||||
import RbModal from '@/components/RbModal'
|
import RbModal from '@/components/RbModal'
|
||||||
import { createApiKey, updateApiKey } from '@/api/apiKey';
|
import { createApiKey, updateApiKey } from '@/api/apiKey';
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ const ApiKeyModal = forwardRef<ApiKeyModalRef, CreateModalProps>(({
|
|||||||
form.validateFields()
|
form.validateFields()
|
||||||
.then((values) => {
|
.then((values) => {
|
||||||
const { memory, rag, expires_at, ...rest } = values
|
const { memory, rag, expires_at, ...rest } = values
|
||||||
let scopes = []
|
const scopes = []
|
||||||
|
|
||||||
if (memory) {
|
if (memory) {
|
||||||
scopes.push('memory')
|
scopes.push('memory')
|
||||||
@@ -130,7 +131,11 @@ const ApiKeyModal = forwardRef<ApiKeyModalRef, CreateModalProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="name"
|
name="name"
|
||||||
label={t('apiKey.name')}
|
label={t('apiKey.name')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.enter')} />
|
<Input placeholder={t('common.enter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -138,6 +143,7 @@ const ApiKeyModal = forwardRef<ApiKeyModalRef, CreateModalProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="description"
|
name="description"
|
||||||
label={t('apiKey.description')}
|
label={t('apiKey.description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('common.pleaseEnter')} rows={3} />
|
<Input.TextArea placeholder={t('common.pleaseEnter')} rows={3} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -169,8 +169,8 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
getApplicationConfig(id as string).then(res => {
|
getApplicationConfig(id as string).then(res => {
|
||||||
const response = res as Config
|
const response = res as Config
|
||||||
const { skills, variables } = response
|
const { skills, variables } = response
|
||||||
let allSkills = Array.isArray(skills?.skill_ids) ? skills?.skill_ids.map(vo => ({ id: vo })) : []
|
const allSkills = Array.isArray(skills?.skill_ids) ? skills?.skill_ids.map(vo => ({ id: vo })) : []
|
||||||
let allTools = Array.isArray(response.tools) ? response.tools : []
|
const allTools = Array.isArray(response.tools) ? response.tools : []
|
||||||
const memoryContent = response.memory?.memory_config_id
|
const memoryContent = response.memory?.memory_config_id
|
||||||
const parsedMemoryContent = memoryContent === null || memoryContent === ''
|
const parsedMemoryContent = memoryContent === null || memoryContent === ''
|
||||||
? undefined
|
? undefined
|
||||||
@@ -431,7 +431,11 @@ const Agent = forwardRef<AgentRef>((_props, ref) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Form.Item name="system_prompt" className="rb:mb-0!">
|
<Form.Item
|
||||||
|
name="system_prompt"
|
||||||
|
className="rb:mb-0!"
|
||||||
|
rules={[{ max: 10000 }]}
|
||||||
|
>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
placeholder={t('application.promptPlaceholder')}
|
placeholder={t('application.promptPlaceholder')}
|
||||||
styles={{
|
styles={{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import WorkflowIcon from '@/assets/images/application/workflow.svg'
|
|||||||
import type { ApplicationModalData, ApplicationModalRef, Application } from '../types'
|
import type { ApplicationModalData, ApplicationModalRef, Application } from '../types'
|
||||||
import RbModal from '@/components/RbModal'
|
import RbModal from '@/components/RbModal'
|
||||||
import { addApplication, updateApplication } from '@/api/application'
|
import { addApplication, updateApplication } from '@/api/application'
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -131,13 +132,18 @@ const ApplicationModal = forwardRef<ApplicationModalRef, ApplicationModalProps>(
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="name"
|
name="name"
|
||||||
label={t('application.applicationName')}
|
label={t('application.applicationName')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.enter')} />
|
<Input placeholder={t('common.enter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem
|
<FormItem
|
||||||
name="description"
|
name="description"
|
||||||
label={t('application.description')}
|
label={t('application.description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('common.enter')} />
|
<Input.TextArea placeholder={t('common.enter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -152,7 +152,11 @@ const MemberModal = forwardRef<MemberModalRef, MemberModalProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="email"
|
name="email"
|
||||||
label={t('member.email')}
|
label={t('member.email')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ type: 'email' },
|
||||||
|
{ max: 100 },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.enterPlaceholder', { title: t('member.email') })} disabled={!!editingUser} />
|
<Input placeholder={t('common.enterPlaceholder', { title: t('member.email') })} disabled={!!editingUser} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import RbModal from '@/components/RbModal'
|
|||||||
import { createMemoryConfig, updateMemoryConfig } from '@/api/memory'
|
import { createMemoryConfig, updateMemoryConfig } from '@/api/memory'
|
||||||
import { getOntologyScenesSimpleUrl } from '@/api/ontology'
|
import { getOntologyScenesSimpleUrl } from '@/api/ontology'
|
||||||
import CustomSelect from '@/components/CustomSelect';
|
import CustomSelect from '@/components/CustomSelect';
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -110,7 +111,11 @@ const MemoryForm = forwardRef<MemoryFormRef, MemoryFormProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="config_name"
|
name="config_name"
|
||||||
label={t('memory.configurationName')}
|
label={t('memory.configurationName')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.pleaseEnter')} />
|
<Input placeholder={t('common.pleaseEnter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -118,6 +123,7 @@ const MemoryForm = forwardRef<MemoryFormRef, MemoryFormProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="config_desc"
|
name="config_desc"
|
||||||
label={t('memory.desc')}
|
label={t('memory.desc')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import CustomSelect from '@/components/CustomSelect'
|
|||||||
import UploadImages from '@/components/Upload/UploadImages'
|
import UploadImages from '@/components/Upload/UploadImages'
|
||||||
import { updateCustomModel, addCustomModel, modelTypeUrl, modelProviderUrl } from '@/api/models'
|
import { updateCustomModel, addCustomModel, modelTypeUrl, modelProviderUrl } from '@/api/models'
|
||||||
import { getFileLink } from '@/api/fileStorage'
|
import { getFileLink } from '@/api/fileStorage'
|
||||||
|
import { validateSquareImage, stringRegExp } from '@/utils/validator'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom model modal component
|
* Custom model modal component
|
||||||
@@ -65,7 +66,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
|||||||
const res = isEdit ? updateCustomModel(model.id, rest) : addCustomModel(data)
|
const res = isEdit ? updateCustomModel(model.id, rest) : addCustomModel(data)
|
||||||
|
|
||||||
res.then(() => {
|
res.then(() => {
|
||||||
refresh && refresh(isEdit)
|
refresh?.(isEdit)
|
||||||
handleClose()
|
handleClose()
|
||||||
message.success(isEdit ? t('common.updateSuccess') : t('common.createSuccess'))
|
message.success(isEdit ? t('common.updateSuccess') : t('common.createSuccess'))
|
||||||
})
|
})
|
||||||
@@ -79,7 +80,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
|||||||
.validateFields()
|
.validateFields()
|
||||||
.then((values) => {
|
.then((values) => {
|
||||||
const { logo, ...rest } = values;
|
const { logo, ...rest } = values;
|
||||||
let formData: CustomModelForm = {
|
const formData: CustomModelForm = {
|
||||||
...rest
|
...rest
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,14 +126,22 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
|||||||
name="logo"
|
name="logo"
|
||||||
label={t('modelNew.logo')}
|
label={t('modelNew.logo')}
|
||||||
valuePropName="fileList"
|
valuePropName="fileList"
|
||||||
rules={[{ required: true, message: t('common.pleaseSelect') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseSelect') },
|
||||||
|
{ validator: validateSquareImage(t('common.imageSquareRequired')) }
|
||||||
|
]}
|
||||||
|
extra={t('common.logoTip')?.split('\n').map((vo, index) => <div key={index}>{vo}</div>)}
|
||||||
>
|
>
|
||||||
<UploadImages />
|
<UploadImages fileSize={2} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label={t('modelNew.name')}
|
label={t('modelNew.name')}
|
||||||
rules={[{ required: true, message: t('common.inputPlaceholder', { title: t('modelNew.name') }) }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.inputPlaceholder', { title: t('modelNew.name') }) },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.pleaseEnter')} />
|
<Input placeholder={t('common.pleaseEnter')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -166,6 +175,7 @@ const CustomModelModal = forwardRef<CustomModelModalRef, CustomModelModalProps>(
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label={t('modelNew.description')}
|
label={t('modelNew.description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: ZhaoYing
|
* @Author: ZhaoYing
|
||||||
* @Date: 2026-02-03 16:49:33
|
* @Date: 2026-02-03 16:49:33
|
||||||
* @Last Modified by: ZhaoYing
|
* @Last Modified by: ZhaoYing
|
||||||
* @Last Modified time: 2026-02-03 16:49:33
|
* @Last Modified time: 2026-03-02 12:23:13
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Group Model Modal
|
* Group Model Modal
|
||||||
@@ -21,6 +21,7 @@ import { updateCompositeModel, modelTypeUrl, addCompositeModel } from '@/api/mod
|
|||||||
import UploadImages from '@/components/Upload/UploadImages'
|
import UploadImages from '@/components/Upload/UploadImages'
|
||||||
import ModelImplement from './ModelImplement'
|
import ModelImplement from './ModelImplement'
|
||||||
import { getFileLink } from '@/api/fileStorage'
|
import { getFileLink } from '@/api/fileStorage'
|
||||||
|
import { validateSquareImage, stringRegExp } from '@/utils/validator'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Group model modal component
|
* Group model modal component
|
||||||
@@ -133,15 +134,26 @@ const GroupModelModal = forwardRef<GroupModelModalRef, GroupModelModalProps>(({
|
|||||||
name="logo"
|
name="logo"
|
||||||
label={t('modelNew.logo')}
|
label={t('modelNew.logo')}
|
||||||
valuePropName="fileList"
|
valuePropName="fileList"
|
||||||
rules={[{ required: true, message: t('common.pleaseSelect') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseSelect') },
|
||||||
|
{ validator: validateSquareImage(t('common.imageSquareRequired')) }
|
||||||
|
]}
|
||||||
|
extra={t('common.logoTip')?.split('\n').map((vo, index) => <div key={index}>{vo}</div>)}
|
||||||
>
|
>
|
||||||
<UploadImages />
|
<UploadImages
|
||||||
|
fileSize={2}
|
||||||
|
fileType={['png', 'jpg']}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label={t('modelNew.name')}
|
label={t('modelNew.name')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.pleaseEnter')} />
|
<Input placeholder={t('common.pleaseEnter')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -165,6 +177,7 @@ const GroupModelModal = forwardRef<GroupModelModalRef, GroupModelModalProps>(({
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label={t('modelNew.description')}
|
label={t('modelNew.description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
<Input.TextArea placeholder={t('common.pleaseEnter')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ const tabKeys = ['group', 'list', 'square']
|
|||||||
{activeTab !== 'list' &&
|
{activeTab !== 'list' &&
|
||||||
<Form.Item name="search" noStyle>
|
<Form.Item name="search" noStyle>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
|
maxLength={50}
|
||||||
placeholder={t(`modelNew.${activeTab}SearchPlaceholder`)}
|
placeholder={t(`modelNew.${activeTab}SearchPlaceholder`)}
|
||||||
className="rb:w-70!"
|
className="rb:w-70!"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -182,7 +182,10 @@ const OntologyClassExtractModal = forwardRef<OntologyClassExtractModalRef, Ontol
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="scenario"
|
name="scenario"
|
||||||
label={t('ontology.scenario')}
|
label={t('ontology.scenario')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 2000 },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('ontology.scenarioPlaceholder')} />
|
<Input.TextArea placeholder={t('ontology.scenarioPlaceholder')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import type { AddClassItem, OntologyClassModalRef } from '../types'
|
import type { AddClassItem, OntologyClassModalRef } from '../types'
|
||||||
import RbModal from '@/components/RbModal'
|
import RbModal from '@/components/RbModal'
|
||||||
import { createOntologyClass } from '@/api/ontology'
|
import { createOntologyClass } from '@/api/ontology'
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -105,7 +106,11 @@ const OntologyClassModal = forwardRef<OntologyClassModalRef, OntologyClassModalP
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="class_name"
|
name="class_name"
|
||||||
label={t('ontology.class_name')}
|
label={t('ontology.class_name')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.enter')} />
|
<Input placeholder={t('common.enter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -113,6 +118,7 @@ const OntologyClassModal = forwardRef<OntologyClassModalRef, OntologyClassModalP
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="class_description"
|
name="class_description"
|
||||||
label={t('ontology.class_description')}
|
label={t('ontology.class_description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('ontology.classDescriptionPlaceholder')} />
|
<Input.TextArea placeholder={t('ontology.classDescriptionPlaceholder')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import type { OntologyItem, OntologyModalData, OntologyModalRef } from '../types'
|
import type { OntologyItem, OntologyModalData, OntologyModalRef } from '../types'
|
||||||
import RbModal from '@/components/RbModal'
|
import RbModal from '@/components/RbModal'
|
||||||
import { createOntologyScene, updateOntologyScene } from '@/api/ontology'
|
import { createOntologyScene, updateOntologyScene } from '@/api/ontology'
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -109,7 +110,11 @@ const OntologyModal = forwardRef<OntologyModalRef, OntologyModalProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="scene_name"
|
name="scene_name"
|
||||||
label={t('ontology.scene_name')}
|
label={t('ontology.scene_name')}
|
||||||
rules={[{ required: true, message: t('common.pleaseEnter') }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.pleaseEnter') },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.enter')} />
|
<Input placeholder={t('common.enter')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -117,6 +122,7 @@ const OntologyModal = forwardRef<OntologyModalRef, OntologyModalProps>(({
|
|||||||
<FormItem
|
<FormItem
|
||||||
name="scene_description"
|
name="scene_description"
|
||||||
label={t('ontology.scene_description')}
|
label={t('ontology.scene_description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('ontology.descriptionPlaceholder')} />
|
<Input.TextArea placeholder={t('ontology.descriptionPlaceholder')} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import type { AiPromptModalRef } from '@/views/ApplicationConfig/types'
|
|||||||
import exitIcon from '@/assets/images/knowledgeBase/exit.png';
|
import exitIcon from '@/assets/images/knowledgeBase/exit.png';
|
||||||
import type { SkillFormData } from '../types'
|
import type { SkillFormData } from '../types'
|
||||||
import { getSkillDetail, createSkill, updateSkill } from '@/api/skill'
|
import { getSkillDetail, createSkill, updateSkill } from '@/api/skill'
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skill Configuration Page Component
|
* Skill Configuration Page Component
|
||||||
@@ -110,7 +111,7 @@ const SkillConfig: FC = () => {
|
|||||||
// Format tools data for API
|
// Format tools data for API
|
||||||
const formData = {
|
const formData = {
|
||||||
...rest,
|
...rest,
|
||||||
tools: tools?.map((item: any) => ({
|
tools: tools?.map((item) => ({
|
||||||
tool_id: item.tool_id,
|
tool_id: item.tool_id,
|
||||||
operation: item.operation
|
operation: item.operation
|
||||||
}))
|
}))
|
||||||
@@ -144,13 +145,18 @@ const SkillConfig: FC = () => {
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label={t('skills.name')}
|
label={t('skills.name')}
|
||||||
rules={[{ required: true, message: t('common.inputPlaceholder', { title: t('skills.name') }) }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.inputPlaceholder', { title: t('skills.name') }) },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.pleaseEnter')} />
|
<Input placeholder={t('common.pleaseEnter')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="description"
|
name="description"
|
||||||
label={t('skills.description')}
|
label={t('skills.description')}
|
||||||
|
rules={[{ max: 500 }]}
|
||||||
>
|
>
|
||||||
<Input.TextArea placeholder={t('skills.descriptionPlaceholder')} />
|
<Input.TextArea placeholder={t('skills.descriptionPlaceholder')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export interface SkillFormData {
|
|||||||
tools: Array<{
|
tools: Array<{
|
||||||
/** Tool identifier */
|
/** Tool identifier */
|
||||||
tool_id: string;
|
tool_id: string;
|
||||||
|
/** Tool operation/action */
|
||||||
|
operation?: string;
|
||||||
}>;
|
}>;
|
||||||
/** Skill configuration settings */
|
/** Skill configuration settings */
|
||||||
config: {
|
config: {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import UploadImages from '@/components/Upload/UploadImages'
|
|||||||
import { getFileLink } from '@/api/fileStorage'
|
import { getFileLink } from '@/api/fileStorage'
|
||||||
import ragIcon from '@/assets/images/space/rag.png'
|
import ragIcon from '@/assets/images/space/rag.png'
|
||||||
import neo4jIcon from '@/assets/images/space/neo4j.png'
|
import neo4jIcon from '@/assets/images/space/neo4j.png'
|
||||||
|
import { stringRegExp } from '@/utils/validator';
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ const SpaceModal = forwardRef<SpaceModalRef, SpaceModalProps>(({
|
|||||||
setCurrentStep(1)
|
setCurrentStep(1)
|
||||||
} else {
|
} else {
|
||||||
const { icon, ...rest } = values
|
const { icon, ...rest } = values
|
||||||
let formData: SpaceModalData = {
|
const formData: SpaceModalData = {
|
||||||
...rest
|
...rest
|
||||||
}
|
}
|
||||||
if (icon?.response?.data.file_id) {
|
if (icon?.response?.data.file_id) {
|
||||||
@@ -164,14 +165,19 @@ const SpaceModal = forwardRef<SpaceModalRef, SpaceModalProps>(({
|
|||||||
valuePropName="fileList"
|
valuePropName="fileList"
|
||||||
hidden={currentStep === 1}
|
hidden={currentStep === 1}
|
||||||
rules={[{ required: true, message: t('common.selectPlaceholder', { title: t('space.spaceIcon') }) }]}
|
rules={[{ required: true, message: t('common.selectPlaceholder', { title: t('space.spaceIcon') }) }]}
|
||||||
|
extra={t('common.logoTip')?.split('\n').map((vo, index) => <div key={index}>{vo}</div>)}
|
||||||
>
|
>
|
||||||
<UploadImages />
|
<UploadImages fileSize={2} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<FormItem
|
<FormItem
|
||||||
name="name"
|
name="name"
|
||||||
label={t('space.spaceName')}
|
label={t('space.spaceName')}
|
||||||
hidden={currentStep === 1}
|
hidden={currentStep === 1}
|
||||||
rules={[{ required: true, message: t('common.inputPlaceholder', { title: t('space.spaceName') }) }]}
|
rules={[
|
||||||
|
{ required: true, message: t('common.inputPlaceholder', { title: t('space.spaceName') }) },
|
||||||
|
{ max: 50 },
|
||||||
|
{ pattern: stringRegExp, message: t('common.nameInvalid') },
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
<Input placeholder={t('common.inputPlaceholder', { title: t('space.spaceName') })} />
|
<Input placeholder={t('common.inputPlaceholder', { title: t('space.spaceName') })} />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|||||||
Reference in New Issue
Block a user