feat(inputs): add support for toggling security on input fields (#1404)

pull/1536/head
Jakob Ankarhem 4 years ago committed by GitHub
parent e3d5e33ec3
commit 4fd452dd18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,54 @@
import { EyeIcon, EyeOffIcon } from '@heroicons/react/solid';
import { Field } from 'formik';
import React, { useState } from 'react';
interface CustomInputProps extends React.ComponentProps<'input'> {
as?: 'input';
}
interface CustomFieldProps extends React.ComponentProps<typeof Field> {
as?: 'field';
}
type SensitiveInputProps = CustomInputProps | CustomFieldProps;
const SensitiveInput: React.FC<SensitiveInputProps> = ({
as = 'input',
...props
}) => {
const [isHidden, setHidden] = useState(true);
const Component = as === 'input' ? 'input' : Field;
const componentProps =
as === 'input'
? props
: {
...props,
as: props.type === 'textarea' && !isHidden ? 'textarea' : undefined,
};
return (
<>
<Component
{...componentProps}
className={`rounded-l-only ${componentProps.className ?? ''}`}
type={
isHidden
? 'password'
: props.type !== 'password'
? props.type
: 'text'
}
/>
<button
onClick={(e) => {
e.preventDefault();
setHidden(!isHidden);
}}
className="input-action"
>
{isHidden ? <EyeOffIcon /> : <EyeIcon />}
</button>
</>
);
};
export default SensitiveInput;

@ -1,5 +1,5 @@
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { Form, Formik } from 'formik';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useState } from 'react';
@ -7,6 +7,7 @@ import { defineMessages, useIntl } from 'react-intl';
import * as Yup from 'yup';
import Button from '../Common/Button';
import ImageFader from '../Common/ImageFader';
import SensitiveInput from '../Common/SensitiveInput';
import LanguagePicker from '../Layout/LanguagePicker';
const messages = defineMessages({
@ -116,7 +117,8 @@ const ResetPassword: React.FC = () => {
</label>
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="password"
name="password"
type="password"
@ -136,7 +138,8 @@ const ResetPassword: React.FC = () => {
</label>
<div className="mt-1 mb-2 sm:mt-0 sm:col-span-2">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="confirmPassword"
name="confirmPassword"
type="password"

@ -10,6 +10,7 @@ import Alert from '../../Common/Alert';
import Badge from '../../Common/Badge';
import Button from '../../Common/Button';
import LoadingSpinner from '../../Common/LoadingSpinner';
import SensitiveInput from '../../Common/SensitiveInput';
import NotificationTypeSelector from '../../NotificationTypeSelector';
const messages = defineMessages({
@ -380,7 +381,8 @@ const NotificationsEmail: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="authPass"
name="authPass"
type="password"
@ -405,10 +407,11 @@ const NotificationsEmail: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="pgpPrivateKey"
name="pgpPrivateKey"
as="textarea"
type="textarea"
rows="10"
className="font-mono text-xs"
/>
@ -434,7 +437,8 @@ const NotificationsEmail: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="pgpPassword"
name="pgpPassword"
type="password"

@ -9,6 +9,7 @@ import globalMessages from '../../../../i18n/globalMessages';
import Alert from '../../../Common/Alert';
import Button from '../../../Common/Button';
import LoadingSpinner from '../../../Common/LoadingSpinner';
import SensitiveInput from '../../../Common/SensitiveInput';
import NotificationTypeSelector from '../../../NotificationTypeSelector';
const messages = defineMessages({
@ -159,7 +160,8 @@ const NotificationsPushbullet: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="accessToken"
name="accessToken"
type="text"

@ -9,6 +9,7 @@ import globalMessages from '../../../i18n/globalMessages';
import Alert from '../../Common/Alert';
import Button from '../../Common/Button';
import LoadingSpinner from '../../Common/LoadingSpinner';
import SensitiveInput from '../../Common/SensitiveInput';
import NotificationTypeSelector from '../../NotificationTypeSelector';
const messages = defineMessages({
@ -220,7 +221,8 @@ const NotificationsTelegram: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="botAPI"
name="botAPI"
type="text"

@ -10,6 +10,7 @@ import * as Yup from 'yup';
import type { RadarrSettings } from '../../../../server/lib/settings';
import globalMessages from '../../../i18n/globalMessages';
import Modal from '../../Common/Modal';
import SensitiveInput from '../../Common/SensitiveInput';
import Transition from '../../Transition';
type OptionType = {
@ -477,7 +478,8 @@ const RadarrModal: React.FC<RadarrModalProps> = ({
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="apiKey"
name="apiKey"
type="text"

@ -13,6 +13,7 @@ import Badge from '../Common/Badge';
import Button from '../Common/Button';
import LoadingSpinner from '../Common/LoadingSpinner';
import PageTitle from '../Common/PageTitle';
import SensitiveInput from '../Common/SensitiveInput';
import LanguageSelector from '../LanguageSelector';
import RegionSelector from '../RegionSelector';
import CopyButton from './CopyButton';
@ -166,7 +167,7 @@ const SettingsMain: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<input
<SensitiveInput
type="text"
id="apiKey"
className="rounded-l-only"

@ -10,6 +10,7 @@ import * as Yup from 'yup';
import type { SonarrSettings } from '../../../../server/lib/settings';
import globalMessages from '../../../i18n/globalMessages';
import Modal from '../../Common/Modal';
import SensitiveInput from '../../Common/SensitiveInput';
import Transition from '../../Transition';
type OptionType = {
@ -508,7 +509,8 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="apiKey"
name="apiKey"
type="text"

@ -27,6 +27,7 @@ import Header from '../Common/Header';
import LoadingSpinner from '../Common/LoadingSpinner';
import Modal from '../Common/Modal';
import PageTitle from '../Common/PageTitle';
import SensitiveInput from '../Common/SensitiveInput';
import Table from '../Common/Table';
import Transition from '../Transition';
import BulkEditModal from './BulkEditModal';
@ -402,7 +403,7 @@ const UserList: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
id="password"
name="password"
type="password"

@ -1,5 +1,5 @@
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import { Form, Formik } from 'formik';
import { useRouter } from 'next/router';
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
@ -13,6 +13,7 @@ import Alert from '../../../Common/Alert';
import Button from '../../../Common/Button';
import LoadingSpinner from '../../../Common/LoadingSpinner';
import PageTitle from '../../../Common/PageTitle';
import SensitiveInput from '../../../Common/SensitiveInput';
const messages = defineMessages({
password: 'Password',
@ -162,7 +163,8 @@ const UserPasswordChange: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="currentPassword"
name="currentPassword"
type="password"
@ -181,7 +183,8 @@ const UserPasswordChange: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="newPassword"
name="newPassword"
type="password"
@ -199,7 +202,8 @@ const UserPasswordChange: React.FC = () => {
</label>
<div className="form-input">
<div className="form-input-field">
<Field
<SensitiveInput
as="field"
id="confirmPassword"
name="confirmPassword"
type="password"

Loading…
Cancel
Save