Improve LanguageSelectInput

pull/7387/head
Mark McDowall 4 months ago committed by Mark McDowall
parent 202190d032
commit 936cf699ff

@ -19,6 +19,7 @@ import DownloadClientSelectInput from './Select/DownloadClientSelectInput';
import EnhancedSelectInput from './Select/EnhancedSelectInput'; import EnhancedSelectInput from './Select/EnhancedSelectInput';
import IndexerFlagsSelectInput from './Select/IndexerFlagsSelectInput'; import IndexerFlagsSelectInput from './Select/IndexerFlagsSelectInput';
import IndexerSelectInput from './Select/IndexerSelectInput'; import IndexerSelectInput from './Select/IndexerSelectInput';
import LanguageSelectInput from './Select/LanguageSelectInput';
import MonitorEpisodesSelectInput from './Select/MonitorEpisodesSelectInput'; import MonitorEpisodesSelectInput from './Select/MonitorEpisodesSelectInput';
import MonitorNewItemsSelectInput from './Select/MonitorNewItemsSelectInput'; import MonitorNewItemsSelectInput from './Select/MonitorNewItemsSelectInput';
import ProviderDataSelectInput from './Select/ProviderOptionSelectInput'; import ProviderDataSelectInput from './Select/ProviderOptionSelectInput';
@ -51,6 +52,9 @@ function getComponent(type: InputType) {
case inputTypes.KEY_VALUE_LIST: case inputTypes.KEY_VALUE_LIST:
return KeyValueListInput; return KeyValueListInput;
case inputTypes.LANGUAGE_SELECT:
return LanguageSelectInput;
case inputTypes.MONITOR_EPISODES_SELECT: case inputTypes.MONITOR_EPISODES_SELECT:
return MonitorEpisodesSelectInput; return MonitorEpisodesSelectInput;

@ -1,43 +1,95 @@
import React, { useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import { EnhancedSelectInputChanged } from 'typings/inputs'; import { useSelector } from 'react-redux';
import Language from 'Language/Language';
import createFilteredLanguagesSelector from 'Store/Selectors/createFilteredLanguagesSelector';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput, { import EnhancedSelectInput, {
EnhancedSelectInputValue, EnhancedSelectInputValue,
} from './EnhancedSelectInput'; } from './EnhancedSelectInput';
interface LanguageSelectInputOnChangeProps {
name: string;
value: number | string | Language;
}
interface LanguageSelectInputProps { interface LanguageSelectInputProps {
name: string; name: string;
value: number; value: number | string | Language;
values: EnhancedSelectInputValue<number>[]; includeNoChange: boolean;
onChange: (change: EnhancedSelectInputChanged<number>) => void; includeNoChangeDisabled?: boolean;
includeMixed: boolean;
onChange: (payload: LanguageSelectInputOnChangeProps) => void;
} }
function LanguageSelectInput({ export default function LanguageSelectInput({
values, value,
includeNoChange,
includeNoChangeDisabled,
includeMixed,
onChange, onChange,
...otherProps ...otherProps
}: LanguageSelectInputProps) { }: LanguageSelectInputProps) {
const mappedValues = useMemo(() => { const { items } = useSelector(createFilteredLanguagesSelector(true));
const minId = values.reduce(
(min: number, v) => (v.key < 1 ? v.key : min),
values[0].key
);
return values.map(({ key, value }) => { const values = useMemo(() => {
const result: EnhancedSelectInputValue<number | string>[] = items.map(
(item) => {
return { return {
key, key: item.id,
value, value: item.name,
dividerAfter: minId < 1 ? key === minId : false,
}; };
}
);
if (includeNoChange) {
result.unshift({
key: 'noChange',
value: translate('NoChange'),
isDisabled: includeNoChangeDisabled,
}); });
}, [values]); }
if (includeMixed) {
result.unshift({
key: 'mixed',
value: `(${translate('Mixed')})`,
isDisabled: true,
});
}
return result;
}, [includeNoChange, includeNoChangeDisabled, includeMixed, items]);
const selectValue =
typeof value === 'number' || typeof value === 'string' ? value : value.id;
const handleChange = useCallback(
(payload: LanguageSelectInputOnChangeProps) => {
if (typeof value === 'number') {
onChange(payload);
} else {
const language = items.find((i) => i.id === payload.value);
onChange({
...payload,
value: language
? {
id: language.id,
name: language.name,
}
: ({ id: payload.value } as Language),
});
}
},
[value, items, onChange]
);
return ( return (
<EnhancedSelectInput <EnhancedSelectInput
{...otherProps} {...otherProps}
values={mappedValues} value={selectValue}
onChange={onChange} values={values}
onChange={handleChange}
/> />
); );
} }
export default LanguageSelectInput;

@ -66,10 +66,10 @@ class UISettings extends Component {
isFetching, isFetching,
error, error,
settings, settings,
languages,
hasSettings, hasSettings,
onInputChange, onInputChange,
onSavePress, onSavePress,
languages,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -213,9 +213,8 @@ class UISettings extends Component {
<FormGroup> <FormGroup>
<FormLabel>{translate('UiLanguage')}</FormLabel> <FormLabel>{translate('UiLanguage')}</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.SELECT} type={inputTypes.LANGUAGE_SELECT}
name="uiLanguage" name="uiLanguage"
values={languages}
helpText={translate('UiLanguageHelpText')} helpText={translate('UiLanguageHelpText')}
helpTextWarning={translate('BrowserReloadRequired')} helpTextWarning={translate('BrowserReloadRequired')}
onChange={onInputChange} onChange={onInputChange}
@ -244,8 +243,8 @@ UISettings.propTypes = {
isFetching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired,
error: PropTypes.object, error: PropTypes.object,
settings: PropTypes.object.isRequired, settings: PropTypes.object.isRequired,
hasSettings: PropTypes.bool.isRequired,
languages: PropTypes.arrayOf(PropTypes.object).isRequired, languages: PropTypes.arrayOf(PropTypes.object).isRequired,
hasSettings: PropTypes.bool.isRequired,
onSavePress: PropTypes.func.isRequired, onSavePress: PropTypes.func.isRequired,
onInputChange: PropTypes.func.isRequired onInputChange: PropTypes.func.isRequired
}; };

@ -0,0 +1,28 @@
import { createSelector } from 'reselect';
import { LanguageSettingsAppState } from 'App/State/SettingsAppState';
import Language from 'Language/Language';
import createLanguagesSelector from './createLanguagesSelector';
export default function createFilteredLanguagesSelector(filterUnknown = false) {
const filterItems = ['Any', 'Original'];
if (filterUnknown) {
filterItems.push('Unknown');
}
return createSelector(createLanguagesSelector(), (languages) => {
const { isFetching, isPopulated, error, items } =
languages as LanguageSettingsAppState;
const filteredLanguages = items.filter(
(lang: Language) => !filterItems.includes(lang.name)
);
return {
isFetching,
isPopulated,
error,
items: filteredLanguages,
};
});
}
Loading…
Cancel
Save