Fix modal bug. Optimize Turnstile load. #39

Merged
FatttSnake merged 2 commits from FatttSnake into dev 2024-03-01 17:52:36 +08:00
14 changed files with 236 additions and 95 deletions

8
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.2.6", "@ant-design/icons": "^5.2.6",
"@marsidev/react-turnstile": "^0.4.1", "@marsidev/react-turnstile": "^0.5.3",
"@monaco-editor/react": "^4.6.0", "@monaco-editor/react": "^4.6.0",
"@typescript/ata": "^0.9.4", "@typescript/ata": "^0.9.4",
"antd": "^5.13.2", "antd": "^5.13.2",
@@ -1240,9 +1240,9 @@
} }
}, },
"node_modules/@marsidev/react-turnstile": { "node_modules/@marsidev/react-turnstile": {
"version": "0.4.1", "version": "0.5.3",
"resolved": "https://registry.npmmirror.com/@marsidev/react-turnstile/-/react-turnstile-0.4.1.tgz", "resolved": "https://registry.npmjs.org/@marsidev/react-turnstile/-/react-turnstile-0.5.3.tgz",
"integrity": "sha512-uZusUW9mPr0csWpls8bApe5iuRK0YK7H1PCKqfM4djW3OA9GB9rU68irjk7xRO8qlHyj0aDTeVu9tTLPExBO4Q==", "integrity": "sha512-lx3p2/56esPt8Ksr37K8uhPt/K4Mg8xaIfCV8MPKmE/1X4aHesRqZok1+L1ySQwsdWoEe5+KJOhBXka8lFBwNg==",
"peerDependencies": { "peerDependencies": {
"react": ">=16.8.0", "react": ">=16.8.0",
"react-dom": ">=16.8.0" "react-dom": ">=16.8.0"

View File

@@ -15,7 +15,7 @@
}, },
"dependencies": { "dependencies": {
"@ant-design/icons": "^5.2.6", "@ant-design/icons": "^5.2.6",
"@marsidev/react-turnstile": "^0.4.1", "@marsidev/react-turnstile": "^0.5.3",
"@monaco-editor/react": "^4.6.0", "@monaco-editor/react": "^4.6.0",
"@typescript/ata": "^0.9.4", "@typescript/ata": "^0.9.4",
"antd": "^5.13.2", "antd": "^5.13.2",

View File

@@ -85,6 +85,11 @@
} }
.sign-up, .sign-in, .forget { .sign-up, .sign-in, .forget {
.loading-turnstile {
display: flex;
justify-content: center;
}
.footer { .footer {
a { a {
font-weight: bolder; font-weight: bolder;

View File

@@ -53,7 +53,7 @@ const Transform = ({ file, theme }: OutputProps) => {
setCompiledCode(code) setCompiledCode(code)
} }
} catch (e) { } catch (e) {
console.log(e) console.error(e)
setCompiledCode('') setCompiledCode('')
} }
} else { } else {

View File

@@ -6,6 +6,7 @@ import {
PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED, PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED,
PERMISSION_RETRIEVE_SUCCESS, PERMISSION_RETRIEVE_SUCCESS,
PERMISSION_USER_NOT_FOUND, PERMISSION_USER_NOT_FOUND,
SIZE_ICON_MD,
SYSTEM_INVALID_CAPTCHA_CODE SYSTEM_INVALID_CAPTCHA_CODE
} from '@/constants/common.constants' } from '@/constants/common.constants'
import { r_auth_forget, r_auth_retrieve } from '@/services/auth' import { r_auth_forget, r_auth_retrieve } from '@/services/auth'
@@ -160,11 +161,21 @@ const Forget = () => {
/> />
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item> <AntdForm.Item>
{!turnstileRef.current && (
<div className={'loading-turnstile'}>
<Icon
component={IconOxygenLoading}
style={{ fontSize: SIZE_ICON_MD }}
spin
/>
</div>
)}
<Turnstile <Turnstile
id={'forget-turnstile'} id={'forget-turnstile'}
ref={turnstileRefCallback} ref={turnstileRefCallback}
siteKey={H_CAPTCHA_SITE_KEY} siteKey={H_CAPTCHA_SITE_KEY}
options={{ theme: 'light', execution: 'execute' }} hidden={!turnstileRef.current}
options={{ theme: 'light' }}
onSuccess={setCaptchaCode} onSuccess={setCaptchaCode}
/> />
</AntdForm.Item> </AntdForm.Item>
@@ -232,11 +243,21 @@ const Forget = () => {
/> />
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item> <AntdForm.Item>
{!turnstileRef.current && (
<div className={'loading-turnstile'}>
<Icon
component={IconOxygenLoading}
style={{ fontSize: SIZE_ICON_MD }}
spin
/>
</div>
)}
<Turnstile <Turnstile
id={'retrieve-turnstile'} id={'retrieve-turnstile'}
ref={retrieveTurnstileRefCallback} ref={retrieveTurnstileRefCallback}
siteKey={H_CAPTCHA_SITE_KEY} siteKey={H_CAPTCHA_SITE_KEY}
options={{ theme: 'light', execution: 'execute' }} hidden={!turnstileRef.current}
options={{ theme: 'light' }}
onSuccess={setRetrieveCaptchaCode} onSuccess={setRetrieveCaptchaCode}
/> />
</AntdForm.Item> </AntdForm.Item>

View File

@@ -8,6 +8,7 @@ import {
PERMISSION_TWO_FACTOR_VERIFICATION_CODE_ERROR, PERMISSION_TWO_FACTOR_VERIFICATION_CODE_ERROR,
PERMISSION_USER_DISABLE, PERMISSION_USER_DISABLE,
PERMISSION_USERNAME_NOT_FOUND, PERMISSION_USERNAME_NOT_FOUND,
SIZE_ICON_MD,
SYSTEM_INVALID_CAPTCHA_CODE SYSTEM_INVALID_CAPTCHA_CODE
} from '@/constants/common.constants' } from '@/constants/common.constants'
import { getUserInfo, setToken } from '@/util/auth' import { getUserInfo, setToken } from '@/util/auth'
@@ -105,24 +106,30 @@ const SignIn = () => {
twoFactorForm.resetFields() twoFactorForm.resetFields()
void modal.confirm({ void modal.confirm({
title: '双因素验证', title: '双因素验证',
getContainer: false,
centered: true, centered: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdForm form={twoFactorForm}> <AntdForm
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'twoFactorCode'} name={'twoFactorCode'}
label={'验证码'} label={'验证码'}
style={{ marginTop: 10 }} style={{ marginTop: 10 }}
rules={[{ required: true, len: 6 }]} rules={[{ required: true, len: 6 }]}
> >
<AntdInput <AntdInput showCount maxLength={6} />
showCount
maxLength={6}
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
</> </>
@@ -220,11 +227,21 @@ const SignIn = () => {
/> />
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item> <AntdForm.Item>
{!turnstileRef.current && (
<div className={'loading-turnstile'}>
<Icon
component={IconOxygenLoading}
style={{ fontSize: SIZE_ICON_MD }}
spin
/>
</div>
)}
<Turnstile <Turnstile
id={'sign-in-turnstile'} id={'sign-in-turnstile'}
ref={turnstileRefCallback} ref={turnstileRefCallback}
siteKey={H_CAPTCHA_SITE_KEY} siteKey={H_CAPTCHA_SITE_KEY}
options={{ theme: 'light', execution: 'execute' }} hidden={!turnstileRef.current}
options={{ theme: 'light' }}
onSuccess={setCaptchaCode} onSuccess={setCaptchaCode}
/> />
</AntdForm.Item> </AntdForm.Item>

View File

@@ -4,6 +4,7 @@ import {
DATABASE_DUPLICATE_KEY, DATABASE_DUPLICATE_KEY,
H_CAPTCHA_SITE_KEY, H_CAPTCHA_SITE_KEY,
PERMISSION_REGISTER_SUCCESS, PERMISSION_REGISTER_SUCCESS,
SIZE_ICON_MD,
SYSTEM_INVALID_CAPTCHA_CODE, SYSTEM_INVALID_CAPTCHA_CODE,
SYSTEM_MATCH_SENSITIVE_WORD SYSTEM_MATCH_SENSITIVE_WORD
} from '@/constants/common.constants' } from '@/constants/common.constants'
@@ -200,11 +201,21 @@ const SignUp = () => {
/> />
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item> <AntdForm.Item>
{!turnstileRef.current && (
<div className={'loading-turnstile'}>
<Icon
component={IconOxygenLoading}
style={{ fontSize: SIZE_ICON_MD }}
spin
/>
</div>
)}
<Turnstile <Turnstile
id={'sign-up-turnstile'} id={'sign-up-turnstile'}
ref={turnstileRefCallback} ref={turnstileRefCallback}
siteKey={H_CAPTCHA_SITE_KEY} siteKey={H_CAPTCHA_SITE_KEY}
options={{ theme: 'light', execution: 'execute' }} hidden={!turnstileRef.current}
options={{ theme: 'light' }}
onSuccess={setCaptchaCode} onSuccess={setCaptchaCode}
/> />
</AntdForm.Item> </AntdForm.Item>

View File

@@ -17,23 +17,31 @@ const Mail = () => {
const handleOnTest = () => { const handleOnTest = () => {
void modal.confirm({ void modal.confirm({
title: '发送测试邮件', title: '发送测试邮件',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdForm form={mailSendForm}> <AntdForm
form={mailSendForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('to').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'to'} name={'to'}
label={'接收人'} label={'接收人'}
style={{ marginTop: 10 }} style={{ marginTop: 10 }}
rules={[{ required: true, type: 'email' }]} rules={[{ required: true, type: 'email' }]}
> >
<AntdInput <AntdInput />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
<AntdTag style={{ whiteSpace: 'normal' }}> <AntdTag style={{ whiteSpace: 'normal' }}>

View File

@@ -234,6 +234,12 @@ const Base = () => {
title: '编译', title: '编译',
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdForm form={compileForm}> <AntdForm form={compileForm}>
@@ -538,11 +544,23 @@ const Base = () => {
const handleOnAddFile = () => { const handleOnAddFile = () => {
void modal.confirm({ void modal.confirm({
title: '新建文件', title: '新建文件',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm form={addFileForm}> <AntdForm
form={addFileForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'fileName'} name={'fileName'}
label={'文件名'} label={'文件名'}
@@ -568,11 +586,7 @@ const Base = () => {
}) })
]} ]}
> >
<AntdInput <AntdInput />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
), ),
@@ -721,11 +735,23 @@ const Base = () => {
renameFileForm.setFieldValue('fileName', fileName) renameFileForm.setFieldValue('fileName', fileName)
void modal.confirm({ void modal.confirm({
title: '重命名文件', title: '重命名文件',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm form={renameFileForm}> <AntdForm
form={renameFileForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'fileName'} name={'fileName'}
label={'新文件名'} label={'新文件名'}
@@ -754,11 +780,7 @@ const Base = () => {
}) })
]} ]}
> >
<AntdInput <AntdInput />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
), ),

View File

@@ -399,11 +399,23 @@ const Template = () => {
const handleOnAddFile = () => { const handleOnAddFile = () => {
void modal.confirm({ void modal.confirm({
title: '新建文件', title: '新建文件',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm form={addFileForm}> <AntdForm
form={addFileForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'fileName'} name={'fileName'}
label={'文件名'} label={'文件名'}
@@ -429,11 +441,7 @@ const Template = () => {
}) })
]} ]}
> >
<AntdInput <AntdInput />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
), ),
@@ -585,11 +593,23 @@ const Template = () => {
renameFileForm.setFieldValue('fileName', fileName) renameFileForm.setFieldValue('fileName', fileName)
void modal.confirm({ void modal.confirm({
title: '重命名文件', title: '重命名文件',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm form={renameFileForm}> <AntdForm
form={renameFileForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('fileName').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'fileName'} name={'fileName'}
label={'新文件名'} label={'新文件名'}
@@ -618,11 +638,7 @@ const Template = () => {
}) })
]} ]}
> >
<AntdInput <AntdInput />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
), ),

View File

@@ -197,6 +197,12 @@ const Tools = () => {
title: '审核', title: '审核',
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm form={form}> <AntdForm form={form}>
<AntdForm.Item <AntdForm.Item

View File

@@ -336,15 +336,25 @@ const User = () => {
{value.username} {value.username}
</> </>
), ),
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm <AntdForm
form={changePasswordForm} form={changePasswordForm}
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }} wrapperCol={{ span: 18 }}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('password').focus()
}, 50)
}}
> >
<AntdForm.Item name={'id'} label={'ID'} labelAlign={'right'}> <AntdForm.Item name={'id'} label={'ID'} labelAlign={'right'}>
<AntdInput disabled /> <AntdInput disabled />
@@ -358,11 +368,7 @@ const User = () => {
} }
]} ]}
> >
<AntdInput.Password <AntdInput.Password />
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item <AntdForm.Item
name={'passwordConfirm'} name={'passwordConfirm'}

