[UI Work] Misc UI Fixes and Tweaks

pull/6/head
Qstick 7 years ago
parent 2a6decdc4c
commit 44cc642ad4

@ -64,12 +64,12 @@ class BlacklistRow extends Component {
return null; return null;
} }
if (name === 'series.sortTitle') { if (name === 'series.sortName') {
return ( return (
<TableRowCell key={name}> <TableRowCell key={name}>
<ArtistNameLink <ArtistNameLink
titleSlug={series.titleSlug} nameSlug={series.nameSlug}
title={series.title} artistName={series.artistName}
/> />
</TableRowCell> </TableRowCell>
); );

@ -115,7 +115,7 @@ class HistoryRow extends Component {
episodeEntity={episodeEntities.EPISODES} episodeEntity={episodeEntities.EPISODES}
artistId={artist.id} artistId={artist.id}
episodeTitle={album.title} episodeTitle={album.title}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
</TableRowCell> </TableRowCell>
); );

@ -163,7 +163,7 @@ class QueueRow extends Component {
episodeFileId={episode.episodeFileId} episodeFileId={episode.episodeFileId}
episodeEntity={episodeEntity} episodeEntity={episodeEntity}
episodeTitle={episode.title} episodeTitle={episode.title}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
</TableRowCell> </TableRowCell>
); );

@ -20,7 +20,7 @@
height: 250px; height: 250px;
} }
.title { .name {
font-weight: 300; font-weight: 300;
font-size: 36px; font-size: 36px;
} }

