From 6d8b2b7393190cce079d00fa7e8aeffa72d32bba Mon Sep 17 00:00:00 2001 From: "Robbin \"Roboroads\" Schepers" Date: Sat, 4 Apr 2026 04:42:46 +0200 Subject: [PATCH] feat(quota): added support for unlimited quota days (#2797) --- server/entity/User.ts | 46 ++++++++++--------- src/components/QuotaSelector/index.tsx | 3 ++ .../RequestModal/QuotaDisplay/index.tsx | 4 +- src/i18n/locale/en.json | 4 +- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/server/entity/User.ts b/server/entity/User.ts index 1255ca895..3965e1b3d 100644 --- a/server/entity/User.ts +++ b/server/entity/User.ts @@ -296,7 +296,7 @@ export class User { requestedBy: { id: this.id, }, - createdAt: AfterDate(movieDate), + ...(movieQuotaDays ? { createdAt: AfterDate(movieDate) } : {}), type: MediaType.MOVIE, status: Not(MediaRequestStatus.DECLINED), }, @@ -314,24 +314,28 @@ export class User { tvDate.setDate(tvDate.getDate() - tvQuotaDays); } const tvQuotaStartDate = tvDate.toJSON(); + const tvQuotaUsedQuery = requestRepository + .createQueryBuilder('request') + .leftJoin('request.requestedBy', 'requestedBy') + .where('request.type = :requestType', { + requestType: MediaType.TV, + }) + .andWhere('requestedBy.id = :userId', { + userId: this.id, + }) + .andWhere('request.status != :declinedStatus', { + declinedStatus: MediaRequestStatus.DECLINED, + }); + + if (tvQuotaDays) { + tvQuotaUsedQuery.andWhere('request.createdAt > :date', { + date: tvQuotaStartDate, + }); + } + const tvQuotaUsed = tvQuotaLimit ? ( - await requestRepository - .createQueryBuilder('request') - .leftJoin('request.seasons', 'seasons') - .leftJoin('request.requestedBy', 'requestedBy') - .where('request.type = :requestType', { - requestType: MediaType.TV, - }) - .andWhere('requestedBy.id = :userId', { - userId: this.id, - }) - .andWhere('request.createdAt > :date', { - date: tvQuotaStartDate, - }) - .andWhere('request.status != :declinedStatus', { - declinedStatus: MediaRequestStatus.DECLINED, - }) + await tvQuotaUsedQuery .addSelect((subQuery) => { return subQuery .select('COUNT(season.id)', 'seasonCount') @@ -351,10 +355,9 @@ export class User { remaining: movieQuotaLimit ? Math.max(0, movieQuotaLimit - movieQuotaUsed) : undefined, - restricted: + restricted: !!( movieQuotaLimit && movieQuotaLimit - movieQuotaUsed <= 0 - ? true - : false, + ), }, tv: { days: tvQuotaDays, @@ -363,8 +366,7 @@ export class User { remaining: tvQuotaLimit ? Math.max(0, tvQuotaLimit - tvQuotaUsed) : undefined, - restricted: - tvQuotaLimit && tvQuotaLimit - tvQuotaUsed <= 0 ? true : false, + restricted: !!(tvQuotaLimit && tvQuotaLimit - tvQuotaUsed <= 0), }, }; } diff --git a/src/components/QuotaSelector/index.tsx b/src/components/QuotaSelector/index.tsx index 0f0454e24..f35a5d1e0 100644 --- a/src/components/QuotaSelector/index.tsx +++ b/src/components/QuotaSelector/index.tsx @@ -79,6 +79,9 @@ const QuotaSelector = ({ onChange={(e) => setQuotaDays(Number(e.target.value))} disabled={isDisabled} > + {[...Array(100)].map((_item, i) => (