Refactor(Form): Optimize form input experience

Add placeholder. Optimize form validation. Hide ID input.
This commit is contained in:
2024-04-22 18:09:42 +08:00
parent 81b170d944
commit 5d28f7d8d7
22 changed files with 213 additions and 130 deletions

View File

@@ -155,8 +155,8 @@ const Forget = () => {
>
<AntdInput
prefix={<Icon component={IconOxygenEmail} />}
placeholder={'邮箱'}
disabled={isSending}
placeholder={'邮箱'}
/>
</AntdForm.Item>
<AntdForm.Item>
@@ -199,6 +199,7 @@ const Forget = () => {
name={'password'}
rules={[
{ required: true, message: '请输入密码' },
{ whitespace: true, message: '密码不能为空字符' },
{ min: 10, message: '密码至少为10位' },
{ max: 30, message: '密码最多为30位' }
]}
@@ -208,8 +209,8 @@ const Forget = () => {
addonBefore={
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
}
placeholder={'密码'}
disabled={isChanging}
placeholder={'密码'}
/>
</AntdForm.Item>
<AntdForm.Item
@@ -234,8 +235,8 @@ const Forget = () => {
<AntdInput.Password
id={'forget-password-confirm'}
addonBefore={'确认密码'}
placeholder={'确认密码'}
disabled={isChanging}
placeholder={'确认密码'}
/>
</AntdForm.Item>
<AntdForm.Item>

View File

@@ -124,6 +124,7 @@ const SignIn = () => {
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
@@ -132,7 +133,7 @@ const SignIn = () => {
name={'twoFactorCode'}
label={'验证码'}
style={{ marginTop: 10 }}
rules={[{ required: true, len: 6 }]}
rules={[{ required: true, whitespace: true, len: 6 }]}
>
<AntdInput
showCount
@@ -217,22 +218,28 @@ const SignIn = () => {
<AntdForm autoComplete={'on'} onFinish={handleOnFinish} className={'form'}>
<AntdForm.Item
name={'account'}
rules={[{ required: true, message: '请输入账号' }]}
rules={[
{ required: true, message: '请输入账号' },
{ whitespace: true, message: '账号不能为空字符' }
]}
>
<AntdInput
prefix={<Icon component={IconOxygenUser} />}
placeholder={'邮箱/用户名'}
disabled={isSigningIn}
placeholder={'邮箱/用户名'}
/>
</AntdForm.Item>
<AntdForm.Item
name={'password'}
rules={[{ required: true, message: '请输入密码' }]}
rules={[
{ required: true, message: '请输入密码' },
{ whitespace: true, message: '密码不能为空字符' }
]}
>
<AntdInput.Password
prefix={<Icon component={IconOxygenPassword} />}
placeholder={'密码'}
disabled={isSigningIn}
placeholder={'密码'}
/>
</AntdForm.Item>
<AntdForm.Item>

View File

@@ -139,6 +139,7 @@ const SignUp = () => {
name={'username'}
rules={[
{ required: true, message: '请输入用户名' },
{ whitespace: true, message: '用户名不能为空字符' },
{
pattern: /^[a-zA-Z-_][0-9a-zA-Z-_]{2,38}$/,
message:
@@ -148,10 +149,10 @@ const SignUp = () => {
>
<AntdInput
prefix={<Icon component={IconOxygenUser} />}
placeholder={'用户名'}
maxLength={39}
showCount={true}
disabled={isSigningUp}
placeholder={'用户名'}
/>
</AntdForm.Item>
<AntdForm.Item
@@ -164,14 +165,15 @@ const SignUp = () => {
<AntdInput
type={'email'}
prefix={<Icon component={IconOxygenEmail} />}
placeholder={'邮箱'}
disabled={isSigningUp}
placeholder={'邮箱'}
/>
</AntdForm.Item>
<AntdForm.Item
name={'password'}
rules={[
{ required: true, message: '请输入密码' },
{ whitespace: true, message: '密码不能为空字符' },
{ min: 10, message: '密码至少为10位' },
{ max: 30, message: '密码最多为30位' }
]}
@@ -179,8 +181,8 @@ const SignUp = () => {
<AntdInput.Password
id={'sign-up-password'}
prefix={<Icon component={IconOxygenPassword} />}
placeholder={'密码'}
disabled={isSigningUp}
placeholder={'密码'}
/>
</AntdForm.Item>
<AntdForm.Item
@@ -202,8 +204,8 @@ const SignUp = () => {
<AntdInput.Password
id={'sign-up-password-confirm'}
prefix={<Icon component={IconOxygenPassword} />}
placeholder={'确认密码'}
disabled={isSigningUp}
placeholder={'确认密码'}
/>
</AntdForm.Item>
<AntdForm.Item>

View File

@@ -195,6 +195,7 @@ const Verify = () => {
name={'nickname'}
rules={[
{ required: true, message: '请输入昵称' },
{ whitespace: true, message: '昵称不能为空字符' },
{ min: 3, message: '昵称至少为3个字符' }
]}
>

View File

@@ -190,8 +190,9 @@ const Group = () => {
const handleOnListDeleteBtnClick = () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除选中的 ${tableSelectedItem.length} 个用户组吗?`
})
.then(
@@ -243,8 +244,9 @@ const Group = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除角色 ${value.name} 吗?`
})
.then(
@@ -543,6 +545,7 @@ const Group = () => {
onChange={handleOnSearchNameChange}
onKeyDown={handleOnSearchNameKeyDown}
status={isRegexLegal ? undefined : 'error'}
placeholder={'请输入搜索内容'}
/>
</Card>
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>
@@ -597,7 +600,7 @@ const Group = () => {
const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting} layout={'vertical'}>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -605,7 +608,7 @@ const Group = () => {
label={'名称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item name={'roleIds'} label={'角色'}>
<AntdSelect
@@ -617,6 +620,7 @@ const Group = () => {
value: value.id,
label: `${value.name}${!value.enable ? '(已禁用)' : ''}`
}))}
placeholder={'请选择角色'}
/>
</AntdForm.Item>
<AntdForm.Item

View File

@@ -250,6 +250,7 @@ const Log = () => {
value={searchRequestUrl}
onChange={handleOnSearchUrlChange}
onKeyDown={handleOnSearchUrlKeyDown}
placeholder={'请输入搜索内容'}
/>
</Card>
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>

View File

@@ -182,8 +182,9 @@ const Role = () => {
const handleOnListDeleteBtnClick = () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除选中的 ${tableSelectedItem.length} 个角色吗?`
})
.then(
@@ -235,8 +236,9 @@ const Role = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除角色 ${value.name} 吗?`
})
.then(
@@ -552,6 +554,7 @@ const Role = () => {
onChange={handleOnSearchNameChange}
onKeyDown={handleOnSearchNameKeyDown}
status={isRegexLegal ? undefined : 'error'}
placeholder={'请输入搜索内容'}
/>
</Card>
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>
@@ -606,7 +609,7 @@ const Role = () => {
const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting} layout={'vertical'}>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -614,7 +617,7 @@ const Role = () => {
label={'名称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item name={'powerIds'} label={'权限'}>
<AntdTreeSelect
@@ -624,6 +627,7 @@ const Role = () => {
allowClear
treeNodeFilterProp={'fullTitle'}
loading={isLoadingPower}
placeholder={'请选择权限'}
/>
</AntdForm.Item>
<AntdForm.Item

View File

@@ -59,16 +59,20 @@ const Base = () => {
disabled={!hasPermission('system:settings:modify:base')}
>
<AntdForm.Item label={'应用名称'} name={'appName'}>
<AntdInput />
<AntdInput placeholder={'请输入应用名称'} />
</AntdForm.Item>
<AntdForm.Item label={'应用 URL'} name={'appUrl'}>
<AntdInput />
<AntdInput placeholder={'请输入应用 URL'} />
</AntdForm.Item>
<AntdForm.Item label={'验证邮箱 URL'} name={'verifyUrl'}>
<AntdInput placeholder={'验证码使用 ${verifyCode} 代替'} />
<AntdInput
placeholder={'请输入验证邮箱 URL验证码使用 ${verifyCode} 代替'}
/>
</AntdForm.Item>
<AntdForm.Item label={'找回密码 URL'} name={'retrieveUrl'}>
<AntdInput placeholder={'验证码使用 ${retrieveCode} 代替'} />
<AntdInput
placeholder={'请输入找回密码 URL验证码使用 ${retrieveCode} 代替'}
/>
</AntdForm.Item>
</AntdForm>
</SettingsCard>

View File

@@ -31,6 +31,7 @@ const Mail = () => {
form={mailSendForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('to').focus()
}, 50)
}}
@@ -41,7 +42,7 @@ const Mail = () => {
style={{ marginTop: 10 }}
rules={[{ required: true, type: 'email' }]}
>
<AntdInput />
<AntdInput placeholder={'请输入接收人'} />
</AntdForm.Item>
</AntdForm>
<AntdTag style={{ whiteSpace: 'normal' }}>
@@ -134,29 +135,34 @@ const Mail = () => {
disabled={!hasPermission('system:settings:modify:mail')}
>
<AntdForm.Item label={'SMTP 服务器'} name={'host'}>
<AntdInput />
<AntdInput placeholder={'请输入 SMTP 服务器'} />
</AntdForm.Item>
<AntdForm.Item label={'端口'} name={'port'}>
<AntdInputNumber min={0} max={65535} style={{ width: '100%' }} />
<AntdForm.Item label={'端口'} name={'port'}>
<AntdInputNumber
min={0}
max={65535}
style={{ width: '100%' }}
placeholder={'请输入端口号'}
/>
</AntdForm.Item>
<AntdForm.Item label={'安全类型'} name={'securityType'}>
<AntdSelect>
<AntdSelect placeholder={'请选择安全类型'}>
<AntdSelect.Option key={'None'}>None</AntdSelect.Option>
<AntdSelect.Option key={'SSL/TLS'}>SSL/TLS</AntdSelect.Option>
<AntdSelect.Option key={'StartTls'}>StartTls</AntdSelect.Option>
</AntdSelect>
</AntdForm.Item>
<AntdForm.Item label={'用户名'} name={'username'}>
<AntdInput />
<AntdInput placeholder={'请输入用户名'} />
</AntdForm.Item>
<AntdForm.Item label={'密码'} name={'password'}>
<AntdInput.Password />
<AntdInput.Password placeholder={'请输入密码'} />
</AntdForm.Item>
<AntdForm.Item label={'发送者'} name={'from'}>
<AntdInput />
<AntdInput placeholder={'请输入发送者'} />
</AntdForm.Item>
<AntdForm.Item label={'发送者名称'} name={'fromName'}>
<AntdInput />
<AntdInput placeholder={'请输入发送者名称'} />
</AntdForm.Item>
</AntdForm>
</SettingsCard>

View File

@@ -153,7 +153,8 @@ const SensitiveWord = () => {
<Icon component={IconOxygenPlus} />
</AntdButton>
}
></AntdInput>
placeholder={'请输入敏感词'}
/>
</SettingsCard>
</>
)

View File

@@ -59,10 +59,15 @@ const TwoFactor = () => {
disabled={!hasPermission('system:settings:modify:two-factor')}
>
<AntdForm.Item label={'提供者'} name={'issuer'}>
<AntdInput />
<AntdInput placeholder={'请输入提供者'} />
</AntdForm.Item>
<AntdForm.Item label={'密钥长度'} name={'secretKeyLength'}>
<AntdInputNumber min={3} max={64} style={{ width: '100%' }} />
<AntdInputNumber
min={3}
max={64}
style={{ width: '100%' }}
placeholder={'请输入密钥长度'}
/>
</AntdForm.Item>
</AntdForm>
</SettingsCard>

View File

@@ -279,9 +279,9 @@ const Base = () => {
compileForm.setFieldValue('entryFileName', undefined)
void modal.confirm({
title: '编译',
centered: true,
maskClosable: true,
title: '编译',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -295,7 +295,7 @@ const Base = () => {
name={'entryFileName'}
label={'入口文件'}
style={{ marginTop: 10 }}
rules={[{ required: true, message: '请选择入口文件' }]}
rules={[{ required: true }]}
>
<AntdSelect
options={Object.keys(files)
@@ -307,6 +307,7 @@ const Base = () => {
].includes(value)
)
.map((value) => ({ value, label: value }))}
placeholder={'请选择入口文件'}
/>
</AntdForm.Item>
</AntdForm>
@@ -428,8 +429,9 @@ const Base = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除基板 ${value.name} 吗?`
})
.then(
@@ -609,9 +611,9 @@ const Base = () => {
const handleOnAddFile = () => {
void modal.confirm({
title: '新建文件',
centered: true,
maskClosable: true,
title: '新建文件',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -623,6 +625,7 @@ const Base = () => {
form={addFileForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
@@ -652,7 +655,7 @@ const Base = () => {
})
]}
>
<AntdInput />
<AntdInput placeholder={'请输入文件名'} />
</AntdForm.Item>
</AntdForm>
),
@@ -800,9 +803,9 @@ const Base = () => {
return () => {
renameFileForm.setFieldValue('fileName', fileName)
void modal.confirm({
title: '重命名文件',
centered: true,
maskClosable: true,
title: '重命名文件',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -814,6 +817,7 @@ const Base = () => {
form={renameFileForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
@@ -846,7 +850,7 @@ const Base = () => {
})
]}
>
<AntdInput />
<AntdInput placeholder={'请输入空文件名'} />
</AntdForm.Item>
</AntdForm>
),
@@ -915,8 +919,9 @@ const Base = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除文件 ${fileName} 吗?`
})
.then(
@@ -1040,7 +1045,7 @@ const Base = () => {
const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting} layout={'vertical'}>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -1048,7 +1053,7 @@ const Base = () => {
label={'名称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item
name={'platform'}
@@ -1056,7 +1061,7 @@ const Base = () => {
rules={[{ required: true }]}
hidden={isDrawerEdit}
>
<AntdSelect>
<AntdSelect placeholder={'请选择平台'}>
<AntdSelect.Option key={'WEB'}>Web</AntdSelect.Option>
<AntdSelect.Option key={'DESKTOP'}>Desktop</AntdSelect.Option>
<AntdSelect.Option key={'ANDROID'}>Android</AntdSelect.Option>

View File

@@ -121,8 +121,9 @@ const Category = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除类别 ${value.name} 吗?`
})
.then(
@@ -266,7 +267,7 @@ const Category = () => {
const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting} layout={'vertical'}>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -274,7 +275,7 @@ const Category = () => {
label={'名称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item name={'enable'} label={'状态'}>
<AntdSwitch checkedChildren={'启用'} unCheckedChildren={'禁用'} />

View File

@@ -12,6 +12,7 @@ import Card from '@/components/common/Card'
const Code = () => {
const navigate = useNavigate()
const [modal, contextHolder] = AntdModal.useModal()
const { id } = useParams()
const [loading, setLoading] = useState(false)
const [files, setFiles] = useState<IFiles>({})
@@ -20,7 +21,15 @@ const Code = () => {
const handleOnRunTool = () => {
if (checkDesktop() || platform !== 'DESKTOP') {
void modal.confirm({
centered: true,
maskClosable: true,
title: '注意',
content: '运行前请仔细查阅工具代码!',
onOk: () => {
navigate(`/system/tools/execute/${id}`)
}
})
} else {
void message.warning('此应用需要桌面端环境,请在桌面端运行')
}
@@ -71,6 +80,7 @@ const Code = () => {
}, [])
return (
<>
<FitFullscreen data-component={'system-tools-code'}>
<Card>
<Playground.CodeEditor
@@ -91,6 +101,8 @@ const Code = () => {
</div>
</Draggable>
</FitFullscreen>
{contextHolder}
</>
)
}

View File

@@ -276,8 +276,9 @@ const Template = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除模板 ${value.name} 吗?`
})
.then(
@@ -464,9 +465,9 @@ const Template = () => {
const handleOnAddFile = () => {
void modal.confirm({
title: '新建文件',
centered: true,
maskClosable: true,
title: '新建文件',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -478,6 +479,7 @@ const Template = () => {
form={addFileForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
@@ -507,7 +509,7 @@ const Template = () => {
})
]}
>
<AntdInput />
<AntdInput placeholder={'请输入文件名'} />
</AntdForm.Item>
</AntdForm>
),
@@ -658,9 +660,9 @@ const Template = () => {
return () => {
renameFileForm.setFieldValue('fileName', fileName)
void modal.confirm({
title: '重命名文件',
centered: true,
maskClosable: true,
title: '重命名文件',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -672,6 +674,7 @@ const Template = () => {
form={renameFileForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
@@ -704,7 +707,7 @@ const Template = () => {
})
]}
>
<AntdInput />
<AntdInput placeholder={'请输入新文件名'} />
</AntdForm.Item>
</AntdForm>
),
@@ -773,8 +776,9 @@ const Template = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除文件 ${fileName} 吗?`
})
.then(
@@ -979,7 +983,7 @@ const Template = () => {
const addAndEditForm = (
<AntdForm form={form} disabled={isSubmitting} layout={'vertical'}>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -987,7 +991,7 @@ const Template = () => {
label={'名称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item
hidden={isDrawerEdit}
@@ -995,10 +999,19 @@ const Template = () => {
label={'基板'}
rules={[{ required: true }]}
>
<AntdCascader showSearch allowClear={false} options={baseDataGroupByPlatform()} />
<AntdCascader
showSearch
allowClear={false}
options={baseDataGroupByPlatform()}
placeholder={'请选择基板'}
/>
</AntdForm.Item>
<AntdForm.Item name={'entryPoint'} label={'入口'} rules={[{ required: true }]}>
<AntdInput allowClear />
<AntdForm.Item
name={'entryPoint'}
label={'入口文件'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear placeholder={'请输入入口文件'} />
</AntdForm.Item>
<AntdForm.Item name={'enable'} label={'状态'}>
<AntdSwitch checkedChildren={'启用'} unCheckedChildren={'禁用'} />

View File

@@ -56,7 +56,7 @@ const Tools = () => {
<AntdAvatar
src={
<AntdImage
preview={{ mask: <Icon component={IconOxygenEye}></Icon> }}
preview={{ mask: <Icon component={IconOxygenEye} /> }}
src={`data:image/svg+xml;base64,${value}`}
alt={'Avatar'}
/>
@@ -204,9 +204,9 @@ const Tools = () => {
return () => {
form.setFieldValue('pass', undefined)
void modal.confirm({
title: '审核',
centered: true,
maskClosable: true,
title: '审核',
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -352,8 +352,9 @@ const Tools = () => {
return () => {
modal
.confirm({
title: '确定下架',
centered: true,
maskClosable: true,
title: '确定下架',
content: `确定下架工具 ${value.author.username}:${value.toolId}:${value.ver} 吗?`
})
.then(
@@ -387,8 +388,9 @@ const Tools = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除工具 ${value.author.username}:${value.toolId}:${value.platform.slice(0, 1)}${value.platform.slice(1).toLowerCase()}:${value.ver} 吗?`
})
.then(
@@ -552,6 +554,7 @@ const Tools = () => {
onChange={handleOnSearchValueChange}
onKeyDown={handleOnSearchValueKeyDown}
status={isRegexLegal ? undefined : 'error'}
placeholder={'请输入搜索内容'}
/>
</Card>
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>

View File

@@ -88,7 +88,7 @@ const User = () => {
<AntdAvatar
src={
<AntdImage
preview={{ mask: <Icon component={IconOxygenEye}></Icon> }}
preview={{ mask: <Icon component={IconOxygenEye} /> }}
src={`data:image/png;base64,${value}`}
alt={'Avatar'}
/>
@@ -285,8 +285,9 @@ const User = () => {
const handleOnListDeleteBtnClick = () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除选中的 ${tableSelectedItem.length} 个用户吗?`
})
.then(
@@ -326,6 +327,8 @@ const User = () => {
value.credentialsExpiration && isPastTime(value.credentialsExpiration)
)
void modal.confirm({
centered: true,
maskClosable: true,
icon: <></>,
title: (
<>
@@ -336,8 +339,6 @@ const User = () => {
{value.username}
</>
),
centered: true,
maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
@@ -352,23 +353,17 @@ const User = () => {
wrapperCol={{ span: 18 }}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('password').focus()
}, 50)
}}
>
<AntdForm.Item name={'id'} label={'ID'} labelAlign={'right'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
name={'password'}
label={'密码'}
rules={[
{
required: true
}
]}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput.Password />
<AntdInput.Password placeholder={'请输入密码'} />
</AntdForm.Item>
<AntdForm.Item
name={'passwordConfirm'}
@@ -387,7 +382,7 @@ const User = () => {
})
]}
>
<AntdInput.Password />
<AntdInput.Password placeholder={'请确认密码'} />
</AntdForm.Item>
{value.id !== '0' && (
<AntdForm.Item
@@ -479,8 +474,9 @@ const User = () => {
return () => {
modal
.confirm({
title: '确定删除',
centered: true,
maskClosable: true,
title: '确定删除',
content: `确定删除用户 ${value.username} 吗?`
})
.then(
@@ -800,7 +796,7 @@ const User = () => {
<AntdForm.Item hidden name={'avatar'}>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item hidden={!isDrawerEdit} name={'id'} label={'ID'}>
<AntdForm.Item hidden name={'id'} label={'ID'}>
<AntdInput disabled />
</AntdForm.Item>
<AntdForm.Item
@@ -808,7 +804,7 @@ const User = () => {
label={'用户名'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入用户名'} />
</AntdForm.Item>
{!isDrawerEdit && (
<>
@@ -817,7 +813,7 @@ const User = () => {
label={'密码'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput.Password allowClear />
<AntdInput.Password allowClear placeholder={'请输入密码'} />
</AntdForm.Item>
</>
)}
@@ -826,14 +822,14 @@ const User = () => {
label={'昵称'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput allowClear />
<AntdInput allowClear placeholder={'请输入昵称'} />
</AntdForm.Item>
<AntdForm.Item
name={'email'}
label={'邮箱'}
rules={[{ required: true, whitespace: true, type: 'email' }]}
rules={[{ required: true, type: 'email' }]}
>
<AntdInput type={'email'} allowClear />
<AntdInput type={'email'} allowClear placeholder={'请输入邮箱'} />
</AntdForm.Item>
{formValues?.id !== '0' && (
<>
@@ -847,6 +843,7 @@ const User = () => {
value: value.id,
label: `${value.name}${!value.enable ? '(已禁用)' : ''}`
}))}
placeholder={'请选择角色'}
/>
</AntdForm.Item>
<AntdForm.Item name={'groupIds'} label={'用户组'}>
@@ -859,6 +856,7 @@ const User = () => {
value: value.id,
label: `${value.name}${!value.enable ? '(已禁用)' : ''}`
}))}
placeholder={'请选择用户组'}
/>
</AntdForm.Item>
<AntdForm.Item name={'verified'} label={'验证'}>
@@ -957,6 +955,7 @@ const User = () => {
onChange={handleOnSearchValueChange}
onKeyDown={handleOnSearchValueKeyDown}
status={isRegexLegal ? undefined : 'error'}
placeholder={'请输入搜索内容'}
/>
</Card>
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>

View File

@@ -241,7 +241,7 @@ const Create = () => {
<AntdForm.Item
label={'名称'}
name={'name'}
rules={[{ required: true }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput
maxLength={20}
@@ -253,7 +253,7 @@ const Create = () => {
label={'工具 ID'}
name={'toolId'}
rules={[
{ required: true },
{ required: true, whitespace: true },
{
pattern: /^[a-zA-Z-_][0-9a-zA-Z-_]{2,19}$/,
message:
@@ -270,11 +270,11 @@ const Create = () => {
<AntdForm.Item
label={'平台'}
name={'platform'}
rules={[{ required: true }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect
placeholder={'请选择平台'}
onChange={handleOnPlatformChange}
placeholder={'请选择平台'}
>
<AntdSelect.Option key={'WEB'}>Web</AntdSelect.Option>
<AntdSelect.Option key={'DESKTOP'}>
@@ -297,7 +297,7 @@ const Create = () => {
label={'版本'}
name={'ver'}
rules={[
{ required: true },
{ required: true, whitespace: true },
{
pattern: /^\d+\.\d+\.\d+$/,
message: `格式必须为 '<数字>.<数字>.<数字>', eg. 1.0.3`
@@ -313,10 +313,9 @@ const Create = () => {
<AntdForm.Item
label={'模板'}
name={'templateId'}
rules={[{ required: true }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect
placeholder={'请选择模板'}
options={templateData?.map((value) => ({
value: value.id,
label: value.name
@@ -324,28 +323,28 @@ const Create = () => {
loading={loadingTemplate}
disabled={loadingTemplate}
onChange={handleOnTemplateChange}
placeholder={'请选择模板'}
/>
</AntdForm.Item>
<AntdForm.Item
label={'关键字'}
tooltip={'工具搜索每个不超过10个字符'}
name={'keywords'}
rules={[{ required: true, message: '请输入关键字' }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect
placeholder={'请输入关键字'}
mode={'tags'}
maxCount={20}
placeholder={'请输入关键字'}
/>
</AntdForm.Item>
<AntdForm.Item
label={'类别'}
tooltip={'工具分类'}
name={'categories'}
rules={[{ required: true }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect
placeholder={'请选择类别'}
mode={'multiple'}
options={categoryData?.map((value) => ({
value: value.id,
@@ -353,6 +352,7 @@ const Create = () => {
}))}
loading={loadingCategory}
disabled={loadingCategory}
placeholder={'请选择类别'}
/>
</AntdForm.Item>
<AntdForm.Item>

View File

@@ -369,7 +369,11 @@ const Edit = () => {
<AntdForm.Item name={'icon'} hidden>
<AntdInput />
</AntdForm.Item>
<AntdForm.Item label={'名称'} name={'name'} rules={[{ required: true }]}>
<AntdForm.Item
label={'名称'}
name={'name'}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput maxLength={20} showCount placeholder={'请输入名称'} />
</AntdForm.Item>
<AntdForm.Item label={'简介'} name={'description'}>
@@ -384,18 +388,17 @@ const Edit = () => {
label={'关键字'}
tooltip={'工具搜索每个不超过10个字符'}
name={'keywords'}
rules={[{ required: true, message: '请输入关键字' }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect placeholder={'请输入关键字'} mode={'tags'} maxCount={20} />
<AntdSelect mode={'tags'} maxCount={20} placeholder={'请输入关键字'} />
</AntdForm.Item>
<AntdForm.Item
label={'类别'}
tooltip={'工具分类'}
name={'categories'}
rules={[{ required: true }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdSelect
placeholder={'请选择类别'}
mode={'multiple'}
options={categoryData?.map((value) => ({
value: value.id,
@@ -403,6 +406,7 @@ const Edit = () => {
}))}
loading={loadingCategory}
disabled={loadingCategory}
placeholder={'请选择类别'}
/>
</AntdForm.Item>
</AntdForm>

View File

@@ -331,11 +331,11 @@ const Store = () => {
>
<div className={`search${hideSearch ? ' hide' : ''}`}>
<AntdInput.Search
placeholder={'请输入工具名或关键字'}
enterButton
allowClear
loading={isLoading}
onSearch={handleOnSearch}
placeholder={'请输入工具名或关键字'}
/>
</div>
<FlexBox direction={'horizontal'} className={'root-content'}>

View File

@@ -348,6 +348,7 @@ const Tools = () => {
form={upgradeForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('toolId').focus()
}, 50)
}}
@@ -376,7 +377,7 @@ const Tools = () => {
name={'ver'}
label={'版本'}
rules={[
{ required: true },
{ required: true, whitespace: true },
{
pattern: /^\d+\.\d+\.\d+$/,
message: `格式必须为 '<数字>.<数字>.<数字>', eg. 1.0.3`

View File

@@ -115,6 +115,7 @@ const User = () => {
wrapperCol={{ span: 18 }}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('originalPassword').focus()
}, 50)
}}
@@ -123,7 +124,7 @@ const User = () => {
name={'originalPassword'}
label={'原密码'}
labelAlign={'right'}
rules={[{ required: true, message: '请输入原密码' }]}
rules={[{ required: true, whitespace: true }]}
>
<AntdInput.Password placeholder={'请输入原密码'} />
</AntdForm.Item>
@@ -132,7 +133,7 @@ const User = () => {
label={'新密码'}
labelAlign={'right'}
rules={[
{ required: true, message: '请输入新密码' },
{ required: true, whitespace: true },
{ min: 10, message: '密码至少为10位' },
{ max: 30, message: '密码最多为30位' }
]}
@@ -144,7 +145,7 @@ const User = () => {
label={'确认密码'}
labelAlign={'right'}
rules={[
{ required: true, message: '请确认密码' },
{ required: true },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('newPassword') === value) {
@@ -247,6 +248,7 @@ const User = () => {
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
@@ -255,12 +257,13 @@ const User = () => {
name={'twoFactorCode'}
label={'验证码'}
style={{ marginTop: 10 }}
rules={[{ required: true, len: 6 }]}
rules={[{ required: true, whitespace: true, len: 6 }]}
>
<AntdInput
showCount
maxLength={6}
autoComplete={'off'}
placeholder={'请输入验证码'}
/>
</AntdForm.Item>
</AntdForm>
@@ -334,6 +337,7 @@ const User = () => {
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
@@ -342,12 +346,15 @@ const User = () => {
name={'twoFactorCode'}
label={'验证码'}
style={{ marginTop: 10, marginRight: 30 }}
rules={[{ required: true, len: 6 }]}
rules={[
{ required: true, whitespace: true, len: 6 }
]}
>
<AntdInput
showCount
maxLength={6}
autoComplete={'off'}
placeholder={'请输入验证码'}
/>
</AntdForm.Item>
</AntdForm>
@@ -410,6 +417,7 @@ const User = () => {
setAvatar(userWithPowerInfoVo.userInfo.avatar)
form.setFieldValue('nickname', userWithPowerInfoVo.userInfo.nickname)
setUserWithPowerInfoVo(userWithPowerInfoVo)
void form.validateFields()
})
.finally(() => {
setIsLoading(false)
@@ -509,7 +517,7 @@ const User = () => {
<AntdForm.Item
name={'nickname'}
rules={[
{ required: true, message: '请输入昵称' },
{ required: true, whitespace: true },
{ min: 3, message: '昵称至少为3个字符' }
]}
style={{ marginBottom: 0 }}
@@ -518,6 +526,7 @@ const User = () => {
maxLength={20}
showCount
disabled={isLoading}
placeholder={'请输入昵称'}
/>
</AntdForm.Item>
</AntdForm>