mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Add password visibility toggle button to UserPasswordForm component
This commit is contained in:
parent
452e732a3a
commit
20ca4f654a
2 changed files with 62 additions and 0 deletions
23
src/components/dashboard/users/UserPasswordForm.scss
Normal file
23
src/components/dashboard/users/UserPasswordForm.scss
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
.inputContainer {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passwordToggle {
|
||||||
|
position: absolute;
|
||||||
|
width: 3em;
|
||||||
|
height: 3em;
|
||||||
|
top: 2.95em;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
right: 0.1em;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.1em;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.passwordToggle .material-icons {
|
||||||
|
font-size: 1.8em;
|
||||||
|
color: #666;
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ import loading from '../../loading/loading';
|
||||||
import toast from '../../toast/toast';
|
import toast from '../../toast/toast';
|
||||||
import ButtonElement from '../../../elements/ButtonElement';
|
import ButtonElement from '../../../elements/ButtonElement';
|
||||||
import InputElement from '../../../elements/InputElement';
|
import InputElement from '../../../elements/InputElement';
|
||||||
|
import IconButtonElement from 'elements/IconButtonElement';
|
||||||
|
import './UserPasswordForm.scss';
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
userId: string | null;
|
userId: string | null;
|
||||||
|
@ -142,8 +144,30 @@ const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const togglePassword = () => {
|
||||||
|
const inputIds = ['#txtCurrentPassword', '#txtNewPassword', '#txtNewPasswordConfirm'];
|
||||||
|
inputIds.forEach(id => {
|
||||||
|
const input = page.querySelector(id) as HTMLInputElement;
|
||||||
|
if (input) {
|
||||||
|
input.type = (input.type === 'password') ? 'text' : 'password';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
page.querySelectorAll('.passwordToggle .material-icons').forEach(icon => {
|
||||||
|
if (icon.classList.contains('visibility')) {
|
||||||
|
icon.classList.remove('visibility');
|
||||||
|
icon.classList.add('visibility_off');
|
||||||
|
} else {
|
||||||
|
icon.classList.remove('visibility_off');
|
||||||
|
icon.classList.add('visibility');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
(page.querySelector('.updatePasswordForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
(page.querySelector('.updatePasswordForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
||||||
(page.querySelector('#btnResetPassword') as HTMLButtonElement).addEventListener('click', resetPassword);
|
(page.querySelector('#btnResetPassword') as HTMLButtonElement).addEventListener('click', resetPassword);
|
||||||
|
page.querySelectorAll('.passwordToggle').forEach(button => {
|
||||||
|
button.addEventListener('click', togglePassword);
|
||||||
|
});
|
||||||
}, [loadUser, userId]);
|
}, [loadUser, userId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -160,6 +184,11 @@ const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
|
||||||
label='LabelCurrentPassword'
|
label='LabelCurrentPassword'
|
||||||
options={'autoComplete="off"'}
|
options={'autoComplete="off"'}
|
||||||
/>
|
/>
|
||||||
|
<IconButtonElement
|
||||||
|
is='paper-icon-button-light'
|
||||||
|
className='passwordToggle'
|
||||||
|
icon='visibility'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='inputContainer'>
|
<div className='inputContainer'>
|
||||||
<InputElement
|
<InputElement
|
||||||
|
@ -168,6 +197,11 @@ const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
|
||||||
label='LabelNewPassword'
|
label='LabelNewPassword'
|
||||||
options={'autoComplete="off"'}
|
options={'autoComplete="off"'}
|
||||||
/>
|
/>
|
||||||
|
<IconButtonElement
|
||||||
|
is='paper-icon-button-light'
|
||||||
|
className='passwordToggle'
|
||||||
|
icon='visibility'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='inputContainer'>
|
<div className='inputContainer'>
|
||||||
<InputElement
|
<InputElement
|
||||||
|
@ -176,6 +210,11 @@ const UserPasswordForm: FunctionComponent<IProps> = ({ userId }: IProps) => {
|
||||||
label='LabelNewPasswordConfirm'
|
label='LabelNewPasswordConfirm'
|
||||||
options={'autoComplete="off"'}
|
options={'autoComplete="off"'}
|
||||||
/>
|
/>
|
||||||
|
<IconButtonElement
|
||||||
|
is='paper-icon-button-light'
|
||||||
|
className='passwordToggle'
|
||||||
|
icon='visibility'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div>
|
<div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue