|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
import _ from 'lodash';
|
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
|
|
|
|
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
|
|
|
|
|
import TextTruncate from 'react-text-truncate';
|
|
|
|
|
import formatBytes from 'Utilities/Number/formatBytes';
|
|
|
|
|
import selectAll from 'Utilities/Table/selectAll';
|
|
|
|
@ -22,20 +22,20 @@ import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
|
|
|
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
|
|
|
|
import Popover from 'Components/Tooltip/Popover';
|
|
|
|
|
import Tooltip from 'Components/Tooltip/Tooltip';
|
|
|
|
|
import TrackFileEditorTable from 'TrackFile/Editor/TrackFileEditorTable';
|
|
|
|
|
import BookFileEditorTable from 'BookFile/Editor/BookFileEditorTable';
|
|
|
|
|
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
|
|
|
|
|
import RetagPreviewModalConnector from 'Retag/RetagPreviewModalConnector';
|
|
|
|
|
import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector';
|
|
|
|
|
import ArtistPoster from 'Artist/ArtistPoster';
|
|
|
|
|
import EditArtistModalConnector from 'Artist/Edit/EditArtistModalConnector';
|
|
|
|
|
import DeleteArtistModal from 'Artist/Delete/DeleteArtistModal';
|
|
|
|
|
import ArtistHistoryTable from 'Artist/History/ArtistHistoryTable';
|
|
|
|
|
import ArtistAlternateTitles from './ArtistAlternateTitles';
|
|
|
|
|
import ArtistDetailsSeasonConnector from './ArtistDetailsSeasonConnector';
|
|
|
|
|
import AuthorPoster from 'Author/AuthorPoster';
|
|
|
|
|
import EditAuthorModalConnector from 'Author/Edit/EditAuthorModalConnector';
|
|
|
|
|
import DeleteAuthorModal from 'Author/Delete/DeleteAuthorModal';
|
|
|
|
|
import AuthorHistoryTable from 'Author/History/AuthorHistoryTable';
|
|
|
|
|
import AuthorAlternateTitles from './AuthorAlternateTitles';
|
|
|
|
|
import AuthorDetailsSeasonConnector from './AuthorDetailsSeasonConnector';
|
|
|
|
|
import AuthorDetailsSeriesConnector from './AuthorDetailsSeriesConnector';
|
|
|
|
|
import ArtistTagsConnector from './ArtistTagsConnector';
|
|
|
|
|
import ArtistDetailsLinks from './ArtistDetailsLinks';
|
|
|
|
|
import styles from './ArtistDetails.css';
|
|
|
|
|
import AuthorTagsConnector from './AuthorTagsConnector';
|
|
|
|
|
import AuthorDetailsLinks from './AuthorDetailsLinks';
|
|
|
|
|
import styles from './AuthorDetails.css';
|
|
|
|
|
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
|
|
|
|
|
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
|
|
|
|
|
import InteractiveImportModal from '../../InteractiveImport/InteractiveImportModal';
|
|
|
|
@ -60,7 +60,7 @@ function getExpandedState(newState) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class ArtistDetails extends Component {
|
|
|
|
|
class AuthorDetails extends Component {
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Lifecycle
|
|
|
|
@ -71,8 +71,8 @@ class ArtistDetails extends Component {
|
|
|
|
|
this.state = {
|
|
|
|
|
isOrganizeModalOpen: false,
|
|
|
|
|
isRetagModalOpen: false,
|
|
|
|
|
isEditArtistModalOpen: false,
|
|
|
|
|
isDeleteArtistModalOpen: false,
|
|
|
|
|
isEditAuthorModalOpen: false,
|
|
|
|
|
isDeleteAuthorModalOpen: false,
|
|
|
|
|
isInteractiveImportModalOpen: false,
|
|
|
|
|
allExpanded: false,
|
|
|
|
|
allCollapsed: false,
|
|
|
|
@ -108,23 +108,23 @@ class ArtistDetails extends Component {
|
|
|
|
|
this.setState({ isInteractiveImportModalOpen: false });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onEditArtistPress = () => {
|
|
|
|
|
this.setState({ isEditArtistModalOpen: true });
|
|
|
|
|
onEditAuthorPress = () => {
|
|
|
|
|
this.setState({ isEditAuthorModalOpen: true });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onEditArtistModalClose = () => {
|
|
|
|
|
this.setState({ isEditArtistModalOpen: false });
|
|
|
|
|
onEditAuthorModalClose = () => {
|
|
|
|
|
this.setState({ isEditAuthorModalOpen: false });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDeleteArtistPress = () => {
|
|
|
|
|
onDeleteAuthorPress = () => {
|
|
|
|
|
this.setState({
|
|
|
|
|
isEditArtistModalOpen: false,
|
|
|
|
|
isDeleteArtistModalOpen: true
|
|
|
|
|
isEditAuthorModalOpen: false,
|
|
|
|
|
isDeleteAuthorModalOpen: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onDeleteArtistModalClose = () => {
|
|
|
|
|
this.setState({ isDeleteArtistModalOpen: false });
|
|
|
|
|
onDeleteAuthorModalClose = () => {
|
|
|
|
|
this.setState({ isDeleteAuthorModalOpen: false });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onExpandAllPress = () => {
|
|
|
|
@ -156,7 +156,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
render() {
|
|
|
|
|
const {
|
|
|
|
|
id,
|
|
|
|
|
artistName,
|
|
|
|
|
authorName,
|
|
|
|
|
ratings,
|
|
|
|
|
path,
|
|
|
|
|
statistics,
|
|
|
|
@ -166,7 +166,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
overview,
|
|
|
|
|
links,
|
|
|
|
|
images,
|
|
|
|
|
artistType,
|
|
|
|
|
authorType,
|
|
|
|
|
alternateTitles,
|
|
|
|
|
tags,
|
|
|
|
|
isSaving,
|
|
|
|
@ -174,30 +174,30 @@ class ArtistDetails extends Component {
|
|
|
|
|
isSearching,
|
|
|
|
|
isFetching,
|
|
|
|
|
isPopulated,
|
|
|
|
|
albumsError,
|
|
|
|
|
trackFilesError,
|
|
|
|
|
hasAlbums,
|
|
|
|
|
hasMonitoredAlbums,
|
|
|
|
|
booksError,
|
|
|
|
|
bookFilesError,
|
|
|
|
|
hasBooks,
|
|
|
|
|
hasMonitoredBooks,
|
|
|
|
|
hasSeries,
|
|
|
|
|
series,
|
|
|
|
|
hasTrackFiles,
|
|
|
|
|
previousArtist,
|
|
|
|
|
nextArtist,
|
|
|
|
|
hasBookFiles,
|
|
|
|
|
previousAuthor,
|
|
|
|
|
nextAuthor,
|
|
|
|
|
onMonitorTogglePress,
|
|
|
|
|
onRefreshPress,
|
|
|
|
|
onSearchPress
|
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
trackFileCount,
|
|
|
|
|
bookFileCount,
|
|
|
|
|
sizeOnDisk
|
|
|
|
|
} = statistics;
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
isOrganizeModalOpen,
|
|
|
|
|
isRetagModalOpen,
|
|
|
|
|
isEditArtistModalOpen,
|
|
|
|
|
isDeleteArtistModalOpen,
|
|
|
|
|
isEditAuthorModalOpen,
|
|
|
|
|
isDeleteAuthorModalOpen,
|
|
|
|
|
isInteractiveImportModalOpen,
|
|
|
|
|
allExpanded,
|
|
|
|
|
allCollapsed,
|
|
|
|
@ -206,14 +206,14 @@ class ArtistDetails extends Component {
|
|
|
|
|
} = this.state;
|
|
|
|
|
|
|
|
|
|
const continuing = status === 'continuing';
|
|
|
|
|
const endedString = artistType === 'Person' ? 'Deceased' : 'Ended';
|
|
|
|
|
const endedString = authorType === 'Person' ? 'Deceased' : 'Ended';
|
|
|
|
|
|
|
|
|
|
let trackFilesCountMessage = 'No track files';
|
|
|
|
|
let bookFilesCountMessage = 'No book files';
|
|
|
|
|
|
|
|
|
|
if (trackFileCount === 1) {
|
|
|
|
|
trackFilesCountMessage = '1 track file';
|
|
|
|
|
} else if (trackFileCount > 1) {
|
|
|
|
|
trackFilesCountMessage = `${trackFileCount} track files`;
|
|
|
|
|
if (bookFileCount === 1) {
|
|
|
|
|
bookFilesCountMessage = '1 book file';
|
|
|
|
|
} else if (bookFileCount > 1) {
|
|
|
|
|
bookFilesCountMessage = `${bookFileCount} book files`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let expandIcon = icons.EXPAND_INDETERMINATE;
|
|
|
|
@ -225,7 +225,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<PageContent title={artistName}>
|
|
|
|
|
<PageContent title={authorName}>
|
|
|
|
|
<PageToolbar>
|
|
|
|
|
<PageToolbarSection>
|
|
|
|
|
<PageToolbarButton
|
|
|
|
@ -240,9 +240,9 @@ class ArtistDetails extends Component {
|
|
|
|
|
<PageToolbarButton
|
|
|
|
|
label="Search Monitored"
|
|
|
|
|
iconName={icons.SEARCH}
|
|
|
|
|
isDisabled={!monitored || !hasMonitoredAlbums || !hasAlbums}
|
|
|
|
|
isDisabled={!monitored || !hasMonitoredBooks || !hasBooks}
|
|
|
|
|
isSpinning={isSearching}
|
|
|
|
|
title={hasMonitoredAlbums ? undefined : 'No monitored albums for this artist'}
|
|
|
|
|
title={hasMonitoredBooks ? undefined : 'No monitored books for this author'}
|
|
|
|
|
onPress={onSearchPress}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
@ -251,14 +251,14 @@ class ArtistDetails extends Component {
|
|
|
|
|
<PageToolbarButton
|
|
|
|
|
label="Preview Rename"
|
|
|
|
|
iconName={icons.ORGANIZE}
|
|
|
|
|
isDisabled={!hasTrackFiles}
|
|
|
|
|
isDisabled={!hasBookFiles}
|
|
|
|
|
onPress={this.onOrganizePress}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* <PageToolbarButton */}
|
|
|
|
|
{/* label="Preview Retag" */}
|
|
|
|
|
{/* iconName={icons.RETAG} */}
|
|
|
|
|
{/* isDisabled={!hasTrackFiles} */}
|
|
|
|
|
{/* isDisabled={!hasBookFiles} */}
|
|
|
|
|
{/* onPress={this.onRetagPress} */}
|
|
|
|
|
{/* /> */}
|
|
|
|
|
|
|
|
|
@ -273,13 +273,13 @@ class ArtistDetails extends Component {
|
|
|
|
|
<PageToolbarButton
|
|
|
|
|
label="Edit"
|
|
|
|
|
iconName={icons.EDIT}
|
|
|
|
|
onPress={this.onEditArtistPress}
|
|
|
|
|
onPress={this.onEditAuthorPress}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<PageToolbarButton
|
|
|
|
|
label="Delete"
|
|
|
|
|
iconName={icons.DELETE}
|
|
|
|
|
onPress={this.onDeleteArtistPress}
|
|
|
|
|
onPress={this.onDeleteAuthorPress}
|
|
|
|
|
/>
|
|
|
|
|
</PageToolbarSection>
|
|
|
|
|
|
|
|
|
@ -304,7 +304,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles.headerContent}>
|
|
|
|
|
<ArtistPoster
|
|
|
|
|
<AuthorPoster
|
|
|
|
|
className={styles.poster}
|
|
|
|
|
images={images}
|
|
|
|
|
size={250}
|
|
|
|
@ -325,7 +325,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles.title}>
|
|
|
|
|
{artistName}
|
|
|
|
|
{authorName}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
@ -339,36 +339,36 @@ class ArtistDetails extends Component {
|
|
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
|
title="Alternate Titles"
|
|
|
|
|
body={<ArtistAlternateTitles alternateTitles={alternateTitles} />}
|
|
|
|
|
body={<AuthorAlternateTitles alternateTitles={alternateTitles} />}
|
|
|
|
|
position={tooltipPositions.BOTTOM}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles.artistNavigationButtons}>
|
|
|
|
|
<div className={styles.authorNavigationButtons}>
|
|
|
|
|
<IconButton
|
|
|
|
|
className={styles.artistNavigationButton}
|
|
|
|
|
className={styles.authorNavigationButton}
|
|
|
|
|
name={icons.ARROW_LEFT}
|
|
|
|
|
size={30}
|
|
|
|
|
title={`Go to ${previousArtist.artistName}`}
|
|
|
|
|
to={`/author/${previousArtist.titleSlug}`}
|
|
|
|
|
title={`Go to ${previousAuthor.authorName}`}
|
|
|
|
|
to={`/author/${previousAuthor.titleSlug}`}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<IconButton
|
|
|
|
|
className={styles.artistNavigationButton}
|
|
|
|
|
className={styles.authorNavigationButton}
|
|
|
|
|
name={icons.ARROW_UP}
|
|
|
|
|
size={30}
|
|
|
|
|
title={'Go to artist listing'}
|
|
|
|
|
title={'Go to author listing'}
|
|
|
|
|
to={'/'}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<IconButton
|
|
|
|
|
className={styles.artistNavigationButton}
|
|
|
|
|
className={styles.authorNavigationButton}
|
|
|
|
|
name={icons.ARROW_RIGHT}
|
|
|
|
|
size={30}
|
|
|
|
|
title={`Go to ${nextArtist.artistName}`}
|
|
|
|
|
to={`/author/${nextArtist.titleSlug}`}
|
|
|
|
|
title={`Go to ${nextAuthor.authorName}`}
|
|
|
|
|
to={`/author/${nextAuthor.titleSlug}`}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -399,7 +399,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
|
|
|
|
|
<Label
|
|
|
|
|
className={styles.detailsLabel}
|
|
|
|
|
title={trackFilesCountMessage}
|
|
|
|
|
title={bookFilesCountMessage}
|
|
|
|
|
size={sizes.LARGE}
|
|
|
|
|
>
|
|
|
|
|
<Icon
|
|
|
|
@ -449,11 +449,11 @@ class ArtistDetails extends Component {
|
|
|
|
|
|
|
|
|
|
<Label
|
|
|
|
|
className={styles.detailsLabel}
|
|
|
|
|
title={continuing ? 'More albums are expected' : 'No additional albums are expected'}
|
|
|
|
|
title={continuing ? 'More books are expected' : 'No additional books are expected'}
|
|
|
|
|
size={sizes.LARGE}
|
|
|
|
|
>
|
|
|
|
|
<Icon
|
|
|
|
|
name={continuing ? icons.ARTIST_CONTINUING : icons.ARTIST_ENDED}
|
|
|
|
|
name={continuing ? icons.AUTHOR_CONTINUING : icons.AUTHOR_ENDED}
|
|
|
|
|
size={17}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
@ -479,7 +479,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
</Label>
|
|
|
|
|
}
|
|
|
|
|
tooltip={
|
|
|
|
|
<ArtistDetailsLinks
|
|
|
|
|
<AuthorDetailsLinks
|
|
|
|
|
links={links}
|
|
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
@ -505,7 +505,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
</span>
|
|
|
|
|
</Label>
|
|
|
|
|
}
|
|
|
|
|
tooltip={<ArtistTagsConnector authorId={id} />}
|
|
|
|
|
tooltip={<AuthorTagsConnector authorId={id} />}
|
|
|
|
|
kind={kinds.INVERSE}
|
|
|
|
|
position={tooltipPositions.BOTTOM}
|
|
|
|
|
/>
|
|
|
|
@ -524,18 +524,18 @@ class ArtistDetails extends Component {
|
|
|
|
|
|
|
|
|
|
<div className={styles.contentContainer}>
|
|
|
|
|
{
|
|
|
|
|
!isPopulated && !albumsError && !trackFilesError &&
|
|
|
|
|
!isPopulated && !booksError && !bookFilesError &&
|
|
|
|
|
<LoadingIndicator />
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
!isFetching && albumsError &&
|
|
|
|
|
<div>Loading albums failed</div>
|
|
|
|
|
!isFetching && booksError &&
|
|
|
|
|
<div>Loading books failed</div>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
!isFetching && trackFilesError &&
|
|
|
|
|
<div>Loading track files failed</div>
|
|
|
|
|
!isFetching && bookFilesError &&
|
|
|
|
|
<div>Loading book files failed</div>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
@ -583,14 +583,14 @@ class ArtistDetails extends Component {
|
|
|
|
|
selectedTabIndex === 3 &&
|
|
|
|
|
<div className={styles.filterIcon}>
|
|
|
|
|
<InteractiveSearchFilterMenuConnector
|
|
|
|
|
type="artist"
|
|
|
|
|
type="author"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
</TabList>
|
|
|
|
|
|
|
|
|
|
<TabPanel>
|
|
|
|
|
<ArtistDetailsSeasonConnector
|
|
|
|
|
<AuthorDetailsSeasonConnector
|
|
|
|
|
authorId={id}
|
|
|
|
|
isExpanded={true}
|
|
|
|
|
onExpandPress={this.onExpandPress}
|
|
|
|
@ -619,20 +619,20 @@ class ArtistDetails extends Component {
|
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
|
|
<TabPanel>
|
|
|
|
|
<ArtistHistoryTable
|
|
|
|
|
<AuthorHistoryTable
|
|
|
|
|
authorId={id}
|
|
|
|
|
/>
|
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
|
|
<TabPanel>
|
|
|
|
|
<InteractiveSearchTable
|
|
|
|
|
type="artist"
|
|
|
|
|
type="author"
|
|
|
|
|
authorId={id}
|
|
|
|
|
/>
|
|
|
|
|
</TabPanel>
|
|
|
|
|
|
|
|
|
|
<TabPanel>
|
|
|
|
|
<TrackFileEditorTable
|
|
|
|
|
<BookFileEditorTable
|
|
|
|
|
authorId={id}
|
|
|
|
|
/>
|
|
|
|
|
</TabPanel>
|
|
|
|
@ -645,7 +645,7 @@ class ArtistDetails extends Component {
|
|
|
|
|
Missing or too many books? Modify or create a new
|
|
|
|
|
<Link to='/settings/profiles'> Metadata Profile </Link>
|
|
|
|
|
or manually
|
|
|
|
|
<Link to={`/add/search?term=${encodeURIComponent(artistName)}`}> Search </Link>
|
|
|
|
|
<Link to={`/add/search?term=${encodeURIComponent(authorName)}`}> Search </Link>
|
|
|
|
|
for new items!
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
@ -661,23 +661,23 @@ class ArtistDetails extends Component {
|
|
|
|
|
onModalClose={this.onRetagModalClose}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<EditArtistModalConnector
|
|
|
|
|
isOpen={isEditArtistModalOpen}
|
|
|
|
|
<EditAuthorModalConnector
|
|
|
|
|
isOpen={isEditAuthorModalOpen}
|
|
|
|
|
authorId={id}
|
|
|
|
|
onModalClose={this.onEditArtistModalClose}
|
|
|
|
|
onDeleteArtistPress={this.onDeleteArtistPress}
|
|
|
|
|
onModalClose={this.onEditAuthorModalClose}
|
|
|
|
|
onDeleteAuthorPress={this.onDeleteAuthorPress}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<DeleteArtistModal
|
|
|
|
|
isOpen={isDeleteArtistModalOpen}
|
|
|
|
|
<DeleteAuthorModal
|
|
|
|
|
isOpen={isDeleteAuthorModalOpen}
|
|
|
|
|
authorId={id}
|
|
|
|
|
onModalClose={this.onDeleteArtistModalClose}
|
|
|
|
|
onModalClose={this.onDeleteAuthorModalClose}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<InteractiveImportModal
|
|
|
|
|
isOpen={isInteractiveImportModalOpen}
|
|
|
|
|
folder={path}
|
|
|
|
|
allowArtistChange={false}
|
|
|
|
|
allowAuthorChange={false}
|
|
|
|
|
showFilterExistingFiles={true}
|
|
|
|
|
showImportMode={false}
|
|
|
|
|
onModalClose={this.onInteractiveImportModalClose}
|
|
|
|
@ -688,15 +688,15 @@ class ArtistDetails extends Component {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArtistDetails.propTypes = {
|
|
|
|
|
AuthorDetails.propTypes = {
|
|
|
|
|
id: PropTypes.number.isRequired,
|
|
|
|
|
artistName: PropTypes.string.isRequired,
|
|
|
|
|
authorName: PropTypes.string.isRequired,
|
|
|
|
|
ratings: PropTypes.object.isRequired,
|
|
|
|
|
path: PropTypes.string.isRequired,
|
|
|
|
|
statistics: PropTypes.object.isRequired,
|
|
|
|
|
qualityProfileId: PropTypes.number.isRequired,
|
|
|
|
|
monitored: PropTypes.bool.isRequired,
|
|
|
|
|
artistType: PropTypes.string,
|
|
|
|
|
authorType: PropTypes.string,
|
|
|
|
|
status: PropTypes.string.isRequired,
|
|
|
|
|
overview: PropTypes.string.isRequired,
|
|
|
|
|
links: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
|
|
@ -708,24 +708,24 @@ ArtistDetails.propTypes = {
|
|
|
|
|
isSearching: PropTypes.bool.isRequired,
|
|
|
|
|
isFetching: PropTypes.bool.isRequired,
|
|
|
|
|
isPopulated: PropTypes.bool.isRequired,
|
|
|
|
|
albumsError: PropTypes.object,
|
|
|
|
|
trackFilesError: PropTypes.object,
|
|
|
|
|
hasAlbums: PropTypes.bool.isRequired,
|
|
|
|
|
hasMonitoredAlbums: PropTypes.bool.isRequired,
|
|
|
|
|
booksError: PropTypes.object,
|
|
|
|
|
bookFilesError: PropTypes.object,
|
|
|
|
|
hasBooks: PropTypes.bool.isRequired,
|
|
|
|
|
hasMonitoredBooks: PropTypes.bool.isRequired,
|
|
|
|
|
hasSeries: PropTypes.bool.isRequired,
|
|
|
|
|
series: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
|
|
|
hasTrackFiles: PropTypes.bool.isRequired,
|
|
|
|
|
previousArtist: PropTypes.object.isRequired,
|
|
|
|
|
nextArtist: PropTypes.object.isRequired,
|
|
|
|
|
hasBookFiles: PropTypes.bool.isRequired,
|
|
|
|
|
previousAuthor: PropTypes.object.isRequired,
|
|
|
|
|
nextAuthor: PropTypes.object.isRequired,
|
|
|
|
|
onMonitorTogglePress: PropTypes.func.isRequired,
|
|
|
|
|
onRefreshPress: PropTypes.func.isRequired,
|
|
|
|
|
onSearchPress: PropTypes.func.isRequired
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ArtistDetails.defaultProps = {
|
|
|
|
|
AuthorDetails.defaultProps = {
|
|
|
|
|
statistics: {},
|
|
|
|
|
tags: [],
|
|
|
|
|
isSaving: false
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default ArtistDetails;
|
|
|
|
|
export default AuthorDetails;
|