From 6838f068bcd04b770cd9c53873f160be97ea745f Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 3 Jan 2025 09:47:17 -0800 Subject: [PATCH] Improve typings in FormInputGroup --- .../src/Components/Form/AutoCompleteInput.tsx | 3 +- frontend/src/Components/Form/CaptchaInput.tsx | 2 +- frontend/src/Components/Form/CheckInput.css | 11 +- .../src/Components/Form/CheckInput.css.d.ts | 8 +- frontend/src/Components/Form/CheckInput.tsx | 5 +- .../src/Components/Form/FormInputGroup.tsx | 204 ++++++++++++------ frontend/src/Components/Form/NumberInput.tsx | 3 +- frontend/src/Components/Form/OAuthInput.tsx | 2 +- frontend/src/Components/Form/PathInput.tsx | 2 +- .../Form/ProviderFieldFormGroup.tsx | 1 + .../Form/Select/DownloadClientSelectInput.tsx | 7 +- .../Form/Select/IndexerFlagsSelectInput.tsx | 2 +- .../Form/Select/IndexerSelectInput.tsx | 4 +- .../Form/Select/LanguageSelectInput.tsx | 10 +- .../Select/MonitorEpisodesSelectInput.tsx | 6 +- .../Select/MonitorNewItemsSelectInput.tsx | 7 +- .../Form/Select/ProviderOptionSelectInput.tsx | 2 +- .../Form/Select/QualityProfileSelectInput.tsx | 4 +- .../Form/Select/RootFolderSelectInput.tsx | 17 +- .../Form/Select/SeriesTypeSelectInput.tsx | 11 +- .../src/Components/Form/Select/UMaskInput.tsx | 13 +- .../src/Components/Form/Tag/DeviceInput.tsx | 2 +- .../Components/Form/Tag/SeriesTagInput.tsx | 50 ++--- frontend/src/Components/Form/Tag/TagInput.tsx | 22 -- .../Components/Form/Tag/TagSelectInput.tsx | 2 +- .../src/Components/Form/Tag/TextTagInput.tsx | 6 +- frontend/src/Components/Form/TextArea.tsx | 2 +- frontend/src/Components/Form/TextInput.tsx | 6 +- .../Table/TableOptions/TableOptionsModal.tsx | 6 +- .../Quality/SelectQualityModalContent.tsx | 6 +- .../Series/Edit/EditSeriesModalContent.tsx | 1 + .../Delete/DeleteSeriesModalContent.tsx | 2 +- .../Select/Edit/EditSeriesModalContent.tsx | 15 +- .../ManageDownloadClientsEditModalContent.tsx | 46 ++-- .../src/Settings/General/BackupSettings.tsx | 1 + .../src/Settings/General/UpdateSettings.tsx | 2 - .../EditImportListExclusionModalContent.tsx | 5 +- .../ManageImportListsEditModalContent.tsx | 34 ++- .../ImportLists/Options/ImportListOptions.tsx | 3 +- .../Edit/ManageIndexersEditModalContent.tsx | 42 ++-- .../MediaManagement/MediaManagement.tsx | 2 +- .../MediaManagement/Naming/Naming.tsx | 5 +- .../Delay/EditDelayProfileModalContent.tsx | 12 +- .../EditReleaseProfileModalContent.tsx | 6 +- 44 files changed, 321 insertions(+), 281 deletions(-) diff --git a/frontend/src/Components/Form/AutoCompleteInput.tsx b/frontend/src/Components/Form/AutoCompleteInput.tsx index 7ba114125..226b40c45 100644 --- a/frontend/src/Components/Form/AutoCompleteInput.tsx +++ b/frontend/src/Components/Form/AutoCompleteInput.tsx @@ -7,8 +7,9 @@ import { import { InputChanged } from 'typings/inputs'; import AutoSuggestInput from './AutoSuggestInput'; -interface AutoCompleteInputProps { +export interface AutoCompleteInputProps { name: string; + readOnly?: boolean; value?: string; values: string[]; onChange: (change: InputChanged) => unknown; diff --git a/frontend/src/Components/Form/CaptchaInput.tsx b/frontend/src/Components/Form/CaptchaInput.tsx index d5a3f11f7..597b1ad4f 100644 --- a/frontend/src/Components/Form/CaptchaInput.tsx +++ b/frontend/src/Components/Form/CaptchaInput.tsx @@ -16,7 +16,7 @@ import FormInputButton from './FormInputButton'; import TextInput from './TextInput'; import styles from './CaptchaInput.css'; -interface CaptchaInputProps { +export interface CaptchaInputProps { className?: string; name: string; value?: string; diff --git a/frontend/src/Components/Form/CheckInput.css b/frontend/src/Components/Form/CheckInput.css index 171121482..6e44bd609 100644 --- a/frontend/src/Components/Form/CheckInput.css +++ b/frontend/src/Components/Form/CheckInput.css @@ -41,10 +41,11 @@ .checkbox:focus + .input { outline: 0; border-color: var(--inputFocusBorderColor); - box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), 0 0 8px var(--inputFocusBoxShadowColor); + box-shadow: inset 0 1px 1px var(--inputBoxShadowColor), + 0 0 8px var(--inputFocusBoxShadowColor); } -.dangerIsChecked { +.danger { border-color: var(--dangerColor); background-color: var(--dangerColor); @@ -53,7 +54,7 @@ } } -.primaryIsChecked { +.primary { border-color: var(--primaryColor); background-color: var(--primaryColor); @@ -62,7 +63,7 @@ } } -.successIsChecked { +.success { border-color: var(--successColor); background-color: var(--successColor); @@ -71,7 +72,7 @@ } } -.warningIsChecked { +.warning { border-color: var(--warningColor); background-color: var(--warningColor); diff --git a/frontend/src/Components/Form/CheckInput.css.d.ts b/frontend/src/Components/Form/CheckInput.css.d.ts index bba6b63bb..850250b67 100644 --- a/frontend/src/Components/Form/CheckInput.css.d.ts +++ b/frontend/src/Components/Form/CheckInput.css.d.ts @@ -3,16 +3,16 @@ interface CssExports { 'checkbox': string; 'container': string; - 'dangerIsChecked': string; + 'danger': string; 'helpText': string; 'input': string; 'isDisabled': string; 'isIndeterminate': string; 'isNotChecked': string; 'label': string; - 'primaryIsChecked': string; - 'successIsChecked': string; - 'warningIsChecked': string; + 'primary': string; + 'success': string; + 'warning': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/Components/Form/CheckInput.tsx b/frontend/src/Components/Form/CheckInput.tsx index 6f5dd0242..107beaa58 100644 --- a/frontend/src/Components/Form/CheckInput.tsx +++ b/frontend/src/Components/Form/CheckInput.tsx @@ -11,7 +11,7 @@ interface ChangeEvent extends SyntheticEvent { target: EventTarget & T; } -interface CheckInputProps { +export interface CheckInputProps { className?: string; containerClassName?: string; name: string; @@ -45,7 +45,6 @@ function CheckInput(props: CheckInputProps) { const isChecked = value === checkedValue; const isUnchecked = value === uncheckedValue; const isIndeterminate = !isChecked && !isUnchecked; - const isCheckClass: keyof typeof styles = `${kind}IsChecked`; const toggleChecked = useCallback( (checked: boolean, shiftKey: boolean) => { @@ -112,7 +111,7 @@ function CheckInput(props: CheckInputProps) {
> = { +const componentMap: Record = { autoComplete: AutoCompleteInput, captcha: CaptchaInput, check: CheckInput, date: TextInput, device: DeviceInput, + downloadClientSelect: DownloadClientSelectInput, + dynamicSelect: ProviderDataSelectInput, file: TextInput, float: NumberInput, + indexerFlagsSelect: IndexerFlagsSelectInput, + indexerSelect: IndexerSelectInput, keyValueList: KeyValueListInput, languageSelect: LanguageSelectInput, monitorEpisodesSelect: MonitorEpisodesSelectInput, @@ -55,21 +77,84 @@ const componentMap: Record> = { password: PasswordInput, path: PathInput, qualityProfileSelect: QualityProfileSelectInput, - indexerSelect: IndexerSelectInput, - indexerFlagsSelect: IndexerFlagsSelectInput, - downloadClientSelect: DownloadClientSelectInput, rootFolderSelect: RootFolderSelectInput, select: EnhancedSelectInput, - dynamicSelect: ProviderDataSelectInput, - tag: SeriesTagInput, seriesTag: SeriesTagInput, seriesTypeSelect: SeriesTypeSelectInput, + tag: SeriesTagInput, + tagSelect: TagSelectInput, text: TextInput, textArea: TextArea, textTag: TextTagInput, - tagSelect: TagSelectInput, umask: UMaskInput, -}; +} as const; + +// type Components = typeof componentMap; + +type PickProps = C extends 'text' + ? TextInputProps + : C extends 'autoComplete' + ? AutoCompleteInputProps + : C extends 'captcha' + ? CaptchaInputProps + : C extends 'check' + ? CheckInputProps + : C extends 'date' + ? TextInputProps + : C extends 'device' + ? DeviceInputProps + : C extends 'downloadClientSelect' + ? DownloadClientSelectInputProps + : C extends 'dynamicSelect' + ? ProviderOptionSelectInputProps + : C extends 'file' + ? TextInputProps + : C extends 'float' + ? TextInputProps + : C extends 'indexerFlagsSelect' + ? IndexerFlagsSelectInputProps + : C extends 'indexerSelect' + ? IndexerSelectInputProps + : C extends 'keyValueList' + ? KeyValueListInputProps + : C extends 'languageSelect' + ? LanguageSelectInputProps + : C extends 'monitorEpisodesSelect' + ? MonitorEpisodesSelectInputProps + : C extends 'monitorNewItemsSelect' + ? MonitorNewItemsSelectInputProps + : C extends 'number' + ? NumberInputProps + : C extends 'oauth' + ? OAuthInputProps + : C extends 'password' + ? TextInputProps + : C extends 'path' + ? PathInputProps + : C extends 'qualityProfileSelect' + ? QualityProfileSelectInputProps + : C extends 'rootFolderSelect' + ? RootFolderSelectInputProps + : C extends 'select' + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + EnhancedSelectInputProps + : C extends 'seriesTag' + ? SeriesTagInputProps + : C extends 'seriesTypeSelect' + ? SeriesTypeSelectInputProps + : C extends 'tag' + ? SeriesTagInputProps + : C extends 'tagSelect' + ? TagSelectInputProps + : C extends 'text' + ? TextInputProps + : C extends 'textArea' + ? TextAreaProps + : C extends 'textTag' + ? TextTagInputProps + : C extends 'umask' + ? UMaskInputProps + : never; export interface FormInputGroupValues { key: T; @@ -82,53 +167,37 @@ export interface ValidationMessage { message: string; } -interface FormInputGroupProps { +export type FormInputGroupProps = Omit< + PickProps, + 'className' +> & { + type: C; className?: string; containerClassName?: string; inputClassName?: string; + autoFocus?: boolean; autocomplete?: string; name: string; - value?: unknown; - values?: FormInputGroupValues[]; - isDisabled?: boolean; - type?: InputType; - kind?: Kind; - min?: number; - max?: number; - unit?: string; buttons?: ReactNode | ReactNode[]; helpText?: string; helpTexts?: string[]; helpTextWarning?: string; helpLink?: string; - placeholder?: string; - autoFocus?: boolean; - includeFiles?: boolean; - includeMissingValue?: boolean; - includeNoChange?: boolean; - includeNoChangeDisabled?: boolean; - valueOptions?: object; - selectedValueOptions?: object; - selectOptionsProviderAction?: string; - indexerFlags?: number; pending?: boolean; - protocol?: DownloadProtocol; - canEdit?: boolean; - includeAny?: boolean; - delimiters?: string[]; - readOnly?: boolean; + placeholder?: string; + unit?: string; errors?: (ValidationMessage | ValidationError)[]; warnings?: (ValidationMessage | ValidationWarning)[]; - onChange: (change: InputChanged) => void; - onFocus?: (event: FocusEvent) => void; -} +}; -function FormInputGroup(props: FormInputGroupProps) { +function FormInputGroup( + props: FormInputGroupProps +) { const { className = styles.inputGroup, containerClassName = styles.inputGroupContainer, inputClassName, - type = 'text', + type, unit, buttons = [], helpText, @@ -153,6 +222,7 @@ function FormInputGroup(props: FormInputGroupProps) {
+ {/* @ts-expect-error - tpyes are validated already */} { +export interface NumberInputProps + extends Omit { value?: number | null; min?: number; max?: number; diff --git a/frontend/src/Components/Form/OAuthInput.tsx b/frontend/src/Components/Form/OAuthInput.tsx index 04d2a0caf..19bc9ba23 100644 --- a/frontend/src/Components/Form/OAuthInput.tsx +++ b/frontend/src/Components/Form/OAuthInput.tsx @@ -6,7 +6,7 @@ import { kinds } from 'Helpers/Props'; import { resetOAuth, startOAuth } from 'Store/Actions/oAuthActions'; import { InputOnChange } from 'typings/inputs'; -interface OAuthInputProps { +export interface OAuthInputProps { label?: string; name: string; provider: string; diff --git a/frontend/src/Components/Form/PathInput.tsx b/frontend/src/Components/Form/PathInput.tsx index 0caf66905..015b835e3 100644 --- a/frontend/src/Components/Form/PathInput.tsx +++ b/frontend/src/Components/Form/PathInput.tsx @@ -24,7 +24,7 @@ import AutoSuggestInput from './AutoSuggestInput'; import FormInputButton from './FormInputButton'; import styles from './PathInput.css'; -interface PathInputProps { +export interface PathInputProps { className?: string; name: string; value?: string; diff --git a/frontend/src/Components/Form/ProviderFieldFormGroup.tsx b/frontend/src/Components/Form/ProviderFieldFormGroup.tsx index ca6685134..214411ab0 100644 --- a/frontend/src/Components/Form/ProviderFieldFormGroup.tsx +++ b/frontend/src/Components/Form/ProviderFieldFormGroup.tsx @@ -120,6 +120,7 @@ function ProviderFieldFormGroup({ helpTextWarning={helpTextWarning} helpLink={helpLink} placeholder={placeholder} + // @ts-expect-error - this isn;'t available on all types selectOptionsProviderAction={selectOptionsProviderAction} value={value} values={selectValues} diff --git a/frontend/src/Components/Form/Select/DownloadClientSelectInput.tsx b/frontend/src/Components/Form/Select/DownloadClientSelectInput.tsx index 4ed3e0952..4dca13db7 100644 --- a/frontend/src/Components/Form/Select/DownloadClientSelectInput.tsx +++ b/frontend/src/Components/Form/Select/DownloadClientSelectInput.tsx @@ -51,8 +51,11 @@ function createDownloadClientsSelector( ); } -interface DownloadClientSelectInputProps - extends EnhancedSelectInputProps, number> { +export interface DownloadClientSelectInputProps + extends Omit< + EnhancedSelectInputProps, number>, + 'values' + > { name: string; value: number; includeAny?: boolean; diff --git a/frontend/src/Components/Form/Select/IndexerFlagsSelectInput.tsx b/frontend/src/Components/Form/Select/IndexerFlagsSelectInput.tsx index a43044156..e4f149d3c 100644 --- a/frontend/src/Components/Form/Select/IndexerFlagsSelectInput.tsx +++ b/frontend/src/Components/Form/Select/IndexerFlagsSelectInput.tsx @@ -30,7 +30,7 @@ const selectIndexerFlagsValues = (selectedFlags: number) => } ); -interface IndexerFlagsSelectInputProps { +export interface IndexerFlagsSelectInputProps { name: string; indexerFlags: number; onChange(payload: EnhancedSelectInputChanged): void; diff --git a/frontend/src/Components/Form/Select/IndexerSelectInput.tsx b/frontend/src/Components/Form/Select/IndexerSelectInput.tsx index 3e9f61ebc..f4c7f4bb5 100644 --- a/frontend/src/Components/Form/Select/IndexerSelectInput.tsx +++ b/frontend/src/Components/Form/Select/IndexerSelectInput.tsx @@ -38,7 +38,7 @@ function createIndexersSelector(includeAny: boolean) { ); } -interface IndexerSelectInputConnectorProps { +export interface IndexerSelectInputProps { name: string; value: number; includeAny?: boolean; @@ -50,7 +50,7 @@ function IndexerSelectInput({ value, includeAny = false, onChange, -}: IndexerSelectInputConnectorProps) { +}: IndexerSelectInputProps) { const dispatch = useDispatch(); const { isFetching, isPopulated, values } = useSelector( createIndexersSelector(includeAny) diff --git a/frontend/src/Components/Form/Select/LanguageSelectInput.tsx b/frontend/src/Components/Form/Select/LanguageSelectInput.tsx index 61bfbf586..2ea9e8093 100644 --- a/frontend/src/Components/Form/Select/LanguageSelectInput.tsx +++ b/frontend/src/Components/Form/Select/LanguageSelectInput.tsx @@ -12,20 +12,20 @@ interface LanguageSelectInputOnChangeProps { value: number | string | Language; } -interface LanguageSelectInputProps { +export interface LanguageSelectInputProps { name: string; value: number | string | Language; - includeNoChange: boolean; + includeNoChange?: boolean; includeNoChangeDisabled?: boolean; - includeMixed: boolean; + includeMixed?: boolean; onChange: (payload: LanguageSelectInputOnChangeProps) => void; } export default function LanguageSelectInput({ value, - includeNoChange, + includeNoChange = false, includeNoChangeDisabled, - includeMixed, + includeMixed = false, onChange, ...otherProps }: LanguageSelectInputProps) { diff --git a/frontend/src/Components/Form/Select/MonitorEpisodesSelectInput.tsx b/frontend/src/Components/Form/Select/MonitorEpisodesSelectInput.tsx index 59fd08513..ccc3455c5 100644 --- a/frontend/src/Components/Form/Select/MonitorEpisodesSelectInput.tsx +++ b/frontend/src/Components/Form/Select/MonitorEpisodesSelectInput.tsx @@ -6,13 +6,13 @@ import EnhancedSelectInput, { EnhancedSelectInputValue, } from './EnhancedSelectInput'; -interface MonitorEpisodesSelectInputProps +export interface MonitorEpisodesSelectInputProps extends Omit< EnhancedSelectInputProps, string>, 'values' > { - includeNoChange: boolean; - includeMixed: boolean; + includeNoChange?: boolean; + includeMixed?: boolean; } function MonitorEpisodesSelectInput(props: MonitorEpisodesSelectInputProps) { diff --git a/frontend/src/Components/Form/Select/MonitorNewItemsSelectInput.tsx b/frontend/src/Components/Form/Select/MonitorNewItemsSelectInput.tsx index ac11f1fca..5bf17704c 100644 --- a/frontend/src/Components/Form/Select/MonitorNewItemsSelectInput.tsx +++ b/frontend/src/Components/Form/Select/MonitorNewItemsSelectInput.tsx @@ -5,19 +5,20 @@ import EnhancedSelectInput, { EnhancedSelectInputValue, } from './EnhancedSelectInput'; -interface MonitorNewItemsSelectInputProps +export interface MonitorNewItemsSelectInputProps extends Omit< EnhancedSelectInputProps, string>, 'values' > { includeNoChange?: boolean; + includeNoChangeDisabled?: boolean; includeMixed?: boolean; - onChange: (...args: unknown[]) => unknown; } function MonitorNewItemsSelectInput(props: MonitorNewItemsSelectInputProps) { const { includeNoChange = false, + includeNoChangeDisabled = true, includeMixed = false, ...otherProps } = props; @@ -30,7 +31,7 @@ function MonitorNewItemsSelectInput(props: MonitorNewItemsSelectInputProps) { values.unshift({ key: 'noChange', value: 'No Change', - isDisabled: true, + isDisabled: includeNoChangeDisabled, }); } diff --git a/frontend/src/Components/Form/Select/ProviderOptionSelectInput.tsx b/frontend/src/Components/Form/Select/ProviderOptionSelectInput.tsx index e4a8003eb..f85fcc8f3 100644 --- a/frontend/src/Components/Form/Select/ProviderOptionSelectInput.tsx +++ b/frontend/src/Components/Form/Select/ProviderOptionSelectInput.tsx @@ -69,7 +69,7 @@ function createProviderOptionsSelector( ); } -interface ProviderOptionSelectInputProps +export interface ProviderOptionSelectInputProps extends Omit< EnhancedSelectInputProps, unknown>, 'values' diff --git a/frontend/src/Components/Form/Select/QualityProfileSelectInput.tsx b/frontend/src/Components/Form/Select/QualityProfileSelectInput.tsx index 485264349..81ad726f1 100644 --- a/frontend/src/Components/Form/Select/QualityProfileSelectInput.tsx +++ b/frontend/src/Components/Form/Select/QualityProfileSelectInput.tsx @@ -56,7 +56,7 @@ function createQualityProfilesSelector( ); } -interface QualityProfileSelectInputConnectorProps +export interface QualityProfileSelectInputProps extends Omit< EnhancedSelectInputProps< EnhancedSelectInputValue, @@ -78,7 +78,7 @@ function QualityProfileSelectInput({ includeMixed = false, onChange, ...otherProps -}: QualityProfileSelectInputConnectorProps) { +}: QualityProfileSelectInputProps) { const values = useSelector( createQualityProfilesSelector( includeNoChange, diff --git a/frontend/src/Components/Form/Select/RootFolderSelectInput.tsx b/frontend/src/Components/Form/Select/RootFolderSelectInput.tsx index 8b278ded7..8ddbd20ea 100644 --- a/frontend/src/Components/Form/Select/RootFolderSelectInput.tsx +++ b/frontend/src/Components/Form/Select/RootFolderSelectInput.tsx @@ -24,16 +24,16 @@ export interface RootFolderSelectInputValue isMissing?: boolean; } -interface RootFolderSelectInputProps +export interface RootFolderSelectInputProps extends Omit< EnhancedSelectInputProps, string>, 'value' | 'values' > { name: string; value?: string; - isSaving: boolean; - saveError?: object; - includeNoChange: boolean; + includeMissingValue?: boolean; + includeNoChange?: boolean; + includeNoChangeDisabled?: boolean; } function createRootFolderOptionsSelector( @@ -107,13 +107,20 @@ function createRootFolderOptionsSelector( function RootFolderSelectInput({ name, value, + includeMissingValue = true, includeNoChange = false, + includeNoChangeDisabled = true, onChange, ...otherProps }: RootFolderSelectInputProps) { const dispatch = useDispatch(); const { values, isSaving, saveError } = useSelector( - createRootFolderOptionsSelector(value, true, includeNoChange, false) + createRootFolderOptionsSelector( + value, + includeMissingValue, + includeNoChange, + includeNoChangeDisabled + ) ); const [isAddNewRootFolderModalOpen, setIsAddNewRootFolderModalOpen] = useState(false); diff --git a/frontend/src/Components/Form/Select/SeriesTypeSelectInput.tsx b/frontend/src/Components/Form/Select/SeriesTypeSelectInput.tsx index 6a3bba650..3b901598f 100644 --- a/frontend/src/Components/Form/Select/SeriesTypeSelectInput.tsx +++ b/frontend/src/Components/Form/Select/SeriesTypeSelectInput.tsx @@ -8,11 +8,14 @@ import EnhancedSelectInput, { import SeriesTypeSelectInputOption from './SeriesTypeSelectInputOption'; import SeriesTypeSelectInputSelectedValue from './SeriesTypeSelectInputSelectedValue'; -interface SeriesTypeSelectInputProps - extends EnhancedSelectInputProps, string> { - includeNoChange: boolean; +export interface SeriesTypeSelectInputProps + extends Omit< + EnhancedSelectInputProps, string>, + 'values' + > { + includeNoChange?: boolean; includeNoChangeDisabled?: boolean; - includeMixed: boolean; + includeMixed?: boolean; } export interface ISeriesTypeOption { diff --git a/frontend/src/Components/Form/Select/UMaskInput.tsx b/frontend/src/Components/Form/Select/UMaskInput.tsx index 1f537f968..2f528ba91 100644 --- a/frontend/src/Components/Form/Select/UMaskInput.tsx +++ b/frontend/src/Components/Form/Select/UMaskInput.tsx @@ -1,5 +1,4 @@ /* eslint-disable no-bitwise */ -import PropTypes from 'prop-types'; import React, { SyntheticEvent } from 'react'; import { InputChanged } from 'typings/inputs'; import translate from 'Utilities/String/translate'; @@ -67,7 +66,7 @@ function formatPermissions(permissions: number) { return result; } -interface UMaskInputProps { +export interface UMaskInputProps { name: string; value: string; hasError?: boolean; @@ -129,14 +128,4 @@ function UMaskInput({ name, value, onChange }: UMaskInputProps) { ); } -UMaskInput.propTypes = { - name: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - hasError: PropTypes.bool, - hasWarning: PropTypes.bool, - onChange: PropTypes.func.isRequired, - onFocus: PropTypes.func, - onBlur: PropTypes.func, -}; - export default UMaskInput; diff --git a/frontend/src/Components/Form/Tag/DeviceInput.tsx b/frontend/src/Components/Form/Tag/DeviceInput.tsx index 3c483d1f2..229776059 100644 --- a/frontend/src/Components/Form/Tag/DeviceInput.tsx +++ b/frontend/src/Components/Form/Tag/DeviceInput.tsx @@ -19,7 +19,7 @@ interface DeviceTag { name: string; } -interface DeviceInputProps extends TagInputProps { +export interface DeviceInputProps extends TagInputProps { className?: string; name: string; value: string[]; diff --git a/frontend/src/Components/Form/Tag/SeriesTagInput.tsx b/frontend/src/Components/Form/Tag/SeriesTagInput.tsx index f72248cf5..1035c0304 100644 --- a/frontend/src/Components/Form/Tag/SeriesTagInput.tsx +++ b/frontend/src/Components/Form/Tag/SeriesTagInput.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { createSelector } from 'reselect'; import { addTag } from 'Store/Actions/tagActions'; @@ -12,10 +12,10 @@ interface SeriesTag extends TagBase { name: string; } -interface SeriesTagInputProps { +export interface SeriesTagInputProps { name: string; - value: number | number[]; - onChange: (change: InputChanged) => void; + value: number[]; + onChange: (change: InputChanged) => void; } const VALID_TAG_REGEX = new RegExp('[^-_a-z0-9]', 'i'); @@ -65,42 +65,22 @@ export default function SeriesTagInput({ onChange, }: SeriesTagInputProps) { const dispatch = useDispatch(); - const isArray = Array.isArray(value); - - const arrayValue = useMemo(() => { - if (isArray) { - return value; - } - - return value === 0 ? [] : [value]; - }, [isArray, value]); const { tags, tagList, allTags } = useSelector( - createSeriesTagsSelector(arrayValue) + createSeriesTagsSelector(value) ); const handleTagCreated = useCallback( (tag: SeriesTag) => { - if (isArray) { - onChange({ name, value: [...value, tag.id] }); - } else { - onChange({ - name, - value: tag.id, - }); - } + onChange({ name, value: [...value, tag.id] }); }, - [name, value, isArray, onChange] + [name, value, onChange] ); const handleTagAdd = useCallback( (newTag: SeriesTag) => { if (newTag.id) { - if (isArray) { - onChange({ name, value: [...value, newTag.id] }); - } else { - onChange({ name, value: newTag.id }); - } + onChange({ name, value: [...value, newTag.id] }); return; } @@ -116,21 +96,17 @@ export default function SeriesTagInput({ ); } }, - [name, value, isArray, allTags, handleTagCreated, onChange, dispatch] + [name, value, allTags, handleTagCreated, onChange, dispatch] ); const handleTagDelete = useCallback( ({ index }: { index: number }) => { - if (isArray) { - const newValue = value.slice(); - newValue.splice(index, 1); + const newValue = value.slice(); + newValue.splice(index, 1); - onChange({ name, value: newValue }); - } else { - onChange({ name, value: 0 }); - } + onChange({ name, value: newValue }); }, - [name, value, isArray, onChange] + [name, value, onChange] ); return ( diff --git a/frontend/src/Components/Form/Tag/TagInput.tsx b/frontend/src/Components/Form/Tag/TagInput.tsx index c99564073..1fb075f69 100644 --- a/frontend/src/Components/Form/Tag/TagInput.tsx +++ b/frontend/src/Components/Form/Tag/TagInput.tsx @@ -1,5 +1,4 @@ import classNames from 'classnames'; -import PropTypes from 'prop-types'; import React, { KeyboardEvent, Ref, @@ -16,9 +15,7 @@ import { SuggestionsFetchRequestedParams, } from 'react-autosuggest'; import useDebouncedCallback from 'Helpers/Hooks/useDebouncedCallback'; -import { kinds } from 'Helpers/Props'; import { Kind } from 'Helpers/Props/kinds'; -import tagShape from 'Helpers/Props/Shapes/tagShape'; import { InputChanged } from 'typings/inputs'; import AutoSuggestInput from '../AutoSuggestInput'; import TagInputInput from './TagInputInput'; @@ -337,23 +334,4 @@ function TagInput({ ); } -TagInput.propTypes = { - className: PropTypes.string, - inputContainerClassName: PropTypes.string, - tags: PropTypes.arrayOf(PropTypes.shape(tagShape)).isRequired, - tagList: PropTypes.arrayOf(PropTypes.shape(tagShape)).isRequired, - allowNew: PropTypes.bool, - kind: PropTypes.oneOf(kinds.all), - placeholder: PropTypes.string, - delimiters: PropTypes.arrayOf(PropTypes.string), - minQueryLength: PropTypes.number, - canEdit: PropTypes.bool, - hasError: PropTypes.bool, - hasWarning: PropTypes.bool, - tagComponent: PropTypes.elementType, - onTagAdd: PropTypes.func.isRequired, - onTagDelete: PropTypes.func.isRequired, - onTagReplace: PropTypes.func, -}; - export default TagInput; diff --git a/frontend/src/Components/Form/Tag/TagSelectInput.tsx b/frontend/src/Components/Form/Tag/TagSelectInput.tsx index 21fde893c..139b7ba84 100644 --- a/frontend/src/Components/Form/Tag/TagSelectInput.tsx +++ b/frontend/src/Components/Form/Tag/TagSelectInput.tsx @@ -13,7 +13,7 @@ interface TagSelectValue { order: number; } -interface TagSelectInputProps extends TagInputProps { +export interface TagSelectInputProps extends TagInputProps { name: string; value: number[]; values: TagSelectValue[]; diff --git a/frontend/src/Components/Form/Tag/TextTagInput.tsx b/frontend/src/Components/Form/Tag/TextTagInput.tsx index 6e2082c50..6d2652030 100644 --- a/frontend/src/Components/Form/Tag/TextTagInput.tsx +++ b/frontend/src/Components/Form/Tag/TextTagInput.tsx @@ -8,7 +8,11 @@ interface TextTag extends TagBase { name: string; } -interface TextTagInputProps extends TagInputProps { +export interface TextTagInputProps + extends Omit< + TagInputProps, + 'tags' | 'tagList' | 'onTagAdd' | 'onTagDelete' + > { name: string; value: string | string[]; onChange: (change: InputChanged) => unknown; diff --git a/frontend/src/Components/Form/TextArea.tsx b/frontend/src/Components/Form/TextArea.tsx index f37d5cb5f..047817eb7 100644 --- a/frontend/src/Components/Form/TextArea.tsx +++ b/frontend/src/Components/Form/TextArea.tsx @@ -9,7 +9,7 @@ import React, { import { InputChanged } from 'typings/inputs'; import styles from './TextArea.css'; -interface TextAreaProps { +export interface TextAreaProps { className?: string; readOnly?: boolean; autoFocus?: boolean; diff --git a/frontend/src/Components/Form/TextInput.tsx b/frontend/src/Components/Form/TextInput.tsx index 5728294b1..9cc2666a3 100644 --- a/frontend/src/Components/Form/TextInput.tsx +++ b/frontend/src/Components/Form/TextInput.tsx @@ -10,7 +10,7 @@ import React, { import { FileInputChanged, InputChanged } from 'typings/inputs'; import styles from './TextInput.css'; -interface CommonTextInputProps { +export interface CommonTextInputProps { className?: string; readOnly?: boolean; autoFocus?: boolean; @@ -23,7 +23,7 @@ interface CommonTextInputProps { step?: number; min?: number; max?: number; - onFocus?: (event: FocusEvent) => void; + onFocus?: (event: FocusEvent) => void; onBlur?: (event: SyntheticEvent) => void; onCopy?: (event: SyntheticEvent) => void; onSelectionChange?: (start: number | null, end: number | null) => void; @@ -102,7 +102,7 @@ function TextInput({ ); const handleFocus = useCallback( - (event: FocusEvent) => { + (event: FocusEvent) => { onFocus?.(event); selectionChanged(); diff --git a/frontend/src/Components/Table/TableOptions/TableOptionsModal.tsx b/frontend/src/Components/Table/TableOptions/TableOptionsModal.tsx index 7812371fe..1d73a5c6d 100644 --- a/frontend/src/Components/Table/TableOptions/TableOptionsModal.tsx +++ b/frontend/src/Components/Table/TableOptions/TableOptionsModal.tsx @@ -61,10 +61,10 @@ function TableOptionsModal({ dropIndex > dragIndex; const handlePageSizeChange = useCallback( - ({ value }: InputChanged) => { + ({ value }: InputChanged) => { let error: string | null = null; - if (value < 5) { + if (value === null || value < 5) { error = translate('TablePageSizeMinimum', { minimumValue: '5', }); @@ -76,7 +76,7 @@ function TableOptionsModal({ onTableOptionChange({ pageSize: value }); } - setPageSize(value); + setPageSize(value ?? 0); setPageSizeError(error); }, [maxPageSize, onTableOptionChange] diff --git a/frontend/src/InteractiveImport/Quality/SelectQualityModalContent.tsx b/frontend/src/InteractiveImport/Quality/SelectQualityModalContent.tsx index edaefdca7..369a5f285 100644 --- a/frontend/src/InteractiveImport/Quality/SelectQualityModalContent.tsx +++ b/frontend/src/InteractiveImport/Quality/SelectQualityModalContent.tsx @@ -78,8 +78,8 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) { }, [items]); const onQualityChange = useCallback( - ({ value }: { value: string }) => { - setQualityId(parseInt(value)); + ({ value }: { value: number }) => { + setQualityId(value); }, [setQualityId] ); @@ -118,7 +118,7 @@ function SelectQualityModalContent(props: SelectQualityModalContentProps) { {modalTitle} - Select Quality - {isFetching && } + {isFetching ? : null} {!isFetching && error ? ( {translate('QualitiesLoadError')} diff --git a/frontend/src/Series/Edit/EditSeriesModalContent.tsx b/frontend/src/Series/Edit/EditSeriesModalContent.tsx index 9a25c0fe5..86318c65a 100644 --- a/frontend/src/Series/Edit/EditSeriesModalContent.tsx +++ b/frontend/src/Series/Edit/EditSeriesModalContent.tsx @@ -241,6 +241,7 @@ function EditSeriesModalContent({ , ]} + includeFiles={false} onChange={handleInputChange} /> diff --git a/frontend/src/Series/Index/Select/Delete/DeleteSeriesModalContent.tsx b/frontend/src/Series/Index/Select/Delete/DeleteSeriesModalContent.tsx index 6ec8249aa..59640400e 100644 --- a/frontend/src/Series/Index/Select/Delete/DeleteSeriesModalContent.tsx +++ b/frontend/src/Series/Index/Select/Delete/DeleteSeriesModalContent.tsx @@ -137,7 +137,7 @@ function DeleteSeriesModalContent(props: DeleteSeriesModalContentProps) { ? translate('DeleteSeriesFoldersHelpText') : translate('DeleteSeriesFolderHelpText') } - kind={kinds.DANGER} + kind="danger" onChange={onDeleteFilesChange} /> diff --git a/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx b/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx index 434318334..d597061f6 100644 --- a/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx +++ b/frontend/src/Series/Index/Select/Edit/EditSeriesModalContent.tsx @@ -9,6 +9,7 @@ import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes } from 'Helpers/Props'; import MoveSeriesModal from 'Series/MoveSeries/MoveSeriesModal'; +import { InputChanged } from 'typings/inputs'; import translate from 'Utilities/String/translate'; import styles from './EditSeriesModalContent.css'; @@ -142,25 +143,25 @@ function EditSeriesModalContent(props: EditSeriesModalContentProps) { ); const onInputChange = useCallback( - ({ name, value }: { name: string; value: string }) => { + ({ name, value }: InputChanged) => { switch (name) { case 'monitored': - setMonitored(value); + setMonitored(value as string); break; case 'monitorNewItems': - setMonitorNewItems(value); + setMonitorNewItems(value as string); break; case 'qualityProfileId': - setQualityProfileId(value); + setQualityProfileId(value as string); break; case 'seriesType': - setSeriesType(value); + setSeriesType(value as string); break; case 'seasonFolder': - setSeasonFolder(value); + setSeasonFolder(value as string); break; case 'rootFolderPath': - setRootFolderPath(value); + setRootFolderPath(value as string); break; default: console.warn('EditSeriesModalContent Unknown Input'); diff --git a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx index 893e2542d..4ef2ac465 100644 --- a/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx +++ b/frontend/src/Settings/DownloadClients/DownloadClients/Manage/Edit/ManageDownloadClientsEditModalContent.tsx @@ -8,6 +8,7 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes } from 'Helpers/Props'; +import { InputChanged } from 'typings/inputs'; import translate from 'Utilities/String/translate'; import styles from './ManageDownloadClientsEditModalContent.css'; @@ -57,7 +58,7 @@ function ManageDownloadClientsEditModalContent( const [removeCompletedDownloads, setRemoveCompletedDownloads] = useState(NO_CHANGE); const [removeFailedDownloads, setRemoveFailedDownloads] = useState(NO_CHANGE); - const [priority, setPriority] = useState(null); + const [priority, setPriority] = useState(null); const save = useCallback(() => { let hasChanges = false; @@ -97,29 +98,26 @@ function ManageDownloadClientsEditModalContent( onModalClose, ]); - const onInputChange = useCallback( - ({ name, value }: { name: string; value: string }) => { - switch (name) { - case 'enable': - setEnable(value); - break; - case 'priority': - setPriority(value); - break; - case 'removeCompletedDownloads': - setRemoveCompletedDownloads(value); - break; - case 'removeFailedDownloads': - setRemoveFailedDownloads(value); - break; - default: - console.warn( - `EditDownloadClientsModalContent Unknown Input: '${name}'` - ); - } - }, - [] - ); + const onInputChange = useCallback(({ name, value }: InputChanged) => { + switch (name) { + case 'enable': + setEnable(value as string); + break; + case 'priority': + setPriority(value as number); + break; + case 'removeCompletedDownloads': + setRemoveCompletedDownloads(value as string); + break; + case 'removeFailedDownloads': + setRemoveFailedDownloads(value as string); + break; + default: + console.warn( + `EditDownloadClientsModalContent Unknown Input: '${name}'` + ); + } + }, []); const selectedCount = downloadClientIds.length; diff --git a/frontend/src/Settings/General/BackupSettings.tsx b/frontend/src/Settings/General/BackupSettings.tsx index 7dd679760..471e1432a 100644 --- a/frontend/src/Settings/General/BackupSettings.tsx +++ b/frontend/src/Settings/General/BackupSettings.tsx @@ -38,6 +38,7 @@ function BackupSettings({ type={inputTypes.PATH} name="backupFolder" helpText={translate('BackupFolderHelpText')} + includeFiles={false} onChange={onInputChange} {...backupFolder} /> diff --git a/frontend/src/Settings/General/UpdateSettings.tsx b/frontend/src/Settings/General/UpdateSettings.tsx index 9dac9c3a0..a138f4ce7 100644 --- a/frontend/src/Settings/General/UpdateSettings.tsx +++ b/frontend/src/Settings/General/UpdateSettings.tsx @@ -66,8 +66,6 @@ function UpdateSettings({ } helpLink="https://wiki.servarr.com/sonarr/settings#updates" {...branch} - // @ts-expect-error - FormInputGroup doesn't accept a values prop - // of string[] which is needed for AutoCompleteInput values={branchValues} readOnly={usingExternalUpdateMechanism} onChange={onInputChange} diff --git a/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx b/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx index 8835a9be1..31e92005d 100644 --- a/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx @@ -22,6 +22,7 @@ import { } from 'Store/Actions/settingsActions'; import selectSettings from 'Store/Selectors/selectSettings'; import ImportListExclusion from 'typings/ImportListExclusion'; +import { InputChanged } from 'typings/inputs'; import { PendingSection } from 'typings/pending'; import translate from 'Utilities/String/translate'; import styles from './EditImportListExclusionModalContent.css'; @@ -102,9 +103,9 @@ function EditImportListExclusionModalContent({ }, [dispatch, id]); const onInputChange = useCallback( - (payload: { name: string; value: string | number }) => { + (change: InputChanged) => { // @ts-expect-error 'setImportListExclusionValue' isn't typed yet - dispatch(setImportListExclusionValue(payload)); + dispatch(setImportListExclusionValue(change)); }, [dispatch] ); diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx index f95d65314..dd07b2d2e 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx @@ -8,6 +8,7 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { inputTypes } from 'Helpers/Props'; +import { InputChanged } from 'typings/inputs'; import translate from 'Utilities/String/translate'; import styles from './ManageImportListsEditModalContent.css'; @@ -90,24 +91,21 @@ function ManageImportListsEditModalContent( onModalClose, ]); - const onInputChange = useCallback( - ({ name, value }: { name: string; value: string }) => { - switch (name) { - case 'enableAutomaticAdd': - setEnableAutomaticAdd(value); - break; - case 'qualityProfileId': - setQualityProfileId(value); - break; - case 'rootFolderPath': - setRootFolderPath(value); - break; - default: - console.warn(`EditImportListModalContent Unknown Input: '${name}'`); - } - }, - [] - ); + const onInputChange = useCallback(({ name, value }: InputChanged) => { + switch (name) { + case 'enableAutomaticAdd': + setEnableAutomaticAdd(value as string); + break; + case 'qualityProfileId': + setQualityProfileId(value as number); + break; + case 'rootFolderPath': + setRootFolderPath(value as string); + break; + default: + console.warn(`EditImportListModalContent Unknown Input: '${name}'`); + } + }, []); const selectedCount = importListIds.length; diff --git a/frontend/src/Settings/ImportLists/Options/ImportListOptions.tsx b/frontend/src/Settings/ImportLists/Options/ImportListOptions.tsx index bfac93f83..0a222ce1e 100644 --- a/frontend/src/Settings/ImportLists/Options/ImportListOptions.tsx +++ b/frontend/src/Settings/ImportLists/Options/ImportListOptions.tsx @@ -107,6 +107,7 @@ function ImportListOptions({ {...listSyncLevel} /> + {listSyncLevel.value === 'keepAndTag' ? ( {translate('ListSyncTag')} (null); + const [priority, setPriority] = useState(null); const save = useCallback(() => { let hasChanges = false; @@ -97,27 +98,24 @@ function ManageIndexersEditModalContent( onModalClose, ]); - const onInputChange = useCallback( - ({ name, value }: { name: string; value: string }) => { - switch (name) { - case 'enableRss': - setEnableRss(value); - break; - case 'enableAutomaticSearch': - setEnableAutomaticSearch(value); - break; - case 'enableInteractiveSearch': - setEnableInteractiveSearch(value); - break; - case 'priority': - setPriority(value); - break; - default: - console.warn(`EditIndexersModalContent Unknown Input: '${name}'`); - } - }, - [] - ); + const onInputChange = useCallback(({ name, value }: InputChanged) => { + switch (name) { + case 'enableRss': + setEnableRss(value as string); + break; + case 'enableAutomaticSearch': + setEnableAutomaticSearch(value as string); + break; + case 'enableInteractiveSearch': + setEnableInteractiveSearch(value as string); + break; + case 'priority': + setPriority(value as number); + break; + default: + console.warn(`EditIndexersModalContent Unknown Input: '${name}'`); + } + }, []); const selectedCount = indexerIds.length; diff --git a/frontend/src/Settings/MediaManagement/MediaManagement.tsx b/frontend/src/Settings/MediaManagement/MediaManagement.tsx index 0fce5a2f0..f9396684d 100644 --- a/frontend/src/Settings/MediaManagement/MediaManagement.tsx +++ b/frontend/src/Settings/MediaManagement/MediaManagement.tsx @@ -464,6 +464,7 @@ function MediaManagement() { type={inputTypes.PATH} name="recycleBin" helpText={translate('RecyclingBinHelpText')} + includeFiles={false} onChange={handleInputChange} {...settings.recycleBin} /> @@ -537,7 +538,6 @@ function MediaManagement() { name="chownGroup" helpText={translate('ChownGroupHelpText')} helpTextWarning={translate('ChownGroupHelpTextWarning')} - values={fileDateOptions} onChange={handleInputChange} {...settings.chownGroup} /> diff --git a/frontend/src/Settings/MediaManagement/Naming/Naming.tsx b/frontend/src/Settings/MediaManagement/Naming/Naming.tsx index a245d2740..0f6e8de05 100644 --- a/frontend/src/Settings/MediaManagement/Naming/Naming.tsx +++ b/frontend/src/Settings/MediaManagement/Naming/Naming.tsx @@ -19,6 +19,7 @@ import { setNamingSettingsValue, } from 'Store/Actions/settingsActions'; import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector'; +import { InputChanged } from 'typings/inputs'; import NamingConfig from 'typings/Settings/NamingConfig'; import translate from 'Utilities/String/translate'; import NamingModal from './NamingModal'; @@ -88,9 +89,9 @@ function Naming() { }, [dispatch]); const handleInputChange = useCallback( - ({ name, value }: { name: string; value: string }) => { + (change: InputChanged) => { // @ts-expect-error 'setNamingSettingsValue' isn't typed yet - dispatch(setNamingSettingsValue({ name, value })); + dispatch(setNamingSettingsValue(change)); if (namingExampleTimeout.current) { clearTimeout(namingExampleTimeout.current); diff --git a/frontend/src/Settings/Profiles/Delay/EditDelayProfileModalContent.tsx b/frontend/src/Settings/Profiles/Delay/EditDelayProfileModalContent.tsx index 3f562d53b..98836aef5 100644 --- a/frontend/src/Settings/Profiles/Delay/EditDelayProfileModalContent.tsx +++ b/frontend/src/Settings/Profiles/Delay/EditDelayProfileModalContent.tsx @@ -21,11 +21,15 @@ import { setDelayProfileValue, } from 'Store/Actions/settingsActions'; import selectSettings from 'Store/Selectors/selectSettings'; +import DelayProfile from 'typings/DelayProfile'; import { InputChanged } from 'typings/inputs'; import translate from 'Utilities/String/translate'; import styles from './EditDelayProfileModalContent.css'; -const newDelayProfile: Record = { +const newDelayProfile: DelayProfile & { [key: string]: unknown } = { + id: 0, + name: '', + order: 0, enableUsenet: true, enableTorrent: true, preferredProtocol: 'usenet', @@ -72,7 +76,11 @@ function createDelayProfileSelector(id: number | undefined) { delayProfiles; const profile = id ? items.find((i) => i.id === id) : newDelayProfile; - const settings = selectSettings(profile!, pendingChanges, saveError); + const settings = selectSettings( + profile!, + pendingChanges, + saveError + ); return { isFetching, diff --git a/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx b/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx index 9fd5a68ba..38ed14bc5 100644 --- a/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx +++ b/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx @@ -19,6 +19,7 @@ import { setReleaseProfileValue, } from 'Store/Actions/Settings/releaseProfiles'; import selectSettings from 'Store/Selectors/selectSettings'; +import { InputChanged } from 'typings/inputs'; import ReleaseProfile from 'typings/Settings/ReleaseProfile'; import translate from 'Utilities/String/translate'; import styles from './EditReleaseProfileModalContent.css'; @@ -101,9 +102,9 @@ function EditReleaseProfileModalContent({ }, [dispatch, id]); const handleInputChange = useCallback( - (payload: { name: string; value: string | number }) => { + (change: InputChanged) => { // @ts-expect-error 'setReleaseProfileValue' isn't typed yet - dispatch(setReleaseProfileValue(payload)); + dispatch(setReleaseProfileValue(change)); }, [dispatch] ); @@ -124,7 +125,6 @@ function EditReleaseProfileModalContent({ name="name" {...name} placeholder={translate('OptionalName')} - canEdit={true} onChange={handleInputChange} />