diff --git a/frontend/src/Artist/Details/AlbumGroupInfo.css b/frontend/src/Artist/Details/AlbumGroupInfo.css
new file mode 100644
index 000000000..b3102d230
--- /dev/null
+++ b/frontend/src/Artist/Details/AlbumGroupInfo.css
@@ -0,0 +1,11 @@
+.title {
+ composes: title from '~Components/DescriptionList/DescriptionListItemTitle.css';
+
+ width: 90px;
+}
+
+.description {
+ composes: title from '~Components/DescriptionList/DescriptionListItemDescription.css';
+
+ margin-left: 110px;
+}
diff --git a/frontend/src/Artist/Details/AlbumGroupInfo.js b/frontend/src/Artist/Details/AlbumGroupInfo.js
new file mode 100644
index 000000000..0702290c9
--- /dev/null
+++ b/frontend/src/Artist/Details/AlbumGroupInfo.js
@@ -0,0 +1,56 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import DescriptionList from 'Components/DescriptionList/DescriptionList';
+import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
+import formatBytes from 'Utilities/Number/formatBytes';
+import styles from './AlbumGroupInfo.css';
+
+function AlbumGroupInfo(props) {
+ const {
+ totalAlbumCount,
+ monitoredAlbumCount,
+ trackFileCount,
+ sizeOnDisk
+ } = props;
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
+
+AlbumGroupInfo.propTypes = {
+ totalAlbumCount: PropTypes.number.isRequired,
+ monitoredAlbumCount: PropTypes.number.isRequired,
+ trackFileCount: PropTypes.number.isRequired,
+ sizeOnDisk: PropTypes.number.isRequired
+};
+
+export default AlbumGroupInfo;
diff --git a/frontend/src/Artist/Details/ArtistDetailsSeason.css b/frontend/src/Artist/Details/ArtistDetailsSeason.css
index b1cb2632e..4421fe7a7 100644
--- a/frontend/src/Artist/Details/ArtistDetailsSeason.css
+++ b/frontend/src/Artist/Details/ArtistDetailsSeason.css
@@ -15,11 +15,10 @@
align-items: center;
width: 100%;
font-size: 24px;
- cursor: pointer;
}
.albumTypeLabel {
- margin-right: 5px;
+ margin-right: 10px;
margin-left: 5px;
}
@@ -29,10 +28,16 @@
font-size: 18px;
}
-.episodeCountTooltip {
+.albumCountTooltip {
display: flex;
}
+.sizeOnDisk {
+ margin-left: 10px;
+ color: #777;
+ font-size: $defaultFontSize;
+}
+
.expandButton {
composes: link from '~Components/Link/Link.css';
@@ -44,7 +49,7 @@
.left {
display: flex;
align-items: center;
- flex: 0 1 300px;
+ flex: 0 1 350px;
}
.left,
@@ -103,7 +108,7 @@
top: 50%;
left: 50%;
margin-top: -12px;
- margin-left: -15px;
+ margin-left: -12px;
}
.noAlbums {
@@ -122,4 +127,8 @@
position: static;
margin: 0;
}
+
+ .sizeOnDisk {
+ display: none;
+ }
}
diff --git a/frontend/src/Artist/Details/ArtistDetailsSeason.js b/frontend/src/Artist/Details/ArtistDetailsSeason.js
index 349184814..e0cbfc87c 100644
--- a/frontend/src/Artist/Details/ArtistDetailsSeason.js
+++ b/frontend/src/Artist/Details/ArtistDetailsSeason.js
@@ -2,18 +2,70 @@ import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
+import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import Link from 'Components/Link/Link';
+import MonitorToggleButton from 'Components/MonitorToggleButton';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
-import { icons, sortDirections } from 'Helpers/Props';
+import Popover from 'Components/Tooltip/Popover';
+import { icons, kinds, sizes, sortDirections, tooltipPositions } from 'Helpers/Props';
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal';
+import isBefore from 'Utilities/Date/isBefore';
+import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import getToggledRange from 'Utilities/Table/getToggledRange';
+import AlbumGroupInfo from './AlbumGroupInfo';
import AlbumRowConnector from './AlbumRowConnector';
import styles from './ArtistDetailsSeason.css';
+function getAlbumTypeStatistics(albums) {
+ let albumCount = 0;
+ let trackFileCount = 0;
+ let totalAlbumCount = 0;
+ let monitoredAlbumCount = 0;
+ let hasMonitoredAlbums = false;
+ let sizeOnDisk = 0;
+
+ albums.forEach((album) => {
+ sizeOnDisk = sizeOnDisk + album.statistics.sizeOnDisk;
+ trackFileCount = trackFileCount + album.statistics.trackFileCount;
+
+ if (album.statistics.trackFileCount === album.statistics.totalTrackCount || (album.monitored && isBefore(album.airDateUtc))) {
+ albumCount++;
+ }
+
+ if (album.monitored) {
+ monitoredAlbumCount++;
+ hasMonitoredAlbums = true;
+ }
+
+ totalAlbumCount++;
+ });
+
+ return {
+ albumCount,
+ totalAlbumCount,
+ trackFileCount,
+ monitoredAlbumCount,
+ sizeOnDisk,
+ hasMonitoredAlbums
+ };
+}
+
+function getAlbumCountKind(monitored, albumCount, monitoredAlbumCount) {
+ if (albumCount === monitoredAlbumCount && monitoredAlbumCount > 0) {
+ return kinds.SUCCESS;
+ }
+
+ if (!monitored) {
+ return kinds.WARNING;
+ }
+
+ return kinds.DANGER;
+}
+
class ArtistDetailsSeason extends Component {
//
@@ -108,7 +160,13 @@ class ArtistDetailsSeason extends Component {
this.setState({ lastToggledAlbum: albumId });
- this.props.onMonitorAlbumPress(_.uniq(albumIds), monitored);
+ this.props.onMonitorAlbumsPress(_.uniq(albumIds), monitored);
+ };
+
+ onMonitorAlbumsPress = (monitored, { shiftKey }) => {
+ const albumIds = this.props.items.map((a) => a.id);
+
+ this.props.onMonitorAlbumsPress(_.uniq(albumIds), monitored);
};
//
@@ -120,7 +178,9 @@ class ArtistDetailsSeason extends Component {
label,
items,
columns,
+ isSaving,
isExpanded,
+ artistMonitored,
sortKey,
sortDirection,
onSortPress,
@@ -128,6 +188,15 @@ class ArtistDetailsSeason extends Component {
onTableOptionChange
} = this.props;
+ const {
+ albumCount,
+ totalAlbumCount,
+ trackFileCount,
+ monitoredAlbumCount,
+ sizeOnDisk,
+ hasMonitoredAlbums
+ } = getAlbumTypeStatistics(items);
+
const {
isOrganizeModalOpen,
isManageTracksOpen
@@ -137,25 +206,55 @@ class ArtistDetailsSeason extends Component {
-
-
-
- {
+
+
+
+
+ {label}
+
+
+ {albumCount} / {monitoredAlbumCount}
+
+ }
+ title="Group Information"
+ body={
-
- {label}
-
-
-
- ({items.length} Releases)
-
+
}
+ position={tooltipPositions.BOTTOM}
+ />
+
+ {
+ sizeOnDisk ?
+
+ {formatBytes(sizeOnDisk)}
+
:
+ null
+ }
+
-
+
}
+
-
-
+
{
@@ -238,16 +337,18 @@ ArtistDetailsSeason.propTypes = {
artistId: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
+ artistMonitored: PropTypes.bool.isRequired,
sortKey: PropTypes.string,
sortDirection: PropTypes.oneOf(sortDirections.all),
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
+ isSaving: PropTypes.bool,
isExpanded: PropTypes.bool,
isSmallScreen: PropTypes.bool.isRequired,
onTableOptionChange: PropTypes.func.isRequired,
onExpandPress: PropTypes.func.isRequired,
onSortPress: PropTypes.func.isRequired,
- onMonitorAlbumPress: PropTypes.func.isRequired,
+ onMonitorAlbumsPress: PropTypes.func.isRequired,
uiSettings: PropTypes.object.isRequired
};
diff --git a/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js b/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
index daa99e49a..6eb98cd52 100644
--- a/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
+++ b/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
@@ -36,9 +36,9 @@ function createMapStateToProps() {
return {
items: sortedAlbums,
columns: albums.columns,
+ artistMonitored: artist.monitored,
sortKey: albums.sortKey,
sortDirection: albums.sortDirection,
- artistMonitored: artist.monitored,
isSmallScreen: dimensions.isSmallScreen,
uiSettings
};
@@ -66,7 +66,7 @@ class ArtistDetailsSeasonConnector extends Component {
this.props.dispatchSetAlbumSort({ sortKey });
};
- onMonitorAlbumPress = (albumIds, monitored) => {
+ onMonitorAlbumsPress = (albumIds, monitored) => {
this.props.toggleAlbumsMonitored({
albumIds,
monitored
@@ -82,7 +82,7 @@ class ArtistDetailsSeasonConnector extends Component {
{...this.props}
onSortPress={this.onSortPress}
onTableOptionChange={this.onTableOptionChange}
- onMonitorAlbumPress={this.onMonitorAlbumPress}
+ onMonitorAlbumsPress={this.onMonitorAlbumsPress}
/>
);
}