This is an automated email from the ASF dual-hosted git repository. shuai pushed a commit to branch dev in repository https://gitbox.apache.org/repos/asf/answer.git
commit 013df362caa2636b2903a5f93869775fb0b138de Author: lihui <[email protected]> AuthorDate: Thu Jan 16 00:03:30 2025 +0800 feat: add password hide show logic for init server --- ui/package.json | 1 + ui/pnpm-lock.yaml | 14 +++++- .../pages/Install/components/FourthStep/index.tsx | 56 +++++++++++++++------- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/ui/package.json b/ui/package.json index 0e645d2e..da8588e6 100644 --- a/ui/package.json +++ b/ui/package.json @@ -39,6 +39,7 @@ "qs": "^6.11.0", "react": "^18.2.0", "react-bootstrap": "^2.10.0", + "react-bootstrap-icons": "^1.11.5", "react-dom": "^18.2.0", "react-helmet-async": "^1.3.0", "react-i18next": "^11.18.3", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 32ce67e7..8aa2dffb 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -77,6 +77,9 @@ importers: react-bootstrap: specifier: ^2.10.0 version: 2.10.0(@types/[email protected])([email protected])([email protected]) + react-bootstrap-icons: + specifier: ^1.11.5 + version: 1.11.5([email protected]) react-dom: specifier: ^18.2.0 version: 18.2.0([email protected]) @@ -8176,7 +8179,7 @@ packages: dependencies: universalify: 2.0.0 optionalDependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 /[email protected]: resolution: {integrity: sha512-pfog5gdDxPdV4eP7Kg87M8/bHgshlZ5pybl+yKxAnCZ5O7lCIn7Ixydj03wOlnDQesky2BPyA91SQ+5Y/mNwzw==} @@ -9913,6 +9916,15 @@ packages: semver: 5.7.1 dev: true + /[email protected]([email protected]): + resolution: {integrity: sha512-eOhtFJMUqw98IJcfKJsSMZkFHCeNPTTwXZAe9V9d4mT22ARmbrISxPO9GmtWWuf72zQctLeZMGodX/q6wrbYYg==} + peerDependencies: + react: '>=16.8.6' + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + dev: false + /[email protected](@types/[email protected])([email protected])([email protected]): resolution: {integrity: sha512-87gRP69VAfeU2yKgp8RI3HvzhPNrnYIV2QNranYXataz3ef+k7OhvKGGdxQLQfUsQ2RTmlY66tn4pdFrZ94hNg==} peerDependencies: diff --git a/ui/src/pages/Install/components/FourthStep/index.tsx b/ui/src/pages/Install/components/FourthStep/index.tsx index 65ffd9d5..066cd079 100644 --- a/ui/src/pages/Install/components/FourthStep/index.tsx +++ b/ui/src/pages/Install/components/FourthStep/index.tsx @@ -17,8 +17,9 @@ * under the License. */ -import { FC, FormEvent } from 'react'; +import { FC, FormEvent, useState } from 'react'; import { Form, Button } from 'react-bootstrap'; +import { Eye, EyeSlash } from 'react-bootstrap-icons'; import { useTranslation } from 'react-i18next'; import type { FormDataType } from '@/common/interface'; @@ -34,6 +35,8 @@ interface Props { const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => { const { t } = useTranslation('translation', { keyPrefix: 'install' }); + const [showPassword, setShowPassword] = useState(false); + const checkValidated = (): boolean => { let bol = true; const { site_name, site_url, contact_email, name, password, email } = data; @@ -295,21 +298,42 @@ const Index: FC<Props> = ({ visible, data, changeCallback, nextCallback }) => { <Form.Group controlId="password" className="mb-3"> <Form.Label>{t('admin_password.label')}</Form.Label> - <Form.Control - required - type="password" - value={data.password.value} - isInvalid={data.password.isInvalid} - onChange={(e) => { - changeCallback({ - password: { - value: e.target.value, - isInvalid: false, - errorMsg: '', - }, - }); - }} - /> + <div className="position-relative"> + <Form.Control + required + type={showPassword ? 'text' : 'password'} + value={data.password.value} + isInvalid={data.password.isInvalid} + style={{ paddingRight: '45px' }} + onChange={(e) => { + changeCallback({ + password: { + value: e.target.value, + isInvalid: false, + errorMsg: '', + }, + }); + }} + /> + <button + type="button" + className="position-absolute top-50 translate-middle-y bg-transparent border-0" + style={{ + cursor: 'pointer', + right: '12px', + padding: '4px', + }} + aria-label={showPassword ? t('hide_password') : t('show_password')} + onMouseDown={() => setShowPassword(true)} + onMouseUp={() => setShowPassword(false)} + onMouseLeave={() => setShowPassword(false)}> + {showPassword ? ( + <Eye className="text-secondary" size={18} /> + ) : ( + <EyeSlash className="text-secondary" size={18} /> + )} + </button> + </div> <Form.Text>{t('admin_password.text')}</Form.Text> <Form.Control.Feedback type="invalid"> {data.password.errorMsg}
