Fix Language Selection on Manual Import

This commit is contained in:
Qstick 2022-08-21 10:46:09 -05:00
parent 89ee7d4452
commit fa1e67a6c8
7 changed files with 166 additions and 61 deletions

View File

@ -487,7 +487,7 @@ class InteractiveImportModalContent extends Component {
<SelectLanguageModal <SelectLanguageModal
isOpen={selectModalOpen === LANGUAGE} isOpen={selectModalOpen === LANGUAGE}
ids={selectedIds} ids={selectedIds}
languageId={0} languageIds={[0]}
modalTitle={modalTitle} modalTitle={modalTitle}
onModalClose={this.onSelectModalClose} onModalClose={this.onSelectModalClose}
/> />

View File

@ -441,7 +441,7 @@ class InteractiveImportRow extends Component {
<SelectLanguageModal <SelectLanguageModal
isOpen={isSelectLanguageModalOpen} isOpen={isSelectLanguageModalOpen}
ids={[id]} ids={[id]}
languageId={languages ? languages.id : 0} languageIds={languages ? languages.map((l) => l.id) : []}
modalTitle={modalTitle} modalTitle={modalTitle}
onModalClose={this.onSelectLanguageModalClose} onModalClose={this.onSelectLanguageModalClose}
/> />

View File

@ -1,6 +1,7 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Modal from 'Components/Modal/Modal'; import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import SelectLanguageModalContentConnector from './SelectLanguageModalContentConnector'; import SelectLanguageModalContentConnector from './SelectLanguageModalContentConnector';
class SelectLanguageModal extends Component { class SelectLanguageModal extends Component {
@ -19,6 +20,7 @@ class SelectLanguageModal extends Component {
<Modal <Modal
isOpen={isOpen} isOpen={isOpen}
onModalClose={onModalClose} onModalClose={onModalClose}
size={sizes.MEDIUM}
> >
<SelectLanguageModalContentConnector <SelectLanguageModalContentConnector
{...otherProps} {...otherProps}

View File

@ -0,0 +1,4 @@
.languageInput {
display: flex;
margin-bottom: 0;
}

View File

@ -1,5 +1,5 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React from 'react'; import React, { Component } from 'react';
import Form from 'Components/Form/Form'; import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputGroup from 'Components/Form/FormInputGroup';
@ -10,73 +10,134 @@ import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent'; import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes } from 'Helpers/Props'; import { inputTypes, kinds, sizes } from 'Helpers/Props';
import styles from './SelectLanguageModalContent.css';
function SelectLanguageModalContent(props) { class SelectLanguageModalContent extends Component {
const {
languageId,
isFetching,
isPopulated,
error,
items,
modalTitle,
onModalClose,
onLanguageSelect
} = props;
const languageOptions = items.map(({ language }) => { //
return { // Lifecycle
key: language.id,
value: language.name constructor(props, context) {
super(props, context);
const {
languageIds
} = props;
this.state = {
languageIds
}; };
}); }
return ( //
<ModalContent onModalClose={onModalClose}> // Listeners
<ModalHeader>
{modalTitle} - Select Language
</ModalHeader>
<ModalBody> onLanguageChange = ({ value, name }) => {
{ const {
isFetching && languageIds
<LoadingIndicator /> } = this.state;
}
{ const changedId = parseInt(name);
!isFetching && !!error &&
<div>Unable to load languages</div>
}
{ let newLanguages = languageIds;
isPopulated && !error &&
<Form>
<FormGroup>
<FormLabel>Language</FormLabel>
<FormInputGroup if (value) {
type={inputTypes.SELECT} newLanguages.push(changedId);
name="language" }
value={languageId}
values={languageOptions}
onChange={onLanguageSelect}
/>
</FormGroup>
</Form>
}
</ModalBody>
<ModalFooter> if (!value) {
<Button onPress={onModalClose}> newLanguages = languageIds.filter((i) => i !== changedId);
Cancel }
</Button>
</ModalFooter> this.setState({ languageIds: newLanguages });
</ModalContent> };
);
onLanguageSelect = () => {
this.props.onLanguageSelect(this.state);
};
//
// Render
render() {
const {
isFetching,
isPopulated,
error,
items,
modalTitle,
onModalClose
} = this.props;
const {
languageIds
} = this.state;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{modalTitle}
</ModalHeader>
<ModalBody>
{
isFetching &&
<LoadingIndicator />
}
{
!isFetching && !!error &&
<div>
Unable To Load Languages
</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}>
Cancel
</Button>
<Button
kind={kinds.SUCCESS}
onPress={this.onLanguageSelect}
>
Select Languages
</Button>
</ModalFooter>
</ModalContent>
);
}
} }
SelectLanguageModalContent.propTypes = { SelectLanguageModalContent.propTypes = {
languageId: PropTypes.number.isRequired, languageIds: PropTypes.arrayOf(PropTypes.number).isRequired,
isFetching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object, error: PropTypes.object,
@ -86,4 +147,8 @@ SelectLanguageModalContent.propTypes = {
onModalClose: PropTypes.func.isRequired onModalClose: PropTypes.func.isRequired
}; };
SelectLanguageModalContent.defaultProps = {
languages: []
};
export default SelectLanguageModalContent; export default SelectLanguageModalContent;

View File

@ -26,7 +26,7 @@ class SelectLanguageModalContentConnector extends Component {
// //
// Listeners // Listeners
onLanguageSelect = ({ value }) => { onLanguageSelect = ({ languageIds }) => {
const { const {
ids, ids,
dispatchUpdateInteractiveImportItems, dispatchUpdateInteractiveImportItems,
@ -35,7 +35,7 @@ class SelectLanguageModalContentConnector extends Component {
const languages = []; const languages = [];
value.forEach((languageId) => { languageIds.forEach((languageId) => {
const language = _.find(this.props.items, const language = _.find(this.props.items,
(item) => item.id === parseInt(languageId)); (item) => item.id === parseInt(languageId));

View File

@ -1,6 +1,7 @@
import { createAction } from 'redux-actions'; import { createAction } from 'redux-actions';
import { filterBuilderTypes, filterBuilderValueTypes, filterTypes, sortDirections } from 'Helpers/Props'; import { filterBuilderTypes, filterBuilderValueTypes, filterTypePredicates, filterTypes, sortDirections } from 'Helpers/Props';
import { createThunk, handleThunks } from 'Store/thunks'; import { createThunk, handleThunks } from 'Store/thunks';
import sortByName from 'Utilities/Array/sortByName';
import createAjaxRequest from 'Utilities/createAjaxRequest'; import createAjaxRequest from 'Utilities/createAjaxRequest';
import createFetchHandler from './Creators/createFetchHandler'; import createFetchHandler from './Creators/createFetchHandler';
import createHandleActions from './Creators/createHandleActions'; import createHandleActions from './Creators/createHandleActions';
@ -37,6 +38,13 @@ export const defaultState = {
return seeders * 1000000 + leechers; return seeders * 1000000 + leechers;
}, },
languages: function(item, direction) {
if (item.languages.length > 1) {
return 10000;
}
return item.languages[0].id;
},
rejections: function(item, direction) { rejections: function(item, direction) {
const rejections = item.rejections; const rejections = item.rejections;
const releaseWeight = item.releaseWeight; const releaseWeight = item.releaseWeight;
@ -95,6 +103,13 @@ export const defaultState = {
return false; return false;
}, },
languages: function(item, filterValue, type) {
const predicate = filterTypePredicates[type];
const languages = item.languages.map((language) => language.name);
return predicate(languages, filterValue);
},
rejectionCount: function(item, value, type) { rejectionCount: function(item, value, type) {
const rejectionCount = item.rejections.length; const rejectionCount = item.rejections.length;
@ -197,6 +212,25 @@ export const defaultState = {
type: filterBuilderTypes.EXACT, type: filterBuilderTypes.EXACT,
valueType: filterBuilderValueTypes.QUALITY valueType: filterBuilderValueTypes.QUALITY
}, },
{
name: 'languages',
label: 'Languages',
type: filterBuilderTypes.ARRAY,
optionsSelector: function(items) {
const genreList = items.reduce((acc, release) => {
release.languages.forEach((language) => {
acc.push({
id: language.name,
name: language.name
});
});
return acc;
}, []);
return genreList.sort(sortByName);
}
},
{ {
name: 'rejectionCount', name: 'rejectionCount',
label: 'Rejection Count', label: 'Rejection Count',