@ -18,7 +18,7 @@ class AddNewArtistSearchResult extends Component {
super(props, context); super(props, context);
this.state = { this.state = {
isNewAddSeriesModalOpen: false isNewAddArtistModalOpen: false
}; };
} }
@ -32,11 +32,11 @@ class AddNewArtistSearchResult extends Component {
// Listeners // Listeners
onPress = () => { onPress = () => {
this.setState({ isNewAddSeriesModalOpen: true }); this.setState({ isNewAddArtistModalOpen: true });
} }
onAddSerisModalClose = () => { onAddSerisModalClose = () => {
this.setState({ isNewAddSeriesModalOpen: false }); this.setState({ isNewAddArtistModalOpen: false });
} }
// //
@ -51,7 +51,7 @@ class AddNewArtistSearchResult extends Component {
network, network,
status, status,
overview, overview,
seasonCount, albumCount,
ratings, ratings,
images, images,
isExistingArtist, isExistingArtist,
@ -61,8 +61,8 @@ class AddNewArtistSearchResult extends Component {
const linkProps = isExistingArtist ? { to: `/artist/${nameSlug}` } : { onPress: this.onPress }; const linkProps = isExistingArtist ? { to: `/artist/${nameSlug}` } : { onPress: this.onPress };
let seasons = '1 Season'; let seasons = '1 Season';
if (seasonCount > 1) { if (albumCount > 1) {
seasons = `${seasonCount} Seasons`; seasons = `${albumCount} Seasons`;
} }
return ( return (
@ -115,7 +115,7 @@ class AddNewArtistSearchResult extends Component {
} }
{ {
!!seasonCount && !!albumCount &&
<Label size={sizes.LARGE}> <Label size={sizes.LARGE}>
{seasons} {seasons}
</Label> </Label>
@ -138,7 +138,7 @@ class AddNewArtistSearchResult extends Component {
</div> </div>
<AddNewArtistModal <AddNewArtistModal
isOpen={this.state.isNewAddSeriesModalOpen && !isExistingArtist} isOpen={this.state.isNewAddArtistModalOpen && !isExistingArtist}
foreignArtistId={foreignArtistId} foreignArtistId={foreignArtistId}
artistName={artistName} artistName={artistName}
year={year} year={year}
@ -159,7 +159,7 @@ AddNewArtistSearchResult.propTypes = {
network: PropTypes.string, network: PropTypes.string,
status: PropTypes.string.isRequired, status: PropTypes.string.isRequired,
overview: PropTypes.string, overview: PropTypes.string,
seasonCount: PropTypes.number, albumCount: PropTypes.number,
ratings: PropTypes.object.isRequired, ratings: PropTypes.object.isRequired,
images: PropTypes.arrayOf(PropTypes.object).isRequired, images: PropTypes.arrayOf(PropTypes.object).isRequired,
isExistingArtist: PropTypes.bool.isRequired, isExistingArtist: PropTypes.bool.isRequired,

@ -17,7 +17,7 @@ function ImportArtistRow(props) {
languageProfileId, languageProfileId,
albumFolder, albumFolder,
// seriesType, // seriesType,
selectedSeries, selectedArtist,
isExistingArtist, isExistingArtist,
showLanguageProfile, showLanguageProfile,
isSelected, isSelected,
@ -31,7 +31,7 @@ function ImportArtistRow(props) {
inputClassName={styles.selectInput} inputClassName={styles.selectInput}
id={id} id={id}
isSelected={isSelected} isSelected={isSelected}
isDisabled={!selectedSeries || isExistingArtist} isDisabled={!selectedArtist || isExistingArtist}
onSelectedChange={onSelectedChange} onSelectedChange={onSelectedChange}
/> />
@ -95,7 +95,7 @@ ImportArtistRow.propTypes = {
languageProfileId: PropTypes.number.isRequired, languageProfileId: PropTypes.number.isRequired,
// seriesType: PropTypes.string.isRequired, // seriesType: PropTypes.string.isRequired,
albumFolder: PropTypes.bool.isRequired, albumFolder: PropTypes.bool.isRequired,
selectedSeries: PropTypes.object, selectedArtist: PropTypes.object,
isExistingArtist: PropTypes.bool.isRequired, isExistingArtist: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
queued: PropTypes.bool.isRequired, queued: PropTypes.bool.isRequired,

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions'; import { queueLookupArtist, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector'; import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
import ImportArtistRow from './ImportArtistRow'; import ImportArtistRow from './ImportArtistRow';
@ -22,8 +22,8 @@ function createMapStateToProps() {
createImportArtistItemSelector(), createImportArtistItemSelector(),
createAllArtistSelector(), createAllArtistSelector(),
(item, series) => { (item, series) => {
const selectedSeries = item && item.selectedSeries; const selectedArtist = item && item.selectedArtist;
const isExistingArtist = !!selectedSeries && _.some(series, { foreignArtistId: selectedSeries.foreignArtistId }); const isExistingArtist = !!selectedArtist && _.some(series, { foreignArtistId: selectedArtist.foreignArtistId });
return { return {
...item, ...item,
@ -34,7 +34,7 @@ function createMapStateToProps() {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
queueLookupSeries, queueLookupArtist,
setImportArtistValue setImportArtistValue
}; };
@ -84,7 +84,7 @@ ImportArtistRowConnector.propTypes = {
// seriesType: PropTypes.string, // seriesType: PropTypes.string,
albumFolder: PropTypes.bool, albumFolder: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.object), items: PropTypes.arrayOf(PropTypes.object),
queueLookupSeries: PropTypes.func.isRequired, queueLookupArtist: PropTypes.func.isRequired,
setImportArtistValue: PropTypes.func.isRequired setImportArtistValue: PropTypes.func.isRequired
}; };

@ -72,30 +72,30 @@ class ImportArtistTable extends Component {
return; return;
} }
const selectedSeries = item.selectedSeries; const selectedArtist = item.selectedArtist;
const isSelected = selectedState[id]; const isSelected = selectedState[id];
const isExistingArtist = !!selectedSeries && const isExistingArtist = !!selectedArtist &&
_.some(prevProps.allSeries, { foreignArtistId: selectedSeries.foreignArtistId }); _.some(prevProps.allArtists, { foreignArtistId: selectedArtist.foreignArtistId });
// Props doesn't have a selected series or // Props doesn't have a selected artist or
// the selected series is an existing series. // the selected artist is an existing artist.
if ((selectedSeries && !prevItem.selectedSeries) || (isExistingArtist && !prevItem.selectedSeries)) { if ((selectedArtist && !prevItem.selectedArtist) || (isExistingArtist && !prevItem.selectedArtist)) {
onSelectedChange({ id, value: false }); onSelectedChange({ id, value: false });
return; return;
} }
// State is selected, but a series isn't selected or // State is selected, but a artist isn't selected or
// the selected series is an existing series. // the selected artist is an existing artist.
if (isSelected && (!selectedSeries || isExistingArtist)) { if (isSelected && (!selectedArtist || isExistingArtist)) {
onSelectedChange({ id, value: false }); onSelectedChange({ id, value: false });
return; return;
} }
// A series is being selected that wasn't previously selected. // A artist is being selected that wasn't previously selected.
if (selectedSeries && selectedSeries !== prevItem.selectedSeries) { if (selectedArtist && selectedArtist !== prevItem.selectedArtist) {
onSelectedChange({ id, value: true }); onSelectedChange({ id, value: true });
return; return;
@ -198,7 +198,7 @@ ImportArtistTable.propTypes = {
allUnselected: PropTypes.bool.isRequired, allUnselected: PropTypes.bool.isRequired,
selectedState: PropTypes.object.isRequired, selectedState: PropTypes.object.isRequired,
isSmallScreen: PropTypes.bool.isRequired, isSmallScreen: PropTypes.bool.isRequired,
allSeries: PropTypes.arrayOf(PropTypes.object), allArtists: PropTypes.arrayOf(PropTypes.object),
contentBody: PropTypes.object.isRequired, contentBody: PropTypes.object.isRequired,
showLanguageProfile: PropTypes.bool.isRequired, showLanguageProfile: PropTypes.bool.isRequired,
scrollTop: PropTypes.number.isRequired, scrollTop: PropTypes.number.isRequired,

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions'; import { queueLookupArtist, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector'; import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
import ImportArtistTable from './ImportArtistTable'; import ImportArtistTable from './ImportArtistTable';
@ -10,7 +10,7 @@ function createMapStateToProps() {
(state) => state.importArtist, (state) => state.importArtist,
(state) => state.app.dimensions, (state) => state.app.dimensions,
createAllArtistSelector(), createAllArtistSelector(),
(addArtist, importArtist, dimensions, allSeries) => { (addArtist, importArtist, dimensions, allArtists) => {
return { return {
defaultMonitor: addArtist.defaults.monitor, defaultMonitor: addArtist.defaults.monitor,
defaultQualityProfileId: addArtist.defaults.qualityProfileId, defaultQualityProfileId: addArtist.defaults.qualityProfileId,
@ -19,7 +19,7 @@ function createMapStateToProps() {
defaultAlbumFolder: addArtist.defaults.albumFolder, defaultAlbumFolder: addArtist.defaults.albumFolder,
items: importArtist.items, items: importArtist.items,
isSmallScreen: dimensions.isSmallScreen, isSmallScreen: dimensions.isSmallScreen,
allSeries allArtists
}; };
} }
); );
@ -28,7 +28,7 @@ function createMapStateToProps() {
function createMapDispatchToProps(dispatch, props) { function createMapDispatchToProps(dispatch, props) {
return { return {
onSeriesLookup(name, path) { onSeriesLookup(name, path) {
dispatch(queueLookupSeries({ dispatch(queueLookupArtist({
name, name,
path, path,
term: name term: name

@ -7,9 +7,7 @@ import styles from './ImportArtistName.css';
function ImportArtistName(props) { function ImportArtistName(props) {
const { const {
artistName, artistName,
overview,
// year, // year,
// network,
isExistingArtist isExistingArtist
} = props; } = props;
@ -18,9 +16,6 @@ function ImportArtistName(props) {
<div className={styles.artistName}> <div className={styles.artistName}>
{artistName} {artistName}
</div> </div>
<div className={styles.overview}>
{overview}
</div>
{ {
isExistingArtist && isExistingArtist &&
@ -36,9 +31,7 @@ function ImportArtistName(props) {
ImportArtistName.propTypes = { ImportArtistName.propTypes = {
artistName: PropTypes.string.isRequired, artistName: PropTypes.string.isRequired,
overview: PropTypes.string.isRequired,
// year: PropTypes.number.isRequired, // year: PropTypes.number.isRequired,
// network: PropTypes.string,
isExistingArtist: PropTypes.bool.isRequired isExistingArtist: PropTypes.bool.isRequired
}; };

@ -19,9 +19,8 @@ class ImportArtistSearchResult extends Component {
render() { render() {
const { const {
artistName, artistName,
overview, // overview,
// year, // year,
// network,
isExistingArtist isExistingArtist
} = this.props; } = this.props;
@ -32,9 +31,8 @@ class ImportArtistSearchResult extends Component {
> >
<ImportArtistName <ImportArtistName
artistName={artistName} artistName={artistName}
overview={overview} // overview={overview}
// year={year} // year={year}
// network={network}
isExistingArtist={isExistingArtist} isExistingArtist={isExistingArtist}
/> />
</Link> </Link>
@ -45,9 +43,8 @@ class ImportArtistSearchResult extends Component {
ImportArtistSearchResult.propTypes = { ImportArtistSearchResult.propTypes = {
foreignArtistId: PropTypes.string.isRequired, foreignArtistId: PropTypes.string.isRequired,
artistName: PropTypes.string.isRequired, artistName: PropTypes.string.isRequired,
overview: PropTypes.string.isRequired, // overview: PropTypes.string.isRequired,
// year: PropTypes.number.isRequired, // year: PropTypes.number.isRequired,
// network: PropTypes.string,
isExistingArtist: PropTypes.bool.isRequired, isExistingArtist: PropTypes.bool.isRequired,
onPress: PropTypes.func.isRequired onPress: PropTypes.func.isRequired
}; };

@ -110,7 +110,7 @@ class ImportArtistSelectArtist extends Component {
render() { render() {
const { const {
selectedSeries, selectedArtist,
isExistingArtist, isExistingArtist,
isFetching, isFetching,
isPopulated, isPopulated,
@ -146,7 +146,7 @@ class ImportArtistSelectArtist extends Component {
} }
{ {
isPopulated && selectedSeries && isExistingArtist && isPopulated && selectedArtist && isExistingArtist &&
<Icon <Icon
className={styles.warningIcon} className={styles.warningIcon}
name={icons.WARNING} name={icons.WARNING}
@ -155,18 +155,17 @@ class ImportArtistSelectArtist extends Component {
} }
{ {
isPopulated && selectedSeries && isPopulated && selectedArtist &&
<ImportArtistName <ImportArtistName
artistName={selectedSeries.artistName} artistName={selectedArtist.artistName}
overview={selectedSeries.overview} overview={selectedArtist.overview}
// year={selectedSeries.year} // year={selectedArtist.year}
// network={selectedSeries.network}
isExistingArtist={isExistingArtist} isExistingArtist={isExistingArtist}
/> />
} }
{ {
isPopulated && !selectedSeries && isPopulated && !selectedArtist &&
<div> <div>
<Icon <Icon
className={styles.warningIcon} className={styles.warningIcon}
@ -230,9 +229,8 @@ class ImportArtistSelectArtist extends Component {
key={item.foreignArtistId} key={item.foreignArtistId}
foreignArtistId={item.foreignArtistId} foreignArtistId={item.foreignArtistId}
artistName={item.artistName} artistName={item.artistName}
overview={item.overview} // overview={item.overview}
// year={item.year} // year={item.year}
// network={item.network}
onPress={this.onArtistSelect} onPress={this.onArtistSelect}
/> />
); );
@ -249,7 +247,7 @@ class ImportArtistSelectArtist extends Component {
ImportArtistSelectArtist.propTypes = { ImportArtistSelectArtist.propTypes = {
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
selectedSeries: PropTypes.object, selectedArtist: PropTypes.object,
isExistingArtist: PropTypes.bool.isRequired, isExistingArtist: PropTypes.bool.isRequired,
isFetching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired,

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { queueLookupSeries, setImportArtistValue } from 'Store/Actions/importArtistActions'; import { queueLookupArtist, setImportArtistValue } from 'Store/Actions/importArtistActions';
import createImportArtistItemSelector from 'Store/Selectors/createImportArtistItemSelector'; import createImportArtistItemSelector from 'Store/Selectors/createImportArtistItemSelector';
import ImportArtistSelectArtist from './ImportArtistSelectArtist'; import ImportArtistSelectArtist from './ImportArtistSelectArtist';
@ -17,7 +17,7 @@ function createMapStateToProps() {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
queueLookupSeries, queueLookupArtist,
setImportArtistValue setImportArtistValue
}; };
@ -27,7 +27,7 @@ class ImportArtistSelectArtistConnector extends Component {
// Listeners // Listeners
onSearchInputChange = (term) => { onSearchInputChange = (term) => {
this.props.queueLookupSeries({ this.props.queueLookupArtist({
name: this.props.id, name: this.props.id,
term term
}); });
@ -41,7 +41,7 @@ class ImportArtistSelectArtistConnector extends Component {
this.props.setImportArtistValue({ this.props.setImportArtistValue({
id, id,
selectedSeries: _.find(items, { foreignArtistId }) selectedArtist: _.find(items, { foreignArtistId })
}); });
} }
@ -62,9 +62,9 @@ class ImportArtistSelectArtistConnector extends Component {
ImportArtistSelectArtistConnector.propTypes = { ImportArtistSelectArtistConnector.propTypes = {
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object), items: PropTypes.arrayOf(PropTypes.object),
selectedSeries: PropTypes.object, selectedArtist: PropTypes.object,
isSelected: PropTypes.bool, isSelected: PropTypes.bool,
queueLookupSeries: PropTypes.func.isRequired, queueLookupArtist: PropTypes.func.isRequired,
setImportArtistValue: PropTypes.func.isRequired setImportArtistValue: PropTypes.func.isRequired
}; };

@ -172,7 +172,7 @@ class AlbumStudio extends Component {
filterValue={filterValue} filterValue={filterValue}
onPress={onFilterSelect} onPress={onFilterSelect}
> >
Missing Episodes Missing Albums
</FilterMenuItem> </FilterMenuItem>
</MenuContent> </MenuContent>
</FilterMenu> </FilterMenu>

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import LazyLoad from 'react-lazyload'; import LazyLoad from 'react-lazyload';
const posterPlaceholder = 'data:image/png;base64,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'; const posterPlaceholder = 'data:image/png;base64,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';
function findPoster(images) { function findPoster(images) {
return _.find(images, { coverType: 'poster' }); return _.find(images, { coverType: 'poster' });

@ -33,7 +33,7 @@ class DeleteArtistModalContent extends Component {
this.setState({ deleteFiles: value }); this.setState({ deleteFiles: value });
} }
onDeleteSeriesConfirmed = () => { onDeleteArtistConfirmed = () => {
const deleteFiles = this.state.deleteFiles; const deleteFiles = this.state.deleteFiles;
this.setState({ deleteFiles: false }); this.setState({ deleteFiles: false });
@ -113,7 +113,7 @@ class DeleteArtistModalContent extends Component {
<Button <Button
kind={kinds.DANGER} kind={kinds.DANGER}
onPress={this.onDeleteSeriesConfirmed} onPress={this.onDeleteArtistConfirmed}
> >
Delete Delete
</Button> </Button>

@ -115,7 +115,7 @@ class AlbumRow extends Component {
episodeId={id} episodeId={id}
artistId={artistId} artistId={artistId}
episodeTitle={title} episodeTitle={title}
showOpenSeriesButton={false} showOpenArtistButton={false}
/> />
</TableRowCell> </TableRowCell>
); );
@ -216,4 +216,11 @@ AlbumRow.propTypes = {
onMonitorAlbumPress: PropTypes.func.isRequired onMonitorAlbumPress: PropTypes.func.isRequired
}; };
AlbumRow.defaultProps = {
statistics: {
trackCount: 0,
trackFileCount: 0
}
};
export default AlbumRow; export default AlbumRow;

@ -102,15 +102,15 @@ class ArtistDetails extends Component {
this.setState({ isManageEpisodesOpen: false }); this.setState({ isManageEpisodesOpen: false });
} }
onEditSeriesPress = () => { onEditArtistPress = () => {
this.setState({ isEditArtistModalOpen: true }); this.setState({ isEditArtistModalOpen: true });
} }
onEditSeriesModalClose = () => { onEditArtistModalClose = () => {
this.setState({ isEditArtistModalOpen: false }); this.setState({ isEditArtistModalOpen: false });
} }
onDeleteSeriesPress = () => { onDeleteArtistPress = () => {
this.setState({ this.setState({
isEditArtistModalOpen: false, isEditArtistModalOpen: false,
isDeleteArtistModalOpen: true isDeleteArtistModalOpen: true
@ -243,13 +243,13 @@ class ArtistDetails extends Component {
<PageToolbarButton <PageToolbarButton
label="Edit" label="Edit"
iconName={icons.EDIT} iconName={icons.EDIT}
onPress={this.onEditSeriesPress} onPress={this.onEditArtistPress}
/> />
<PageToolbarButton <PageToolbarButton
label="Delete" label="Delete"
iconName={icons.DELETE} iconName={icons.DELETE}
onPress={this.onDeleteSeriesPress} onPress={this.onDeleteArtistPress}
/> />
</PageToolbarSection> </PageToolbarSection>
@ -517,8 +517,8 @@ class ArtistDetails extends Component {
<EditArtistModalConnector <EditArtistModalConnector
isOpen={isEditArtistModalOpen} isOpen={isEditArtistModalOpen}
artistId={id} artistId={id}
onModalClose={this.onEditSeriesModalClose} onModalClose={this.onEditArtistModalClose}
onDeleteSeriesPress={this.onDeleteSeriesPress} onDeleteArtistPress={this.onDeleteArtistPress}
/> />
<DeleteArtistModal <DeleteArtistModal

@ -20,17 +20,17 @@ function createMapStateToProps() {
(state) => state.episodeFiles, (state) => state.episodeFiles,
createAllArtistSelector(), createAllArtistSelector(),
createCommandsSelector(), createCommandsSelector(),
(nameSlug, episodes, episodeFiles, allSeries, commands) => { (nameSlug, episodes, episodeFiles, allArtists, commands) => {
const sortedArtist = _.orderBy(allSeries, 'sortName'); const sortedArtist = _.orderBy(allArtists, 'sortName');
const seriesIndex = _.findIndex(sortedArtist, { nameSlug }); const artistIndex = _.findIndex(sortedArtist, { nameSlug });
const series = sortedArtist[seriesIndex]; const series = sortedArtist[artistIndex];
if (!series) { if (!series) {
return {}; return {};
} }
const previousArtist = sortedArtist[seriesIndex - 1] || _.last(sortedArtist); const previousArtist = sortedArtist[artistIndex - 1] || _.last(sortedArtist);
const nextArtist = sortedArtist[seriesIndex + 1] || _.first(sortedArtist); const nextArtist = sortedArtist[artistIndex + 1] || _.first(sortedArtist);
const isArtistRefreshing = !!findCommand(commands, { name: commandNames.REFRESH_ARTIST, artistId: series.id }); const isArtistRefreshing = !!findCommand(commands, { name: commandNames.REFRESH_ARTIST, artistId: series.id });
const allArtistRefreshing = _.some(commands, (command) => command.name === commandNames.REFRESH_ARTIST && !command.body.artistId); const allArtistRefreshing = _.some(commands, (command) => command.name === commandNames.REFRESH_ARTIST && !command.body.artistId);
const isRefreshing = isArtistRefreshing || allArtistRefreshing; const isRefreshing = isArtistRefreshing || allArtistRefreshing;

@ -12,11 +12,11 @@ function createMapStateToProps() {
return createSelector( return createSelector(
(state, { match }) => match, (state, { match }) => match,
createAllArtistSelector(), createAllArtistSelector(),
(match, allSeries) => { (match, allArtists) => {
const nameSlug = match.params.nameSlug; const nameSlug = match.params.nameSlug;
const seriesIndex = _.findIndex(allSeries, { nameSlug }); const artistIndex = _.findIndex(allArtists, { nameSlug });
if (seriesIndex > -1) { if (artistIndex > -1) {
return { return {
nameSlug nameSlug
}; };

@ -27,7 +27,7 @@ class EditArtistModalContent extends Component {
onInputChange, onInputChange,
onSavePress, onSavePress,
onModalClose, onModalClose,
onDeleteSeriesPress, onDeleteArtistPress,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -127,7 +127,7 @@ class EditArtistModalContent extends Component {
<Button <Button
className={styles.deleteButton} className={styles.deleteButton}
kind={kinds.DANGER} kind={kinds.DANGER}
onPress={onDeleteSeriesPress} onPress={onDeleteArtistPress}
> >
Delete Delete
</Button> </Button>
@ -159,7 +159,7 @@ EditArtistModalContent.propTypes = {
onInputChange: PropTypes.func.isRequired, onInputChange: PropTypes.func.isRequired,
onSavePress: PropTypes.func.isRequired, onSavePress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired, onModalClose: PropTypes.func.isRequired,
onDeleteSeriesPress: PropTypes.func.isRequired onDeleteArtistPress: PropTypes.func.isRequired
}; };
export default EditArtistModalContent; export default EditArtistModalContent;

@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import selectSettings from 'Store/Selectors/selectSettings'; import selectSettings from 'Store/Selectors/selectSettings';
import createArtistSelector from 'Store/Selectors/createArtistSelector'; import createArtistSelector from 'Store/Selectors/createArtistSelector';
import { setSeriesValue, saveArtist } from 'Store/Actions/artistActions'; import { setArtistValue, saveArtist } from 'Store/Actions/artistActions';
import EditArtistModalContent from './EditArtistModalContent'; import EditArtistModalContent from './EditArtistModalContent';
function createMapStateToProps() { function createMapStateToProps() {
@ -46,7 +46,7 @@ function createMapStateToProps() {
} }
const mapDispatchToProps = { const mapDispatchToProps = {
setSeriesValue, setArtistValue,
saveArtist saveArtist
}; };
@ -65,7 +65,7 @@ class EditArtistModalContentConnector extends Component {
// Listeners // Listeners
onInputChange = ({ name, value }) => { onInputChange = ({ name, value }) => {
this.props.setSeriesValue({ name, value }); this.props.setArtistValue({ name, value });
} }
onSavePress = () => { onSavePress = () => {
@ -90,7 +90,7 @@ EditArtistModalContentConnector.propTypes = {
artistId: PropTypes.number, artistId: PropTypes.number,
isSaving: PropTypes.bool.isRequired, isSaving: PropTypes.bool.isRequired,
saveError: PropTypes.object, saveError: PropTypes.object,
setSeriesValue: PropTypes.func.isRequired, setArtistValue: PropTypes.func.isRequired,
saveArtist: PropTypes.func.isRequired, saveArtist: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired onModalClose: PropTypes.func.isRequired
}; };

@ -220,7 +220,7 @@ class ArtistEditor extends Component {
filterValue={filterValue} filterValue={filterValue}
onPress={onFilterSelect} onPress={onFilterSelect}
> >
Missing Episodes Missing Albums
</FilterMenuItem> </FilterMenuItem>
</MenuContent> </MenuContent>
</FilterMenu> </FilterMenu>

@ -51,7 +51,7 @@
justify-content: space-between; justify-content: space-between;
} }
.selectedSeriesLabel { .selectedArtistLabel {
text-align: left; text-align: left;
} }
} }

@ -5,7 +5,7 @@ import SelectInput from 'Components/Form/SelectInput';
import LanguageProfileSelectInputConnector from 'Components/Form/LanguageProfileSelectInputConnector'; import LanguageProfileSelectInputConnector from 'Components/Form/LanguageProfileSelectInputConnector';
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector'; import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector'; import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
import SeriesTypeSelectInput from 'Components/Form/SeriesTypeSelectInput'; // import SeriesTypeSelectInput from 'Components/Form/SeriesTypeSelectInput';
import SpinnerButton from 'Components/Link/SpinnerButton'; import SpinnerButton from 'Components/Link/SpinnerButton';
import PageContentFooter from 'Components/Page/PageContentFooter'; import PageContentFooter from 'Components/Page/PageContentFooter';
import TagsModal from './Tags/TagsModal'; import TagsModal from './Tags/TagsModal';

@ -31,7 +31,7 @@ class DeleteArtistModalContent extends Component {
this.setState({ deleteFiles: value }); this.setState({ deleteFiles: value });
} }
onDeleteSeriesConfirmed = () => { onDeleteArtistConfirmed = () => {
const deleteFiles = this.state.deleteFiles; const deleteFiles = this.state.deleteFiles;
this.setState({ deleteFiles: false }); this.setState({ deleteFiles: false });
@ -104,7 +104,7 @@ class DeleteArtistModalContent extends Component {
<Button <Button
kind={kinds.DANGER} kind={kinds.DANGER}
onPress={this.onDeleteSeriesConfirmed} onPress={this.onDeleteArtistConfirmed}
> >
Delete Delete
</Button> </Button>

@ -9,12 +9,12 @@ function createMapStateToProps() {
return createSelector( return createSelector(
(state, { artistIds }) => artistIds, (state, { artistIds }) => artistIds,
createAllArtistSelector(), createAllArtistSelector(),
(artistIds, allSeries) => { (artistIds, allArtists) => {
const selectedSeries = _.intersectionWith(allSeries, artistIds, (s, id) => { const selectedArtist = _.intersectionWith(allArtists, artistIds, (s, id) => {
return s.id === id; return s.id === id;
}); });
const sortedArtist = _.orderBy(selectedSeries, 'sortName'); const sortedArtist = _.orderBy(selectedArtist, 'sortName');
const series = _.map(sortedArtist, (s) => { const series = _.map(sortedArtist, (s) => {
return { return {
artistName: s.artistName, artistName: s.artistName,

@ -12,8 +12,8 @@ function createMapStateToProps() {
return createSelector( return createSelector(
(state, { artistIds }) => artistIds, (state, { artistIds }) => artistIds,
createAllArtistSelector(), createAllArtistSelector(),
(artistIds, allSeries) => { (artistIds, allArtists) => {
const series = _.intersectionWith(allSeries, artistIds, (s, id) => { const series = _.intersectionWith(allArtists, artistIds, (s, id) => {
return s.id === id; return s.id === id;
}); });

@ -10,8 +10,8 @@ function createMapStateToProps() {
(state, { artistIds }) => artistIds, (state, { artistIds }) => artistIds,
createAllArtistSelector(), createAllArtistSelector(),
createTagsSelector(), createTagsSelector(),
(artistIds, allSeries, tagList) => { (artistIds, allArtists, tagList) => {
const series = _.intersectionWith(allSeries, artistIds, (s, id) => { const series = _.intersectionWith(allArtists, artistIds, (s, id) => {
return s.id === id; return s.id === id;
}); });

@ -85,7 +85,7 @@ class ArtistIndex extends Component {
sortDirection sortDirection
} = this.props; } = this.props;
// Reset if not sorting by sortTitle // Reset if not sorting by sortName
if (sortKey !== 'sortName') { if (sortKey !== 'sortName') {
this.setState({ jumpBarItems: [] }); this.setState({ jumpBarItems: [] });
return; return;
@ -162,7 +162,7 @@ class ArtistIndex extends Component {
sortKey, sortKey,
sortDirection, sortDirection,
view, view,
isRefreshingSeries, isRefreshingArtist,
isRssSyncExecuting, isRssSyncExecuting,
scrollTop, scrollTop,
onSortSelect, onSortSelect,
@ -191,7 +191,7 @@ class ArtistIndex extends Component {
label="Update all" label="Update all"
iconName={icons.REFRESH} iconName={icons.REFRESH}
spinningName={icons.REFRESH} spinningName={icons.REFRESH}
isSpinning={isRefreshingSeries} isSpinning={isRefreshingArtist}
onPress={onRefreshArtistPress} onPress={onRefreshArtistPress}
/> />
@ -311,7 +311,7 @@ ArtistIndex.propTypes = {
sortKey: PropTypes.string, sortKey: PropTypes.string,
sortDirection: PropTypes.oneOf(sortDirections.all), sortDirection: PropTypes.oneOf(sortDirections.all),
view: PropTypes.string.isRequired, view: PropTypes.string.isRequired,
isRefreshingSeries: PropTypes.bool.isRequired, isRefreshingArtist: PropTypes.bool.isRequired,
isRssSyncExecuting: PropTypes.bool.isRequired, isRssSyncExecuting: PropTypes.bool.isRequired,
scrollTop: PropTypes.number.isRequired, scrollTop: PropTypes.number.isRequired,
isSmallScreen: PropTypes.bool.isRequired, isSmallScreen: PropTypes.bool.isRequired,

@ -40,17 +40,17 @@ function getScrollTop(view, scrollTop, isSmallScreen) {
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state) => state.series, (state) => state.series,
(state) => state.seriesIndex, (state) => state.artistIndex,
createCommandSelector(commandNames.REFRESH_ARTIST), createCommandSelector(commandNames.REFRESH_ARTIST),
createCommandSelector(commandNames.RSS_SYNC), createCommandSelector(commandNames.RSS_SYNC),
createDimensionsSelector(), createDimensionsSelector(),
(series, seriesIndex, isRefreshingSeries, isRssSyncExecuting, dimensionsState) => { (series, artistIndex, isRefreshingArtist, isRssSyncExecuting, dimensionsState) => {
return { return {
isRefreshingSeries, isRefreshingArtist,
isRssSyncExecuting, isRssSyncExecuting,
isSmallScreen: dimensionsState.isSmallScreen, isSmallScreen: dimensionsState.isSmallScreen,
...series, ...series,
...seriesIndex ...artistIndex
}; };
} }
); );
@ -109,7 +109,7 @@ class ArtistIndexConnector extends Component {
this.setState({ this.setState({
scrollTop scrollTop
}, () => { }, () => {
scrollPositions.seriesIndex = scrollTop; scrollPositions.artistIndex = scrollTop;
}); });
} }
@ -156,5 +156,5 @@ ArtistIndexConnector.propTypes = {
export default withScrollPosition( export default withScrollPosition(
connect(createMapStateToProps, mapDispatchToProps)(ArtistIndexConnector), connect(createMapStateToProps, mapDispatchToProps)(ArtistIndexConnector),
'seriesIndex' 'artistIndex'
); );

@ -6,15 +6,15 @@ import styles from './ArtistIndexFooter.css';
function ArtistIndexFooter({ series }) { function ArtistIndexFooter({ series }) {
const count = series.length; const count = series.length;
let episodes = 0; let tracks = 0;
let episodeFiles = 0; let trackFiles = 0;
let ended = 0; let ended = 0;
let continuing = 0; let continuing = 0;
let monitored = 0; let monitored = 0;
series.forEach((s) => { series.forEach((s) => {
episodes += s.trackCount || 0; tracks += s.trackCount || 0;
episodeFiles += s.trackFileCount || 0; trackFiles += s.trackFileCount || 0;
if (s.status === 'ended') { if (s.status === 'ended') {
ended++; ended++;
@ -84,12 +84,12 @@ function ArtistIndexFooter({ series }) {
<DescriptionList> <DescriptionList>
<DescriptionListItem <DescriptionListItem
title="Tracks" title="Tracks"
data={episodes} data={tracks}
/> />
<DescriptionListItem <DescriptionListItem
title="Files" title="Files"
data={episodeFiles} data={trackFiles}
/> />
</DescriptionList> </DescriptionList>
</div> </div>

@ -12,23 +12,23 @@ import * as commandNames from 'Commands/commandNames';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state, { id }) => id, (state, { id }) => id,
(state, { seasons }) => seasons, (state, { albums }) => albums,
createQualityProfileSelector(), createQualityProfileSelector(),
createLanguageProfileSelector(), createLanguageProfileSelector(),
createCommandsSelector(), createCommandsSelector(),
(artistId, seasons, qualityProfile, languageProfile, commands) => { (artistId, albums, qualityProfile, languageProfile, commands) => {
const isRefreshingSeries = _.some(commands, (command) => { const isRefreshingArtist = _.some(commands, (command) => {
return command.name === commandNames.REFRESH_ARTIST && return command.name === commandNames.REFRESH_ARTIST &&
command.body.artistId === artistId; command.body.artistId === artistId;
}); });
const latestSeason = _.maxBy(seasons, (season) => season.seasonNumber); const latestAlbum = _.first(_.orderBy(albums, 'releaseDate', 'desc'));
return { return {
qualityProfile, qualityProfile,
languageProfile, languageProfile,
latestSeason, latestAlbum,
isRefreshingSeries isRefreshingArtist
}; };
} }
); );

@ -60,7 +60,7 @@ function ArtistIndexFilterMenu(props) {
filterValue={filterValue} filterValue={filterValue}
onPress={onFilterSelect} onPress={onFilterSelect}
> >
Missing Episodes Missing Albums
</FilterMenuItem> </FilterMenuItem>
</MenuContent> </MenuContent>
</FilterMenu> </FilterMenu>

@ -24,15 +24,6 @@ function ArtistIndexSortMenu(props) {
Name Name
</SortMenuItem> </SortMenuItem>
<SortMenuItem
name="network"
sortKey={sortKey}
sortDirection={sortDirection}
onPress={onSortSelect}
>
Network
</SortMenuItem>
<SortMenuItem <SortMenuItem
name="qualityProfileId" name="qualityProfileId"
sortKey={sortKey} sortKey={sortKey}
@ -106,12 +97,12 @@ function ArtistIndexSortMenu(props) {
</SortMenuItem> </SortMenuItem>
<SortMenuItem <SortMenuItem
name="latestSeason" name="latestAlbum"
sortKey={sortKey} sortKey={sortKey}
sortDirection={sortDirection} sortDirection={sortDirection}
onPress={onSortSelect} onPress={onSortSelect}
> >
Latest Season Latest Album
</SortMenuItem> </SortMenuItem>
<SortMenuItem <SortMenuItem

@ -30,15 +30,15 @@ class ArtistIndexPoster extends Component {
// //
// Listeners // Listeners
onEditSeriesPress = () => { onEditArtistPress = () => {
this.setState({ isEditArtistModalOpen: true }); this.setState({ isEditArtistModalOpen: true });
} }
onEditSeriesModalClose = () => { onEditArtistModalClose = () => {
this.setState({ isEditArtistModalOpen: false }); this.setState({ isEditArtistModalOpen: false });
} }
onDeleteSeriesPress = () => { onDeleteArtistPress = () => {
this.setState({ this.setState({
isEditArtistModalOpen: false, isEditArtistModalOpen: false,
isDeleteArtistModalOpen: true isDeleteArtistModalOpen: true
@ -73,7 +73,7 @@ class ArtistIndexPoster extends Component {
showRelativeDates, showRelativeDates,
shortDateFormat, shortDateFormat,
timeFormat, timeFormat,
isRefreshingSeries, isRefreshingArtist,
onRefreshArtistPress, onRefreshArtistPress,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -99,7 +99,7 @@ class ArtistIndexPoster extends Component {
className={styles.action} className={styles.action}
name={icons.REFRESH} name={icons.REFRESH}
title="Refresh Artist" title="Refresh Artist"
isSpinning={isRefreshingSeries} isSpinning={isRefreshingArtist}
onPress={onRefreshArtistPress} onPress={onRefreshArtistPress}
/> />
@ -107,7 +107,7 @@ class ArtistIndexPoster extends Component {
className={styles.action} className={styles.action}
name={icons.EDIT} name={icons.EDIT}
title="Edit Artist" title="Edit Artist"
onPress={this.onEditSeriesPress} onPress={this.onEditArtistPress}
/> />
</Label> </Label>
@ -183,8 +183,8 @@ class ArtistIndexPoster extends Component {
<EditArtistModalConnector <EditArtistModalConnector
isOpen={isEditArtistModalOpen} isOpen={isEditArtistModalOpen}
artistId={id} artistId={id}
onModalClose={this.onEditSeriesModalClose} onModalClose={this.onEditArtistModalClose}
onDeleteSeriesPress={this.onDeleteSeriesPress} onDeleteArtistPress={this.onDeleteArtistPress}
/> />
<DeleteArtistModal <DeleteArtistModal
@ -218,7 +218,7 @@ ArtistIndexPoster.propTypes = {
showRelativeDates: PropTypes.bool.isRequired, showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired, shortDateFormat: PropTypes.string.isRequired,
timeFormat: PropTypes.string.isRequired, timeFormat: PropTypes.string.isRequired,
isRefreshingSeries: PropTypes.bool.isRequired, isRefreshingArtist: PropTypes.bool.isRequired,
onRefreshArtistPress: PropTypes.func.isRequired onRefreshArtistPress: PropTypes.func.isRequired
}; };

@ -6,7 +6,6 @@ import styles from './ArtistIndexPosterInfo.css';
function ArtistIndexPosterInfo(props) { function ArtistIndexPosterInfo(props) {
const { const {
network,
qualityProfile, qualityProfile,
previousAiring, previousAiring,
added, added,
@ -19,14 +18,6 @@ function ArtistIndexPosterInfo(props) {
timeFormat timeFormat
} = props; } = props;
if (sortKey === 'network' && network) {
return (
<div className={styles.info}>
{network}
</div>
);
}
if (sortKey === 'qualityProfileId') { if (sortKey === 'qualityProfileId') {
return ( return (
<div className={styles.info}> <div className={styles.info}>
@ -72,17 +63,17 @@ function ArtistIndexPosterInfo(props) {
} }
if (sortKey === 'albumCount') { if (sortKey === 'albumCount') {
let seasons = '1 season'; let albums = '1 album';
if (albumCount === 0) { if (albumCount === 0) {
seasons = 'No seasons'; albums = 'No albums';
} else if (albumCount > 1) { } else if (albumCount > 1) {
seasons = `${albumCount} seasons`; albums = `${albumCount} albums`;
} }
return ( return (
<div className={styles.info}> <div className={styles.info}>
{seasons} {albums}
</div> </div>
); );
} }
@ -107,7 +98,6 @@ function ArtistIndexPosterInfo(props) {
} }
ArtistIndexPosterInfo.propTypes = { ArtistIndexPosterInfo.propTypes = {
network: PropTypes.string,
qualityProfile: PropTypes.object.isRequired, qualityProfile: PropTypes.object.isRequired,
previousAiring: PropTypes.string, previousAiring: PropTypes.string,
added: PropTypes.string, added: PropTypes.string,

@ -60,7 +60,6 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
} }
switch (sortKey) { switch (sortKey) {
case 'network':
case 'seasons': case 'seasons':
case 'previousAiring': case 'previousAiring':
case 'added': case 'added':
@ -79,7 +78,7 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
} }
function calculatePosterHeight(posterWidth) { function calculatePosterHeight(posterWidth) {
return Math.ceil((250 / 170) * posterWidth); return Math.ceil(posterWidth);
} }
class ArtistIndexPosters extends Component { class ArtistIndexPosters extends Component {
@ -94,7 +93,7 @@ class ArtistIndexPosters extends Component {
width: 0, width: 0,
columnWidth: 182, columnWidth: 182,
columnCount: 1, columnCount: 1,
posterWidth: 162, posterWidth: 238,
posterHeight: 238, posterHeight: 238,
rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {}) rowHeight: calculateRowHeight(238, null, props.isSmallScreen, {})
}; };
@ -149,7 +148,7 @@ class ArtistIndexPosters extends Component {
} = this.state; } = this.state;
const index = _.findIndex(items, (item) => { const index = _.findIndex(items, (item) => {
const firstCharacter = item.sortTitle.charAt(0); const firstCharacter = item.sortName.charAt(0);
if (character === '#') { if (character === '#') {
return !isNaN(firstCharacter); return !isNaN(firstCharacter);

@ -7,7 +7,7 @@ import ArtistIndexPosters from './ArtistIndexPosters';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state) => state.seriesIndex.posterOptions, (state) => state.artistIndex.posterOptions,
createClientSideCollectionSelector(), createClientSideCollectionSelector(),
createUISettingsSelector(), createUISettingsSelector(),
createDimensionsSelector(), createDimensionsSelector(),
@ -29,5 +29,5 @@ export default connectSection(
undefined, undefined,
undefined, undefined,
{ withRef: true }, { withRef: true },
{ section: 'series', uiSection: 'seriesIndex' } { section: 'series', uiSection: 'artistIndex' }
)(ArtistIndexPosters); )(ArtistIndexPosters);

@ -124,13 +124,13 @@ class ArtistIndexPosterOptionsModalContent extends Component {
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<FormLabel>Show Title</FormLabel> <FormLabel>Show Name</FormLabel>
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showTitle" name="showTitle"
value={showTitle} value={showTitle}
helpText="Show series title under poster" helpText="Show artist name under poster"
onChange={this.onChangePosterOption} onChange={this.onChangePosterOption}
/> />
</FormGroup> </FormGroup>

@ -5,9 +5,9 @@ import ArtistIndexPosterOptionsModalContent from './ArtistIndexPosterOptionsModa
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state) => state.seriesIndex, (state) => state.artistIndex,
(seriesIndex) => { (artistIndex) => {
return seriesIndex.posterOptions; return artistIndex.posterOptions;
} }
); );
} }

@ -24,15 +24,15 @@ class ArtistIndexActionsCell extends Component {
// //
// Listeners // Listeners
onEditSeriesPress = () => { onEditArtistPress = () => {
this.setState({ isEditArtistModalOpen: true }); this.setState({ isEditArtistModalOpen: true });
} }
onEditSeriesModalClose = () => { onEditArtistModalClose = () => {
this.setState({ isEditArtistModalOpen: false }); this.setState({ isEditArtistModalOpen: false });
} }
onDeleteSeriesPress = () => { onDeleteArtistPress = () => {
this.setState({ this.setState({
isEditArtistModalOpen: false, isEditArtistModalOpen: false,
isDeleteArtistModalOpen: true isDeleteArtistModalOpen: true
@ -49,7 +49,7 @@ class ArtistIndexActionsCell extends Component {
render() { render() {
const { const {
id, id,
isRefreshingSeries, isRefreshingArtist,
onRefreshArtistPress, onRefreshArtistPress,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -66,21 +66,21 @@ class ArtistIndexActionsCell extends Component {
<SpinnerIconButton <SpinnerIconButton
name={icons.REFRESH} name={icons.REFRESH}
title="Refresh Artist" title="Refresh Artist"
isSpinning={isRefreshingSeries} isSpinning={isRefreshingArtist}
onPress={onRefreshArtistPress} onPress={onRefreshArtistPress}
/> />
<IconButton <IconButton
name={icons.EDIT} name={icons.EDIT}
title="Edit Artist" title="Edit Artist"
onPress={this.onEditSeriesPress} onPress={this.onEditArtistPress}
/> />
<EditArtistModalConnector <EditArtistModalConnector
isOpen={isEditArtistModalOpen} isOpen={isEditArtistModalOpen}
artistId={id} artistId={id}
onModalClose={this.onEditSeriesModalClose} onModalClose={this.onEditArtistModalClose}
onDeleteSeriesPress={this.onDeleteSeriesPress} onDeleteArtistPress={this.onDeleteArtistPress}
/> />
<DeleteArtistModal <DeleteArtistModal
@ -95,7 +95,7 @@ class ArtistIndexActionsCell extends Component {
ArtistIndexActionsCell.propTypes = { ArtistIndexActionsCell.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
isRefreshingSeries: PropTypes.bool.isRequired, isRefreshingArtist: PropTypes.bool.isRequired,
onRefreshArtistPress: PropTypes.func.isRequired onRefreshArtistPress: PropTypes.func.isRequired
}; };

@ -10,12 +10,6 @@
flex: 4 0 110px; flex: 4 0 110px;
} }
.network {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
flex: 2 0 90px;
}
.qualityProfileId, .qualityProfileId,
.languageProfileId { .languageProfileId {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css'; composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
@ -38,7 +32,7 @@
} }
.trackProgress, .trackProgress,
.latestSeason { .latestAlbum {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css'; composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
flex: 0 0 150px; flex: 0 0 150px;

@ -10,12 +10,6 @@
flex: 4 0 110px; flex: 4 0 110px;
} }
.network {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
flex: 2 0 90px;
}
.qualityProfileId, .qualityProfileId,
.languageProfileId { .languageProfileId {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css'; composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
@ -38,7 +32,7 @@
} }
.trackProgress, .trackProgress,
.latestSeason { .latestAlbum {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css'; composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
display: flex; display: flex;

@ -31,15 +31,15 @@ class ArtistIndexRow extends Component {
}; };
} }
onEditSeriesPress = () => { onEditArtistPress = () => {
this.setState({ isEditArtistModalOpen: true }); this.setState({ isEditArtistModalOpen: true });
} }
onEditSeriesModalClose = () => { onEditArtistModalClose = () => {
this.setState({ isEditArtistModalOpen: false }); this.setState({ isEditArtistModalOpen: false });
} }
onDeleteSeriesPress = () => { onDeleteArtistPress = () => {
this.setState({ this.setState({
isEditArtistModalOpen: false, isEditArtistModalOpen: false,
isDeleteArtistModalOpen: true isDeleteArtistModalOpen: true
@ -66,7 +66,6 @@ class ArtistIndexRow extends Component {
status, status,
artistName, artistName,
nameSlug, nameSlug,
network,
qualityProfile, qualityProfile,
languageProfile, languageProfile,
nextAiring, nextAiring,
@ -76,13 +75,13 @@ class ArtistIndexRow extends Component {
trackCount, trackCount,
trackFileCount, trackFileCount,
totalTrackCount, totalTrackCount,
latestSeason, latestAlbum,
path, path,
sizeOnDisk, sizeOnDisk,
tags, tags,
// useSceneNumbering, // useSceneNumbering,
columns, columns,
isRefreshingSeries, isRefreshingArtist,
onRefreshArtistPress onRefreshArtistPress
} = this.props; } = this.props;
@ -130,17 +129,6 @@ class ArtistIndexRow extends Component {
); );
} }
if (name === 'network') {
return (
<VirtualTableRowCell
key={name}
className={styles[name]}
>
{network}
</VirtualTableRowCell>
);
}
if (name === 'qualityProfileId') { if (name === 'qualityProfileId') {
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
@ -227,9 +215,9 @@ class ArtistIndexRow extends Component {
); );
} }
if (name === 'latestSeason') { if (name === 'latestAlbum') {
const seasonStatistics = latestSeason.statistics; const albumStatistics = latestAlbum.statistics;
const progress = seasonStatistics.episodeCount ? seasonStatistics.episodeFileCount / seasonStatistics.episodeCount * 100 : 100; const progress = albumStatistics.trackCount ? albumStatistics.trackFileCount / albumStatistics.trackCount * 100 : 100;
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
@ -240,8 +228,8 @@ class ArtistIndexRow extends Component {
progress={progress} progress={progress}
kind={getProgressBarKind(status, monitored, progress)} kind={getProgressBarKind(status, monitored, progress)}
showText={true} showText={true}
text={`${seasonStatistics.episodeFileCount} / ${seasonStatistics.episodeCount}`} text={`${albumStatistics.trackFileCount} / ${albumStatistics.trackCount}`}
title={`${seasonStatistics.episodeFileCount} / ${seasonStatistics.episodeCount} (Total: ${seasonStatistics.totalEpisodeCount})`} title={`${albumStatistics.trackFileCount} / ${albumStatistics.trackCount} (Total: ${albumStatistics.totalTrackCount})`}
width={125} width={125}
/> />
</VirtualTableRowCell> </VirtualTableRowCell>
@ -320,14 +308,14 @@ class ArtistIndexRow extends Component {
<SpinnerIconButton <SpinnerIconButton
name={icons.REFRESH} name={icons.REFRESH}
title="Refresh Artist" title="Refresh Artist"
isSpinning={isRefreshingSeries} isSpinning={isRefreshingArtist}
onPress={onRefreshArtistPress} onPress={onRefreshArtistPress}
/> />
<IconButton <IconButton
name={icons.EDIT} name={icons.EDIT}
title="Edit Artist" title="Edit Artist"
onPress={this.onEditSeriesPress} onPress={this.onEditArtistPress}
/> />
</VirtualTableRowCell> </VirtualTableRowCell>
); );
@ -340,8 +328,8 @@ class ArtistIndexRow extends Component {
<EditArtistModalConnector <EditArtistModalConnector
isOpen={isEditArtistModalOpen} isOpen={isEditArtistModalOpen}
artistId={id} artistId={id}
onModalClose={this.onEditSeriesModalClose} onModalClose={this.onEditArtistModalClose}
onDeleteSeriesPress={this.onDeleteSeriesPress} onDeleteArtistPress={this.onDeleteArtistPress}
/> />
<DeleteArtistModal <DeleteArtistModal
@ -361,7 +349,6 @@ ArtistIndexRow.propTypes = {
status: PropTypes.string.isRequired, status: PropTypes.string.isRequired,
artistName: PropTypes.string.isRequired, artistName: PropTypes.string.isRequired,
nameSlug: PropTypes.string.isRequired, nameSlug: PropTypes.string.isRequired,
network: PropTypes.string,
qualityProfile: PropTypes.object.isRequired, qualityProfile: PropTypes.object.isRequired,
languageProfile: PropTypes.object.isRequired, languageProfile: PropTypes.object.isRequired,
nextAiring: PropTypes.string, nextAiring: PropTypes.string,
@ -371,13 +358,13 @@ ArtistIndexRow.propTypes = {
trackCount: PropTypes.number, trackCount: PropTypes.number,
trackFileCount: PropTypes.number, trackFileCount: PropTypes.number,
totalTrackCount: PropTypes.number, totalTrackCount: PropTypes.number,
latestSeason: PropTypes.object, latestAlbum: PropTypes.object,
path: PropTypes.string.isRequired, path: PropTypes.string.isRequired,
sizeOnDisk: PropTypes.number, sizeOnDisk: PropTypes.number,
tags: PropTypes.arrayOf(PropTypes.number).isRequired, tags: PropTypes.arrayOf(PropTypes.number).isRequired,
// useSceneNumbering: PropTypes.bool.isRequired, // useSceneNumbering: PropTypes.bool.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired, columns: PropTypes.arrayOf(PropTypes.object).isRequired,
isRefreshingSeries: PropTypes.bool.isRequired, isRefreshingArtist: PropTypes.bool.isRequired,
onRefreshArtistPress: PropTypes.func.isRequired onRefreshArtistPress: PropTypes.func.isRequired
}; };

@ -45,7 +45,7 @@ class ArtistIndexTable extends Component {
const items = this.props.items; const items = this.props.items;
const row = _.findIndex(items, (item) => { const row = _.findIndex(items, (item) => {
const firstCharacter = item.sortTitle.charAt(0); const firstCharacter = item.sortName.charAt(0);
if (character === '#') { if (character === '#') {
return !isNaN(firstCharacter); return !isNaN(firstCharacter);

@ -30,5 +30,5 @@ export default connectSection(
createMapDispatchToProps, createMapDispatchToProps,
undefined, undefined,
{ withRef: true }, { withRef: true },
{ section: 'series', uiSection: 'seriesIndex' } { section: 'series', uiSection: 'artistIndex' }
)(ArtistIndexTable); )(ArtistIndexTable);

@ -23,7 +23,6 @@ export default function artistIndexCellRenderers(cellProps) {
status, status,
name, name,
nameSlug, nameSlug,
network,
qualityProfileId, qualityProfileId,
nextAiring, nextAiring,
previousAiring, previousAiring,
@ -46,7 +45,7 @@ export default function artistIndexCellRenderers(cellProps) {
); );
} }
if (dataKey === 'sortTitle') { if (dataKey === 'sortName') {
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
key={cellKey} key={cellKey}
@ -61,18 +60,6 @@ export default function artistIndexCellRenderers(cellProps) {
); );
} }
if (dataKey === 'network') {
return (
<VirtualTableRowCell
key={cellKey}
{...otherProps}
>
{network}
</VirtualTableRowCell>
);
}
if (dataKey === 'qualityProfileId') { if (dataKey === 'qualityProfileId') {
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
@ -97,7 +84,7 @@ export default function artistIndexCellRenderers(cellProps) {
); );
} }
if (dataKey === 'seasonCount') { if (dataKey === 'albumCount') {
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
key={cellKey} key={cellKey}
@ -108,7 +95,7 @@ export default function artistIndexCellRenderers(cellProps) {
); );
} }
if (dataKey === 'episodeProgress') { if (dataKey === 'trackProgress') {
return ( return (
<VirtualTableRowCell <VirtualTableRowCell
key={cellKey} key={cellKey}

@ -70,8 +70,8 @@
composes: missing from 'Calendar/Events/CalendarEvent.css'; composes: missing from 'Calendar/Events/CalendarEvent.css';
} }
.unaired { .unreleased {
composes: unaired from 'Calendar/Events/CalendarEvent.css'; composes: unreleased from 'Calendar/Events/CalendarEvent.css';
} }
@media only screen and (max-width: $breakpointSmall) { @media only screen and (max-width: $breakpointSmall) {

@ -123,7 +123,7 @@ class AgendaEvent extends Component {
episodeEntity={episodeEntities.CALENDAR} episodeEntity={episodeEntities.CALENDAR}
artistId={artist.id} artistId={artist.id}
episodeTitle={title} episodeTitle={title}
showOpenSeriesButton={true} showOpenArtistButton={true}
onModalClose={this.onDetailsModalClose} onModalClose={this.onDetailsModalClose}
/> />
</div> </div>

@ -61,7 +61,7 @@
} }
} }
.unaired { .unreleased {
border-left-color: $primaryColor; border-left-color: $primaryColor;
&:global(.colorImpaired) { &:global(.colorImpaired) {

@ -116,7 +116,7 @@ class CalendarEvent extends Component {
episodeEntity={episodeEntities.CALENDAR} episodeEntity={episodeEntities.CALENDAR}
artistId={artist.id} artistId={artist.id}
episodeTitle={title} episodeTitle={title}
showOpenSeriesButton={true} showOpenArtistButton={true}
onModalClose={this.onDetailsModalClose} onModalClose={this.onDetailsModalClose}
/> />
</div> </div>

@ -22,7 +22,7 @@ function Legend({ colorImpairedMode }) {
<div> <div>
<LegendItem <LegendItem
status="unaired" status="unreleased"
tooltip="Album hasn't released yet" tooltip="Album hasn't released yet"
colorImpairedMode={colorImpairedMode} colorImpairedMode={colorImpairedMode}
/> />

@ -32,6 +32,6 @@
composes: missing from 'Calendar/Events/CalendarEvent.css'; composes: missing from 'Calendar/Events/CalendarEvent.css';
} }
.unaired { .unreleased {
composes: unaired from 'Calendar/Events/CalendarEvent.css'; composes: unreleased from 'Calendar/Events/CalendarEvent.css';
} }

@ -19,7 +19,7 @@ function getStatusStyle(episodeNumber, downloading, startTime, isMonitored) {
return 'missing'; return 'missing';
} }
return 'unaired'; return 'unreleased';
} }
export default getStatusStyle; export default getStatusStyle;

@ -76,7 +76,7 @@ class ArtistSearchInput extends Component {
); );
} }
goToSeries(series) { goToArtist(series) {
this.setState({ value: '' }); this.setState({ value: '' });
this.props.onGoToSeries(series.nameSlug); this.props.onGoToSeries(series.nameSlug);
} }
@ -121,9 +121,9 @@ class ArtistSearchInput extends Component {
// otherwise go to the selected series. // otherwise go to the selected series.
if (highlightedSuggestionIndex == null) { if (highlightedSuggestionIndex == null) {
this.goToSeries(suggestions[0]); this.goToArtist(suggestions[0]);
} else { } else {
this.goToSeries(suggestions[highlightedSuggestionIndex]); this.goToArtist(suggestions[highlightedSuggestionIndex]);
} }
} }
@ -155,7 +155,7 @@ class ArtistSearchInput extends Component {
if (suggestion.type === ADD_NEW_TYPE) { if (suggestion.type === ADD_NEW_TYPE) {
this.props.onGoToAddNewArtist(this.state.value); this.props.onGoToAddNewArtist(this.state.value);
} else { } else {
this.goToSeries(suggestion); this.goToArtist(suggestion);
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

@ -1,4 +1,4 @@
.seriesTitle { .artistName {
margin-left: 5px; margin-left: 5px;
} }

@ -47,7 +47,7 @@ class EpisodeDetailsModalContent extends Component {
episodeId, episodeId,
episodeEntity, episodeEntity,
artistId, artistId,
seriesTitle, artistName,
nameSlug, nameSlug,
albumLabel, albumLabel,
artistMonitored, artistMonitored,
@ -55,7 +55,7 @@ class EpisodeDetailsModalContent extends Component {
releaseDate, releaseDate,
monitored, monitored,
isSaving, isSaving,
showOpenSeriesButton, showOpenArtistButton,
startInteractiveSearch, startInteractiveSearch,
onMonitorAlbumPress, onMonitorAlbumPress,
onModalClose onModalClose
@ -78,8 +78,8 @@ class EpisodeDetailsModalContent extends Component {
onPress={onMonitorAlbumPress} onPress={onMonitorAlbumPress}
/> />
<span className={styles.seriesTitle}> <span className={styles.artistName}>
{seriesTitle} {artistName}
</span> </span>
<span className={styles.separator}>-</span> <span className={styles.separator}>-</span>
@ -146,7 +146,7 @@ class EpisodeDetailsModalContent extends Component {
<ModalFooter> <ModalFooter>
{ {
showOpenSeriesButton && showOpenArtistButton &&
<Button <Button
className={styles.openSeriesButton} className={styles.openSeriesButton}
to={seriesLink} to={seriesLink}
@ -171,7 +171,7 @@ EpisodeDetailsModalContent.propTypes = {
episodeId: PropTypes.number.isRequired, episodeId: PropTypes.number.isRequired,
episodeEntity: PropTypes.string.isRequired, episodeEntity: PropTypes.string.isRequired,
artistId: PropTypes.number.isRequired, artistId: PropTypes.number.isRequired,
seriesTitle: PropTypes.string.isRequired, artistName: PropTypes.string.isRequired,
nameSlug: PropTypes.string.isRequired, nameSlug: PropTypes.string.isRequired,
artistMonitored: PropTypes.bool.isRequired, artistMonitored: PropTypes.bool.isRequired,
releaseDate: PropTypes.string.isRequired, releaseDate: PropTypes.string.isRequired,
@ -179,7 +179,7 @@ EpisodeDetailsModalContent.propTypes = {
episodeTitle: PropTypes.string.isRequired, episodeTitle: PropTypes.string.isRequired,
monitored: PropTypes.bool.isRequired, monitored: PropTypes.bool.isRequired,
isSaving: PropTypes.bool, isSaving: PropTypes.bool,
showOpenSeriesButton: PropTypes.bool, showOpenArtistButton: PropTypes.bool,
selectedTab: PropTypes.string.isRequired, selectedTab: PropTypes.string.isRequired,
startInteractiveSearch: PropTypes.bool.isRequired, startInteractiveSearch: PropTypes.bool.isRequired,
onMonitorAlbumPress: PropTypes.func.isRequired, onMonitorAlbumPress: PropTypes.func.isRequired,

@ -15,14 +15,14 @@ function createMapStateToProps() {
createArtistSelector(), createArtistSelector(),
(episode, series) => { (episode, series) => {
const { const {
artistName: seriesTitle, artistName,
nameSlug, nameSlug,
monitored: artistMonitored, monitored: artistMonitored,
seriesType seriesType
} = series; } = series;
return { return {
seriesTitle, artistName,
nameSlug, nameSlug,
artistMonitored, artistMonitored,
seriesType, seriesType,

@ -147,14 +147,14 @@ class InteractiveImportRow extends Component {
isSelectQualityModalOpen isSelectQualityModalOpen
} = this.state; } = this.state;
const seriesTitle = artist ? artist.artistName : ''; const artistName = artist ? artist.artistName : '';
const albumTitle = album ? album.title : ''; const albumTitle = album ? album.title : '';
const trackNumbers = tracks.map((episode) => episode.trackNumber) const trackNumbers = tracks.map((episode) => episode.trackNumber)
.join(', '); .join(', ');
const showSeriesPlaceholder = isSelected && !artist; const showArtistPlaceholder = isSelected && !artist;
const showSeasonNumberPlaceholder = isSelected && !!artist && !album; const showAlbumNumberPlaceholder = isSelected && !!artist && !album;
const showEpisodeNumbersPlaceholder = isSelected && !!album && !tracks.length; const showTrackNumbersPlaceholder = isSelected && !!album && !tracks.length;
return ( return (
<TableRow> <TableRow>
@ -175,7 +175,7 @@ class InteractiveImportRow extends Component {
onPress={this.onSelectArtistPress} onPress={this.onSelectArtistPress}
> >
{ {
showSeriesPlaceholder ? <InteractiveImportRowCellPlaceholder /> : seriesTitle showArtistPlaceholder ? <InteractiveImportRowCellPlaceholder /> : artistName
} }
</TableRowCellButton> </TableRowCellButton>
@ -184,7 +184,7 @@ class InteractiveImportRow extends Component {
onPress={this.onSelectAlbumPress} onPress={this.onSelectAlbumPress}
> >
{ {
showSeasonNumberPlaceholder ? <InteractiveImportRowCellPlaceholder /> : albumTitle showAlbumNumberPlaceholder ? <InteractiveImportRowCellPlaceholder /> : albumTitle
} }
</TableRowCellButton> </TableRowCellButton>
@ -193,7 +193,7 @@ class InteractiveImportRow extends Component {
onPress={this.onSelectTrackPress} onPress={this.onSelectTrackPress}
> >
{ {
showEpisodeNumbersPlaceholder ? <InteractiveImportRowCellPlaceholder /> : trackNumbers showTrackNumbersPlaceholder ? <InteractiveImportRowCellPlaceholder /> : trackNumbers
} }
</TableRowCellButton> </TableRowCellButton>

@ -78,7 +78,7 @@ class MediaManagement extends Component {
<FormInputGroup <FormInputGroup
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="createEmptyArtistFolders" name="createEmptyArtistFolders"
helpText="Create missing series folders during disk scan" helpText="Create missing artist folders during disk scan"
onChange={onInputChange} onChange={onInputChange}
{...settings.createEmptyArtistFolders} {...settings.createEmptyArtistFolders}
/> />
@ -284,7 +284,7 @@ class MediaManagement extends Component {
<FormInputGroup <FormInputGroup
type={inputTypes.TEXT} type={inputTypes.TEXT}
name="folderChmod" name="folderChmod"
helpText="Octal, applied to series/season folders created by Lidarr" helpText="Octal, applied to artist/album folders created by Lidarr"
values={fileDateOptions} values={fileDateOptions}
onChange={onInputChange} onChange={onInputChange}
{...settings.folderChmod} {...settings.folderChmod}

@ -18,10 +18,10 @@ const albumStudioActionHandlers = {
let monitoringOptions = null; let monitoringOptions = null;
const series = []; const series = [];
const allSeries = getState().series.items; const allArtists = getState().series.items;
artistIds.forEach((id) => { artistIds.forEach((id) => {
const s = _.find(allSeries, { id }); const s = _.find(allArtists, { id });
const seriesToUpdate = { id }; const seriesToUpdate = { id };
if (payload.hasOwnProperty('monitored')) { if (payload.hasOwnProperty('monitored')) {

@ -8,7 +8,7 @@ export const deleteArtist = artistActionHandlers[types.DELETE_ARTIST];
export const toggleSeriesMonitored = artistActionHandlers[types.TOGGLE_ARTIST_MONITORED]; export const toggleSeriesMonitored = artistActionHandlers[types.TOGGLE_ARTIST_MONITORED];
export const toggleSeasonMonitored = artistActionHandlers[types.TOGGLE_ALBUM_MONITORED]; export const toggleSeasonMonitored = artistActionHandlers[types.TOGGLE_ALBUM_MONITORED];
export const setSeriesValue = createAction(types.SET_ARTIST_VALUE, (payload) => { export const setArtistValue = createAction(types.SET_ARTIST_VALUE, (payload) => {
return { return {
section: 'series', section: 'series',
...payload ...payload

@ -80,7 +80,7 @@ const importArtistActionHandlers = {
error: null, error: null,
items: data, items: data,
queued: false, queued: false,
selectedSeries: queued.selectedSeries || data[0] selectedArtist: queued.selectedArtist || data[0]
})); }));
}); });
@ -112,12 +112,12 @@ const importArtistActionHandlers = {
const allNewSeries = ids.reduce((acc, id) => { const allNewSeries = ids.reduce((acc, id) => {
const item = _.find(items, { id }); const item = _.find(items, { id });
const selectedSeries = item.selectedSeries; const selectedArtist = item.selectedArtist;
// Make sure we have a selected series and // Make sure we have a selected series and
// the same series hasn't been added yet. // the same series hasn't been added yet.
if (selectedSeries && !_.some(acc, { foreignArtistId: selectedSeries.foreignArtistId })) { if (selectedArtist && !_.some(acc, { foreignArtistId: selectedArtist.foreignArtistId })) {
const newSeries = getNewSeries(_.cloneDeep(selectedSeries), item); const newSeries = getNewSeries(_.cloneDeep(selectedArtist), item);
newSeries.path = item.path; newSeries.path = item.path;
addedIds.push(id); addedIds.push(id);

@ -2,7 +2,7 @@ import { createAction } from 'redux-actions';
import * as types from './actionTypes'; import * as types from './actionTypes';
import importArtistActionHandlers from './importArtistActionHandlers'; import importArtistActionHandlers from './importArtistActionHandlers';
export const queueLookupSeries = importArtistActionHandlers[types.QUEUE_LOOKUP_ARTIST]; export const queueLookupArtist = importArtistActionHandlers[types.QUEUE_LOOKUP_ARTIST];
export const startLookupSeries = importArtistActionHandlers[types.START_LOOKUP_ARTIST]; export const startLookupSeries = importArtistActionHandlers[types.START_LOOKUP_ARTIST];
export const importArtist = importArtistActionHandlers[types.IMPORT_ARTIST]; export const importArtist = importArtistActionHandlers[types.IMPORT_ARTIST];
export const clearImportArtist = createAction(types.CLEAR_IMPORT_ARTIST); export const clearImportArtist = createAction(types.CLEAR_IMPORT_ARTIST);

@ -1,7 +1,6 @@
import { applyMiddleware, compose } from 'redux'; import { applyMiddleware, compose } from 'redux';
import Raven from 'raven-js'; import Raven from 'raven-js';
import createRavenMiddleware from 'raven-for-redux'; import createRavenMiddleware from 'raven-for-redux';
// import ravenMiddleware from 'redux-raven-middleware';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
import { routerMiddleware } from 'react-router-redux'; import { routerMiddleware } from 'react-router-redux';
import persistState from './persistState'; import persistState from './persistState';

@ -8,9 +8,9 @@ import createSetClientSideCollectionFilterReducer from './Creators/createSetClie
export const defaultState = { export const defaultState = {
isSaving: false, isSaving: false,
saveError: null, saveError: null,
sortKey: 'sortTitle', sortKey: 'sortName',
sortDirection: sortDirections.ASCENDING, sortDirection: sortDirections.ASCENDING,
secondarySortKey: 'sortTitle', secondarySortKey: 'sortName',
secondarySortDirection: sortDirections.ASCENDING, secondarySortDirection: sortDirections.ASCENDING,
filterKey: null, filterKey: null,
filterValue: null, filterValue: null,

@ -10,9 +10,9 @@ export const defaultState = {
saveError: null, saveError: null,
isDeleting: false, isDeleting: false,
deleteError: null, deleteError: null,
sortKey: 'sortTitle', sortKey: 'sortName',
sortDirection: sortDirections.ASCENDING, sortDirection: sortDirections.ASCENDING,
secondarySortKey: 'sortTitle', secondarySortKey: 'sortName',
secondarySortDirection: sortDirections.ASCENDING, secondarySortDirection: sortDirections.ASCENDING,
filterKey: null, filterKey: null,
filterValue: null, filterValue: null,

@ -8,9 +8,9 @@ import createSetClientSideCollectionSortReducer from './Creators/createSetClient
import createSetClientSideCollectionFilterReducer from './Creators/createSetClientSideCollectionFilterReducer'; import createSetClientSideCollectionFilterReducer from './Creators/createSetClientSideCollectionFilterReducer';
export const defaultState = { export const defaultState = {
sortKey: 'sortTitle', sortKey: 'sortName',
sortDirection: sortDirections.ASCENDING, sortDirection: sortDirections.ASCENDING,
secondarySortKey: 'sortTitle', secondarySortKey: 'sortName',
secondarySortDirection: sortDirections.ASCENDING, secondarySortDirection: sortDirections.ASCENDING,
filterKey: null, filterKey: null,
filterValue: null, filterValue: null,
@ -38,12 +38,6 @@ export const defaultState = {
isVisible: true, isVisible: true,
isModifiable: false isModifiable: false
}, },
{
name: 'network',
label: 'Network',
isSortable: true,
isVisible: true
},
{ {
name: 'qualityProfileId', name: 'qualityProfileId',
label: 'Quality Profile', label: 'Quality Profile',
@ -93,8 +87,8 @@ export const defaultState = {
isVisible: false isVisible: false
}, },
{ {
name: 'latestSeason', name: 'latestAlbum',
label: 'Latest Season', label: 'Latest Album',
isSortable: true, isSortable: true,
isVisible: false isVisible: false
}, },
@ -116,12 +110,6 @@ export const defaultState = {
isSortable: false, isSortable: false,
isVisible: false isVisible: false
}, },
{
name: 'useSceneNumbering',
label: 'Scene Numbering',
isSortable: true,
isVisible: false
},
{ {
name: 'actions', name: 'actions',
columnLabel: 'Actions', columnLabel: 'Actions',
@ -131,12 +119,6 @@ export const defaultState = {
], ],
sortPredicates: { sortPredicates: {
network: function(item) {
const network = item.network;
return network ? network.toLowerCase() : '';
},
nextAiring: function(item, direction) { nextAiring: function(item, direction) {
const nextAiring = item.nextAiring; const nextAiring = item.nextAiring;
@ -151,37 +133,37 @@ export const defaultState = {
return Number.MAX_VALUE; return Number.MAX_VALUE;
}, },
episodeProgress: function(item) { trackProgress: function(item) {
const { const {
episodeCount = 0, trackCount = 0,
episodeFileCount trackFileCount
} = item; } = item;
const progress = episodeCount ? episodeFileCount / episodeCount * 100 : 100; const progress = trackCount ? trackFileCount / trackCount * 100 : 100;
return progress + episodeCount / 1000000; return progress + trackCount / 1000000;
} }
}, },
filterPredicates: { filterPredicates: {
missing: function(item) { missing: function(item) {
return item.episodeCount - item.episodeFileCount > 0; return item.trackCount - item.trackFileCount > 0;
} }
} }
}; };
export const persistState = [ export const persistState = [
'seriesIndex.sortKey', 'artistIndex.sortKey',
'seriesIndex.sortDirection', 'artistIndex.sortDirection',
'seriesIndex.filterKey', 'artistIndex.filterKey',
'seriesIndex.filterValue', 'artistIndex.filterValue',
'seriesIndex.filterType', 'artistIndex.filterType',
'seriesIndex.view', 'artistIndex.view',
'seriesIndex.columns', 'artistIndex.columns',
'seriesIndex.posterOptions' 'artistIndex.posterOptions'
]; ];
const reducerSection = 'seriesIndex'; const reducerSection = 'artistIndex';
const artistIndexReducers = handleActions({ const artistIndexReducers = handleActions({

@ -15,7 +15,7 @@ export const defaultState = {
isSaving: false, isSaving: false,
saveError: null, saveError: null,
items: [], items: [],
sortKey: 'sortTitle', sortKey: 'sortName',
sortDirection: sortDirections.ASCENDING, sortDirection: sortDirections.ASCENDING,
pendingChanges: {} pendingChanges: {}
}; };

@ -19,8 +19,8 @@ export const defaultState = {
columns: [ columns: [
{ {
name: 'series.sortTitle', name: 'series.sortName',
label: 'Series Title', label: 'Artist Name',
isSortable: true, isSortable: true,
isVisible: true isVisible: true
}, },

@ -4,8 +4,8 @@ import { routerReducer } from 'react-router-redux';
import app, { defaultState as defaultappState } from './appReducers'; import app, { defaultState as defaultappState } from './appReducers';
import addArtist, { defaultState as defaultAddSeriesState } from './addArtistReducers'; import addArtist, { defaultState as defaultAddSeriesState } from './addArtistReducers';
import importArtist, { defaultState as defaultImportArtistState } from './importArtistReducers'; import importArtist, { defaultState as defaultImportArtistState } from './importArtistReducers';
import series, { defaultState as defaultSeriesState } from './artistReducers'; import series, { defaultState as defaultArtistState } from './artistReducers';
import seriesIndex, { defaultState as defaultSeriesIndexState } from './artistIndexReducers'; import artistIndex, { defaultState as defaultArtistIndexState } from './artistIndexReducers';
import artistEditor, { defaultState as defaultArtistEditorState } from './artistEditorReducers'; import artistEditor, { defaultState as defaultArtistEditorState } from './artistEditorReducers';
import albumStudio, { defaultState as defaultAlbumStudioState } from './albumStudioReducers'; import albumStudio, { defaultState as defaultAlbumStudioState } from './albumStudioReducers';
import calendar, { defaultState as defaultCalendarState } from './calendarReducers'; import calendar, { defaultState as defaultCalendarState } from './calendarReducers';
@ -32,8 +32,8 @@ export const defaultState = {
app: defaultappState, app: defaultappState,
addArtist: defaultAddSeriesState, addArtist: defaultAddSeriesState,
importArtist: defaultImportArtistState, importArtist: defaultImportArtistState,
series: defaultSeriesState, series: defaultArtistState,
seriesIndex: defaultSeriesIndexState, artistIndex: defaultArtistIndexState,
artistEditor: defaultArtistEditorState, artistEditor: defaultArtistEditorState,
albumStudio: defaultAlbumStudioState, albumStudio: defaultAlbumStudioState,
calendar: defaultCalendarState, calendar: defaultCalendarState,
@ -62,7 +62,7 @@ export default enableBatching(combineReducers({
addArtist, addArtist,
importArtist, importArtist,
series, series,
seriesIndex, artistIndex,
artistEditor, artistEditor,
albumStudio, albumStudio,
calendar, calendar,

@ -20,7 +20,7 @@ export const defaultState = {
series: function(item, direction) { series: function(item, direction) {
const series = item.series; const series = item.series;
return series ? series.sortTitle : ''; return series ? series.sortName : '';
}, },
quality: function(item, direction) { quality: function(item, direction) {

@ -71,8 +71,8 @@ export const defaultState = {
columns: [ columns: [
{ {
name: 'series.sortTitle', name: 'series.sortName',
label: 'Series Title', label: 'Artist Name',
isSortable: true, isSortable: true,
isVisible: true isVisible: true
}, },

@ -10,8 +10,8 @@ function createImportArtistItemSelector() {
createAllArtistSelector(), createAllArtistSelector(),
(id, addArtist, importArtist, series) => { (id, addArtist, importArtist, series) => {
const item = _.find(importArtist.items, { id }) || {}; const item = _.find(importArtist.items, { id }) || {};
const selectedSeries = item && item.selectedSeries; const selectedArtist = item && item.selectedArtist;
const isExistingArtist = !!selectedSeries && _.some(series, { foreignArtistId: selectedSeries.foreignArtistId }); const isExistingArtist = !!selectedArtist && _.some(series, { foreignArtistId: selectedArtist.foreignArtistId });
return { return {
defaultMonitor: addArtist.defaults.monitor, defaultMonitor: addArtist.defaults.monitor,

@ -1,5 +1,5 @@
const scrollPositions = { const scrollPositions = {
seriesIndex: 0 artistIndex: 0
}; };
export default scrollPositions; export default scrollPositions;

@ -45,7 +45,7 @@ class CutoffUnmet extends Component {
this.setState((state) => { this.setState((state) => {
return removeOldSelectedState(state, prevProps.items); return removeOldSelectedState(state, prevProps.items);
}); });
}s; }
} }
// //

@ -50,7 +50,7 @@ function CutoffUnmetRow(props) {
return null; return null;
} }
if (name === 'series.sortTitle') { if (name === 'series.sortName') {
return ( return (
<TableRowCell key={name}> <TableRowCell key={name}>
<ArtistNameLink <ArtistNameLink
@ -88,7 +88,7 @@ function CutoffUnmetRow(props) {
artistId={series.id} artistId={series.id}
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET} episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
episodeTitle={title} episodeTitle={title}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
</TableRowCell> </TableRowCell>
); );
@ -139,7 +139,7 @@ function CutoffUnmetRow(props) {
artistId={series.id} artistId={series.id}
episodeTitle={title} episodeTitle={title}
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET} episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
); );
} }

@ -87,7 +87,7 @@ function MissingRow(props) {
artistId={artist.id} artistId={artist.id}
episodeEntity={episodeEntities.WANTED_MISSING} episodeEntity={episodeEntities.WANTED_MISSING}
episodeTitle={title} episodeTitle={title}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
</TableRowCell> </TableRowCell>
); );
@ -125,7 +125,7 @@ function MissingRow(props) {
artistId={artist.id} artistId={artist.id}
episodeTitle={title} episodeTitle={title}
episodeEntity={episodeEntities.WANTED_MISSING} episodeEntity={episodeEntities.WANTED_MISSING}
showOpenSeriesButton={true} showOpenArtistButton={true}
/> />
); );
} }

Loading…
Cancel
Save