1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-21 22:05:43 -04:00

Convert Manual Import to Typescript

This commit is contained in:
Qstick
2023-05-02 23:07:12 -05:00
parent d2112f2bdc
commit eeb997430c
130 changed files with 3314 additions and 3161 deletions
@@ -1,39 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import SelectLanguageModalContentConnector from './SelectLanguageModalContentConnector';
class SelectLanguageModal extends Component {
//
// Render
render() {
const {
isOpen,
onModalClose,
...otherProps
} = this.props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
size={sizes.MEDIUM}
>
<SelectLanguageModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
}
SelectLanguageModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default SelectLanguageModal;
@@ -0,0 +1,31 @@
import React from 'react';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import Language from 'Language/Language';
import SelectLanguageModalContent from './SelectLanguageModalContent';
interface SelectLanguageModalProps {
isOpen: boolean;
languageIds: number[];
modalTitle: string;
onLanguagesSelect(languages: Language[]): void;
onModalClose(): void;
}
function SelectLanguageModal(props: SelectLanguageModalProps) {
const { isOpen, languageIds, modalTitle, onLanguagesSelect, onModalClose } =
props;
return (
<Modal isOpen={isOpen} onModalClose={onModalClose} size={sizes.MEDIUM}>
<SelectLanguageModalContent
languageIds={languageIds}
modalTitle={modalTitle}
onLanguagesSelect={onLanguagesSelect}
onModalClose={onModalClose}
/>
</Modal>
);
}
export default SelectLanguageModal;
@@ -1,153 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './SelectLanguageModalContent.css';
class SelectLanguageModalContent extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
const {
languageIds
} = props;
this.state = {
languageIds
};
}
//
// Listeners
onLanguageChange = ({ value, name }) => {
const {
languageIds
} = this.state;
const changedId = parseInt(name);
let newLanguages = languageIds;
if (value) {
newLanguages.push(changedId);
}
if (!value) {
newLanguages = languageIds.filter((i) => i !== changedId);
}
this.setState({ languageIds: newLanguages });
};
onLanguageSelect = () => {
this.props.onLanguageSelect(this.state);
};
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
onModalClose
} = this.props;
const {
languageIds
} = this.state;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('ManualImportSelectLanguage')}
</ModalHeader>
<ModalBody>
{
isFetching &&
<LoadingIndicator />
}
{
!isFetching && !!error &&
<div>
{translate('UnableToLoadLanguages')}
</div>
}
{
isPopulated && !error &&
<Form>
{
items.map(( language ) => {
return (
<FormGroup
key={language.id}
size={sizes.EXTRA_SMALL}
className={styles.languageInput}
>
<FormLabel>{language.name}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name={language.id.toString()}
value={languageIds.includes(language.id)}
onChange={this.onLanguageChange}
/>
</FormGroup>
);
})
}
</Form>
}
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Cancel')}
</Button>
<Button
kind={kinds.SUCCESS}
onPress={this.onLanguageSelect}
>
{translate('SelectLanguages')}
</Button>
</ModalFooter>
</ModalContent>
);
}
}
SelectLanguageModalContent.propTypes = {
languageIds: PropTypes.arrayOf(PropTypes.number).isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onLanguageSelect: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
SelectLanguageModalContent.defaultProps = {
languages: []
};
export default SelectLanguageModalContent;
@@ -0,0 +1,126 @@
import React, { useCallback, useState } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import { LanguageSettingsAppState } from 'App/State/SettingsAppState';
import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds, sizes } from 'Helpers/Props';
import Language from 'Language/Language';
import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
import translate from 'Utilities/String/translate';
import styles from './SelectLanguageModalContent.css';
interface SelectLanguageModalContentProps {
languageIds: number[];
modalTitle: string;
onLanguagesSelect(languages: Language[]): void;
onModalClose(): void;
}
function createFilteredLanguagesSelector() {
return createSelector(createLanguagesSelector(), (languages) => {
const { isFetching, isPopulated, error, items } =
languages as LanguageSettingsAppState;
const filterItems = ['Any', 'Original'];
const filteredLanguages = items.filter(
(lang: Language) => !filterItems.includes(lang.name)
);
return {
isFetching,
isPopulated,
error,
items: filteredLanguages,
};
});
}
function SelectLanguageModalContent(props: SelectLanguageModalContentProps) {
const { modalTitle, onLanguagesSelect, onModalClose } = props;
const { isFetching, isPopulated, error, items } = useSelector(
createFilteredLanguagesSelector()
);
const [languageIds, setLanguageIds] = useState(props.languageIds);
const onLanguageChange = useCallback(
({ name, value }: { name: string; value: boolean }) => {
const changedId = parseInt(name);
let newLanguages = [...languageIds];
if (value) {
newLanguages.push(changedId);
} else {
newLanguages = languageIds.filter((i) => i !== changedId);
}
setLanguageIds(newLanguages);
},
[languageIds, setLanguageIds]
);
const onLanguagesSelectWrapper = useCallback(() => {
const languages = items.filter((lang) => languageIds.includes(lang.id));
onLanguagesSelect(languages);
}, [items, languageIds, onLanguagesSelect]);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{modalTitle} - {translate('SelectLanguage')}
</ModalHeader>
<ModalBody>
{isFetching ? <LoadingIndicator /> : null}
{!isFetching && error ? (
<div>{translate('UnableToLoadLanguages')}</div>
) : null}
{isPopulated && !error ? (
<Form>
{items.map((language) => {
return (
<FormGroup
key={language.id}
size={sizes.EXTRA_SMALL}
className={styles.languageInput}
>
<FormLabel>{language.name}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name={language.id.toString()}
value={languageIds.includes(language.id)}
onChange={onLanguageChange}
/>
</FormGroup>
);
})}
</Form>
) : null}
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
<Button kind={kinds.SUCCESS} onPress={onLanguagesSelectWrapper}>
{translate('SelectLanguages')}
</Button>
</ModalFooter>
</ModalContent>
);
}
export default SelectLanguageModalContent;
@@ -1,107 +0,0 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { reprocessInteractiveImportItems, updateInteractiveImportItems } from 'Store/Actions/interactiveImportActions';
import { fetchLanguages } from 'Store/Actions/settingsActions';
import SelectLanguageModalContent from './SelectLanguageModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.languages,
(languages) => {
const {
isFetching,
isPopulated,
error,
items
} = languages;
const filterItems = ['Any', 'Original'];
const filteredLanguages = items.filter((lang) => !filterItems.includes(lang.name));
return {
isFetching,
isPopulated,
error,
items: filteredLanguages
};
}
);
}
const mapDispatchToProps = {
dispatchFetchLanguages: fetchLanguages,
dispatchReprocessInteractiveImportItems: reprocessInteractiveImportItems,
dispatchUpdateInteractiveImportItems: updateInteractiveImportItems
};
class SelectLanguageModalContentConnector extends Component {
//
// Lifecycle
componentDidMount = () => {
if (!this.props.isPopulated) {
this.props.dispatchFetchLanguages();
}
};
//
// Listeners
onLanguageSelect = ({ languageIds }) => {
const {
ids,
dispatchUpdateInteractiveImportItems,
dispatchReprocessInteractiveImportItems
} = this.props;
const languages = [];
languageIds.forEach((languageId) => {
const language = _.find(this.props.items,
(item) => item.id === parseInt(languageId));
if (language !== undefined) {
languages.push(language);
}
});
dispatchUpdateInteractiveImportItems({
ids,
languages
});
dispatchReprocessInteractiveImportItems({ ids });
this.props.onModalClose(true);
};
//
// Render
render() {
return (
<SelectLanguageModalContent
{...this.props}
onLanguageSelect={this.onLanguageSelect}
/>
);
}
}
SelectLanguageModalContentConnector.propTypes = {
ids: PropTypes.arrayOf(PropTypes.number).isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
dispatchFetchLanguages: PropTypes.func.isRequired,
dispatchUpdateInteractiveImportItems: PropTypes.func.isRequired,
dispatchReprocessInteractiveImportItems: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(SelectLanguageModalContentConnector);