feat: toggle password visibility (#2127)

* Toggle password in ProxySettings

Input 'password' in ProxySettings (Preferences) can be toggled to be visible or not.

* Solving button overlap

- Button to toggle password won't cover the text;
- Added toggle password feature in CollectionSettings (ClientCertSettings and ProxySettings).
This commit is contained in:
Gustavo Ferreira da Silva 2024-04-21 15:20:16 -03:00 committed by GitHub
parent 59ffb0166f
commit 28e4159c21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 75 additions and 36 deletions

View File

@ -9,7 +9,7 @@ const StyledWrapper = styled.div`
color: ${(props) => props.theme.colors.text.yellow};
}
input {
.non-passphrase-input {
width: 300px;
}

View File

@ -3,6 +3,8 @@ import { IconCertificate, IconTrash, IconWorld } from '@tabler/icons';
import { useFormik } from 'formik';
import { uuid } from 'utils/common';
import * as Yup from 'yup';
import { IconEye, IconEyeOff } from '@tabler/icons';
import { useState } from 'react';
import StyledWrapper from './StyledWrapper';
@ -29,6 +31,8 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
formik.values[e.name] = e.files[0].path;
};
const [passwordVisible, setPasswordVisible] = useState(false);
return (
<StyledWrapper className="w-full h-full">
<div className="text-xs mb-4 text-muted">Add client certificates to be used for specific domains.</div>
@ -63,7 +67,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
type="text"
name="domain"
placeholder="*.example.org"
className="block textbox"
className="block textbox non-passphrase-input"
onChange={formik.handleChange}
value={formik.values.domain || ''}
/>
@ -79,7 +83,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
id="certFilePath"
type="file"
name="certFilePath"
className="block"
className="block non-passphrase-input"
onChange={(e) => getFile(e.target)}
/>
{formik.touched.certFilePath && formik.errors.certFilePath ? (
@ -94,7 +98,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
id="keyFilePath"
type="file"
name="keyFilePath"
className="block"
className="block non-passphrase-input"
onChange={(e) => getFile(e.target)}
/>
{formik.touched.keyFilePath && formik.errors.keyFilePath ? (
@ -105,14 +109,23 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
<label className="settings-label" htmlFor="passphrase">
Passphrase
</label>
<input
id="passphrase"
type="password"
name="passphrase"
className="block textbox"
onChange={formik.handleChange}
value={formik.values.passphrase || ''}
/>
<div className="textbox flex flex-row items-center w-[300px] h-[1.70rem] relative">
<input
id="passphrase"
type={passwordVisible ? 'text' : 'password'}
name="passphrase"
className="outline-none w-64 bg-transparent"
onChange={formik.handleChange}
value={formik.values.passphrase || ''}
/>
<button
type="button"
className="btn btn-sm absolute right-0 l"
onClick={() => setPasswordVisible(!passwordVisible)}
>
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
</button>
</div>
{formik.touched.passphrase && formik.errors.passphrase ? (
<div className="ml-1 text-red-500">{formik.errors.passphrase}</div>
) : null}

View File

@ -4,6 +4,8 @@ import Tooltip from 'components/Tooltip';
import StyledWrapper from './StyledWrapper';
import * as Yup from 'yup';
import toast from 'react-hot-toast';
import { IconEye, IconEyeOff } from '@tabler/icons';
import { useState } from 'react';
const ProxySettings = ({ proxyConfig, onUpdate }) => {
const proxySchema = Yup.object({
@ -78,6 +80,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
});
}
});
const [passwordVisible, setPasswordVisible] = useState(false);
useEffect(() => {
formik.setValues({
@ -277,18 +280,27 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
<label className="settings-label" htmlFor="auth.password">
Password
</label>
<input
id="auth.password"
type="password"
name="auth.password"
className="block textbox"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={formik.values.auth.password}
onChange={formik.handleChange}
/>
<div className="textbox flex flex-row items-center w-[13.2rem] h-[1.70rem] relative">
<input
id="auth.password"
type={passwordVisible ? 'text' : 'password'}
name="auth.password"
className="outline-none bg-transparent w-[10.5rem]"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={formik.values.auth.password}
onChange={formik.handleChange}
/>
<button
type="button"
className="btn btn-sm absolute right-0"
onClick={() => setPasswordVisible(!passwordVisible)}
>
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
</button>
</div>
{formik.touched.auth?.password && formik.errors.auth?.password ? (
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
) : null}

View File

@ -6,6 +6,8 @@ import { savePreferences } from 'providers/ReduxStore/slices/app';
import StyledWrapper from './StyledWrapper';
import { useDispatch, useSelector } from 'react-redux';
import { IconEye, IconEyeOff } from '@tabler/icons';
import { useState } from 'react';
const ProxySettings = ({ close }) => {
const preferences = useSelector((state) => state.app.preferences);
@ -88,6 +90,8 @@ const ProxySettings = ({ close }) => {
});
};
const [passwordVisible, setPasswordVisible] = useState(false);
useEffect(() => {
formik.setValues({
enabled: preferences.proxy.enabled || false,
@ -164,6 +168,7 @@ const ProxySettings = ({ close }) => {
</label>
</div>
</div>
<div className="mb-3 flex items-center">
<label className="settings-label" htmlFor="hostname">
Hostname
@ -240,18 +245,27 @@ const ProxySettings = ({ close }) => {
<label className="settings-label" htmlFor="auth.password">
Password
</label>
<input
id="auth.password"
type="password"
name="auth.password"
className="block textbox"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={formik.values.auth.password}
onChange={formik.handleChange}
/>
<div className="textbox flex flex-row items-center w-[13.2rem] h-[2.25rem] relative">
<input
id="auth.password"
type={passwordVisible ? `text` : 'password'}
name="auth.password"
className="outline-none w-[10.5rem] bg-transparent"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={formik.values.auth.password}
onChange={formik.handleChange}
/>
<button
type="button"
className="btn btn-sm absolute right-0"
onClick={() => setPasswordVisible(!passwordVisible)}
>
{passwordVisible ? <IconEyeOff size={18} strokeWidth={2} /> : <IconEye size={18} strokeWidth={2} />}
</button>
</div>
{formik.touched.auth?.password && formik.errors.auth?.password ? (
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
) : null}