View File

@@ -262,12 +262,24 @@ const Tools = () => {
const handleOnUpgradeTool = (tool: ToolVo) => { const handleOnUpgradeTool = (tool: ToolVo) => {
void modal.confirm({ void modal.confirm({
title: '更新工具', title: '更新工具',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdForm form={upgradeForm}> <AntdForm
form={upgradeForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('toolId').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
initialValue={tool.toolId} initialValue={tool.toolId}
name={'toolId'} name={'toolId'}
@@ -287,14 +299,7 @@ const Tools = () => {
} }
]} ]}
> >
<AntdInput <AntdInput maxLength={10} showCount placeholder={'请输入版本'} />
maxLength={10}
showCount
placeholder={'请输入版本'}
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
</> </>

View File

@@ -99,15 +99,25 @@ const User = () => {
</> </>
), ),
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<AntdForm <AntdForm
form={changePasswordForm} form={changePasswordForm}
style={{ marginTop: 20 }} style={{ marginTop: 20 }}
labelCol={{ span: 6 }} labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }} wrapperCol={{ span: 18 }}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('originalPassword').focus()
}, 50)
}}
> >
<AntdForm.Item <AntdForm.Item
name={'originalPassword'} name={'originalPassword'}
@@ -115,12 +125,7 @@ const User = () => {
labelAlign={'right'} labelAlign={'right'}
rules={[{ required: true, message: '请输入原密码' }]} rules={[{ required: true, message: '请输入原密码' }]}
> >
<AntdInput.Password <AntdInput.Password placeholder={'请输入原密码'} />
placeholder={'请输入原密码'}
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
<AntdForm.Item <AntdForm.Item
name={'newPassword'} name={'newPassword'}
@@ -217,29 +222,42 @@ const User = () => {
title: '双因素', title: '双因素',
centered: true, centered: true,
maskClosable: true, maskClosable: true,
focusTriggerAfterClose: false,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: '确定解除双因素?', content: '确定解除双因素?',
onOk: () => { onOk: () => {
void modal.confirm({ void modal.confirm({
title: '解除双因素', title: '解除双因素',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdForm form={twoFactorForm}> <AntdForm
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'twoFactorCode'} name={'twoFactorCode'}
label={'验证码'} label={'验证码'}
style={{ marginTop: 10 }} style={{ marginTop: 10 }}
rules={[{ required: true, len: 6 }]} rules={[{ required: true, len: 6 }]}
> >
<AntdInput <AntdInput showCount maxLength={6} />
showCount
maxLength={6}
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
</> </>
@@ -289,9 +307,14 @@ const User = () => {
if (response.success) { if (response.success) {
void modal.confirm({ void modal.confirm({
title: '绑定双因素', title: '绑定双因素',
getContainer: false,
centered: true, centered: true,
maskClosable: true, maskClosable: true,
footer: (_, { OkBtn, CancelBtn }) => (
<>
<OkBtn />
<CancelBtn />
</>
),
content: ( content: (
<> <>
<AntdImage <AntdImage
@@ -299,20 +322,21 @@ const User = () => {
alt={'Two-factor'} alt={'Two-factor'}
preview={false} preview={false}
/> />
<AntdForm form={twoFactorForm}> <AntdForm
form={twoFactorForm}
ref={(ref) => {
setTimeout(() => {
ref?.getFieldInstance('twoFactorCode').focus()
}, 50)
}}
>
<AntdForm.Item <AntdForm.Item
name={'twoFactorCode'} name={'twoFactorCode'}
label={'验证码'} label={'验证码'}
style={{ marginTop: 10, marginRight: 30 }} style={{ marginTop: 10, marginRight: 30 }}
rules={[{ required: true, len: 6 }]} rules={[{ required: true, len: 6 }]}
> >
<AntdInput <AntdInput showCount maxLength={6} />
showCount
maxLength={6}
ref={(input) => {
input?.focus()
}}
/>
</AntdForm.Item> </AntdForm.Item>
</AntdForm> </AntdForm>
</> </>