[UI Work] Add Artist, Import Artist, Calendar

This commit is contained in:
Qstick 2017-09-07 23:09:52 -04:00
parent a747c5f135
commit 77f1d2e64c
109 changed files with 891 additions and 1082 deletions

View file

@ -8,10 +8,10 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import TextInput from 'Components/Form/TextInput';
import PageContent from 'Components/Page/PageContent';
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
import AddNewSeriesSearchResultConnector from './AddNewSeriesSearchResultConnector';
import styles from './AddNewSeries.css';
import AddNewArtistSearchResultConnector from './AddNewArtistSearchResultConnector';
import styles from './AddNewArtist.css';
class AddNewSeries extends Component {
class AddNewArtist extends Component {
//
// Lifecycle
@ -29,7 +29,7 @@ class AddNewSeries extends Component {
const term = this.state.term;
if (term) {
this.props.onSeriesLookupChange(term);
this.props.onArtistLookupChange(term);
}
}
@ -44,7 +44,7 @@ class AddNewSeries extends Component {
term,
isFetching: true
});
this.props.onSeriesLookupChange(term);
this.props.onArtistLookupChange(term);
} else if (isFetching !== prevProps.isFetching) {
this.setState({
isFetching
@ -60,16 +60,16 @@ class AddNewSeries extends Component {
this.setState({ term: value, isFetching: hasValue }, () => {
if (hasValue) {
this.props.onSeriesLookupChange(value);
this.props.onArtistLookupChange(value);
} else {
this.props.onClearSeriesLookup();
this.props.onClearArtistLookup();
}
});
}
onClearSeriesLookupPress = () => {
onClearArtistLookupPress = () => {
this.setState({ term: '' });
this.props.onClearSeriesLookup();
this.props.onClearArtistLookup();
}
//
@ -97,7 +97,7 @@ class AddNewSeries extends Component {
<TextInput
className={styles.searchInput}
name="seriesLookup"
name="artistLookup"
value={term}
placeholder="eg. Breaking Benjamin, lidarr:####"
onChange={this.onSearchInputChange}
@ -105,7 +105,7 @@ class AddNewSeries extends Component {
<Button
className={styles.clearLookupButton}
onPress={this.onClearSeriesLookupPress}
onPress={this.onClearArtistLookupPress}
>
<Icon
name={icons.REMOVE}
@ -130,7 +130,7 @@ class AddNewSeries extends Component {
{
items.map((item) => {
return (
<AddNewSeriesSearchResultConnector
<AddNewArtistSearchResultConnector
key={item.foreignArtistId}
{...item}
/>
@ -157,7 +157,7 @@ class AddNewSeries extends Component {
!term &&
<div className={styles.message}>
<div className={styles.helpText}>It's easy to add a new artist, just start typing the name the artist you want to add.</div>
<div>You can also search using MusicBrainz ID of a show. eg. lidarr:71663</div>
<div>You can also search using MusicBrainz ID of a show. eg. lidarr:cc197bad-dc9c-440d-a5b5-d52ba2e14234</div>
</div>
}
@ -170,15 +170,15 @@ class AddNewSeries extends Component {
}
}
AddNewSeries.propTypes = {
AddNewArtist.propTypes = {
term: PropTypes.string,
isFetching: PropTypes.bool.isRequired,
error: PropTypes.object,
isAdding: PropTypes.bool.isRequired,
addError: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onSeriesLookupChange: PropTypes.func.isRequired,
onClearSeriesLookup: PropTypes.func.isRequired
onArtistLookupChange: PropTypes.func.isRequired,
onClearArtistLookup: PropTypes.func.isRequired
};
export default AddNewSeries;
export default AddNewArtist;

View file

@ -3,32 +3,32 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import queryString from 'query-string';
import { lookupSeries, clearAddSeries } from 'Store/Actions/addSeriesActions';
import { lookupArtist, clearAddArtist } from 'Store/Actions/addArtistActions';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import AddNewSeries from './AddNewSeries';
import AddNewArtist from './AddNewArtist';
function createMapStateToProps() {
return createSelector(
(state) => state.addSeries,
(state) => state.addArtist,
(state) => state.routing.location,
(addSeries, location) => {
(addArtist, location) => {
const query = queryString.parse(location.search);
return {
term: query.term,
...addSeries
...addArtist
};
}
);
}
const mapDispatchToProps = {
lookupSeries,
clearAddSeries,
lookupArtist,
clearAddArtist,
fetchRootFolders
};
class AddNewSeriesConnector extends Component {
class AddNewArtistConnector extends Component {
//
// Lifecycle
@ -36,7 +36,7 @@ class AddNewSeriesConnector extends Component {
constructor(props, context) {
super(props, context);
this._seriesLookupTimeout = null;
this._artistLookupTimeout = null;
}
componentDidMount() {
@ -44,32 +44,32 @@ class AddNewSeriesConnector extends Component {
}
componentWillUnmount() {
if (this._seriesLookupTimeout) {
clearTimeout(this._seriesLookupTimeout);
if (this._artistLookupTimeout) {
clearTimeout(this._artistLookupTimeout);
}
this.props.clearAddSeries();
this.props.clearAddArtist();
}
//
// Listeners
onSeriesLookupChange = (term) => {
if (this._seriesLookupTimeout) {
clearTimeout(this._seriesLookupTimeout);
onArtistLookupChange = (term) => {
if (this._artistLookupTimeout) {
clearTimeout(this._artistLookupTimeout);
}
if (term.trim() === '') {
this.props.clearAddSeries();
this.props.clearAddArtist();
} else {
this._seriesLookupTimeout = setTimeout(() => {
this.props.lookupSeries({ term });
this._artistLookupTimeout = setTimeout(() => {
this.props.lookupArtist({ term });
}, 300);
}
}
onClearSeriesLookup = () => {
this.props.clearAddSeries();
onClearArtistLookup = () => {
this.props.clearAddArtist();
}
//
@ -82,21 +82,21 @@ class AddNewSeriesConnector extends Component {
} = this.props;
return (
<AddNewSeries
<AddNewArtist
term={term}
{...otherProps}
onSeriesLookupChange={this.onSeriesLookupChange}
onClearSeriesLookup={this.onClearSeriesLookup}
onArtistLookupChange={this.onArtistLookupChange}
onClearArtistLookup={this.onClearArtistLookup}
/>
);
}
}
AddNewSeriesConnector.propTypes = {
AddNewArtistConnector.propTypes = {
term: PropTypes.string,
lookupSeries: PropTypes.func.isRequired,
clearAddSeries: PropTypes.func.isRequired,
lookupArtist: PropTypes.func.isRequired,
clearAddArtist: PropTypes.func.isRequired,
fetchRootFolders: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AddNewSeriesConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(AddNewArtistConnector);

View file

@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import AddNewSeriesModalContentConnector from './AddNewSeriesModalContentConnector';
import AddNewArtistModalContentConnector from './AddNewArtistModalContentConnector';
function AddNewSeriesModal(props) {
function AddNewArtistModal(props) {
const {
isOpen,
onModalClose,
@ -15,7 +15,7 @@ function AddNewSeriesModal(props) {
isOpen={isOpen}
onModalClose={onModalClose}
>
<AddNewSeriesModalContentConnector
<AddNewArtistModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
@ -23,9 +23,9 @@ function AddNewSeriesModal(props) {
);
}
AddNewSeriesModal.propTypes = {
AddNewArtistModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default AddNewSeriesModal;
export default AddNewArtistModal;

View file

@ -25,23 +25,23 @@
margin-left: 8px;
}
.searchForMissingEpisodesLabelContainer {
.searchForMissingAlbumsLabelContainer {
display: flex;
margin-top: 2px;
}
.searchForMissingEpisodesLabel {
.searchForMissingAlbumsLabel {
margin-right: 8px;
font-weight: normal;
}
.searchForMissingEpisodesContainer {
.searchForMissingAlbumsContainer {
composes: container from 'Components/Form/CheckInput.css';
flex: 0 1 0;
}
.searchForMissingEpisodesInput {
.searchForMissingAlbumsInput {
composes: input from 'Components/Form/CheckInput.css';
margin-top: 0;

View file

@ -14,11 +14,11 @@ import ModalBody from 'Components/Modal/ModalBody';
import ModalFooter from 'Components/Modal/ModalFooter';
import Popover from 'Components/Tooltip/Popover';
import ArtistPoster from 'Artist/ArtistPoster';
import SeriesMonitoringOptionsPopoverContent from 'AddArtist/SeriesMonitoringOptionsPopoverContent';
import SeriesTypePopoverContent from 'AddArtist/SeriesTypePopoverContent';
import styles from './AddNewSeriesModalContent.css';
import ArtistMonitoringOptionsPopoverContent from 'AddArtist/ArtistMonitoringOptionsPopoverContent';
// import SeriesTypePopoverContent from 'AddArtist/SeriesTypePopoverContent';
import styles from './AddNewArtistModalContent.css';
class AddNewSeriesModalContent extends Component {
class AddNewArtistModalContent extends Component {
//
// Lifecycle
@ -27,15 +27,15 @@ class AddNewSeriesModalContent extends Component {
super(props, context);
this.state = {
searchForMissingEpisodes: false
searchForMissingAlbums: false
};
}
//
// Listeners
onSearchForMissingEpisodesChange = ({ value }) => {
this.setState({ searchForMissingEpisodes: value });
onSearchForMissingAlbumsChange = ({ value }) => {
this.setState({ searchForMissingAlbums: value });
}
onQualityProfileIdChange = ({ value }) => {
@ -46,8 +46,8 @@ class AddNewSeriesModalContent extends Component {
this.props.onInputChange({ name: 'languageProfileId', value: parseInt(value) });
}
onAddSeriesPress = () => {
this.props.onAddSeriesPress(this.state.searchForMissingEpisodes);
onAddArtistPress = () => {
this.props.onAddArtistPress(this.state.searchForMissingAlbums);
}
//
@ -56,7 +56,7 @@ class AddNewSeriesModalContent extends Component {
render() {
const {
artistName,
year,
// year,
overview,
images,
isAdding,
@ -64,7 +64,7 @@ class AddNewSeriesModalContent extends Component {
monitor,
qualityProfileId,
languageProfileId,
seriesType,
// seriesType,
albumFolder,
tags,
showLanguageProfile,
@ -77,11 +77,6 @@ class AddNewSeriesModalContent extends Component {
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{artistName}
{
!name.contains(year) &&
<span className={styles.year}>({year})</span>
}
</ModalHeader>
<ModalBody>
@ -126,13 +121,13 @@ class AddNewSeriesModalContent extends Component {
/>
}
title="Monitoring Options"
body={<SeriesMonitoringOptionsPopoverContent />}
body={<ArtistMonitoringOptionsPopoverContent />}
position={tooltipPositions.RIGHT}
/>
</FormLabel>
<FormInputGroup
type={inputTypes.MONITOR_EPISODES_SELECT}
type={inputTypes.MONITOR_ALBUMS_SELECT}
name="monitor"
onChange={onInputChange}
{...monitor}
@ -161,31 +156,6 @@ class AddNewSeriesModalContent extends Component {
/>
</FormGroup>
<FormGroup>
<FormLabel>
Series Type
<Popover
anchor={
<Icon
className={styles.labelIcon}
name={icons.INFO}
/>
}
title="Series Types"
body={<SeriesTypePopoverContent />}
position={tooltipPositions.RIGHT}
/>
</FormLabel>
<FormInputGroup
type={inputTypes.SERIES_TYPE_SELECT}
name="seriesType"
onChange={onInputChange}
{...seriesType}
/>
</FormGroup>
<FormGroup>
<FormLabel>Album Folder</FormLabel>
@ -213,17 +183,17 @@ class AddNewSeriesModalContent extends Component {
</ModalBody>
<ModalFooter className={styles.modalFooter}>
<label className={styles.searchForMissingEpisodesLabelContainer}>
<span className={styles.searchForMissingEpisodesLabel}>
Start search for missing episodes
<label className={styles.searchForMissingAlbumsLabelContainer}>
<span className={styles.searchForMissingAlbumsLabel}>
Start search for missing albums
</span>
<CheckInput
containerClassName={styles.searchForMissingEpisodesContainer}
className={styles.searchForMissingEpisodesInput}
name="searchForMissingEpisodes"
value={this.state.searchForMissingEpisodes}
onChange={this.onSearchForMissingEpisodesChange}
containerClassName={styles.searchForMissingAlbumsContainer}
className={styles.searchForMissingAlbumsInput}
name="searchForMissingAlbums"
value={this.state.searchForMissingAlbums}
onChange={this.onSearchForMissingAlbumsChange}
/>
</label>
@ -231,7 +201,7 @@ class AddNewSeriesModalContent extends Component {
className={styles.addButton}
kind={kinds.SUCCESS}
isSpinning={isAdding}
onPress={this.onAddSeriesPress}
onPress={this.onAddArtistPress}
>
Add {artistName}
</SpinnerButton>
@ -241,9 +211,9 @@ class AddNewSeriesModalContent extends Component {
}
}
AddNewSeriesModalContent.propTypes = {
AddNewArtistModalContent.propTypes = {
artistName: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
// year: PropTypes.number.isRequired,
overview: PropTypes.string,
images: PropTypes.arrayOf(PropTypes.object).isRequired,
isAdding: PropTypes.bool.isRequired,
@ -252,14 +222,14 @@ AddNewSeriesModalContent.propTypes = {
monitor: PropTypes.object.isRequired,
qualityProfileId: PropTypes.object,
languageProfileId: PropTypes.object,
seriesType: PropTypes.object.isRequired,
// seriesType: PropTypes.object.isRequired,
albumFolder: PropTypes.object.isRequired,
tags: PropTypes.object.isRequired,
showLanguageProfile: PropTypes.bool.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired,
onInputChange: PropTypes.func.isRequired,
onAddSeriesPress: PropTypes.func.isRequired
onAddArtistPress: PropTypes.func.isRequired
};
export default AddNewSeriesModalContent;
export default AddNewArtistModalContent;

View file

@ -2,22 +2,22 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { setAddSeriesDefault, addSeries } from 'Store/Actions/addSeriesActions';
import { setAddArtistDefault, addArtist } from 'Store/Actions/addArtistActions';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import selectSettings from 'Store/Selectors/selectSettings';
import AddNewSeriesModalContent from './AddNewSeriesModalContent';
import AddNewArtistModalContent from './AddNewArtistModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.addSeries,
(state) => state.addArtist,
(state) => state.settings.languageProfiles,
createDimensionsSelector(),
(addSeriesState, languageProfiles, dimensions) => {
(addArtistState, languageProfiles, dimensions) => {
const {
isAdding,
addError,
defaults
} = addSeriesState;
} = addArtistState;
const {
settings,
@ -39,20 +39,20 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
setAddSeriesDefault,
addSeries
setAddArtistDefault,
addArtist
};
class AddNewSeriesModalContentConnector extends Component {
class AddNewArtistModalContentConnector extends Component {
//
// Listeners
onInputChange = ({ name, value }) => {
this.props.setAddSeriesDefault({ [name]: value });
this.props.setAddArtistDefault({ [name]: value });
}
onAddSeriesPress = (searchForMissingEpisodes) => {
onAddArtistPress = (searchForMissingAlbums) => {
const {
foreignArtistId,
rootFolderPath,
@ -63,7 +63,7 @@ class AddNewSeriesModalContentConnector extends Component {
tags
} = this.props;
this.props.addSeries({
this.props.addArtist({
foreignArtistId,
rootFolderPath: rootFolderPath.value,
monitor: monitor.value,
@ -71,7 +71,7 @@ class AddNewSeriesModalContentConnector extends Component {
languageProfileId: languageProfileId.value,
albumFolder: albumFolder.value,
tags: tags.value,
searchForMissingEpisodes
searchForMissingAlbums
});
}
@ -80,16 +80,16 @@ class AddNewSeriesModalContentConnector extends Component {
render() {
return (
<AddNewSeriesModalContent
<AddNewArtistModalContent
{...this.props}
onInputChange={this.onInputChange}
onAddSeriesPress={this.onAddSeriesPress}
onAddArtistPress={this.onAddArtistPress}
/>
);
}
}
AddNewSeriesModalContentConnector.propTypes = {
AddNewArtistModalContentConnector.propTypes = {
foreignArtistId: PropTypes.string.isRequired,
rootFolderPath: PropTypes.object,
monitor: PropTypes.object.isRequired,
@ -98,8 +98,8 @@ AddNewSeriesModalContentConnector.propTypes = {
albumFolder: PropTypes.object.isRequired,
tags: PropTypes.object.isRequired,
onModalClose: PropTypes.func.isRequired,
setAddSeriesDefault: PropTypes.func.isRequired,
addSeries: PropTypes.func.isRequired
setAddArtistDefault: PropTypes.func.isRequired,
addArtist: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AddNewSeriesModalContentConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(AddNewArtistModalContentConnector);

View file

@ -6,10 +6,10 @@ import Icon from 'Components/Icon';
import Label from 'Components/Label';
import Link from 'Components/Link/Link';
import ArtistPoster from 'Artist/ArtistPoster';
import AddNewSeriesModal from './AddNewSeriesModal';
import styles from './AddNewSeriesSearchResult.css';
import AddNewArtistModal from './AddNewArtistModal';
import styles from './AddNewArtistSearchResult.css';
class AddNewSeriesSearchResult extends Component {
class AddNewArtistSearchResult extends Component {
//
// Lifecycle
@ -23,7 +23,7 @@ class AddNewSeriesSearchResult extends Component {
}
componentDidUpdate(prevProps) {
if (!prevProps.isExistingSeries && this.props.isExistingSeries) {
if (!prevProps.isExistingArtist && this.props.isExistingArtist) {
this.onAddSerisModalClose();
}
}
@ -54,11 +54,11 @@ class AddNewSeriesSearchResult extends Component {
seasonCount,
ratings,
images,
isExistingSeries,
isExistingArtist,
isSmallScreen
} = this.props;
const linkProps = isExistingSeries ? { to: `/series/${nameSlug}` } : { onPress: this.onPress };
const linkProps = isExistingArtist ? { to: `/series/${nameSlug}` } : { onPress: this.onPress };
let seasons = '1 Season';
if (seasonCount > 1) {
@ -89,12 +89,12 @@ class AddNewSeriesSearchResult extends Component {
}
{
isExistingSeries &&
isExistingArtist &&
<Icon
className={styles.alreadyExistsIcon}
name={icons.CHECK_CIRCLE}
size={36}
artistName="Already in your library"
title="Already in your library"
/>
}
</div>
@ -137,8 +137,8 @@ class AddNewSeriesSearchResult extends Component {
</div>
</div>
<AddNewSeriesModal
isOpen={this.state.isNewAddSeriesModalOpen && !isExistingSeries}
<AddNewArtistModal
isOpen={this.state.isNewAddSeriesModalOpen && !isExistingArtist}
foreignArtistId={foreignArtistId}
artistName={artistName}
year={year}
@ -151,7 +151,7 @@ class AddNewSeriesSearchResult extends Component {
}
}
AddNewSeriesSearchResult.propTypes = {
AddNewArtistSearchResult.propTypes = {
foreignArtistId: PropTypes.string.isRequired,
artistName: PropTypes.string.isRequired,
nameSlug: PropTypes.string.isRequired,
@ -162,8 +162,8 @@ AddNewSeriesSearchResult.propTypes = {
seasonCount: PropTypes.number,
ratings: PropTypes.object.isRequired,
images: PropTypes.arrayOf(PropTypes.object).isRequired,
isExistingSeries: PropTypes.bool.isRequired,
isExistingArtist: PropTypes.bool.isRequired,
isSmallScreen: PropTypes.bool.isRequired
};
export default AddNewSeriesSearchResult;
export default AddNewArtistSearchResult;

View file

@ -1,20 +1,20 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createExistingSeriesSelector from 'Store/Selectors/createExistingSeriesSelector';
import createExistingArtistSelector from 'Store/Selectors/createExistingArtistSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import AddNewSeriesSearchResult from './AddNewSeriesSearchResult';
import AddNewArtistSearchResult from './AddNewArtistSearchResult';
function createMapStateToProps() {
return createSelector(
createExistingSeriesSelector(),
createExistingArtistSelector(),
createDimensionsSelector(),
(isExistingSeries, dimensions) => {
(isExistingArtist, dimensions) => {
return {
isExistingSeries,
isExistingArtist,
isSmallScreen: dimensions.isSmallScreen
};
}
);
}
export default connect(createMapStateToProps)(AddNewSeriesSearchResult);
export default connect(createMapStateToProps)(AddNewArtistSearchResult);

View file

@ -0,0 +1,46 @@
import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
function ArtistMonitoringOptionsPopoverContent() {
return (
<DescriptionList>
<DescriptionListItem
title="All Albums"
data="Monitor all albums except specials"
/>
<DescriptionListItem
title="Future Albums"
data="Monitor albums that have not released yet"
/>
<DescriptionListItem
title="Missing Albums"
data="Monitor albums that do not have files or have not released yet"
/>
<DescriptionListItem
title="Existing Albums"
data="Monitor albums that have files or have not released yet"
/>
<DescriptionListItem
title="First Album"
data="Monitor the first albums. All other albums will be ignored"
/>
<DescriptionListItem
title="Latest Album"
data="Monitor the latest albums and future albums"
/>
<DescriptionListItem
title="None"
data="No albums will be monitored."
/>
</DescriptionList>
);
}
export default ArtistMonitoringOptionsPopoverContent;

View file

@ -6,10 +6,10 @@ import toggleSelected from 'Utilities/Table/toggleSelected';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import PageContent from 'Components/Page/PageContent';
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
import ImportSeriesTableConnector from './ImportSeriesTableConnector';
import ImportSeriesFooterConnector from './ImportSeriesFooterConnector';
import ImportArtistTableConnector from './ImportArtistTableConnector';
import ImportArtistFooterConnector from './ImportArtistFooterConnector';
class ImportSeries extends Component {
class ImportArtist extends Component {
//
// Lifecycle
@ -98,7 +98,7 @@ class ImportSeries extends Component {
} = this.state;
return (
<PageContent title="Import Series">
<PageContent title="Import Artist">
<PageContentBodyConnector
ref={this.setContentBodyRef}
onScroll={this.onScroll}
@ -122,7 +122,7 @@ class ImportSeries extends Component {
{
!rootFoldersError && rootFoldersPopulated && !!unmappedFolders.length && contentBody &&
<ImportSeriesTableConnector
<ImportArtistTableConnector
rootFolderId={rootFolderId}
unmappedFolders={unmappedFolders}
allSelected={allSelected}
@ -141,7 +141,7 @@ class ImportSeries extends Component {
{
!rootFoldersError && rootFoldersPopulated && !!unmappedFolders.length &&
<ImportSeriesFooterConnector
<ImportArtistFooterConnector
selectedIds={this.getSelectedIds()}
showLanguageProfile={showLanguageProfile}
onInputChange={this.onInputChange}
@ -153,7 +153,7 @@ class ImportSeries extends Component {
}
}
ImportSeries.propTypes = {
ImportArtist.propTypes = {
rootFolderId: PropTypes.number.isRequired,
path: PropTypes.string,
rootFoldersFetching: PropTypes.bool.isRequired,
@ -166,8 +166,8 @@ ImportSeries.propTypes = {
onImportPress: PropTypes.func.isRequired
};
ImportSeries.defaultProps = {
ImportArtist.defaultProps = {
unmappedFolders: []
};
export default ImportSeries;
export default ImportArtist;

View file

@ -3,20 +3,20 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { setImportSeriesValue, importSeries, clearImportSeries } from 'Store/Actions/importSeriesActions';
import { setImportArtistValue, importArtist, clearImportArtist } from 'Store/Actions/importArtistActions';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import { setAddSeriesDefault } from 'Store/Actions/addSeriesActions';
import { setAddArtistDefault } from 'Store/Actions/addArtistActions';
import createRouteMatchShape from 'Helpers/Props/Shapes/createRouteMatchShape';
import ImportSeries from './ImportSeries';
import ImportArtist from './ImportArtist';
function createMapStateToProps() {
return createSelector(
(state, { match }) => match,
(state) => state.rootFolders,
(state) => state.addSeries,
(state) => state.importSeries,
(state) => state.addArtist,
(state) => state.importArtist,
(state) => state.settings.languageProfiles,
(match, rootFolders, addSeries, importSeriesState, languageProfiles) => {
(match, rootFolders, addArtist, importArtistState, languageProfiles) => {
const {
isFetching: rootFoldersFetching,
isPopulated: rootFoldersPopulated,
@ -40,7 +40,7 @@ function createMapStateToProps() {
return {
...result,
...rootFolder,
items: importSeriesState.items
items: importArtistState.items
};
}
@ -50,14 +50,14 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
setImportSeriesValue,
importSeries,
clearImportSeries,
setImportArtistValue,
importArtist,
clearImportArtist,
fetchRootFolders,
setAddSeriesDefault
setAddArtistDefault
};
class ImportSeriesConnector extends Component {
class ImportArtistConnector extends Component {
//
// Lifecycle
@ -69,17 +69,17 @@ class ImportSeriesConnector extends Component {
}
componentWillUnmount() {
this.props.clearImportSeries();
this.props.clearImportArtist();
}
//
// Listeners
onInputChange = (ids, name, value) => {
this.props.setAddSeriesDefault({ [name]: value });
this.props.setAddArtistDefault({ [name]: value });
ids.forEach((id) => {
this.props.setImportSeriesValue({
this.props.setImportArtistValue({
id,
[name]: value
});
@ -87,7 +87,7 @@ class ImportSeriesConnector extends Component {
}
onImportPress = (ids) => {
this.props.importSeries({ ids });
this.props.importArtist({ ids });
}
//
@ -95,7 +95,7 @@ class ImportSeriesConnector extends Component {
render() {
return (
<ImportSeries
<ImportArtist
{...this.props}
onInputChange={this.onInputChange}
onImportPress={this.onImportPress}
@ -108,14 +108,14 @@ const routeMatchShape = createRouteMatchShape({
rootFolderId: PropTypes.string.isRequired
});
ImportSeriesConnector.propTypes = {
ImportArtistConnector.propTypes = {
match: routeMatchShape.isRequired,
rootFoldersPopulated: PropTypes.bool.isRequired,
setImportSeriesValue: PropTypes.func.isRequired,
importSeries: PropTypes.func.isRequired,
clearImportSeries: PropTypes.func.isRequired,
setImportArtistValue: PropTypes.func.isRequired,
importArtist: PropTypes.func.isRequired,
clearImportArtist: PropTypes.func.isRequired,
fetchRootFolders: PropTypes.func.isRequired,
setAddSeriesDefault: PropTypes.func.isRequired
setAddArtistDefault: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(ImportArtistConnector);

View file

@ -7,11 +7,11 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import CheckInput from 'Components/Form/CheckInput';
import FormInputGroup from 'Components/Form/FormInputGroup';
import PageContentFooter from 'Components/Page/PageContentFooter';
import styles from './ImportSeriesFooter.css';
import styles from './ImportArtistFooter.css';
const MIXED = 'mixed';
class ImportSeriesFooter extends Component {
class ImportArtistFooter extends Component {
//
// Lifecycle
@ -23,7 +23,7 @@ class ImportSeriesFooter extends Component {
defaultMonitor,
defaultQualityProfileId,
defaultLanguageProfileId,
defaultSeasonFolder,
defaultAlbumFolder,
defaultSeriesType
} = props;
@ -32,7 +32,7 @@ class ImportSeriesFooter extends Component {
qualityProfileId: defaultQualityProfileId,
languageProfileId: defaultLanguageProfileId,
seriesType: defaultSeriesType,
seasonFolder: defaultSeasonFolder
albumFolder: defaultAlbumFolder
};
}
@ -41,21 +41,21 @@ class ImportSeriesFooter extends Component {
defaultMonitor,
defaultQualityProfileId,
defaultLanguageProfileId,
defaultSeriesType,
defaultSeasonFolder,
// defaultSeriesType,
defaultAlbumFolder,
isMonitorMixed,
isQualityProfileIdMixed,
isLanguageProfileIdMixed,
isSeriesTypeMixed,
isSeasonFolderMixed
// isSeriesTypeMixed,
isAlbumFolderMixed
} = this.props;
const {
monitor,
qualityProfileId,
languageProfileId,
seriesType,
seasonFolder
// seriesType,
albumFolder
} = this.state;
const newState = {};
@ -78,16 +78,10 @@ class ImportSeriesFooter extends Component {
newState.languageProfileId = defaultLanguageProfileId;
}
if (isSeriesTypeMixed && seriesType !== MIXED) {
newState.seriesType = MIXED;
} else if (!isSeriesTypeMixed && seriesType !== defaultSeriesType) {
newState.seriesType = defaultSeriesType;
}
if (isSeasonFolderMixed && seasonFolder != null) {
newState.seasonFolder = null;
} else if (!isSeasonFolderMixed && seasonFolder !== defaultSeasonFolder) {
newState.seasonFolder = defaultSeasonFolder;
if (isAlbumFolderMixed && albumFolder != null) {
newState.albumFolder = null;
} else if (!isAlbumFolderMixed && albumFolder !== defaultAlbumFolder) {
newState.albumFolder = defaultAlbumFolder;
}
if (!_.isEmpty(newState)) {
@ -110,11 +104,11 @@ class ImportSeriesFooter extends Component {
const {
selectedCount,
isImporting,
isLookingUpSeries,
isLookingUpArtist,
isMonitorMixed,
isQualityProfileIdMixed,
isLanguageProfileIdMixed,
isSeriesTypeMixed,
// isSeriesTypeMixed,
showLanguageProfile,
onImportPress
} = this.props;
@ -123,8 +117,8 @@ class ImportSeriesFooter extends Component {
monitor,
qualityProfileId,
languageProfileId,
seriesType,
seasonFolder
// seriesType,
albumFolder
} = this.state;
return (
@ -135,7 +129,7 @@ class ImportSeriesFooter extends Component {
</div>
<FormInputGroup
type={inputTypes.MONITOR_EPISODES_SELECT}
type={inputTypes.MONITOR_ALBUMS_SELECT}
name="monitor"
value={monitor}
isDisabled={!selectedCount}
@ -180,27 +174,12 @@ class ImportSeriesFooter extends Component {
<div className={styles.inputContainer}>
<div className={styles.label}>
Series Type
</div>
<FormInputGroup
type={inputTypes.SERIES_TYPE_SELECT}
name="seriesType"
value={seriesType}
isDisabled={!selectedCount}
includeMixed={isSeriesTypeMixed}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<div className={styles.label}>
Season Folder
Album Folder
</div>
<CheckInput
name="seasonFolder"
value={seasonFolder}
name="albumFolder"
value={albumFolder}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
@ -216,14 +195,14 @@ class ImportSeriesFooter extends Component {
className={styles.importButton}
kind={kinds.PRIMARY}
isSpinning={isImporting}
isDisabled={!selectedCount || isLookingUpSeries}
isDisabled={!selectedCount || isLookingUpArtist}
onPress={onImportPress}
>
Import {selectedCount} Series
Import {selectedCount} Artist(s)
</SpinnerButton>
{
isLookingUpSeries &&
isLookingUpArtist &&
<LoadingIndicator
className={styles.loading}
size={24}
@ -231,7 +210,7 @@ class ImportSeriesFooter extends Component {
}
{
isLookingUpSeries &&
isLookingUpArtist &&
'Processing Folders'
}
</div>
@ -241,23 +220,23 @@ class ImportSeriesFooter extends Component {
}
}
ImportSeriesFooter.propTypes = {
ImportArtistFooter.propTypes = {
selectedCount: PropTypes.number.isRequired,
isImporting: PropTypes.bool.isRequired,
isLookingUpSeries: PropTypes.bool.isRequired,
isLookingUpArtist: PropTypes.bool.isRequired,
defaultMonitor: PropTypes.string.isRequired,
defaultQualityProfileId: PropTypes.number,
defaultLanguageProfileId: PropTypes.number,
defaultSeriesType: PropTypes.string.isRequired,
defaultSeasonFolder: PropTypes.bool.isRequired,
defaultAlbumFolder: PropTypes.bool.isRequired,
isMonitorMixed: PropTypes.bool.isRequired,
isQualityProfileIdMixed: PropTypes.bool.isRequired,
isLanguageProfileIdMixed: PropTypes.bool.isRequired,
isSeriesTypeMixed: PropTypes.bool.isRequired,
isSeasonFolderMixed: PropTypes.bool.isRequired,
// isSeriesTypeMixed: PropTypes.bool.isRequired,
isAlbumFolderMixed: PropTypes.bool.isRequired,
showLanguageProfile: PropTypes.bool.isRequired,
onInputChange: PropTypes.func.isRequired,
onImportPress: PropTypes.func.isRequired
};
export default ImportSeriesFooter;
export default ImportArtistFooter;

View file

@ -1,7 +1,7 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import ImportSeriesFooter from './ImportSeriesFooter';
import ImportArtistFooter from './ImportArtistFooter';
function isMixed(items, selectedIds, defaultValue, key) {
return _.some(items, (series) => {
@ -11,21 +11,21 @@ function isMixed(items, selectedIds, defaultValue, key) {
function createMapStateToProps() {
return createSelector(
(state) => state.addSeries,
(state) => state.importSeries,
(state) => state.addArtist,
(state) => state.importArtist,
(state, { selectedIds }) => selectedIds,
(addSeries, importSeries, selectedIds) => {
(addArtist, importArtist, selectedIds) => {
const {
monitor: defaultMonitor,
qualityProfileId: defaultQualityProfileId,
languageProfileId: defaultLanguageProfileId,
seriesType: defaultSeriesType,
seasonFolder: defaultSeasonFolder
} = addSeries.defaults;
albumFolder: defaultAlbumFolder
} = addArtist.defaults;
const items = importSeries.items;
const items = importArtist.items;
const isLookingUpSeries = _.some(importSeries.items, (series) => {
const isLookingUpArtist = _.some(importArtist.items, (series) => {
return !series.isPopulated && series.error == null;
});
@ -33,25 +33,25 @@ function createMapStateToProps() {
const isQualityProfileIdMixed = isMixed(items, selectedIds, defaultQualityProfileId, 'qualityProfileId');
const isLanguageProfileIdMixed = isMixed(items, selectedIds, defaultLanguageProfileId, 'languageProfileId');
const isSeriesTypeMixed = isMixed(items, selectedIds, defaultSeriesType, 'seriesType');
const isSeasonFolderMixed = isMixed(items, selectedIds, defaultSeasonFolder, 'seasonFolder');
const isAlbumFolderMixed = isMixed(items, selectedIds, defaultAlbumFolder, 'albumFolder');
return {
selectedCount: selectedIds.length,
isImporting: importSeries.isImporting,
isLookingUpSeries,
isImporting: importArtist.isImporting,
isLookingUpArtist,
defaultMonitor,
defaultQualityProfileId,
defaultLanguageProfileId,
defaultSeriesType,
defaultSeasonFolder,
defaultAlbumFolder,
isMonitorMixed,
isQualityProfileIdMixed,
isLanguageProfileIdMixed,
isSeriesTypeMixed,
isSeasonFolderMixed
isAlbumFolderMixed
};
}
);
}
export default connect(createMapStateToProps)(ImportSeriesFooter);
export default connect(createMapStateToProps)(ImportArtistFooter);

View file

@ -26,14 +26,14 @@
min-width: 120px;
}
.seasonFolder {
.albumFolder {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
flex: 0 1 150px;
min-width: 120px;
}
.series {
.artist {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
flex: 0 1 400px;

View file

@ -6,11 +6,11 @@ import Popover from 'Components/Tooltip/Popover';
import VirtualTableHeader from 'Components/Table/VirtualTableHeader';
import VirtualTableHeaderCell from 'Components/Table/VirtualTableHeaderCell';
import VirtualTableSelectAllHeaderCell from 'Components/Table/VirtualTableSelectAllHeaderCell';
import SeriesMonitoringOptionsPopoverContent from 'AddArtist/SeriesMonitoringOptionsPopoverContent';
import SeriesTypePopoverContent from 'AddArtist/SeriesTypePopoverContent';
import styles from './ImportSeriesHeader.css';
import ArtistMonitoringOptionsPopoverContent from 'AddArtist/ArtistMonitoringOptionsPopoverContent';
// import SeriesTypePopoverContent from 'AddArtist/SeriesTypePopoverContent';
import styles from './ImportArtistHeader.css';
function ImportSeriesHeader(props) {
function ImportArtistHeader(props) {
const {
showLanguageProfile,
allSelected,
@ -47,7 +47,7 @@ function ImportSeriesHeader(props) {
/>
}
title="Monitoring Options"
body={<SeriesMonitoringOptionsPopoverContent />}
body={<ArtistMonitoringOptionsPopoverContent />}
position={tooltipPositions.RIGHT}
/>
</VirtualTableHeaderCell>
@ -70,46 +70,27 @@ function ImportSeriesHeader(props) {
}
<VirtualTableHeaderCell
className={styles.seriesType}
name="seriesType"
className={styles.albumFolder}
name="albumFolder"
>
Series Type
<Popover
anchor={
<Icon
className={styles.detailsIcon}
name={icons.INFO}
/>
}
title="Series Type"
body={<SeriesTypePopoverContent />}
position={tooltipPositions.RIGHT}
/>
Album Folder
</VirtualTableHeaderCell>
<VirtualTableHeaderCell
className={styles.seasonFolder}
name="seasonFolder"
>
Season Folder
</VirtualTableHeaderCell>
<VirtualTableHeaderCell
className={styles.series}
className={styles.artist}
name="series"
>
Series
Artist
</VirtualTableHeaderCell>
</VirtualTableHeader>
);
}
ImportSeriesHeader.propTypes = {
ImportArtistHeader.propTypes = {
showLanguageProfile: PropTypes.bool.isRequired,
allSelected: PropTypes.bool.isRequired,
allUnselected: PropTypes.bool.isRequired,
onSelectAllChange: PropTypes.func.isRequired
};
export default ImportSeriesHeader;
export default ImportArtistHeader;

View file

@ -31,7 +31,7 @@
min-width: 120px;
}
.seasonFolder {
.albumFolder {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
flex: 0 1 150px;

View file

@ -5,20 +5,20 @@ import FormInputGroup from 'Components/Form/FormInputGroup';
import VirtualTableRow from 'Components/Table/VirtualTableRow';
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell';
import ImportSeriesSelectSeriesConnector from './SelectSeries/ImportSeriesSelectSeriesConnector';
import styles from './ImportSeriesRow.css';
import ImportArtistSelectArtistConnector from './SelectArtist/ImportArtistSelectArtistConnector';
import styles from './ImportArtistRow.css';
function ImportSeriesRow(props) {
function ImportArtistRow(props) {
const {
style,
id,
monitor,
qualityProfileId,
languageProfileId,
seasonFolder,
seriesType,
albumFolder,
// seriesType,
selectedSeries,
isExistingSeries,
isExistingArtist,
showLanguageProfile,
isSelected,
onSelectedChange,
@ -31,7 +31,7 @@ function ImportSeriesRow(props) {
inputClassName={styles.selectInput}
id={id}
isSelected={isSelected}
isDisabled={!selectedSeries || isExistingSeries}
isDisabled={!selectedSeries || isExistingArtist}
onSelectedChange={onSelectedChange}
/>
@ -41,7 +41,7 @@ function ImportSeriesRow(props) {
<VirtualTableRowCell className={styles.monitor}>
<FormInputGroup
type={inputTypes.MONITOR_EPISODES_SELECT}
type={inputTypes.MONITOR_ALBUMS_SELECT}
name="monitor"
value={monitor}
onChange={onInputChange}
@ -68,44 +68,35 @@ function ImportSeriesRow(props) {
/>
</VirtualTableRowCell>
<VirtualTableRowCell className={styles.seriesType}>
<FormInputGroup
type={inputTypes.SERIES_TYPE_SELECT}
name="seriesType"
value={seriesType}
onChange={onInputChange}
/>
</VirtualTableRowCell>
<VirtualTableRowCell className={styles.seasonFolder}>
<VirtualTableRowCell className={styles.albumFolder}>
<FormInputGroup
type={inputTypes.CHECK}
name="seasonFolder"
value={seasonFolder}
name="albumFolder"
value={albumFolder}
onChange={onInputChange}
/>
</VirtualTableRowCell>
<VirtualTableRowCell className={styles.series}>
<ImportSeriesSelectSeriesConnector
<ImportArtistSelectArtistConnector
id={id}
isExistingSeries={isExistingSeries}
isExistingArtist={isExistingArtist}
/>
</VirtualTableRowCell>
</VirtualTableRow>
);
}
ImportSeriesRow.propTypes = {
ImportArtistRow.propTypes = {
style: PropTypes.object.isRequired,
id: PropTypes.string.isRequired,
monitor: PropTypes.string.isRequired,
qualityProfileId: PropTypes.number.isRequired,
languageProfileId: PropTypes.number.isRequired,
seriesType: PropTypes.string.isRequired,
seasonFolder: PropTypes.bool.isRequired,
// seriesType: PropTypes.string.isRequired,
albumFolder: PropTypes.bool.isRequired,
selectedSeries: PropTypes.object,
isExistingSeries: PropTypes.bool.isRequired,
isExistingArtist: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
queued: PropTypes.bool.isRequired,
showLanguageProfile: PropTypes.bool.isRequired,
@ -114,8 +105,8 @@ ImportSeriesRow.propTypes = {
onInputChange: PropTypes.func.isRequired
};
ImportSeriesRow.defaultsProps = {
ImportArtistRow.defaultsProps = {
items: []
};
export default ImportSeriesRow;
export default ImportArtistRow;

View file

@ -3,14 +3,14 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { queueLookupSeries, setImportSeriesValue } from 'Store/Actions/importSeriesActions';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector';
import ImportSeriesRow from './ImportSeriesRow';
import ImportArtistRow from './ImportArtistRow';
function createImportSeriesItemSelector() {
function createImportArtistItemSelector() {
return createSelector(
(state, { id }) => id,
(state) => state.importSeries.items,
(state) => state.importArtist.items,
(id, items) => {
return _.find(items, { id }) || {};
}
@ -19,15 +19,15 @@ function createImportSeriesItemSelector() {
function createMapStateToProps() {
return createSelector(
createImportSeriesItemSelector(),
createImportArtistItemSelector(),
createAllSeriesSelector(),
(item, series) => {
const selectedSeries = item && item.selectedSeries;
const isExistingSeries = !!selectedSeries && _.some(series, { tvdbId: selectedSeries.tvdbId });
const isExistingArtist = !!selectedSeries && _.some(series, { foreignArtistId: selectedSeries.foreignArtistId });
return {
...item,
isExistingSeries
isExistingArtist
};
}
);
@ -35,16 +35,16 @@ function createMapStateToProps() {
const mapDispatchToProps = {
queueLookupSeries,
setImportSeriesValue
setImportArtistValue
};
class ImportSeriesRowConnector extends Component {
class ImportArtistRowConnector extends Component {
//
// Listeners
onInputChange = ({ name, value }) => {
this.props.setImportSeriesValue({
this.props.setImportArtistValue({
id: this.props.id,
[name]: value
});
@ -59,16 +59,16 @@ class ImportSeriesRowConnector extends Component {
const {
items,
monitor,
seriesType,
seasonFolder
// seriesType,
albumFolder
} = this.props;
if (!items || !monitor || !seriesType || !seasonFolder == null) {
if (!items || !monitor || !albumFolder == null) {
return null;
}
return (
<ImportSeriesRow
<ImportArtistRow
{...this.props}
onInputChange={this.onInputChange}
onSeriesSelect={this.onSeriesSelect}
@ -77,15 +77,15 @@ class ImportSeriesRowConnector extends Component {
}
}
ImportSeriesRowConnector.propTypes = {
ImportArtistRowConnector.propTypes = {
rootFolderId: PropTypes.number.isRequired,
id: PropTypes.string.isRequired,
monitor: PropTypes.string,
seriesType: PropTypes.string,
seasonFolder: PropTypes.bool,
// seriesType: PropTypes.string,
albumFolder: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.object),
queueLookupSeries: PropTypes.func.isRequired,
setImportSeriesValue: PropTypes.func.isRequired
setImportArtistValue: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesRowConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(ImportArtistRowConnector);

View file

@ -2,10 +2,10 @@ import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import VirtualTable from 'Components/Table/VirtualTable';
import ImportSeriesHeader from './ImportSeriesHeader';
import ImportSeriesRowConnector from './ImportSeriesRowConnector';
import ImportArtistHeader from './ImportArtistHeader';
import ImportArtistRowConnector from './ImportArtistRowConnector';
class ImportSeriesTable extends Component {
class ImportArtistTable extends Component {
//
// Lifecycle
@ -23,9 +23,9 @@ class ImportSeriesTable extends Component {
defaultQualityProfileId,
defaultLanguageProfileId,
defaultSeriesType,
defaultSeasonFolder,
defaultAlbumFolder,
onSeriesLookup,
onSetImportSeriesValue
onSetImportArtistValue
} = this.props;
const values = {
@ -33,7 +33,7 @@ class ImportSeriesTable extends Component {
qualityProfileId: defaultQualityProfileId,
languageProfileId: defaultLanguageProfileId,
seriesType: defaultSeriesType,
seasonFolder: defaultSeasonFolder
albumFolder: defaultAlbumFolder
};
unmappedFolders.forEach((unmappedFolder) => {
@ -41,7 +41,7 @@ class ImportSeriesTable extends Component {
onSeriesLookup(id, unmappedFolder.path);
onSetImportSeriesValue({
onSetImportArtistValue({
id,
...values
});
@ -75,12 +75,12 @@ class ImportSeriesTable extends Component {
const selectedSeries = item.selectedSeries;
const isSelected = selectedState[id];
const isExistingSeries = !!selectedSeries &&
const isExistingArtist = !!selectedSeries &&
_.some(prevProps.allSeries, { tvdbId: selectedSeries.tvdbId });
// Props doesn't have a selected series or
// the selected series is an existing series.
if ((selectedSeries && !prevItem.selectedSeries) || (isExistingSeries && !prevItem.selectedSeries)) {
if ((selectedSeries && !prevItem.selectedSeries) || (isExistingArtist && !prevItem.selectedSeries)) {
onSelectedChange({ id, value: false });
return;
@ -88,7 +88,7 @@ class ImportSeriesTable extends Component {
// State is selected, but a series isn't selected or
// the selected series is an existing series.
if (isSelected && (!selectedSeries || isExistingSeries)) {
if (isSelected && (!selectedSeries || isExistingArtist)) {
onSelectedChange({ id, value: false });
return;
@ -129,7 +129,7 @@ class ImportSeriesTable extends Component {
const item = items[rowIndex];
return (
<ImportSeriesRowConnector
<ImportArtistRowConnector
key={key}
style={style}
rootFolderId={rootFolderId}
@ -172,7 +172,7 @@ class ImportSeriesTable extends Component {
overscanRowCount={2}
rowRenderer={this.rowRenderer}
header={
<ImportSeriesHeader
<ImportArtistHeader
showLanguageProfile={showLanguageProfile}
allSelected={allSelected}
allUnselected={allUnselected}
@ -185,7 +185,7 @@ class ImportSeriesTable extends Component {
}
}
ImportSeriesTable.propTypes = {
ImportArtistTable.propTypes = {
rootFolderId: PropTypes.number.isRequired,
items: PropTypes.arrayOf(PropTypes.object),
unmappedFolders: PropTypes.arrayOf(PropTypes.object),
@ -193,7 +193,7 @@ ImportSeriesTable.propTypes = {
defaultQualityProfileId: PropTypes.number,
defaultLanguageProfileId: PropTypes.number,
defaultSeriesType: PropTypes.string.isRequired,
defaultSeasonFolder: PropTypes.bool.isRequired,
defaultAlbumFolder: PropTypes.bool.isRequired,
allSelected: PropTypes.bool.isRequired,
allUnselected: PropTypes.bool.isRequired,
selectedState: PropTypes.object.isRequired,
@ -206,8 +206,8 @@ ImportSeriesTable.propTypes = {
onSelectedChange: PropTypes.func.isRequired,
onRemoveSelectedStateItem: PropTypes.func.isRequired,
onSeriesLookup: PropTypes.func.isRequired,
onSetImportSeriesValue: PropTypes.func.isRequired,
onSetImportArtistValue: PropTypes.func.isRequired,
onScroll: PropTypes.func.isRequired
};
export default ImportSeriesTable;
export default ImportArtistTable;

View file

@ -0,0 +1,44 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector';
import ImportArtistTable from './ImportArtistTable';
function createMapStateToProps() {
return createSelector(
(state) => state.addArtist,
(state) => state.importArtist,
(state) => state.app.dimensions,
createAllSeriesSelector(),
(addArtist, importArtist, dimensions, allSeries) => {
return {
defaultMonitor: addArtist.defaults.monitor,
defaultQualityProfileId: addArtist.defaults.qualityProfileId,
defaultLanguageProfileId: addArtist.defaults.languageProfileId,
defaultSeriesType: addArtist.defaults.seriesType,
defaultAlbumFolder: addArtist.defaults.albumFolder,
items: importArtist.items,
isSmallScreen: dimensions.isSmallScreen,
allSeries
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
onSeriesLookup(name, path) {
dispatch(queueLookupSeries({
name,
path,
term: name
}));
},
onSetImportArtistValue(values) {
dispatch(setImportArtistValue(values));
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(ImportArtistTable);

View file

@ -1,12 +1,17 @@
.titleContainer {
.artistNameContainer {
display: flex;
align-items: center;
}
.title {
.artistName {
margin-right: 5px;
}
.overview {
margin-right: 5px;
color: $disabledColor;
}
.year {
margin-left: 5px;
color: $disabledColor;

View file

@ -0,0 +1,45 @@
import PropTypes from 'prop-types';
import React from 'react';
import { kinds } from 'Helpers/Props';
import Label from 'Components/Label';
import styles from './ImportArtistName.css';
function ImportArtistName(props) {
const {
artistName,
overview,
// year,
// network,
isExistingArtist
} = props;
return (
<div className={styles.artistNameContainer}>
<div className={styles.artistName}>
{artistName}
</div>
<div className={styles.overview}>
{overview}
</div>
{
isExistingArtist &&
<Label
kind={kinds.WARNING}
>
Existing
</Label>
}
</div>
);
}
ImportArtistName.propTypes = {
artistName: PropTypes.string.isRequired,
overview: PropTypes.string.isRequired,
// year: PropTypes.number.isRequired,
// network: PropTypes.string,
isExistingArtist: PropTypes.bool.isRequired
};
export default ImportArtistName;

View file

@ -0,0 +1,55 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Link from 'Components/Link/Link';
import ImportArtistName from './ImportArtistName';
import styles from './ImportArtistSearchResult.css';
class ImportArtistSearchResult extends Component {
//
// Listeners
onPress = () => {
this.props.onPress(this.props.foreignArtistId);
}
//
// Render
render() {
const {
artistName,
overview,
// year,
// network,
isExistingArtist
} = this.props;
return (
<Link
className={styles.artist}
onPress={this.onPress}
>
<ImportArtistName
artistName={artistName}
overview={overview}
// year={year}
// network={network}
isExistingArtist={isExistingArtist}
/>
</Link>
);
}
}
ImportArtistSearchResult.propTypes = {
foreignArtistId: PropTypes.string.isRequired,
artistName: PropTypes.string.isRequired,
overview: PropTypes.string.isRequired,
// year: PropTypes.number.isRequired,
// network: PropTypes.string,
isExistingArtist: PropTypes.bool.isRequired,
onPress: PropTypes.func.isRequired
};
export default ImportArtistSearchResult;

View file

@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createExistingArtistSelector from 'Store/Selectors/createExistingArtistSelector';
import ImportArtistSearchResult from './ImportArtistSearchResult';
function createMapStateToProps() {
return createSelector(
createExistingArtistSelector(),
(isExistingArtist) => {
return {
isExistingArtist
};
}
);
}
export default connect(createMapStateToProps)(ImportArtistSearchResult);

View file

@ -8,9 +8,9 @@ import SpinnerIcon from 'Components/SpinnerIcon';
import Link from 'Components/Link/Link';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import TextInput from 'Components/Form/TextInput';
import ImportSeriesSearchResultConnector from './ImportSeriesSearchResultConnector';
import ImportSeriesTitle from './ImportSeriesTitle';
import styles from './ImportSeriesSelectSeries.css';
import ImportArtistSearchResultConnector from './ImportArtistSearchResultConnector';
import ImportArtistName from './ImportArtistName';
import styles from './ImportArtistSelectArtist.css';
const tetherOptions = {
skipMoveElement: true,
@ -25,7 +25,7 @@ const tetherOptions = {
targetAttachment: 'bottom center'
};
class ImportSeriesSelectSeries extends Component {
class ImportArtistSelectArtist extends Component {
//
// Lifecycle
@ -33,7 +33,7 @@ class ImportSeriesSelectSeries extends Component {
constructor(props, context) {
super(props, context);
this._seriesLookupTimeout = null;
this._artistLookupTimeout = null;
this.state = {
term: props.id,
@ -88,12 +88,12 @@ class ImportSeriesSelectSeries extends Component {
}
onSearchInputChange = ({ value }) => {
if (this._seriesLookupTimeout) {
clearTimeout(this._seriesLookupTimeout);
if (this._artistLookupTimeout) {
clearTimeout(this._artistLookupTimeout);
}
this.setState({ term: value }, () => {
this._seriesLookupTimeout = setTimeout(() => {
this._artistLookupTimeout = setTimeout(() => {
this.props.onSearchInputChange(value);
}, 200);
});
@ -111,7 +111,7 @@ class ImportSeriesSelectSeries extends Component {
render() {
const {
selectedSeries,
isExistingSeries,
isExistingArtist,
isFetching,
isPopulated,
error,
@ -146,7 +146,7 @@ class ImportSeriesSelectSeries extends Component {
}
{
isPopulated && selectedSeries && isExistingSeries &&
isPopulated && selectedSeries && isExistingArtist &&
<Icon
className={styles.warningIcon}
name={icons.WARNING}
@ -156,11 +156,12 @@ class ImportSeriesSelectSeries extends Component {
{
isPopulated && selectedSeries &&
<ImportSeriesTitle
title={selectedSeries.title}
year={selectedSeries.year}
network={selectedSeries.network}
isExistingSeries={isExistingSeries}
<ImportArtistName
artistName={selectedSeries.artistName}
overview={selectedSeries.overview}
// year={selectedSeries.year}
// network={selectedSeries.network}
isExistingArtist={isExistingArtist}
/>
}
@ -225,12 +226,13 @@ class ImportSeriesSelectSeries extends Component {
{
items.map((item) => {
return (
<ImportSeriesSearchResultConnector
key={item.tvdbId}
tvdbId={item.tvdbId}
title={item.title}
year={item.year}
network={item.network}
<ImportArtistSearchResultConnector
key={item.foreignArtistId}
foreignArtistId={item.foreignArtistId}
artistName={item.artistName}
overview={item.overview}
// year={item.year}
// network={item.network}
onPress={this.onSeriesSelect}
/>
);
@ -245,10 +247,10 @@ class ImportSeriesSelectSeries extends Component {
}
}
ImportSeriesSelectSeries.propTypes = {
ImportArtistSelectArtist.propTypes = {
id: PropTypes.string.isRequired,
selectedSeries: PropTypes.object,
isExistingSeries: PropTypes.bool.isRequired,
isExistingArtist: PropTypes.bool.isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
@ -258,11 +260,11 @@ ImportSeriesSelectSeries.propTypes = {
onSeriesSelect: PropTypes.func.isRequired
};
ImportSeriesSelectSeries.defaultProps = {
ImportArtistSelectArtist.defaultProps = {
isFetching: true,
isPopulated: false,
items: [],
queued: true
};
export default ImportSeriesSelectSeries;
export default ImportArtistSelectArtist;

View file

@ -3,13 +3,13 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { queueLookupSeries, setImportSeriesValue } from 'Store/Actions/importSeriesActions';
import createImportSeriesItemSelector from 'Store/Selectors/createImportSeriesItemSelector';
import ImportSeriesSelectSeries from './ImportSeriesSelectSeries';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createImportArtistItemSelector from 'Store/Selectors/createImportArtistItemSelector';
import ImportArtistSelectArtist from './ImportArtistSelectArtist';
function createMapStateToProps() {
return createSelector(
createImportSeriesItemSelector(),
createImportArtistItemSelector(),
(item) => {
return item;
}
@ -18,10 +18,10 @@ function createMapStateToProps() {
const mapDispatchToProps = {
queueLookupSeries,
setImportSeriesValue
setImportArtistValue
};
class ImportSeriesSelectSeriesConnector extends Component {
class ImportArtistSelectArtistConnector extends Component {
//
// Listeners
@ -33,15 +33,15 @@ class ImportSeriesSelectSeriesConnector extends Component {
});
}
onSeriesSelect = (tvdbId) => {
onSeriesSelect = (foreignArtistId) => {
const {
id,
items
} = this.props;
this.props.setImportSeriesValue({
this.props.setImportArtistValue({
id,
selectedSeries: _.find(items, { tvdbId })
selectedSeries: _.find(items, { foreignArtistId })
});
}
@ -50,7 +50,7 @@ class ImportSeriesSelectSeriesConnector extends Component {
render() {
return (
<ImportSeriesSelectSeries
<ImportArtistSelectArtist
{...this.props}
onSearchInputChange={this.onSearchInputChange}
onSeriesSelect={this.onSeriesSelect}
@ -59,13 +59,13 @@ class ImportSeriesSelectSeriesConnector extends Component {
}
}
ImportSeriesSelectSeriesConnector.propTypes = {
ImportArtistSelectArtistConnector.propTypes = {
id: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object),
selectedSeries: PropTypes.object,
isSelected: PropTypes.bool,
queueLookupSeries: PropTypes.func.isRequired,
setImportSeriesValue: PropTypes.func.isRequired
setImportArtistValue: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesSelectSeriesConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(ImportArtistSelectArtistConnector);

View file

@ -0,0 +1,30 @@
import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Switch from 'Components/Router/Switch';
import ImportArtistSelectFolderConnector from 'AddArtist/ImportArtist/SelectFolder/ImportArtistSelectFolderConnector';
import ImportArtistConnector from 'AddArtist/ImportArtist/Import/ImportArtistConnector';
class ImportArtist extends Component {
//
// Render
render() {
return (
<Switch>
<Route
exact={true}
path="/add/import"
component={ImportArtistSelectFolderConnector}
/>
<Route
path="/add/import/:rootFolderId"
component={ImportArtistConnector}
/>
</Switch>
);
}
}
export default ImportArtist;

View file

@ -6,9 +6,9 @@ import IconButton from 'Components/Link/IconButton';
import Link from 'Components/Link/Link';
import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import styles from './ImportSeriesRootFolderRow.css';
import styles from './ImportArtistRootFolderRow.css';
function ImportSeriesRootFolderRow(props) {
function ImportArtistRootFolderRow(props) {
const {
id,
path,
@ -48,7 +48,7 @@ function ImportSeriesRootFolderRow(props) {
);
}
ImportSeriesRootFolderRow.propTypes = {
ImportArtistRootFolderRow.propTypes = {
id: PropTypes.number.isRequired,
path: PropTypes.string.isRequired,
freeSpace: PropTypes.number.isRequired,
@ -56,9 +56,9 @@ ImportSeriesRootFolderRow.propTypes = {
onDeletePress: PropTypes.func.isRequired
};
ImportSeriesRootFolderRow.defaultProps = {
ImportArtistRootFolderRow.defaultProps = {
freeSpace: 0,
unmappedFolders: []
};
export default ImportSeriesRootFolderRow;
export default ImportArtistRootFolderRow;

View file

@ -3,7 +3,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { deleteRootFolder } from 'Store/Actions/rootFolderActions';
import ImportSeriesRootFolderRow from './ImportSeriesRootFolderRow';
import ImportArtistRootFolderRow from './ImportArtistRootFolderRow';
function createMapStateToProps() {
return createSelector(
@ -18,7 +18,7 @@ const mapDispatchToProps = {
deleteRootFolder
};
class ImportSeriesRootFolderRowConnector extends Component {
class ImportArtistRootFolderRowConnector extends Component {
//
// Listeners
@ -32,7 +32,7 @@ class ImportSeriesRootFolderRowConnector extends Component {
render() {
return (
<ImportSeriesRootFolderRow
<ImportArtistRootFolderRow
{...this.props}
onDeletePress={this.onDeletePress}
/>
@ -40,9 +40,9 @@ class ImportSeriesRootFolderRowConnector extends Component {
}
}
ImportSeriesRootFolderRowConnector.propTypes = {
ImportArtistRootFolderRowConnector.propTypes = {
id: PropTypes.number.isRequired,
deleteRootFolder: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesRootFolderRowConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(ImportArtistRootFolderRowConnector);

View file

@ -10,8 +10,8 @@ import PageContent from 'Components/Page/PageContent';
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import ImportSeriesRootFolderRowConnector from './ImportSeriesRootFolderRowConnector';
import styles from './ImportSeriesSelectFolder.css';
import ImportArtistRootFolderRowConnector from './ImportArtistRootFolderRowConnector';
import styles from './ImportArtistSelectFolder.css';
const rootFolderColumns = [
{
@ -35,7 +35,7 @@ const rootFolderColumns = [
}
];
class ImportSeriesSelectFolder extends Component {
class ImportArtistSelectFolder extends Component {
//
// Lifecycle
@ -75,7 +75,7 @@ class ImportSeriesSelectFolder extends Component {
} = this.props;
return (
<PageContent title="Import Series">
<PageContent title="Import Artist">
<PageContentBodyConnector>
{
isFetching && !isPopulated &&
@ -91,17 +91,14 @@ class ImportSeriesSelectFolder extends Component {
!error && isPopulated &&
<div>
<div className={styles.header}>
Import series you already have
Import artist(s) you already have
</div>
<div className={styles.tips}>
Some tips to ensure the import goes smoothly:
<ul>
<li className={styles.tip}>
Make sure your files include the quality in the name. eg. <span className={styles.code}>episode.s02e15.bluray.mkv</span>
</li>
<li className={styles.tip}>
Point Sonarr to the folder containing all of your tv shows not a specific one. eg. <span className={styles.code}>"\tv shows\"</span> and not <span className={styles.code}>"\tv shows\the simpsons\"</span>
Point Lidarr to the folder containing all of your music not a specific artist. eg. <span className={styles.code}>"\music\"</span> and not <span className={styles.code}>"\music\alien ant farm\"</span>
</li>
</ul>
</div>
@ -119,7 +116,7 @@ class ImportSeriesSelectFolder extends Component {
{
items.map((rootFolder) => {
return (
<ImportSeriesRootFolderRowConnector
<ImportArtistRootFolderRowConnector
key={rootFolder.id}
id={rootFolder.id}
path={rootFolder.path}
@ -176,7 +173,7 @@ class ImportSeriesSelectFolder extends Component {
}
}
ImportSeriesSelectFolder.propTypes = {
ImportArtistSelectFolder.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
@ -185,4 +182,4 @@ ImportSeriesSelectFolder.propTypes = {
onDeleteRootFolderPress: PropTypes.func.isRequired
};
export default ImportSeriesSelectFolder;
export default ImportArtistSelectFolder;

View file

@ -6,7 +6,7 @@ import { createSelector } from 'reselect';
import { push } from 'react-router-redux';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import { fetchRootFolders, addRootFolder, deleteRootFolder } from 'Store/Actions/rootFolderActions';
import ImportSeriesSelectFolder from './ImportSeriesSelectFolder';
import ImportArtistSelectFolder from './ImportArtistSelectFolder';
function createMapStateToProps() {
return createSelector(
@ -24,7 +24,7 @@ const mapDispatchToProps = {
push
};
class ImportSeriesSelectFolderConnector extends Component {
class ImportArtistSelectFolderConnector extends Component {
//
// Lifecycle
@ -65,7 +65,7 @@ class ImportSeriesSelectFolderConnector extends Component {
render() {
return (
<ImportSeriesSelectFolder
<ImportArtistSelectFolder
{...this.props}
onNewRootFolderSelect={this.onNewRootFolderSelect}
onDeleteRootFolderPress={this.onDeleteRootFolderPress}
@ -74,7 +74,7 @@ class ImportSeriesSelectFolderConnector extends Component {
}
}
ImportSeriesSelectFolderConnector.propTypes = {
ImportArtistSelectFolderConnector.propTypes = {
isSaving: PropTypes.bool.isRequired,
saveError: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
@ -84,4 +84,4 @@ ImportSeriesSelectFolderConnector.propTypes = {
push: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesSelectFolderConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(ImportArtistSelectFolderConnector);

View file

@ -1,44 +0,0 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { queueLookupSeries, setImportSeriesValue } from 'Store/Actions/importSeriesActions';
import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector';
import ImportSeriesTable from './ImportSeriesTable';
function createMapStateToProps() {
return createSelector(
(state) => state.addSeries,
(state) => state.importSeries,
(state) => state.app.dimensions,
createAllSeriesSelector(),
(addSeries, importSeries, dimensions, allSeries) => {
return {
defaultMonitor: addSeries.defaults.monitor,
defaultQualityProfileId: addSeries.defaults.qualityProfileId,
defaultLanguageProfileId: addSeries.defaults.languageProfileId,
defaultSeriesType: addSeries.defaults.seriesType,
defaultSeasonFolder: addSeries.defaults.seasonFolder,
items: importSeries.items,
isSmallScreen: dimensions.isSmallScreen,
allSeries
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
onSeriesLookup(name, path) {
dispatch(queueLookupSeries({
name,
path,
term: name
}));
},
onSetImportSeriesValue(values) {
dispatch(setImportSeriesValue(values));
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(ImportSeriesTable);

View file

@ -1,52 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Link from 'Components/Link/Link';
import ImportSeriesTitle from './ImportSeriesTitle';
import styles from './ImportSeriesSearchResult.css';
class ImportSeriesSearchResult extends Component {
//
// Listeners
onPress = () => {
this.props.onPress(this.props.tvdbId);
}
//
// Render
render() {
const {
title,
year,
network,
isExistingSeries
} = this.props;
return (
<Link
className={styles.series}
onPress={this.onPress}
>
<ImportSeriesTitle
title={title}
year={year}
network={network}
isExistingSeries={isExistingSeries}
/>
</Link>
);
}
}
ImportSeriesSearchResult.propTypes = {
tvdbId: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
network: PropTypes.string,
isExistingSeries: PropTypes.bool.isRequired,
onPress: PropTypes.func.isRequired
};
export default ImportSeriesSearchResult;

View file

@ -1,17 +0,0 @@
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createExistingSeriesSelector from 'Store/Selectors/createExistingSeriesSelector';
import ImportSeriesSearchResult from './ImportSeriesSearchResult';
function createMapStateToProps() {
return createSelector(
createExistingSeriesSelector(),
(isExistingSeries) => {
return {
isExistingSeries
};
}
);
}
export default connect(createMapStateToProps)(ImportSeriesSearchResult);

View file

@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import { kinds } from 'Helpers/Props';
import Label from 'Components/Label';
import styles from './ImportSeriesTitle.css';
function ImportSeriesTitle(props) {
const {
title,
year,
network,
isExistingSeries
} = props;
return (
<div className={styles.titleContainer}>
<div className={styles.title}>
{title}
{
!title.contains(year) &&
<span className={styles.year}>({year})</span>
}
</div>
{
!!network &&
<Label>{network}</Label>
}
{
isExistingSeries &&
<Label
kind={kinds.WARNING}
>
Existing
</Label>
}
</div>
);
}
ImportSeriesTitle.propTypes = {
title: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
network: PropTypes.string,
isExistingSeries: PropTypes.bool.isRequired
};
export default ImportSeriesTitle;

View file

@ -1,30 +0,0 @@
import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Switch from 'Components/Router/Switch';
import ImportSeriesSelectFolderConnector from 'AddArtist/ImportSeries/SelectFolder/ImportSeriesSelectFolderConnector';
import ImportSeriesConnector from 'AddArtist/ImportSeries/Import/ImportSeriesConnector';
class ImportSeries extends Component {
//
// Render
render() {
return (
<Switch>
<Route
exact={true}
path="/add/import"
component={ImportSeriesSelectFolderConnector}
/>
<Route
path="/add/import/:rootFolderId"
component={ImportSeriesConnector}
/>
</Switch>
);
}
}
export default ImportSeries;

View file

@ -1,46 +0,0 @@
import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
function SeriesMonitoringOptionsPopoverContent() {
return (
<DescriptionList>
<DescriptionListItem
title="All Episodes"
data="Monitor all episodes except specials"
/>
<DescriptionListItem
title="Future Episodes"
data="Monitor episodes that have not aired yet"
/>
<DescriptionListItem
title="Missing Episodes"
data="Monitor episodes that do not have files or have not aired yet"
/>
<DescriptionListItem
title="Existing Episodes"
data="Monitor episodes that have files or have not aired yet"
/>
<DescriptionListItem
title="First Season"
data="Monitor all episodes of the first season. All other seasons will be ignored"
/>
<DescriptionListItem
title="Latest Season"
data="Monitor all episodes of the latest season and future seasons"
/>
<DescriptionListItem
title="None"
data="No episodes will be monitored."
/>
</DescriptionList>
);
}
export default SeriesMonitoringOptionsPopoverContent;

View file

@ -1,26 +0,0 @@
import React from 'react';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
function SeriesTypePopoverContent() {
return (
<DescriptionList>
<DescriptionListItem
title="Anime"
data="Episodes released using an absolute episode number"
/>
<DescriptionListItem
title="Daily"
data="Episodes released daily or less frequently that use year-month-day (2017-05-25)"
/>
<DescriptionListItem
title="Standard"
data="Episodes released with SxxEyy pattern"
/>
</DescriptionList>
);
}
export default SeriesTypePopoverContent;