Refactor Episode section naming to Album in UI

This commit is contained in:
Qstick 2018-01-01 01:05:24 -05:00
parent 0e7a22dc95
commit b1a016289c
66 changed files with 372 additions and 372 deletions

View File

@ -54,7 +54,7 @@ class History extends Component {
totalRecords,
isAlbumsFetching,
isAlbumsPopulated,
episodesError,
albumsError,
onFilterSelect,
onFirstPagePress,
...otherProps
@ -62,7 +62,7 @@ class History extends Component {
const isFetchingAny = isFetching || isAlbumsFetching;
const isAllPopulated = isPopulated && (isAlbumsPopulated || !items.length);
const hasError = error || episodesError;
const hasError = error || albumsError;
return (
<PageContent title="History">
@ -209,7 +209,7 @@ History.propTypes = {
totalRecords: PropTypes.number,
isAlbumsFetching: PropTypes.bool.isRequired,
isAlbumsPopulated: PropTypes.bool.isRequired,
episodesError: PropTypes.object,
albumsError: PropTypes.object,
onFilterSelect: PropTypes.func.isRequired,
onFirstPagePress: PropTypes.func.isRequired
};

View File

@ -6,20 +6,20 @@ import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePo
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import * as historyActions from 'Store/Actions/historyActions';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
import { fetchTracks, clearTracks } from 'Store/Actions/trackActions';
import History from './History';
function createMapStateToProps() {
return createSelector(
(state) => state.history,
(state) => state.episodes,
(state) => state.albums,
(state) => state.tracks,
(history, episodes, tracks) => {
(history, albums, tracks) => {
return {
isAlbumsFetching: episodes.isFetching,
isAlbumsPopulated: episodes.isPopulated,
episodesError: episodes.error,
isAlbumsFetching: albums.isFetching,
isAlbumsPopulated: albums.isPopulated,
albumsError: albums.error,
isTracksFetching: tracks.isFetching,
isTracksPopulated: tracks.isPopulated,
tracksError: tracks.error,
@ -31,8 +31,8 @@ function createMapStateToProps() {
const mapDispatchToProps = {
...historyActions,
fetchEpisodes,
clearEpisodes,
fetchAlbums,
clearAlbums,
fetchTracks,
clearTracks
};
@ -52,9 +52,9 @@ class HistoryConnector extends Component {
const albumIds = selectUniqueIds(this.props.items, 'albumId');
const trackIds = selectUniqueIds(this.props.items, 'trackId');
if (albumIds.length) {
this.props.fetchEpisodes({ albumIds });
this.props.fetchAlbums({ albumIds });
} else {
this.props.clearEpisodes();
this.props.clearAlbums();
}
if (trackIds.length) {
this.props.fetchTracks({ trackIds });
@ -67,7 +67,7 @@ class HistoryConnector extends Component {
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearHistory();
this.props.clearEpisodes();
this.props.clearAlbums();
this.props.clearTracks();
}
@ -149,8 +149,8 @@ HistoryConnector.propTypes = {
setHistoryFilter: PropTypes.func.isRequired,
setHistoryTableOption: PropTypes.func.isRequired,
clearHistory: PropTypes.func.isRequired,
fetchEpisodes: PropTypes.func.isRequired,
clearEpisodes: PropTypes.func.isRequired,
fetchAlbums: PropTypes.func.isRequired,
clearAlbums: PropTypes.func.isRequired,
fetchTracks: PropTypes.func.isRequired,
clearTracks: PropTypes.func.isRequired
};

View File

@ -5,8 +5,8 @@ import IconButton from 'Components/Link/IconButton';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import episodeEntities from 'Album/episodeEntities';
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
import albumEntities from 'Album/albumEntities';
import AlbumTitleLink from 'Album/AlbumTitleLink';
import EpisodeLanguage from 'Album/EpisodeLanguage';
import EpisodeQuality from 'Album/EpisodeQuality';
import ArtistNameLink from 'Artist/ArtistNameLink';
@ -110,14 +110,14 @@ class HistoryRow extends Component {
);
}
if (name === 'episodeTitle') {
if (name === 'albumTitle') {
return (
<TableRowCell key={name}>
<EpisodeTitleLink
<AlbumTitleLink
albumId={albumId}
episodeEntity={episodeEntities.EPISODES}
albumEntity={albumEntities.ALBUMS}
artistId={artist.id}
episodeTitle={album.title}
albumTitle={album.title}
showOpenArtistButton={true}
/>
</TableRowCell>

View File

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createTrackSelector from 'Store/Selectors/createTrackSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import HistoryRow from './HistoryRow';
@ -12,7 +12,7 @@ import HistoryRow from './HistoryRow';
function createMapStateToProps() {
return createSelector(
createArtistSelector(),
createEpisodeSelector(),
createAlbumSelector(),
createTrackSelector(),
createUISettingsSelector(),
(artist, album, track, uiSettings) => {

View File

@ -119,7 +119,7 @@ class Queue extends Component {
items,
isAlbumsFetching,
isAlbumsPopulated,
episodesError,
albumsError,
columns,
totalRecords,
isGrabbing,
@ -139,7 +139,7 @@ class Queue extends Component {
const isRefreshing = isFetching || isAlbumsFetching || isCheckForFinishedDownloadExecuting;
const isAllPopulated = isPopulated && (isAlbumsPopulated || !items.length);
const hasError = error || episodesError;
const hasError = error || albumsError;
const selectedCount = this.getSelectedIds().length;
const disableSelectedActions = selectedCount === 0;
@ -250,7 +250,7 @@ Queue.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired,
isAlbumsFetching: PropTypes.bool.isRequired,
isAlbumsPopulated: PropTypes.bool.isRequired,
episodesError: PropTypes.object,
albumsError: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
totalRecords: PropTypes.number,
isGrabbing: PropTypes.bool.isRequired,

View File

@ -9,22 +9,22 @@ import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import { executeCommand } from 'Store/Actions/commandActions';
import * as queueActions from 'Store/Actions/queueActions';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
import * as commandNames from 'Commands/commandNames';
import Queue from './Queue';
function createMapStateToProps() {
return createSelector(
(state) => state.episodes,
(state) => state.albums,
(state) => state.queue.paged,
createCommandsSelector(),
(episodes, queue, commands) => {
(albums, queue, commands) => {
const isCheckForFinishedDownloadExecuting = _.some(commands, { name: commandNames.CHECK_FOR_FINISHED_DOWNLOAD });
return {
isAlbumsFetching: episodes.isFetching,
isAlbumsPopulated: episodes.isPopulated,
episodesError: episodes.error,
isAlbumsFetching: albums.isFetching,
isAlbumsPopulated: albums.isPopulated,
albumsError: albums.error,
isCheckForFinishedDownloadExecuting,
...queue
};
@ -34,8 +34,8 @@ function createMapStateToProps() {
const mapDispatchToProps = {
...queueActions,
fetchEpisodes,
clearEpisodes,
fetchAlbums,
clearAlbums,
executeCommand
};
@ -53,9 +53,9 @@ class QueueConnector extends Component {
if (hasDifferentItems(prevProps.items, this.props.items)) {
const albumIds = selectUniqueIds(this.props.items, 'albumId');
if (albumIds.length) {
this.props.fetchEpisodes({ albumIds });
this.props.fetchAlbums({ albumIds });
} else {
this.props.clearEpisodes();
this.props.clearAlbums();
}
}
@ -64,7 +64,7 @@ class QueueConnector extends Component {
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearQueue();
this.props.clearEpisodes();
this.props.clearAlbums();
}
//
@ -158,8 +158,8 @@ QueueConnector.propTypes = {
clearQueue: PropTypes.func.isRequired,
grabQueueItems: PropTypes.func.isRequired,
removeQueueItems: PropTypes.func.isRequired,
fetchEpisodes: PropTypes.func.isRequired,
clearEpisodes: PropTypes.func.isRequired,
fetchAlbums: PropTypes.func.isRequired,
clearAlbums: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};

View File

@ -76,7 +76,7 @@ function QueueDetails(props) {
return (
<Icon
name={icons.DOWNLOADING}
title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}
title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}
/>
);
}

View File

@ -8,7 +8,7 @@ import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
import ProtocolLabel from 'Activity/Queue/ProtocolLabel';
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
import AlbumTitleLink from 'Album/AlbumTitleLink';
import EpisodeQuality from 'Album/EpisodeQuality';
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
import ArtistNameLink from 'Artist/ArtistNameLink';
@ -68,7 +68,7 @@ class QueueRow extends Component {
statusMessages,
errorMessage,
artist,
episode,
album,
quality,
protocol,
indexer,
@ -152,14 +152,14 @@ class QueueRow extends Component {
);
}
if (name === 'episodeTitle') {
if (name === 'albumTitle') {
return (
<TableRowCell key={name}>
<EpisodeTitleLink
albumId={episode.id}
<AlbumTitleLink
albumId={album.id}
artistId={artist.id}
trackFileId={episode.trackFileId}
episodeTitle={episode.title}
trackFileId={album.trackFileId}
albumTitle={album.title}
showOpenArtistButton={true}
/>
</TableRowCell>
@ -300,7 +300,7 @@ QueueRow.propTypes = {
statusMessages: PropTypes.arrayOf(PropTypes.object),
errorMessage: PropTypes.string,
artist: PropTypes.object.isRequired,
episode: PropTypes.object.isRequired,
album: PropTypes.object.isRequired,
quality: PropTypes.object.isRequired,
protocol: PropTypes.string.isRequired,
indexer: PropTypes.string,

View File

@ -5,16 +5,16 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { grabQueueItem, removeQueueItem } from 'Store/Actions/queueActions';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import QueueRow from './QueueRow';
function createMapStateToProps() {
return createSelector(
createArtistSelector(),
createEpisodeSelector(),
createAlbumSelector(),
createUISettingsSelector(),
(artist, episode, uiSettings) => {
(artist, album, uiSettings) => {
const result = _.pick(uiSettings, [
'showRelativeDates',
'shortDateFormat',
@ -22,7 +22,7 @@ function createMapStateToProps() {
]);
result.artist = artist;
result.episode = episode;
result.album = album;
return result;
}
@ -51,7 +51,7 @@ class QueueRowConnector extends Component {
// Render
render() {
if (!this.props.episode) {
if (!this.props.album) {
return null;
}
@ -67,7 +67,7 @@ class QueueRowConnector extends Component {
QueueRowConnector.propTypes = {
id: PropTypes.number.isRequired,
episode: PropTypes.object,
album: PropTypes.object,
grabQueueItem: PropTypes.func.isRequired,
removeQueueItem: PropTypes.func.isRequired
};

View File

@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Modal from 'Components/Modal/Modal';
import EpisodeDetailsModalContentConnector from './EpisodeDetailsModalContentConnector';
import AlbumDetailsModalContentConnector from './AlbumDetailsModalContentConnector';
class EpisodeDetailsModal extends Component {
class AlbumDetailsModal extends Component {
//
// Render
@ -20,7 +20,7 @@ class EpisodeDetailsModal extends Component {
isOpen={isOpen}
onModalClose={onModalClose}
>
<EpisodeDetailsModalContentConnector
<AlbumDetailsModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
@ -29,9 +29,9 @@ class EpisodeDetailsModal extends Component {
}
}
EpisodeDetailsModal.propTypes = {
AlbumDetailsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default EpisodeDetailsModal;
export default AlbumDetailsModal;

View File

@ -1,17 +1,17 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import episodeEntities from 'Album/episodeEntities';
import albumEntities from 'Album/albumEntities';
import Button from 'Components/Link/Button';
import ModalContent from 'Components/Modal/ModalContent';
import ModalHeader from 'Components/Modal/ModalHeader';
import ModalBody from 'Components/Modal/ModalBody';
import ModalFooter from 'Components/Modal/ModalFooter';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import EpisodeSummaryConnector from './Summary/EpisodeSummaryConnector';
import AlbumSummaryConnector from './Summary/AlbumSummaryConnector';
import AlbumHistoryConnector from './History/AlbumHistoryConnector';
import EpisodeSearchConnector from './Search/EpisodeSearchConnector';
import styles from './EpisodeDetailsModalContent.css';
import AlbumSearchConnector from './Search/AlbumSearchConnector';
import styles from './AlbumDetailsModalContent.css';
const tabs = [
'details',
@ -19,7 +19,7 @@ const tabs = [
'search'
];
class EpisodeDetailsModalContent extends Component {
class AlbumDetailsModalContent extends Component {
//
// Lifecycle
@ -45,13 +45,13 @@ class EpisodeDetailsModalContent extends Component {
render() {
const {
albumId,
episodeEntity,
albumEntity,
artistId,
artistName,
nameSlug,
albumLabel,
artistMonitored,
episodeTitle,
albumTitle,
releaseDate,
monitored,
isSaving,
@ -84,7 +84,7 @@ class EpisodeDetailsModalContent extends Component {
<span className={styles.separator}>-</span>
{episodeTitle}
{albumTitle}
</ModalHeader>
<ModalBody>
@ -119,9 +119,9 @@ class EpisodeDetailsModalContent extends Component {
</TabList>
<TabPanel className={styles.tabPanel}>
<EpisodeSummaryConnector
<AlbumSummaryConnector
albumId={albumId}
episodeEntity={episodeEntity}
albumEntity={albumEntity}
releaseDate={releaseDate}
albumLabel={albumLabel}
artistId={artistId}
@ -135,7 +135,7 @@ class EpisodeDetailsModalContent extends Component {
</TabPanel>
<TabPanel className={styles.tabPanel}>
<EpisodeSearchConnector
<AlbumSearchConnector
albumId={albumId}
startInteractiveSearch={startInteractiveSearch}
onModalClose={onModalClose}
@ -167,16 +167,16 @@ class EpisodeDetailsModalContent extends Component {
}
}
EpisodeDetailsModalContent.propTypes = {
AlbumDetailsModalContent.propTypes = {
albumId: PropTypes.number.isRequired,
episodeEntity: PropTypes.string.isRequired,
albumEntity: PropTypes.string.isRequired,
artistId: PropTypes.number.isRequired,
artistName: PropTypes.string.isRequired,
nameSlug: PropTypes.string.isRequired,
artistMonitored: PropTypes.bool.isRequired,
releaseDate: PropTypes.string.isRequired,
albumLabel: PropTypes.arrayOf(PropTypes.string).isRequired,
episodeTitle: PropTypes.string.isRequired,
albumTitle: PropTypes.string.isRequired,
monitored: PropTypes.bool.isRequired,
isSaving: PropTypes.bool,
showOpenArtistButton: PropTypes.bool,
@ -186,11 +186,11 @@ EpisodeDetailsModalContent.propTypes = {
onModalClose: PropTypes.func.isRequired
};
EpisodeDetailsModalContent.defaultProps = {
AlbumDetailsModalContent.defaultProps = {
selectedTab: 'details',
albumLabel: ['Unknown'],
episodeEntity: episodeEntities.EPISODES,
albumEntity: albumEntities.ALBUMS,
startInteractiveSearch: false
};
export default EpisodeDetailsModalContent;
export default AlbumDetailsModalContent;

View File

@ -3,16 +3,16 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
import { toggleEpisodeMonitored } from 'Store/Actions/episodeActions';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import { toggleAlbumMonitored } from 'Store/Actions/albumActions';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import episodeEntities from 'Album/episodeEntities';
import albumEntities from 'Album/albumEntities';
import { fetchTracks, clearTracks } from 'Store/Actions/trackActions';
import EpisodeDetailsModalContent from './EpisodeDetailsModalContent';
import AlbumDetailsModalContent from './AlbumDetailsModalContent';
function createMapStateToProps() {
return createSelector(
createEpisodeSelector(),
createAlbumSelector(),
createArtistSelector(),
(album, artist) => {
const {
@ -52,11 +52,11 @@ function createMapDispatchToProps(dispatch, props) {
onMonitorAlbumPress(monitored) {
const {
albumId,
episodeEntity
albumEntity
} = this.props;
dispatch(toggleEpisodeMonitored({
episodeEntity,
dispatch(toggleAlbumMonitored({
albumEntity,
albumId,
monitored
}));
@ -64,7 +64,7 @@ function createMapDispatchToProps(dispatch, props) {
};
}
class EpisodeDetailsModalContentConnector extends Component {
class AlbumDetailsModalContentConnector extends Component {
//
// Lifecycle
@ -103,14 +103,14 @@ class EpisodeDetailsModalContentConnector extends Component {
} = this.props;
return (
<EpisodeDetailsModalContent {...otherProps} />
<AlbumDetailsModalContent {...otherProps} />
);
}
}
EpisodeDetailsModalContentConnector.propTypes = {
AlbumDetailsModalContentConnector.propTypes = {
albumId: PropTypes.number.isRequired,
episodeEntity: PropTypes.string.isRequired,
albumEntity: PropTypes.string.isRequired,
artistId: PropTypes.number.isRequired,
dispatchFetchTracks: PropTypes.func.isRequired,
dispatchClearTracks: PropTypes.func.isRequired,
@ -118,8 +118,8 @@ EpisodeDetailsModalContentConnector.propTypes = {
dispatchClearReleases: PropTypes.func.isRequired
};
EpisodeDetailsModalContentConnector.defaultProps = {
episodeEntity: episodeEntities.EPISODES
AlbumDetailsModalContentConnector.defaultProps = {
albumEntity: albumEntities.ALBUMS
};
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeDetailsModalContentConnector);
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumDetailsModalContentConnector);

View File

@ -1,4 +1,4 @@
.episodeSearchCell {
.AlbumSearchCell {
composes: cell from 'Components/Table/Cells/TableRowCell.css';
width: 70px;

View File

@ -4,10 +4,10 @@ import { icons } from 'Helpers/Props';
import IconButton from 'Components/Link/IconButton';
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import EpisodeDetailsModal from './EpisodeDetailsModal';
import styles from './EpisodeSearchCell.css';
import AlbumDetailsModal from './AlbumDetailsModal';
import styles from './AlbumSearchCell.css';
class EpisodeSearchCell extends Component {
class AlbumSearchCell extends Component {
//
// Lifecycle
@ -38,14 +38,14 @@ class EpisodeSearchCell extends Component {
const {
albumId,
artistId,
episodeTitle,
albumTitle,
isSearching,
onSearchPress,
...otherProps
} = this.props;
return (
<TableRowCell className={styles.episodeSearchCell}>
<TableRowCell className={styles.AlbumSearchCell}>
<SpinnerIconButton
name={icons.SEARCH}
isSpinning={isSearching}
@ -57,11 +57,11 @@ class EpisodeSearchCell extends Component {
onPress={this.onManualSearchPress}
/>
<EpisodeDetailsModal
<AlbumDetailsModal
isOpen={this.state.isDetailsModalOpen}
albumId={albumId}
artistId={artistId}
episodeTitle={episodeTitle}
albumTitle={albumTitle}
selectedTab="search"
startInteractiveSearch={true}
onModalClose={this.onDetailsModalClose}
@ -72,12 +72,12 @@ class EpisodeSearchCell extends Component {
}
}
EpisodeSearchCell.propTypes = {
AlbumSearchCell.propTypes = {
albumId: PropTypes.number.isRequired,
artistId: PropTypes.number.isRequired,
episodeTitle: PropTypes.string.isRequired,
albumTitle: PropTypes.string.isRequired,
isSearching: PropTypes.bool.isRequired,
onSearchPress: PropTypes.func.isRequired
};
export default EpisodeSearchCell;
export default AlbumSearchCell;

View File

@ -5,7 +5,7 @@ import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
import EpisodeSearchCell from './EpisodeSearchCell';
import AlbumSearchCell from './AlbumSearchCell';
function createMapStateToProps() {
return createSelector(
@ -15,9 +15,9 @@ function createMapStateToProps() {
createCommandsSelector(),
(albumId, sceneSeasonNumber, artist, commands) => {
const isSearching = _.some(commands, (command) => {
const episodeSearch = command.name === commandNames.ALBUM_SEARCH;
const albumSearch = command.name === commandNames.ALBUM_SEARCH;
if (!episodeSearch) {
if (!albumSearch) {
return false;
}
@ -44,4 +44,4 @@ function createMapDispatchToProps(dispatch, props) {
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeSearchCell);
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumSearchCell);

View File

@ -1,10 +1,10 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Link from 'Components/Link/Link';
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
import styles from './EpisodeTitleLink.css';
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
import styles from './AlbumTitleLink.css';
class EpisodeTitleLink extends Component {
class AlbumTitleLink extends Component {
//
// Lifecycle
@ -33,7 +33,7 @@ class EpisodeTitleLink extends Component {
render() {
const {
episodeTitle,
albumTitle,
...otherProps
} = this.props;
@ -43,12 +43,12 @@ class EpisodeTitleLink extends Component {
className={styles.link}
onPress={this.onLinkPress}
>
{episodeTitle}
{albumTitle}
</Link>
<EpisodeDetailsModal
<AlbumDetailsModal
isOpen={this.state.isDetailsModalOpen}
episodeTitle={episodeTitle}
albumTitle={albumTitle}
{...otherProps}
onModalClose={this.onModalClose}
/>
@ -57,12 +57,12 @@ class EpisodeTitleLink extends Component {
}
}
EpisodeTitleLink.propTypes = {
episodeTitle: PropTypes.string.isRequired
AlbumTitleLink.propTypes = {
albumTitle: PropTypes.string.isRequired
};
EpisodeTitleLink.defaultProps = {
AlbumTitleLink.defaultProps = {
showArtistButton: false
};
export default EpisodeTitleLink;
export default AlbumTitleLink;

View File

@ -3,18 +3,18 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector';
import createTrackFileSelector from 'Store/Selectors/createTrackFileSelector';
import EpisodeStatus from './EpisodeStatus';
function createMapStateToProps() {
return createSelector(
createEpisodeSelector(),
createAlbumSelector(),
createQueueItemSelector(),
createTrackFileSelector(),
(episode, queueItem, trackFile) => {
const result = _.pick(episode, [
(album, queueItem, trackFile) => {
const result = _.pick(album, [
'airDateUtc',
'monitored',
'grabbed'

View File

@ -3,9 +3,9 @@ import React from 'react';
import { icons, kinds, sizes } from 'Helpers/Props';
import Button from 'Components/Link/Button';
import Icon from 'Components/Icon';
import styles from './EpisodeSearch.css';
import styles from './AlbumSearch.css';
function EpisodeSearch(props) {
function AlbumSearch(props) {
const {
onQuickSearchPress,
onInteractiveSearchPress
@ -47,9 +47,9 @@ function EpisodeSearch(props) {
);
}
EpisodeSearch.propTypes = {
AlbumSearch.propTypes = {
onQuickSearchPress: PropTypes.func.isRequired,
onInteractiveSearchPress: PropTypes.func.isRequired
};
export default EpisodeSearch;
export default AlbumSearch;

View File

@ -4,8 +4,8 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
import EpisodeSearch from './EpisodeSearch';
import InteractiveEpisodeSearchConnector from './InteractiveEpisodeSearchConnector';
import AlbumSearch from './AlbumSearch';
import InteractiveAlbumSearchConnector from './InteractiveAlbumSearchConnector';
function createMapStateToProps() {
return createSelector(
@ -22,7 +22,7 @@ const mapDispatchToProps = {
executeCommand
};
class EpisodeSearchConnector extends Component {
class AlbumSearchConnector extends Component {
//
// Lifecycle
@ -63,14 +63,14 @@ class EpisodeSearchConnector extends Component {
render() {
if (this.state.isInteractiveSearchOpen) {
return (
<InteractiveEpisodeSearchConnector
<InteractiveAlbumSearchConnector
{...this.props}
/>
);
}
return (
<EpisodeSearch
<AlbumSearch
{...this.props}
onQuickSearchPress={this.onQuickSearchPress}
onInteractiveSearchPress={this.onInteractiveSearchPress}
@ -79,7 +79,7 @@ class EpisodeSearchConnector extends Component {
}
}
EpisodeSearchConnector.propTypes = {
AlbumSearchConnector.propTypes = {
albumId: PropTypes.number.isRequired,
isPopulated: PropTypes.bool.isRequired,
startInteractiveSearch: PropTypes.bool.isRequired,
@ -87,4 +87,4 @@ EpisodeSearchConnector.propTypes = {
executeCommand: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(EpisodeSearchConnector);
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumSearchConnector);

View File

@ -5,7 +5,7 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Icon from 'Components/Icon';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import InteractiveEpisodeSearchRow from './InteractiveEpisodeSearchRow';
import InteractiveAlbumSearchRow from './InteractiveAlbumSearchRow';
const columns = [
{
@ -66,7 +66,7 @@ const columns = [
}
];
function InteractiveEpisodeSearch(props) {
function InteractiveAlbumSearch(props) {
const {
isFetching,
isPopulated,
@ -99,7 +99,7 @@ function InteractiveEpisodeSearch(props) {
{
items.map((item) => {
return (
<InteractiveEpisodeSearchRow
<InteractiveAlbumSearchRow
key={item.guid}
{...item}
longDateFormat={longDateFormat}
@ -114,7 +114,7 @@ function InteractiveEpisodeSearch(props) {
);
}
InteractiveEpisodeSearch.propTypes = {
InteractiveAlbumSearch.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
@ -127,4 +127,4 @@ InteractiveEpisodeSearch.propTypes = {
onGrabPress: PropTypes.func.isRequired
};
export default InteractiveEpisodeSearch;
export default InteractiveAlbumSearch;

View File

@ -5,7 +5,7 @@ import connectSection from 'Store/connectSection';
import { fetchReleases, setReleasesSort, grabRelease } from 'Store/Actions/releaseActions';
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import InteractiveEpisodeSearch from './InteractiveEpisodeSearch';
import InteractiveAlbumSearch from './InteractiveAlbumSearch';
function createMapStateToProps() {
return createSelector(
@ -27,7 +27,7 @@ const mapDispatchToProps = {
grabRelease
};
class InteractiveEpisodeSearchConnector extends Component {
class InteractiveAlbumSearchConnector extends Component {
//
// Lifecycle
@ -64,7 +64,7 @@ class InteractiveEpisodeSearchConnector extends Component {
render() {
return (
<InteractiveEpisodeSearch
<InteractiveAlbumSearch
{...this.props}
onSortPress={this.onSortPress}
onGrabPress={this.onGrabPress}
@ -73,7 +73,7 @@ class InteractiveEpisodeSearchConnector extends Component {
}
}
InteractiveEpisodeSearchConnector.propTypes = {
InteractiveAlbumSearchConnector.propTypes = {
albumId: PropTypes.number.isRequired,
isPopulated: PropTypes.bool.isRequired,
fetchReleases: PropTypes.func.isRequired,
@ -87,4 +87,4 @@ export default connectSection(
undefined,
undefined,
{ section: 'releases' }
)(InteractiveEpisodeSearchConnector);
)(InteractiveAlbumSearchConnector);

View File

@ -13,7 +13,7 @@ import Popover from 'Components/Tooltip/Popover';
import EpisodeQuality from 'Album/EpisodeQuality';
import ProtocolLabel from 'Activity/Queue/ProtocolLabel';
import Peers from './Peers';
import styles from './InteractiveEpisodeSearchRow.css';
import styles from './InteractiveAlbumSearchRow.css';
function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
if (isGrabbing) {
@ -39,7 +39,7 @@ function getDownloadTooltip(isGrabbing, isGrabbed, grabError) {
return 'Add to downloaded queue';
}
class InteractiveEpisodeSearchRow extends Component {
class InteractiveAlbumSearchRow extends Component {
//
// Listeners
@ -171,7 +171,7 @@ class InteractiveEpisodeSearchRow extends Component {
}
}
InteractiveEpisodeSearchRow.propTypes = {
InteractiveAlbumSearchRow.propTypes = {
guid: PropTypes.string.isRequired,
protocol: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
@ -196,9 +196,9 @@ InteractiveEpisodeSearchRow.propTypes = {
onGrabPress: PropTypes.func.isRequired
};
InteractiveEpisodeSearchRow.defaultProps = {
InteractiveAlbumSearchRow.defaultProps = {
isGrabbing: false,
isGrabbed: false
};
export default InteractiveEpisodeSearchRow;
export default InteractiveAlbumSearchRow;

View File

@ -7,7 +7,7 @@ import isTomorrow from 'Utilities/Date/isTomorrow';
import { kinds, sizes } from 'Helpers/Props';
import Label from 'Components/Label';
function EpisodeAiring(props) {
function AlbumReleasing(props) {
const {
releaseDate,
albumLabel,
@ -71,11 +71,11 @@ function EpisodeAiring(props) {
);
}
EpisodeAiring.propTypes = {
AlbumReleasing.propTypes = {
releaseDate: PropTypes.string.isRequired,
albumLabel: PropTypes.arrayOf(PropTypes.string).isRequired,
shortDateFormat: PropTypes.string.isRequired,
showRelativeDates: PropTypes.bool.isRequired
};
export default EpisodeAiring;
export default AlbumReleasing;

View File

@ -2,7 +2,7 @@ import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import EpisodeAiring from './EpisodeAiring';
import AlbumReleasing from './AlbumReleasing';
function createMapStateToProps() {
return createSelector(
@ -16,4 +16,4 @@ function createMapStateToProps() {
);
}
export default connect(createMapStateToProps)(EpisodeAiring);
export default connect(createMapStateToProps)(AlbumReleasing);

View File

@ -6,11 +6,11 @@ import Label from 'Components/Label';
import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import EpisodeAiringConnector from './EpisodeAiringConnector';
import AlbumReleasingConnector from './AlbumReleasingConnector';
import TrackDetailRow from './TrackDetailRow';
import styles from './EpisodeSummary.css';
import styles from './AlbumSummary.css';
class EpisodeSummary extends Component {
class AlbumSummary extends Component {
//
// Lifecycle
@ -63,7 +63,7 @@ class EpisodeSummary extends Component {
<div>
<span className={styles.infoTitle}>Releases</span>
<EpisodeAiringConnector
<AlbumReleasingConnector
releaseDate={releaseDate}
albumLabel={albumLabel}
/>
@ -92,7 +92,7 @@ class EpisodeSummary extends Component {
<div>
{
<div className={styles.episodes}>
<div className={styles.albums}>
{
items.length ?
<Table
@ -113,7 +113,7 @@ class EpisodeSummary extends Component {
</TableBody>
</Table> :
<div className={styles.noEpisodes}>
<div className={styles.noAlbums}>
No tracks in this group
</div>
}
@ -124,7 +124,7 @@ class EpisodeSummary extends Component {
<ConfirmModal
isOpen={this.state.isRemoveTrackFileModalOpen}
kind={kinds.DANGER}
title="Delete Episode File"
title="Delete Track File"
message={`Are you sure you want to delete '${path}'?`}
confirmLabel="Delete"
onConfirm={this.onConfirmRemoveTrackFile}
@ -135,7 +135,7 @@ class EpisodeSummary extends Component {
}
}
EpisodeSummary.propTypes = {
AlbumSummary.propTypes = {
qualityProfileId: PropTypes.number.isRequired,
overview: PropTypes.string,
albumLabel: PropTypes.arrayOf(PropTypes.string),
@ -149,4 +149,4 @@ EpisodeSummary.propTypes = {
onDeleteTrackFile: PropTypes.func.isRequired
};
export default EpisodeSummary;
export default AlbumSummary;

View File

@ -2,29 +2,29 @@ import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { deleteTrackFile } from 'Store/Actions/trackFileActions';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import EpisodeSummary from './EpisodeSummary';
import AlbumSummary from './AlbumSummary';
function createMapStateToProps() {
return createSelector(
(state) => state.tracks,
createEpisodeSelector(),
createAlbumSelector(),
createCommandsSelector(),
createDimensionsSelector(),
createArtistSelector(),
(tracks, episode, commands, dimensions, artist) => {
const filteredItems = _.filter(tracks.items, { albumId: episode.id });
(tracks, album, commands, dimensions, artist) => {
const filteredItems = _.filter(tracks.items, { albumId: album.id });
const mediumSortedItems = _.orderBy(filteredItems, 'absoluteTrackNumber');
const items = _.orderBy(mediumSortedItems, 'mediumNumber');
return {
network: episode.label,
network: album.label,
qualityProfileId: artist.qualityProfileId,
releaseDate: episode.releaseDate,
overview: episode.overview,
releaseDate: album.releaseDate,
overview: album.overview,
items,
columns: tracks.columns
};
@ -37,10 +37,10 @@ function createMapDispatchToProps(dispatch, props) {
onDeleteTrackFile() {
dispatch(deleteTrackFile({
id: props.trackFileId,
episodeEntity: props.episodeEntity
albumEntity: props.albumEntity
}));
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeSummary);
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumSummary);

View File

@ -1,12 +1,12 @@
export const CALENDAR = 'calendar';
export const EPISODES = 'episodes';
export const INTERACTIVE_IMPORT = 'interactiveImport.episodes';
export const ALBUMS = 'albums';
export const INTERACTIVE_IMPORT = 'interactiveImport.albums';
export const WANTED_CUTOFF_UNMET = 'wanted.cutoffUnmet';
export const WANTED_MISSING = 'wanted.missing';
export default {
CALENDAR,
EPISODES,
ALBUMS,
INTERACTIVE_IMPORT,
WANTED_CUTOFF_UNMET,
WANTED_MISSING

View File

@ -13,12 +13,12 @@
padding: 0 4px;
}
.episodes {
.tracks {
padding: 0 4px;
background-color: $white;
color: $defaultColor;
}
.allEpisodes {
.allTracks {
background-color: #e0ffe0;
}

View File

@ -54,8 +54,8 @@ class AlbumStudioAlbum extends Component {
<div
className={classNames(
styles.episodes,
percentOfTracks === 100 && styles.allEpisodes
styles.tracks,
percentOfTracks === 100 && styles.allTracks
)}
title={`${trackFileCount}/${totalTrackCount} tracks downloaded`}
>

View File

@ -4,7 +4,7 @@ import { createSelector } from 'reselect';
import connectSection from 'Store/connectSection';
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
import { setAlbumStudioSort, setAlbumStudioFilter, saveAlbumStudio } from 'Store/Actions/albumStudioActions';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
import AlbumStudio from './AlbumStudio';
function createMapStateToProps() {
@ -19,8 +19,8 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
fetchEpisodes,
clearEpisodes,
fetchAlbums,
clearAlbums,
setAlbumStudioSort,
setAlbumStudioFilter,
saveAlbumStudio
@ -43,11 +43,11 @@ class AlbumStudioConnector extends Component {
// Control
populate = () => {
this.props.fetchEpisodes();
this.props.fetchAlbums();
}
unpopulate = () => {
this.props.clearEpisodes();
this.props.clearAlbums();
}
//
@ -83,8 +83,8 @@ class AlbumStudioConnector extends Component {
AlbumStudioConnector.propTypes = {
setAlbumStudioSort: PropTypes.func.isRequired,
setAlbumStudioFilter: PropTypes.func.isRequired,
fetchEpisodes: PropTypes.func.isRequired,
clearEpisodes: PropTypes.func.isRequired,
fetchAlbums: PropTypes.func.isRequired,
clearAlbums: PropTypes.func.isRequired,
saveAlbumStudio: PropTypes.func.isRequired
};

View File

@ -5,15 +5,15 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import { toggleArtistMonitored } from 'Store/Actions/artistActions';
import { toggleEpisodeMonitored } from 'Store/Actions/episodeActions';
import { toggleAlbumMonitored } from 'Store/Actions/albumActions';
import AlbumStudioRow from './AlbumStudioRow';
function createMapStateToProps() {
return createSelector(
(state) => state.episodes,
(state) => state.albums,
createArtistSelector(),
(episodes, artist) => {
const albumsInArtist = _.filter(episodes.items, { artistId: artist.id });
(albums, artist) => {
const albumsInArtist = _.filter(albums.items, { artistId: artist.id });
const sortedAlbums = _.orderBy(albumsInArtist, 'releaseDate', 'desc');
return {
@ -32,7 +32,7 @@ function createMapStateToProps() {
const mapDispatchToProps = {
toggleArtistMonitored,
toggleEpisodeMonitored
toggleAlbumMonitored
};
class AlbumStudioRowConnector extends Component {
@ -53,7 +53,7 @@ class AlbumStudioRowConnector extends Component {
}
onAlbumMonitoredPress = (albumId, monitored) => {
this.props.toggleEpisodeMonitored({
this.props.toggleAlbumMonitored({
albumId,
monitored
});
@ -77,7 +77,7 @@ AlbumStudioRowConnector.propTypes = {
artistId: PropTypes.number.isRequired,
monitored: PropTypes.bool.isRequired,
toggleArtistMonitored: PropTypes.func.isRequired,
toggleEpisodeMonitored: PropTypes.func.isRequired
toggleAlbumMonitored: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumStudioRowConnector);

View File

@ -7,13 +7,13 @@ import TableRow from 'Components/Table/TableRow';
import Label from 'Components/Label';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
import EpisodeSearchCellConnector from 'Album/EpisodeSearchCellConnector';
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
import AlbumTitleLink from 'Album/AlbumTitleLink';
import styles from './AlbumRow.css';
function getEpisodeCountKind(monitored, trackFileCount, episodeCount) {
if (trackFileCount === episodeCount && episodeCount > 0) {
function getTrackCountKind(monitored, trackFileCount, trackCount) {
if (trackFileCount === trackCount && trackCount > 0) {
return kinds.SUCCESS;
}
@ -111,10 +111,10 @@ class AlbumRow extends Component {
key={name}
className={styles.title}
>
<EpisodeTitleLink
<AlbumTitleLink
albumId={id}
artistId={artistId}
episodeTitle={title}
albumTitle={title}
showOpenArtistButton={false}
/>
</TableRowCell>
@ -168,7 +168,7 @@ class AlbumRow extends Component {
>
<Label
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
kind={getEpisodeCountKind(monitored, trackFileCount, trackCount)}
kind={getTrackCountKind(monitored, trackFileCount, trackCount)}
size={sizes.MEDIUM}
>
{
@ -181,11 +181,11 @@ class AlbumRow extends Component {
if (name === 'actions') {
return (
<EpisodeSearchCellConnector
<AlbumSearchCellConnector
key={name}
albumId={id}
artistId={artistId}
episodeTitle={title}
albumTitle={title}
/>
);
}

View File

@ -91,7 +91,7 @@ class ArtistDetails extends Component {
this.state = {
isOrganizeModalOpen: false,
isManageEpisodesOpen: false,
isManageTracksOpen: false,
isEditArtistModalOpen: false,
isDeleteArtistModalOpen: false,
isArtistHistoryModalOpen: false,
@ -113,12 +113,12 @@ class ArtistDetails extends Component {
this.setState({ isOrganizeModalOpen: false });
}
onManageEpisodesPress = () => {
this.setState({ isManageEpisodesOpen: true });
onManageTracksPress = () => {
this.setState({ isManageTracksOpen: true });
}
onManageEpisodesModalClose = () => {
this.setState({ isManageEpisodesOpen: false });
onManageTracksModalClose = () => {
this.setState({ isManageTracksOpen: false });
}
onInteractiveImportPress = () => {
@ -203,7 +203,7 @@ class ArtistDetails extends Component {
isSearching,
isFetching,
isPopulated,
episodesError,
albumsError,
trackFilesError,
previousArtist,
nextArtist,
@ -213,7 +213,7 @@ class ArtistDetails extends Component {
const {
isOrganizeModalOpen,
isManageEpisodesOpen,
isManageTracksOpen,
isEditArtistModalOpen,
isDeleteArtistModalOpen,
isArtistHistoryModalOpen,
@ -271,8 +271,8 @@ class ArtistDetails extends Component {
<PageToolbarButton
label="Manage Tracks"
iconName={icons.EPISODE_FILE}
onPress={this.onManageEpisodesPress}
iconName={icons.TRACK_FILE}
onPress={this.onManageTracksPress}
/>
<PageToolbarButton
@ -524,12 +524,12 @@ class ArtistDetails extends Component {
<div className={styles.contentContainer}>
{
!isPopulated && !episodesError && !trackFilesError &&
!isPopulated && !albumsError && !trackFilesError &&
<LoadingIndicator />
}
{
!isFetching && episodesError &&
!isFetching && albumsError &&
<div>Loading albums failed</div>
}
@ -568,9 +568,9 @@ class ArtistDetails extends Component {
/>
<TrackFileEditorModal
isOpen={isManageEpisodesOpen}
isOpen={isManageTracksOpen}
artistId={id}
onModalClose={this.onManageEpisodesModalClose}
onModalClose={this.onManageTracksModalClose}
/>
<ArtistHistoryModal
@ -624,7 +624,7 @@ ArtistDetails.propTypes = {
isSearching: PropTypes.bool.isRequired,
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
episodesError: PropTypes.object,
albumsError: PropTypes.object,
trackFilesError: PropTypes.object,
previousArtist: PropTypes.object.isRequired,
nextArtist: PropTypes.object.isRequired,

View File

@ -8,7 +8,7 @@ import { findCommand } from 'Utilities/Command';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
import { fetchTrackFiles, clearTrackFiles } from 'Store/Actions/trackFileActions';
import { fetchQueueDetails, clearQueueDetails } from 'Store/Actions/queueActions';
import { executeCommand } from 'Store/Actions/commandActions';
@ -18,11 +18,11 @@ import ArtistDetails from './ArtistDetails';
function createMapStateToProps() {
return createSelector(
(state, { nameSlug }) => nameSlug,
(state) => state.episodes,
(state) => state.albums,
(state) => state.trackFiles,
createAllArtistSelector(),
createCommandsSelector(),
(nameSlug, episodes, trackFiles, allArtists, commands) => {
(nameSlug, albums, trackFiles, allArtists, commands) => {
const sortedArtist = _.orderBy(allArtists, 'sortName');
const artistIndex = _.findIndex(sortedArtist, { nameSlug });
const artist = sortedArtist[artistIndex];
@ -41,9 +41,9 @@ function createMapStateToProps() {
const isRenamingArtistCommand = findCommand(commands, { name: commandNames.RENAME_ARTIST });
const isRenamingArtist = !!(isRenamingArtistCommand && isRenamingArtistCommand.body.artistId.indexOf(artist.id) > -1);
const isFetching = episodes.isFetching || trackFiles.isFetching;
const isPopulated = episodes.isPopulated && trackFiles.isPopulated;
const episodesError = episodes.error;
const isFetching = albums.isFetching || trackFiles.isFetching;
const isPopulated = albums.isPopulated && trackFiles.isPopulated;
const albumsError = albums.error;
const trackFilesError = trackFiles.error;
const alternateTitles = _.reduce(artist.alternateTitles, (acc, alternateTitle) => {
if ((alternateTitle.seasonNumber === -1 || alternateTitle.seasonNumber === undefined) &&
@ -65,7 +65,7 @@ function createMapStateToProps() {
isRenamingArtist,
isFetching,
isPopulated,
episodesError,
albumsError,
trackFilesError,
previousArtist,
nextArtist
@ -75,8 +75,8 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
fetchEpisodes,
clearEpisodes,
fetchAlbums,
clearAlbums,
fetchTrackFiles,
clearTrackFiles,
fetchQueueDetails,
@ -112,7 +112,7 @@ class ArtistDetailsConnector extends Component {
this.populate();
}
// If the id has changed we need to clear the episodes/episode
// If the id has changed we need to clear the albums
// files and fetch from the server.
if (prevProps.id !== id) {
@ -132,13 +132,13 @@ class ArtistDetailsConnector extends Component {
populate = () => {
const artistId = this.props.id;
this.props.fetchEpisodes({ artistId });
this.props.fetchAlbums({ artistId });
this.props.fetchTrackFiles({ artistId });
this.props.fetchQueueDetails({ artistId });
}
unpopulate = () => {
this.props.clearEpisodes();
this.props.clearAlbums();
this.props.clearTrackFiles();
this.props.clearQueueDetails();
}
@ -182,8 +182,8 @@ ArtistDetailsConnector.propTypes = {
isRefreshing: PropTypes.bool.isRequired,
isRenamingFiles: PropTypes.bool.isRequired,
isRenamingArtist: PropTypes.bool.isRequired,
fetchEpisodes: PropTypes.func.isRequired,
clearEpisodes: PropTypes.func.isRequired,
fetchAlbums: PropTypes.func.isRequired,
clearAlbums: PropTypes.func.isRequired,
fetchTrackFiles: PropTypes.func.isRequired,
clearTrackFiles: PropTypes.func.isRequired,
fetchQueueDetails: PropTypes.func.isRequired,

View File

@ -75,7 +75,7 @@
width: 30px;
}
.episodes {
.albums {
padding-top: 15px;
border-top: 1px solid $borderColor;
}
@ -100,7 +100,7 @@
margin-left: -15px;
}
.noEpisodes {
.noAlbums {
margin-bottom: 15px;
text-align: center;
}

View File

@ -24,8 +24,8 @@ class ArtistDetailsSeason extends Component {
this.state = {
isOrganizeModalOpen: false,
isManageEpisodesOpen: false,
lastToggledEpisode: null
isManageTracksOpen: false,
lastToggledAlbum: null
};
}
@ -68,12 +68,12 @@ class ArtistDetailsSeason extends Component {
this.setState({ isOrganizeModalOpen: false });
}
onManageEpisodesPress = () => {
this.setState({ isManageEpisodesOpen: true });
onManageTracksPress = () => {
this.setState({ isManageTracksOpen: true });
}
onManageEpisodesModalClose = () => {
this.setState({ isManageEpisodesOpen: false });
onManageTracksModalClose = () => {
this.setState({ isManageTracksOpen: false });
}
onExpandPress = () => {
@ -86,7 +86,7 @@ class ArtistDetailsSeason extends Component {
}
onMonitorAlbumPress = (albumId, monitored, { shiftKey }) => {
const lastToggled = this.state.lastToggledEpisode;
const lastToggled = this.state.lastToggledAlbum;
const albumIds = [albumId];
if (shiftKey && lastToggled) {
@ -98,7 +98,7 @@ class ArtistDetailsSeason extends Component {
}
}
this.setState({ lastToggledEpisode: albumId });
this.setState({ lastToggledAlbum: albumId });
this.props.onMonitorAlbumPress(_.uniq(albumIds), monitored);
}
@ -120,7 +120,7 @@ class ArtistDetailsSeason extends Component {
const {
isOrganizeModalOpen,
isManageEpisodesOpen
isManageTracksOpen
} = this.state;
return (
@ -166,7 +166,7 @@ class ArtistDetailsSeason extends Component {
<div>
{
isExpanded &&
<div className={styles.episodes}>
<div className={styles.albums}>
{
items.length ?
<Table
@ -189,7 +189,7 @@ class ArtistDetailsSeason extends Component {
</TableBody>
</Table> :
<div className={styles.noEpisodes}>
<div className={styles.noAlbums}>
No albums in this group
</div>
}
@ -212,9 +212,9 @@ class ArtistDetailsSeason extends Component {
/>
<TrackFileEditorModal
isOpen={isManageEpisodesOpen}
isOpen={isManageTracksOpen}
artistId={artistId}
onModalClose={this.onManageEpisodesModalClose}
onModalClose={this.onManageTracksModalClose}
/>
</div>
);

View File

@ -8,7 +8,7 @@ import { findCommand } from 'Utilities/Command';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import { toggleEpisodesMonitored, setEpisodesTableOption } from 'Store/Actions/episodeActions';
import { toggleAlbumsMonitored, setAlbumsTableOption } from 'Store/Actions/albumActions';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
import ArtistDetailsSeason from './ArtistDetailsSeason';
@ -16,18 +16,18 @@ import ArtistDetailsSeason from './ArtistDetailsSeason';
function createMapStateToProps() {
return createSelector(
(state, { label }) => label,
(state) => state.episodes,
(state) => state.albums,
createArtistSelector(),
createCommandsSelector(),
createDimensionsSelector(),
(label, episodes, artist, commands, dimensions) => {
(label, albums, artist, commands, dimensions) => {
const episodesInSeason = _.filter(episodes.items, { albumType: label });
const sortedEpisodes = _.orderBy(episodesInSeason, 'releaseDate', 'desc');
const albumsInGroup = _.filter(albums.items, { albumType: label });
const sortedAlbums = _.orderBy(albumsInGroup, 'releaseDate', 'desc');
return {
items: sortedEpisodes,
columns: episodes.columns,
items: sortedAlbums,
columns: albums.columns,
artistMonitored: artist.monitored,
isSmallScreen: dimensions.isSmallScreen
};
@ -36,8 +36,8 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
toggleEpisodesMonitored,
setEpisodesTableOption,
toggleAlbumsMonitored,
setAlbumsTableOption,
executeCommand
};
@ -47,11 +47,11 @@ class ArtistDetailsSeasonConnector extends Component {
// Listeners
onTableOptionChange = (payload) => {
this.props.setEpisodesTableOption(payload);
this.props.setAlbumsTableOption(payload);
}
onMonitorAlbumPress = (albumIds, monitored) => {
this.props.toggleEpisodesMonitored({
this.props.toggleAlbumsMonitored({
albumIds,
monitored
});
@ -73,8 +73,8 @@ class ArtistDetailsSeasonConnector extends Component {
ArtistDetailsSeasonConnector.propTypes = {
artistId: PropTypes.number.isRequired,
toggleEpisodesMonitored: PropTypes.func.isRequired,
setEpisodesTableOption: PropTypes.func.isRequired,
toggleAlbumsMonitored: PropTypes.func.isRequired,
setAlbumsTableOption: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};

View File

@ -2,13 +2,13 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import ArtistHistoryRow from './ArtistHistoryRow';
function createMapStateToProps() {
return createSelector(
createArtistSelector(),
createEpisodeSelector(),
createAlbumSelector(),
(artist, album) => {
return {
artist,

View File

@ -42,7 +42,7 @@
flex: 0 0 100px;
}
.episodeSeparator {
.albumSeparator {
display: none;
}
@ -98,7 +98,7 @@
flex: 0 0 auto;
}
.episodeSeparator {
.albumSeparator {
display: inline-block;
margin: 0 5px;
}

View File

@ -7,8 +7,8 @@ import { icons } from 'Helpers/Props';
import getStatusStyle from 'Calendar/getStatusStyle';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import episodeEntities from 'Album/episodeEntities';
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
import albumEntities from 'Album/albumEntities';
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
import CalendarEventQueueDetails from 'Calendar/Events/CalendarEventQueueDetails';
import styles from './AgendaEvent.css';
@ -88,7 +88,7 @@ class AgendaEvent extends Component {
{artist.artistName}
</div>
<div className={styles.episodeSeparator}> - </div>
<div className={styles.albumSeparator}> - </div>
<div className={styles.albumTitle}>
{title}
@ -110,12 +110,12 @@ class AgendaEvent extends Component {
}
</Link>
<EpisodeDetailsModal
<AlbumDetailsModal
isOpen={this.state.isDetailsModalOpen}
albumId={id}
episodeEntity={episodeEntities.CALENDAR}
albumEntity={albumEntities.CALENDAR}
artistId={artist.id}
episodeTitle={title}
albumTitle={title}
showOpenArtistButton={true}
onModalClose={this.onDetailsModalClose}
/>

View File

@ -4,10 +4,10 @@ import React, { Component } from 'react';
import classNames from 'classnames';
import { icons } from 'Helpers/Props';
import getStatusStyle from 'Calendar/getStatusStyle';
import episodeEntities from 'Album/episodeEntities';
import albumEntities from 'Album/albumEntities';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
import CalendarEventQueueDetails from './CalendarEventQueueDetails';
import styles from './CalendarEvent.css';
@ -108,12 +108,12 @@ class CalendarEvent extends Component {
</div>
</Link>
<EpisodeDetailsModal
<AlbumDetailsModal
isOpen={this.state.isDetailsModalOpen}
albumId={id}
episodeEntity={episodeEntities.CALENDAR}
albumEntity={albumEntities.CALENDAR}
artistId={artist.id}
episodeTitle={title}
albumTitle={title}
showOpenArtistButton={true}
onModalClose={this.onDetailsModalClose}
/>

View File

@ -25,7 +25,7 @@ function CalendarEventQueueDetails(props) {
status={status}
errorMessage={errorMessage}
progressBar={
<div title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}>
<div title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}>
<CircularProgressBar
progress={progress}
size={20}

View File

@ -13,7 +13,7 @@ function getIconName(name) {
return icons.BACKUP;
case 'CheckHealth':
return icons.HEALTH;
case 'EpisodeSearch':
case 'AlbumSearch':
return icons.SEARCH;
case 'Housekeeping':
return icons.HOUSEKEEPING;

View File

@ -127,8 +127,8 @@ class SignalRConnector extends Component {
return;
}
if (name === 'episode') {
this.handleEpisode(body);
if (name === 'album') {
this.handleAlbum(body);
return;
}
@ -137,7 +137,7 @@ class SignalRConnector extends Component {
return;
}
if (name === 'episodefile') {
if (name === 'trackfile') {
this.handleTrackFile(body);
return;
}
@ -207,10 +207,10 @@ class SignalRConnector extends Component {
}
}
handleEpisode = (body) => {
handleAlbum = (body) => {
if (body.action === 'updated') {
this.props.updateItem({
section: 'episodes',
section: 'albums',
updateOnly: true,
...body.resource
});

View File

@ -27,7 +27,7 @@ export const DOWNLOADED = 'fa fa-download';
export const DOWNLOADING = 'fa fa-cloud-download';
export const DRIVE = 'fa fa-hdd-o';
export const EDIT = 'fa fa-wrench';
export const EPISODE_FILE = 'fa fa-file-video-o';
export const TRACK_FILE = 'fa fa-file-audio-o';
export const EXPAND = 'fa fa-chevron-circle-down';
export const EXPAND_INDETERMINATE = 'fa fa-chevron-circle-right';
export const EXTERNAL_LINK = 'fa fa-external-link';

View File

@ -15,8 +15,8 @@ import SelectAlbumModalContent from './SelectAlbumModalContent';
function createMapStateToProps() {
return createSelector(
createClientSideCollectionSelector(),
(episodes) => {
return episodes;
(albums) => {
return albums;
}
);
}

View File

@ -99,7 +99,7 @@ function EditNotificationModalContent(props) {
<FormInputGroup
type={inputTypes.CHECK}
name="onGrab"
helpText="Be notified when episodes are available for download and has been sent to a download client"
helpText="Be notified when albums are available for download and has been sent to a download client"
isDisabled={!supportsOnGrab.value}
{...onGrab}
onChange={onInputChange}
@ -127,7 +127,7 @@ function EditNotificationModalContent(props) {
<FormInputGroup
type={inputTypes.CHECK}
name="onUpgrade"
helpText="Be notified when episodes are upgraded to a better quality"
helpText="Be notified when tracks are upgraded to a better quality"
isDisabled={!supportsOnUpgrade.value}
{...onUpgrade}
onChange={onInputChange}
@ -141,7 +141,7 @@ function EditNotificationModalContent(props) {
<FormInputGroup
type={inputTypes.CHECK}
name="onRename"
helpText="Be notified when episodes are renamed"
helpText="Be notified when tracks are renamed"
isDisabled={!supportsOnRename.value}
{...onRename}
onChange={onInputChange}

View File

@ -81,7 +81,7 @@ function EditLanguageProfileModalContent(props) {
{...cutoff}
value={cutoff ? cutoff.value.id : 0}
values={languages}
helpText="Once this language is reached Lidarr will no longer download episodes"
helpText="Once this language is reached Lidarr will no longer download albums"
onChange={onCutoffChange}
/>
</FormGroup>

View File

@ -87,7 +87,7 @@ function Settings() {
</Link>
<div className={styles.summary}>
Create metadata files when episodes are imported or artist are refreshed
Create metadata files when tracks are imported or artist are refreshed
</div>
<Link

View File

@ -6,7 +6,7 @@ import { sortDirections } from 'Helpers/Props';
import { createThunk, handleThunks } from 'Store/thunks';
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptionReducer';
import episodeEntities from 'Album/episodeEntities';
import albumEntities from 'Album/albumEntities';
import createFetchHandler from './Creators/createFetchHandler';
import createHandleActions from './Creators/createHandleActions';
import { updateItem } from './baseActions';
@ -14,7 +14,7 @@ import { updateItem } from './baseActions';
//
// Variables
export const section = 'episodes';
export const section = 'albums';
//
// State
@ -74,47 +74,47 @@ export const defaultState = {
};
export const persistState = [
'episodes.columns'
'albums.columns'
];
//
// Actions Types
export const FETCH_EPISODES = 'episodes/fetchEpisodes';
export const SET_EPISODES_SORT = 'episodes/setEpisodesSort';
export const SET_EPISODES_TABLE_OPTION = 'episodes/setEpisodesTableOption';
export const CLEAR_EPISODES = 'episodes/clearEpisodes';
export const TOGGLE_EPISODE_MONITORED = 'episodes/toggleEpisodeMonitored';
export const TOGGLE_EPISODES_MONITORED = 'episodes/toggleEpisodesMonitored';
export const FETCH_ALBUMS = 'albums/fetchAlbums';
export const SET_ALBUMS_SORT = 'albums/setAlbumsSort';
export const SET_ALBUMS_TABLE_OPTION = 'albums/setAlbumsTableOption';
export const CLEAR_ALBUMS = 'albums/clearAlbums';
export const TOGGLE_ALBUM_MONITORED = 'albums/toggleAlbumMonitored';
export const TOGGLE_ALBUMS_MONITORED = 'albums/toggleAlbumsMonitored';
//
// Action Creators
export const fetchEpisodes = createThunk(FETCH_EPISODES);
export const setEpisodesSort = createAction(SET_EPISODES_SORT);
export const setEpisodesTableOption = createAction(SET_EPISODES_TABLE_OPTION);
export const clearEpisodes = createAction(CLEAR_EPISODES);
export const toggleEpisodeMonitored = createThunk(TOGGLE_EPISODE_MONITORED);
export const toggleEpisodesMonitored = createThunk(TOGGLE_EPISODES_MONITORED);
export const fetchAlbums = createThunk(FETCH_ALBUMS);
export const setAlbumsSort = createAction(SET_ALBUMS_SORT);
export const setAlbumsTableOption = createAction(SET_ALBUMS_TABLE_OPTION);
export const clearAlbums = createAction(CLEAR_ALBUMS);
export const toggleAlbumMonitored = createThunk(TOGGLE_ALBUM_MONITORED);
export const toggleAlbumsMonitored = createThunk(TOGGLE_ALBUMS_MONITORED);
//
// Action Handlers
export const actionHandlers = handleThunks({
[FETCH_EPISODES]: createFetchHandler(section, '/album'),
[FETCH_ALBUMS]: createFetchHandler(section, '/album'),
[TOGGLE_EPISODE_MONITORED]: function(getState, payload, dispatch) {
[TOGGLE_ALBUM_MONITORED]: function(getState, payload, dispatch) {
const {
albumId,
episodeEntity = episodeEntities.EPISODES,
albumEntity = albumEntities.ALBUMS,
monitored
} = payload;
const episodeSection = _.last(episodeEntity.split('.'));
const albumSection = _.last(albumEntity.split('.'));
dispatch(updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: true
}));
@ -128,7 +128,7 @@ export const actionHandlers = handleThunks({
promise.done((data) => {
dispatch(updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: false,
monitored
}));
@ -137,26 +137,26 @@ export const actionHandlers = handleThunks({
promise.fail((xhr) => {
dispatch(updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: false
}));
});
},
[TOGGLE_EPISODES_MONITORED]: function(getState, payload, dispatch) {
[TOGGLE_ALBUMS_MONITORED]: function(getState, payload, dispatch) {
const {
albumIds,
episodeEntity = episodeEntities.EPISODES,
albumEntity = albumEntities.ALBUMS,
monitored
} = payload;
const episodeSection = _.last(episodeEntity.split('.'));
const albumSection = _.last(albumEntity.split('.'));
dispatch(batchActions(
albumIds.map((albumId) => {
return updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: true
});
})
@ -174,7 +174,7 @@ export const actionHandlers = handleThunks({
albumIds.map((albumId) => {
return updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: false,
monitored
});
@ -187,7 +187,7 @@ export const actionHandlers = handleThunks({
albumIds.map((albumId) => {
return updateItem({
id: albumId,
section: episodeSection,
section: albumSection,
isSaving: false
});
})
@ -201,9 +201,9 @@ export const actionHandlers = handleThunks({
export const reducers = createHandleActions({
[SET_EPISODES_TABLE_OPTION]: createSetTableOptionReducer(section),
[SET_ALBUMS_TABLE_OPTION]: createSetTableOptionReducer(section),
[CLEAR_EPISODES]: (state) => {
[CLEAR_ALBUMS]: (state) => {
return Object.assign({}, state, {
isFetching: false,
isPopulated: false,
@ -212,6 +212,6 @@ export const reducers = createHandleActions({
});
},
[SET_EPISODES_SORT]: createSetClientSideCollectionSortReducer(section)
[SET_ALBUMS_SORT]: createSetClientSideCollectionSortReducer(section)
}, defaultState, section);

View File

@ -175,7 +175,7 @@ export const actionHandlers = handleThunks({
});
promise.done((data) => {
const episodes = _.filter(getState().episodes.items, { artistId: id, seasonNumber });
const albums = _.filter(getState().albums.items, { artistId: id, seasonNumber });
dispatch(batchActions([
updateItem({
@ -184,10 +184,10 @@ export const actionHandlers = handleThunks({
...data
}),
...episodes.map((episode) => {
...albums.map((album) => {
return updateItem({
id: episode.id,
section: 'episodes',
id: album.id,
section: 'albums',
monitored
});
})

View File

@ -42,7 +42,7 @@ export const defaultState = {
isVisible: true
},
{
name: 'episodeTitle',
name: 'albumTitle',
label: 'Album Title',
isVisible: true
},

View File

@ -4,7 +4,7 @@ import * as blacklist from './blacklistActions';
import * as captcha from './captchaActions';
import * as calendar from './calendarActions';
import * as commands from './commandActions';
import * as episodes from './episodeActions';
import * as albums from './albumActions';
import * as trackFiles from './trackFileActions';
import * as albumHistory from './albumHistoryActions';
import * as history from './historyActions';
@ -34,7 +34,7 @@ export default [
captcha,
calendar,
commands,
episodes,
albums,
trackFiles,
albumHistory,
history,

View File

@ -64,7 +64,7 @@ export const defaultState = {
isVisible: true
},
{
name: 'episodeTitle',
name: 'albumTitle',
label: 'Album Title',
isVisible: true
},

View File

@ -3,7 +3,7 @@ import $ from 'jquery';
import { createAction } from 'redux-actions';
import { batchActions } from 'redux-batched-actions';
import { createThunk, handleThunks } from 'Store/thunks';
import episodeEntities from 'Album/episodeEntities';
import albumEntities from 'Album/albumEntities';
import createFetchHandler from './Creators/createFetchHandler';
import createHandleActions from './Creators/createHandleActions';
import createRemoveItemHandler from './Creators/createRemoveItemHandler';
@ -60,20 +60,20 @@ export const actionHandlers = handleThunks({
[DELETE_TRACK_FILE]: function(getState, payload, dispatch) {
const {
id: trackFileId,
episodeEntity = episodeEntities.EPISODES
albumEntity = albumEntities.ALBUMS
} = payload;
const episodeSection = _.last(episodeEntity.split('.'));
const albumSection = _.last(albumEntity.split('.'));
const deletePromise = deleteTrackFileHelper(getState, payload, dispatch);
deletePromise.done(() => {
const episodes = getState().episodes.items;
const tracksWithRemovedFiles = _.filter(episodes, { trackFileId });
const albums = getState().albums.items;
const tracksWithRemovedFiles = _.filter(albums, { trackFileId });
dispatch(batchActions([
...tracksWithRemovedFiles.map((track) => {
return updateItem({
section: episodeSection,
section: albumSection,
...track,
trackFileId: 0,
hasFile: false

View File

@ -0,0 +1,15 @@
import _ from 'lodash';
import { createSelector } from 'reselect';
import albumEntities from 'Album/albumEntities';
function createAlbumSelector() {
return createSelector(
(state, { albumId }) => albumId,
(state, { albumEntity = albumEntities.ALBUMS }) => _.get(state, albumEntity, { items: [] }),
(albumId, albums) => {
return _.find(albums.items, { id: albumId });
}
);
}
export default createAlbumSelector;

View File

@ -1,15 +0,0 @@
import _ from 'lodash';
import { createSelector } from 'reselect';
import episodeEntities from 'Album/episodeEntities';
function createEpisodeSelector() {
return createSelector(
(state, { albumId }) => albumId,
(state, { episodeEntity = episodeEntities.EPISODES }) => _.get(state, episodeEntity, { items: [] }),
(albumId, episodes) => {
return _.find(episodes.items, { id: albumId });
}
);
}
export default createEpisodeSelector;

View File

@ -2,8 +2,8 @@
import _ from 'lodash';
import { update } from 'Store/Actions/baseActions';
function updateAlbums(dispatch, section, episodes, albumIds, options) {
const data = _.reduce(episodes, (result, item) => {
function updateAlbums(dispatch, section, albums, albumIds, options) {
const data = _.reduce(albums, (result, item) => {
if (albumIds.indexOf(item.id) > -1) {
result.push({
...item,

View File

@ -242,11 +242,11 @@ class CutoffUnmet extends Component {
<ConfirmModal
isOpen={isConfirmSearchAllCutoffUnmetModalOpen}
kind={kinds.DANGER}
title="Search for all Cutoff Unmet episodes"
title="Search for all Cutoff Unmet albums"
message={
<div>
<div>
Are you sure you want to search for all {totalRecords} Cutoff Unmet episodes?
Are you sure you want to search for all {totalRecords} Cutoff Unmet albums?
</div>
<div>
This cannot be cancelled once started without restarting Lidarr.

View File

@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React from 'react';
import episodeEntities from 'Album/episodeEntities';
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
import albumEntities from 'Album/albumEntities';
import AlbumTitleLink from 'Album/AlbumTitleLink';
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector';
import EpisodeSearchCellConnector from 'Album/EpisodeSearchCellConnector';
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
import TrackFileLanguageConnector from 'TrackFile/TrackFileLanguageConnector';
import ArtistNameLink from 'Artist/ArtistNameLink';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
@ -58,11 +58,11 @@ function CutoffUnmetRow(props) {
if (name === 'albumTitle') {
return (
<TableRowCell key={name}>
<EpisodeTitleLink
<AlbumTitleLink
albumId={id}
artistId={artist.id}
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
episodeTitle={title}
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
albumTitle={title}
showOpenArtistButton={true}
/>
</TableRowCell>
@ -108,7 +108,7 @@ function CutoffUnmetRow(props) {
<EpisodeStatusConnector
albumId={id}
trackFileId={trackFileId}
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
/>
</TableRowCell>
);
@ -116,12 +116,12 @@ function CutoffUnmetRow(props) {
if (name === 'actions') {
return (
<EpisodeSearchCellConnector
<AlbumSearchCellConnector
key={name}
albumId={id}
artistId={artist.id}
episodeTitle={title}
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
albumTitle={title}
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
showOpenArtistButton={true}
/>
);

View File

@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React from 'react';
import episodeEntities from 'Album/episodeEntities';
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
import albumEntities from 'Album/albumEntities';
import AlbumTitleLink from 'Album/AlbumTitleLink';
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector';
import EpisodeSearchCellConnector from 'Album/EpisodeSearchCellConnector';
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
import ArtistNameLink from 'Artist/ArtistNameLink';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRow from 'Components/Table/TableRow';
@ -75,11 +75,11 @@ function MissingRow(props) {
if (name === 'albumTitle') {
return (
<TableRowCell key={name}>
<EpisodeTitleLink
<AlbumTitleLink
albumId={id}
artistId={artist.id}
episodeEntity={episodeEntities.WANTED_MISSING}
episodeTitle={title}
albumEntity={albumEntities.WANTED_MISSING}
albumTitle={title}
showOpenArtistButton={true}
/>
</TableRowCell>
@ -112,7 +112,7 @@ function MissingRow(props) {
// <EpisodeStatusConnector
// albumId={id}
// trackFileId={trackFileId}
// episodeEntity={episodeEntities.WANTED_MISSING}
// albumEntity={albumEntities.WANTED_MISSING}
// />
// </TableRowCell>
// );
@ -120,12 +120,12 @@ function MissingRow(props) {
if (name === 'actions') {
return (
<EpisodeSearchCellConnector
<AlbumSearchCellConnector
key={name}
albumId={id}
artistId={artist.id}
episodeTitle={title}
episodeEntity={episodeEntities.WANTED_MISSING}
albumTitle={title}
albumEntity={albumEntities.WANTED_MISSING}
showOpenArtistButton={true}
/>
);