Convert ProviderFieldFormGroup to TypeScript

(cherry picked from commit 2935d148a8ee2717421609eb26e2005eda963110)
This commit is contained in:
Mark McDowall 2024-12-22 14:23:38 -08:00 committed by Bogdan
parent 2c81f3be0f
commit 0694f2fa76
6 changed files with 147 additions and 165 deletions

View file

@ -6,7 +6,7 @@ import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import { inputTypes } from 'Helpers/Props';
import { gotoQueuePage, setQueueOption } from 'Store/Actions/queueActions';
import { CheckInputChanged } from 'typings/inputs';
import { InputChanged } from 'typings/inputs';
import translate from 'Utilities/String/translate';
function QueueOptions() {
@ -16,7 +16,7 @@ function QueueOptions() {
);
const handleOptionChange = useCallback(
({ name, value }: CheckInputChanged) => {
({ name, value }: InputChanged<boolean>) => {
dispatch(
setQueueOption({
[name]: value,

View file

@ -1,156 +0,0 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import { inputTypes } from 'Helpers/Props';
function getType({ type, selectOptionsProviderAction }) {
switch (type) {
case 'captcha':
return inputTypes.CAPTCHA;
case 'checkbox':
return inputTypes.CHECK;
case 'device':
return inputTypes.DEVICE;
case 'keyValueList':
return inputTypes.KEY_VALUE_LIST;
case 'password':
return inputTypes.PASSWORD;
case 'number':
return inputTypes.NUMBER;
case 'path':
return inputTypes.PATH;
case 'filePath':
return inputTypes.PATH;
case 'select':
if (selectOptionsProviderAction) {
return inputTypes.DYNAMIC_SELECT;
}
return inputTypes.SELECT;
case 'movieTag':
return inputTypes.MOVIE_TAG;
case 'tag':
return inputTypes.TEXT_TAG;
case 'tagSelect':
return inputTypes.TAG_SELECT;
case 'textbox':
return inputTypes.TEXT;
case 'oAuth':
return inputTypes.OAUTH;
case 'rootFolder':
return inputTypes.ROOT_FOLDER_SELECT;
case 'qualityProfile':
return inputTypes.QUALITY_PROFILE_SELECT;
default:
return inputTypes.TEXT;
}
}
function getSelectValues(selectOptions) {
if (!selectOptions) {
return;
}
return _.reduce(selectOptions, (result, option) => {
result.push({
key: option.value,
value: option.name,
dividerAfter: option.dividerAfter,
hint: option.hint
});
return result;
}, []);
}
function ProviderFieldFormGroup(props) {
const {
advancedSettings,
name,
label,
helpText,
helpTextWarning,
helpLink,
placeholder,
value,
type,
advanced,
hidden,
pending,
errors,
warnings,
selectOptions,
onChange,
...otherProps
} = props;
if (
hidden === 'hidden' ||
(hidden === 'hiddenIfNotSet' && !value)
) {
return null;
}
return (
<FormGroup
advancedSettings={advancedSettings}
isAdvanced={advanced}
>
<FormLabel>{label}</FormLabel>
<FormInputGroup
type={getType(props)}
name={name}
label={label}
helpText={helpText}
helpTextWarning={helpTextWarning}
helpLink={helpLink}
placeholder={placeholder}
value={value}
values={getSelectValues(selectOptions)}
errors={errors}
warnings={warnings}
pending={pending}
includeFiles={type === 'filePath' ? true : undefined}
onChange={onChange}
{...otherProps}
/>
</FormGroup>
);
}
const selectOptionsShape = {
name: PropTypes.string.isRequired,
value: PropTypes.number.isRequired,
hint: PropTypes.string
};
ProviderFieldFormGroup.propTypes = {
advancedSettings: PropTypes.bool.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
helpText: PropTypes.string,
helpTextWarning: PropTypes.string,
helpLink: PropTypes.string,
placeholder: PropTypes.string,
value: PropTypes.any,
type: PropTypes.string.isRequired,
advanced: PropTypes.bool.isRequired,
hidden: PropTypes.string,
isDisabled: PropTypes.bool,
provider: PropTypes.string,
pending: PropTypes.bool.isRequired,
errors: PropTypes.arrayOf(PropTypes.object).isRequired,
warnings: PropTypes.arrayOf(PropTypes.object).isRequired,
selectOptions: PropTypes.arrayOf(PropTypes.shape(selectOptionsShape)),
selectOptionsProviderAction: PropTypes.string,
onChange: PropTypes.func.isRequired
};
ProviderFieldFormGroup.defaultProps = {
advancedSettings: false
};
export default ProviderFieldFormGroup;

View file

@ -0,0 +1,138 @@
import React, { useMemo } from 'react';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import { FieldSelectOption } from 'typings/Field';
import { InputChanged } from 'typings/inputs';
import { Failure } from 'typings/pending';
interface ProviderFieldFormGroupProps<T> {
advancedSettings: boolean;
name: string;
label: string;
helpText?: string;
helpTextWarning?: string;
helpLink?: string;
placeholder?: string;
value?: T;
type: string;
advanced: boolean;
hidden?: string;
isDisabled?: boolean;
provider?: string;
providerData?: object;
pending: boolean;
errors: Failure[];
warnings: Failure[];
selectOptions?: FieldSelectOption<T>[];
selectOptionsProviderAction?: string;
onChange: (change: InputChanged<T>) => void;
}
function ProviderFieldFormGroup<T>({
advancedSettings = false,
name,
label,
helpText,
helpTextWarning,
helpLink,
placeholder,
value,
type: providerType,
advanced,
hidden,
pending,
errors,
warnings,
selectOptions,
selectOptionsProviderAction,
onChange,
...otherProps
}: ProviderFieldFormGroupProps<T>) {
const type = useMemo(() => {
switch (providerType) {
case 'captcha':
return 'captcha';
case 'checkbox':
return 'check';
case 'device':
return 'device';
case 'keyValueList':
return 'keyValueList';
case 'password':
return 'password';
case 'number':
return 'number';
case 'path':
return 'path';
case 'filePath':
return 'path';
case 'select':
if (selectOptionsProviderAction) {
return 'dynamicSelect';
}
return 'select';
case 'movieTag':
return 'movieTag';
case 'tag':
return 'textTag';
case 'tagSelect':
return 'tagSelect';
case 'textbox':
return 'text';
case 'oAuth':
return 'oauth';
case 'rootFolder':
return 'rootFolderSelect';
case 'qualityProfile':
return 'qualityProfileSelect';
default:
return 'text';
}
}, [providerType, selectOptionsProviderAction]);
const selectValues = useMemo(() => {
if (!selectOptions) {
return;
}
return selectOptions.map((option) => {
return {
key: option.value,
value: option.name,
hint: option.hint,
};
});
}, [selectOptions]);
if (hidden === 'hidden' || (hidden === 'hiddenIfNotSet' && !value)) {
return null;
}
return (
<FormGroup advancedSettings={advancedSettings} isAdvanced={advanced}>
<FormLabel>{label}</FormLabel>
<FormInputGroup
type={type}
name={name}
helpText={helpText}
helpTextWarning={helpTextWarning}
helpLink={helpLink}
placeholder={placeholder}
// @ts-expect-error - this isn't available on all types
selectOptionsProviderAction={selectOptionsProviderAction}
value={value}
values={selectValues}
errors={errors}
warnings={warnings}
pending={pending}
includeFiles={providerType === 'filePath' ? true : undefined}
onChange={onChange}
{...otherProps}
/>
</FormGroup>
);
}
export default ProviderFieldFormGroup;

View file

@ -17,7 +17,7 @@ import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds } from 'Helpers/Props';
import Quality, { QualityModel } from 'Quality/Quality';
import { fetchQualityProfileSchema } from 'Store/Actions/settingsActions';
import { CheckInputChanged } from 'typings/inputs';
import { InputChanged } from 'typings/inputs';
import getQualities from 'Utilities/Quality/getQualities';
import translate from 'Utilities/String/translate';
@ -93,14 +93,14 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) {
);
const onProperChange = useCallback(
({ value }: CheckInputChanged) => {
({ value }: InputChanged<boolean>) => {
setProper(value);
},
[setProper]
);
const onRealChange = useCallback(
({ value }: CheckInputChanged) => {
({ value }: InputChanged<boolean>) => {
setReal(value);
},
[setReal]

View file

@ -15,7 +15,7 @@ import { inputTypes, kinds } from 'Helpers/Props';
import Movie from 'Movie/Movie';
import { bulkDeleteMovie, setDeleteOption } from 'Store/Actions/movieActions';
import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector';
import { CheckInputChanged } from 'typings/inputs';
import { InputChanged } from 'typings/inputs';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import styles from './DeleteMovieModalContent.css';
@ -48,7 +48,7 @@ function DeleteMovieModalContent(props: DeleteMovieModalContentProps) {
}, [movieIds, allMovies]);
const onDeleteFilesChange = useCallback(
({ value }: CheckInputChanged) => {
({ value }: InputChanged<boolean>) => {
setDeleteFiles(value);
},
[setDeleteFiles]

View file

@ -4,7 +4,7 @@ import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import { inputTypes } from 'Helpers/Props';
import { CheckInputChanged } from 'typings/inputs';
import { InputChanged } from 'typings/inputs';
import translate from 'Utilities/String/translate';
import selectTableOptions from './selectTableOptions';
@ -20,7 +20,7 @@ function MovieIndexTableOptions(props: MovieIndexTableOptionsProps) {
const { showSearchAction } = tableOptions;
const onTableOptionChangeWrapper = useCallback(
({ name, value }: CheckInputChanged) => {
({ name, value }: InputChanged<boolean>) => {
onTableOptionChange({
tableOptions: {
...tableOptions,