diff --git a/frontend/src/Store/Actions/movieCollectionActions.js b/frontend/src/Store/Actions/movieCollectionActions.js index c9cc494af..5897f44af 100644 --- a/frontend/src/Store/Actions/movieCollectionActions.js +++ b/frontend/src/Store/Actions/movieCollectionActions.js @@ -1,10 +1,12 @@ import _ from 'lodash'; import { createAction } from 'redux-actions'; import { batchActions } from 'redux-batched-actions'; -import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props'; +import { filterBuilderTypes, filterBuilderValueTypes, filterTypePredicates, sortDirections } from 'Helpers/Props'; import { createThunk, handleThunks } from 'Store/thunks'; +import sortByName from 'Utilities/Array/sortByName'; import createAjaxRequest from 'Utilities/createAjaxRequest'; import getNewMovie from 'Utilities/Movie/getNewMovie'; +import translate from 'Utilities/String/translate'; import { set, update, updateItem } from './baseActions'; import createHandleActions from './Creators/createHandleActions'; import createSaveProviderHandler from './Creators/createSaveProviderHandler'; @@ -63,19 +65,81 @@ export const defaultState = { } ], - filterPredicates: {}, + filterPredicates: { + genres: function(item, filterValue, type) { + const predicate = filterTypePredicates[type]; + + let allGenres = []; + item.movies.forEach((movie) => { + allGenres = allGenres.concat(movie.genres); + }); + + const genres = Array.from(new Set(allGenres)).slice(0, 3); + + return predicate(genres, filterValue); + }, + totalMovies: function(item, filterValue, type) { + const predicate = filterTypePredicates[type]; + const { movies } = item; + + const totalMovies = movies.length; + return predicate(totalMovies, filterValue); + } + }, filterBuilderProps: [ { name: 'title', - label: 'Title', + label: translate('Title'), type: filterBuilderTypes.STRING }, { name: 'monitored', - label: 'Monitored', + label: translate('Monitored'), type: filterBuilderTypes.EXACT, valueType: filterBuilderValueTypes.BOOL + }, + { + name: 'qualityProfileId', + label: translate('QualityProfile'), + type: filterBuilderTypes.EXACT, + valueType: filterBuilderValueTypes.QUALITY_PROFILE + }, + { + name: 'rootFolderPath', + label: translate('RootFolder'), + type: filterBuilderTypes.STRING + }, + { + name: 'genres', + label: translate('Genres'), + type: filterBuilderTypes.ARRAY, + optionsSelector: function(items) { + const genreList = items.reduce((acc, collection) => { + let collectionGenres = []; + collection.movies.forEach((movie) => { + collectionGenres = collectionGenres.concat(movie.genres); + }); + + const genres = Array.from(new Set(collectionGenres)).slice(0, 3); + + genres.forEach((genre) => { + acc.push({ + id: genre, + name: genre + }); + }); + + return acc; + }, []); + + return genreList.sort(sortByName); + } + }, + { + name: 'totalMovies', + label: translate('TotalMovies'), + type: filterBuilderTypes.NUMBER } ] }; diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 4b5bb204b..ec02f86a0 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1027,6 +1027,7 @@ "Torrents": "Torrents", "TorrentsDisabled": "Torrents Disabled", "TotalFileSize": "Total File Size", + "TotalMovies": "Total Movies", "TotalSpace": "Total Space", "Trace": "Trace", "Trailer": "Trailer", diff --git a/src/Radarr.Api.V3/Collections/CollectionController.cs b/src/Radarr.Api.V3/Collections/CollectionController.cs index 36e243daf..f1438450b 100644 --- a/src/Radarr.Api.V3/Collections/CollectionController.cs +++ b/src/Radarr.Api.V3/Collections/CollectionController.cs @@ -55,9 +55,7 @@ namespace Radarr.Api.V3.Collections [HttpGet] public List GetCollections() { - var collectionMovies = _movieMetadataService.GetMoviesWithCollections(); - - return MapToResource(_collectionService.GetAllCollections(), collectionMovies).ToList(); + return MapToResource(_collectionService.GetAllCollections()).ToList(); } [RestPutById] @@ -116,10 +114,11 @@ namespace Radarr.Api.V3.Collections return Accepted(updated); } - private IEnumerable MapToResource(List collections, List collectionMovies) + private IEnumerable MapToResource(List collections) { // Avoid calling for naming spec on every movie in filenamebuilder var namingConfig = _namingService.GetConfig(); + var collectionMovies = _movieMetadataService.GetMoviesWithCollections(); foreach (var collection in collections) {