mirror of
https://github.com/Sonarr/Sonarr
synced 2026-01-24 00:12:07 +01:00
parent
ee875ae654
commit
5f8297da6c
13 changed files with 96 additions and 51 deletions
|
|
@ -16,11 +16,11 @@ import DefaultFilterBuilderRowValue from './DefaultFilterBuilderRowValue';
|
|||
import HistoryEventTypeFilterBuilderRowValue from './HistoryEventTypeFilterBuilderRowValue';
|
||||
import IndexerFilterBuilderRowValue from './IndexerFilterBuilderRowValue';
|
||||
import LanguageFilterBuilderRowValue from './LanguageFilterBuilderRowValue';
|
||||
import MonitoredStatusFilterBuilderRowValue from './MonitoredStatusFilterBuilderRowValue';
|
||||
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
|
||||
import QualityFilterBuilderRowValue from './QualityFilterBuilderRowValue';
|
||||
import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue';
|
||||
import QueueStatusFilterBuilderRowValue from './QueueStatusFilterBuilderRowValue';
|
||||
import SeasonsMonitoredStatusFilterBuilderRowValue from './SeasonsMonitoredStatusFilterBuilderRowValue';
|
||||
import SeriesFilterBuilderRowValue from './SeriesFilterBuilderRowValue';
|
||||
import SeriesStatusFilterBuilderRowValue from './SeriesStatusFilterBuilderRowValue';
|
||||
import SeriesTypeFilterBuilderRowValue from './SeriesTypeFilterBuilderRowValue';
|
||||
|
|
@ -109,8 +109,8 @@ function getRowValueConnector<T>(
|
|||
case filterBuilderValueTypes.QUEUE_STATUS:
|
||||
return QueueStatusFilterBuilderRowValue;
|
||||
|
||||
case filterBuilderValueTypes.SEASONS_MONITORED_STATUS:
|
||||
return SeasonsMonitoredStatusFilterBuilderRowValue;
|
||||
case filterBuilderValueTypes.MONITORED_STATUS:
|
||||
return MonitoredStatusFilterBuilderRowValue;
|
||||
|
||||
case filterBuilderValueTypes.SERIES:
|
||||
return SeriesFilterBuilderRowValue;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FilterBuilderRowValue, {
|
||||
FilterBuilderRowValueProps,
|
||||
} from './FilterBuilderRowValue';
|
||||
|
||||
const monitoredStatusList = [
|
||||
{
|
||||
id: 'all',
|
||||
get name() {
|
||||
return translate('MonitoredAll');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'partial',
|
||||
get name() {
|
||||
return translate('MonitoredPartial');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'none',
|
||||
get name() {
|
||||
return translate('MonitoredNone');
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
type MonitoredStatusFilterBuilderRowValueProps<T> = Omit<
|
||||
FilterBuilderRowValueProps<T, string, string>,
|
||||
'tagList'
|
||||
>;
|
||||
|
||||
function MonitoredStatusFilterBuilderRowValue<T>(
|
||||
props: MonitoredStatusFilterBuilderRowValueProps<T>
|
||||
) {
|
||||
return <FilterBuilderRowValue tagList={monitoredStatusList} {...props} />;
|
||||
}
|
||||
|
||||
export default MonitoredStatusFilterBuilderRowValue;
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import React from 'react';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FilterBuilderRowValue, {
|
||||
FilterBuilderRowValueProps,
|
||||
} from './FilterBuilderRowValue';
|
||||
|
||||
const seasonsMonitoredStatusList = [
|
||||
{
|
||||
id: 'all',
|
||||
get name() {
|
||||
return translate('SeasonsMonitoredAll');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'partial',
|
||||
get name() {
|
||||
return translate('SeasonsMonitoredPartial');
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'none',
|
||||
get name() {
|
||||
return translate('SeasonsMonitoredNone');
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
type SeasonsMonitoredStatusFilterBuilderRowValueProps<T> = Omit<
|
||||
FilterBuilderRowValueProps<T, string, string>,
|
||||
'tagList'
|
||||
>;
|
||||
|
||||
function SeasonsMonitoredStatusFilterBuilderRowValue<T>(
|
||||
props: SeasonsMonitoredStatusFilterBuilderRowValueProps<T>
|
||||
) {
|
||||
return (
|
||||
<FilterBuilderRowValue tagList={seasonsMonitoredStatusList} {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
export default SeasonsMonitoredStatusFilterBuilderRowValue;
|
||||
|
|
@ -9,7 +9,7 @@ export const PROTOCOL = 'protocol';
|
|||
export const QUALITY = 'quality';
|
||||
export const QUALITY_PROFILE = 'qualityProfile';
|
||||
export const QUEUE_STATUS = 'queueStatus';
|
||||
export const SEASONS_MONITORED_STATUS = 'seasonsMonitoredStatus';
|
||||
export const MONITORED_STATUS = 'monitoredStatus';
|
||||
export const SERIES = 'series';
|
||||
export const SERIES_STATUS = 'seriesStatus';
|
||||
export const SERIES_TYPES = 'seriesType';
|
||||
|
|
@ -27,7 +27,7 @@ export type FilterBuildValueType =
|
|||
| 'quality'
|
||||
| 'qualityProfile'
|
||||
| 'queueStatus'
|
||||
| 'seasonsMonitoredStatus'
|
||||
| 'monitoredStatus'
|
||||
| 'series'
|
||||
| 'seriesStatus'
|
||||
| 'seriesType'
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ export interface Statistics {
|
|||
releaseGroups: string[];
|
||||
sizeOnDisk: number;
|
||||
totalEpisodeCount: number;
|
||||
monitoredEpisodeCount: number;
|
||||
lastAired?: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { SortDirection } from 'Helpers/Props/sortDirections';
|
|||
import sortByProp from 'Utilities/Array/sortByProp';
|
||||
import clientSideFilterAndSort from 'Utilities/Filter/clientSideFilterAndSort';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import Series from './Series';
|
||||
import Series, { Statistics } from './Series';
|
||||
import { useSeriesOptions } from './seriesOptionsStore';
|
||||
|
||||
// Date filter predicate helper
|
||||
|
|
@ -315,6 +315,37 @@ const FILTER_PREDICATES = {
|
|||
|
||||
return predicate(seasonsMonitoredStatus, filterValue);
|
||||
},
|
||||
|
||||
episodesMonitoredStatus: (
|
||||
item: Series,
|
||||
filterValue: string,
|
||||
type: FilterType
|
||||
) => {
|
||||
const predicate = getFilterTypePredicate(type);
|
||||
const { seasons, statistics = {} as Statistics } = item;
|
||||
const { monitoredEpisodeCount = 0, totalEpisodeCount = 0 } = statistics;
|
||||
const specials = seasons?.find((s) => s.seasonNumber === 0);
|
||||
|
||||
// The monitored count and total count include specials, but those areskipped
|
||||
// for seasons monitored status so we should to exclude them here too.
|
||||
|
||||
const monitoredCount =
|
||||
monitoredEpisodeCount -
|
||||
(specials?.statistics?.monitoredEpisodeCount ?? 0);
|
||||
|
||||
const totalCount =
|
||||
totalEpisodeCount - (specials?.statistics?.totalEpisodeCount ?? 0);
|
||||
|
||||
let episodesMonitoredStatus = 'partial';
|
||||
|
||||
if (monitoredCount === 0) {
|
||||
episodesMonitoredStatus = 'none';
|
||||
} else if (totalCount - monitoredCount === 0) {
|
||||
episodesMonitoredStatus = 'all';
|
||||
}
|
||||
|
||||
return predicate(episodesMonitoredStatus, filterValue);
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const FILTER_BUILDER: FilterBuilderProp<Series>[] = [
|
||||
|
|
@ -498,7 +529,13 @@ export const FILTER_BUILDER: FilterBuilderProp<Series>[] = [
|
|||
name: 'seasonsMonitoredStatus',
|
||||
label: () => translate('SeasonsMonitoredStatus'),
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.SEASONS_MONITORED_STATUS,
|
||||
valueType: filterBuilderValueTypes.MONITORED_STATUS,
|
||||
},
|
||||
{
|
||||
name: 'episodesMonitoredStatus',
|
||||
label: () => translate('EpisodesMonitoredStatus'),
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.MONITORED_STATUS,
|
||||
},
|
||||
{
|
||||
name: 'year',
|
||||
|
|
|
|||
|
|
@ -683,6 +683,7 @@
|
|||
"Episodes": "Episodes",
|
||||
"EpisodesInSeason": "{episodeCount} episodes in season",
|
||||
"EpisodesLoadError": "Unable to load episodes",
|
||||
"EpisodesMonitoredStatus": "Episodes Monitored",
|
||||
"Error": "Error",
|
||||
"ErrorLoadingContent": "There was an error loading this content",
|
||||
"ErrorLoadingContents": "Error loading contents",
|
||||
|
|
@ -1282,8 +1283,11 @@
|
|||
"MonitorSpecialEpisodes": "Monitor Specials",
|
||||
"MonitorSpecialEpisodesDescription": "Monitor all special episodes without changing the monitored status of other episodes",
|
||||
"Monitored": "Monitored",
|
||||
"MonitoredAll": "All",
|
||||
"MonitoredEpisodesHelpText": "Download monitored episodes in this series",
|
||||
"MonitoredNone": "None",
|
||||
"MonitoredOnly": "Monitored Only",
|
||||
"MonitoredPartial": "Partial",
|
||||
"MonitoredStatus": "Monitored/Status",
|
||||
"Monitoring": "Monitoring",
|
||||
"MonitoringOptions": "Monitoring Options",
|
||||
|
|
@ -1892,9 +1896,6 @@
|
|||
"SeasonPremiere": "Season Premiere",
|
||||
"SeasonPremieresOnly": "Season Premieres Only",
|
||||
"Seasons": "Seasons",
|
||||
"SeasonsMonitoredAll": "All",
|
||||
"SeasonsMonitoredNone": "None",
|
||||
"SeasonsMonitoredPartial": "Partial",
|
||||
"SeasonsMonitoredStatus": "Seasons Monitored",
|
||||
"SecretToken": "Secret Token",
|
||||
"Security": "Security",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class SeasonStatistics : ResultSet
|
|||
public int EpisodeCount { get; set; }
|
||||
public int AvailableEpisodeCount { get; set; }
|
||||
public int TotalEpisodeCount { get; set; }
|
||||
public int MonitoredEpisodeCount { get; set; }
|
||||
public long SizeOnDisk { get; set; }
|
||||
public string ReleaseGroupsString { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public class SeriesStatistics : ResultSet
|
|||
public int EpisodeFileCount { get; set; }
|
||||
public int EpisodeCount { get; set; }
|
||||
public int TotalEpisodeCount { get; set; }
|
||||
public int MonitoredEpisodeCount { get; set; }
|
||||
public long SizeOnDisk { get; set; }
|
||||
public List<string> ReleaseGroups { get; set; }
|
||||
public List<SeasonStatistics> SeasonStatistics { get; set; }
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ private SqlBuilder EpisodesBuilder(DateTime currentDate)
|
|||
SUM(CASE WHEN ""AirDateUtc"" <= @currentDate OR ""EpisodeFileId"" > 0 THEN 1 ELSE 0 END) AS AvailableEpisodeCount,
|
||||
SUM(CASE WHEN (""Monitored"" = {trueIndicator} AND ""AirDateUtc"" <= @currentDate) OR ""EpisodeFileId"" > 0 THEN 1 ELSE 0 END) AS EpisodeCount,
|
||||
SUM(CASE WHEN ""EpisodeFileId"" > 0 THEN 1 ELSE 0 END) AS EpisodeFileCount,
|
||||
SUM(CASE WHEN ""Monitored"" = {trueIndicator} THEN 1 ELSE 0 END) AS MonitoredEpisodeCount,
|
||||
MIN(CASE WHEN ""AirDateUtc"" < @currentDate OR ""Monitored"" = {falseIndicator} THEN NULL ELSE ""AirDateUtc"" END) AS NextAiringString,
|
||||
MAX(CASE WHEN ""AirDateUtc"" >= @currentDate OR ""Monitored"" = {falseIndicator} THEN NULL ELSE ""AirDateUtc"" END) AS PreviousAiringString,
|
||||
MAX(""AirDate"") AS LastAiredString",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ private SeriesStatistics MapSeriesStatistics(List<SeasonStatistics> seasonStatis
|
|||
EpisodeFileCount = seasonStatistics.Sum(s => s.EpisodeFileCount),
|
||||
EpisodeCount = seasonStatistics.Sum(s => s.EpisodeCount),
|
||||
TotalEpisodeCount = seasonStatistics.Sum(s => s.TotalEpisodeCount),
|
||||
MonitoredEpisodeCount = seasonStatistics.Sum(s => s.MonitoredEpisodeCount),
|
||||
SizeOnDisk = seasonStatistics.Sum(s => s.SizeOnDisk),
|
||||
ReleaseGroups = seasonStatistics.SelectMany(s => s.ReleaseGroups).Distinct().ToList()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ public class SeasonStatisticsResource
|
|||
public int EpisodeFileCount { get; set; }
|
||||
public int EpisodeCount { get; set; }
|
||||
public int TotalEpisodeCount { get; set; }
|
||||
public int MonitoredEpisodeCount { get; set; }
|
||||
public long SizeOnDisk { get; set; }
|
||||
public List<string>? ReleaseGroups { get; set; }
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ public static SeasonStatisticsResource ToResource(this SeasonStatistics model)
|
|||
EpisodeFileCount = model.EpisodeFileCount,
|
||||
EpisodeCount = model.EpisodeCount,
|
||||
TotalEpisodeCount = model.TotalEpisodeCount,
|
||||
MonitoredEpisodeCount = model.MonitoredEpisodeCount,
|
||||
SizeOnDisk = model.SizeOnDisk,
|
||||
ReleaseGroups = model.ReleaseGroups
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ public class SeriesStatisticsResource
|
|||
public int EpisodeFileCount { get; set; }
|
||||
public int EpisodeCount { get; set; }
|
||||
public int TotalEpisodeCount { get; set; }
|
||||
public int MonitoredEpisodeCount { get; set; }
|
||||
public long SizeOnDisk { get; set; }
|
||||
public List<string>? ReleaseGroups { get; set; }
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ public static SeriesStatisticsResource ToResource(this SeriesStatistics model, L
|
|||
EpisodeFileCount = model.EpisodeFileCount,
|
||||
EpisodeCount = model.EpisodeCount,
|
||||
TotalEpisodeCount = model.TotalEpisodeCount,
|
||||
MonitoredEpisodeCount = model.MonitoredEpisodeCount,
|
||||
SizeOnDisk = model.SizeOnDisk,
|
||||
ReleaseGroups = model.ReleaseGroups
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue