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