mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
fix: better ordering of RequestButton options & properly handle failed requests (#2944)
* fix: better ordering of RequestButton options & properly handle failed requests * fix: appease prettier
This commit is contained in:
@@ -4430,7 +4430,16 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
enum: [all, approved, available, pending, processing, unavailable]
|
||||
enum:
|
||||
[
|
||||
all,
|
||||
approved,
|
||||
available,
|
||||
pending,
|
||||
processing,
|
||||
unavailable,
|
||||
failed,
|
||||
]
|
||||
- in: query
|
||||
name: sort
|
||||
schema:
|
||||
|
@@ -2,6 +2,7 @@ export enum MediaRequestStatus {
|
||||
PENDING = 1,
|
||||
APPROVED,
|
||||
DECLINED,
|
||||
FAILED,
|
||||
}
|
||||
|
||||
export enum MediaType {
|
||||
|
@@ -451,10 +451,13 @@ export class MediaRequest {
|
||||
await mediaRepository.save(media);
|
||||
})
|
||||
.catch(async () => {
|
||||
media[this.is4k ? 'status4k' : 'status'] = MediaStatus.UNKNOWN;
|
||||
await mediaRepository.save(media);
|
||||
const requestRepository = getRepository(MediaRequest);
|
||||
|
||||
this.status = MediaRequestStatus.FAILED;
|
||||
requestRepository.save(this);
|
||||
|
||||
logger.warn(
|
||||
'Something went wrong sending movie request to Radarr, marking status as UNKNOWN',
|
||||
'Something went wrong sending movie request to Radarr, marking status as FAILED',
|
||||
{
|
||||
label: 'Media Request',
|
||||
requestId: this.id,
|
||||
@@ -684,10 +687,13 @@ export class MediaRequest {
|
||||
await mediaRepository.save(media);
|
||||
})
|
||||
.catch(async () => {
|
||||
media[this.is4k ? 'status4k' : 'status'] = MediaStatus.UNKNOWN;
|
||||
await mediaRepository.save(media);
|
||||
const requestRepository = getRepository(MediaRequest);
|
||||
|
||||
this.status = MediaRequestStatus.FAILED;
|
||||
requestRepository.save(this);
|
||||
|
||||
logger.warn(
|
||||
'Something went wrong sending series request to Sonarr, marking status as UNKNOWN',
|
||||
'Something went wrong sending series request to Sonarr, marking status as FAILED',
|
||||
{
|
||||
label: 'Media Request',
|
||||
requestId: this.id,
|
||||
|
@@ -40,11 +40,15 @@ requestRoutes.get<Record<string, unknown>, RequestResultsResponse>(
|
||||
MediaRequestStatus.APPROVED,
|
||||
];
|
||||
break;
|
||||
case 'failed':
|
||||
statusFilter = [MediaRequestStatus.FAILED];
|
||||
break;
|
||||
default:
|
||||
statusFilter = [
|
||||
MediaRequestStatus.PENDING,
|
||||
MediaRequestStatus.APPROVED,
|
||||
MediaRequestStatus.DECLINED,
|
||||
MediaRequestStatus.FAILED,
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -179,6 +179,11 @@ const RequestBlock = ({ request, onUpdate }: RequestBlockProps) => {
|
||||
{intl.formatMessage(globalMessages.pending)}
|
||||
</Badge>
|
||||
)}
|
||||
{request.status === MediaRequestStatus.FAILED && (
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.failed)}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2 flex items-center text-sm leading-5 sm:mt-0">
|
||||
|
@@ -77,13 +77,13 @@ const RequestButton = ({
|
||||
(request) => request.status === MediaRequestStatus.PENDING && request.is4k
|
||||
);
|
||||
|
||||
// Current user's pending request, or the first pending request
|
||||
const activeRequest = useMemo(() => {
|
||||
return activeRequests && activeRequests.length > 0
|
||||
? activeRequests.find((request) => request.requestedBy.id === user?.id) ??
|
||||
activeRequests[0]
|
||||
: undefined;
|
||||
}, [activeRequests, user]);
|
||||
|
||||
const active4kRequest = useMemo(() => {
|
||||
return active4kRequests && active4kRequests.length > 0
|
||||
? active4kRequests.find(
|
||||
@@ -121,54 +121,9 @@ const RequestButton = ({
|
||||
};
|
||||
|
||||
const buttons: ButtonOption[] = [];
|
||||
if (
|
||||
(!media || media.status === MediaStatus.UNKNOWN) &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST,
|
||||
mediaType === 'movie'
|
||||
? Permission.REQUEST_MOVIE
|
||||
: Permission.REQUEST_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
)
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request',
|
||||
text: intl.formatMessage(globalMessages.request),
|
||||
action: () => {
|
||||
setEditRequest(false);
|
||||
setShowRequestModal(true);
|
||||
},
|
||||
svg: <DownloadIcon />,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
(!media || media.status4k === MediaStatus.UNKNOWN) &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST_4K,
|
||||
mediaType === 'movie'
|
||||
? Permission.REQUEST_4K_MOVIE
|
||||
: Permission.REQUEST_4K_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
((settings.currentSettings.movie4kEnabled && mediaType === 'movie') ||
|
||||
(settings.currentSettings.series4kEnabled && mediaType === 'tv'))
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request4k',
|
||||
text: intl.formatMessage(globalMessages.request4k),
|
||||
action: () => {
|
||||
setEditRequest(false);
|
||||
setShowRequest4kModal(true);
|
||||
},
|
||||
svg: <DownloadIcon />,
|
||||
});
|
||||
}
|
||||
|
||||
// If there are pending requests, show request management options first
|
||||
if (activeRequest || active4kRequest) {
|
||||
if (
|
||||
activeRequest &&
|
||||
(activeRequest.requestedBy.id === user?.id ||
|
||||
@@ -186,23 +141,6 @@ const RequestButton = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
active4kRequest &&
|
||||
(active4kRequest.requestedBy.id === user?.id ||
|
||||
(active4kRequests?.length === 1 &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS)))
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'active-4k-request',
|
||||
text: intl.formatMessage(messages.viewrequest4k),
|
||||
action: () => {
|
||||
setEditRequest(true);
|
||||
setShowRequest4kModal(true);
|
||||
},
|
||||
svg: <InformationCircleIcon />,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
activeRequest &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) &&
|
||||
@@ -226,9 +164,7 @@ const RequestButton = ({
|
||||
svg: <XIcon />,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
} else if (
|
||||
activeRequests &&
|
||||
activeRequests.length > 0 &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) &&
|
||||
@@ -258,6 +194,23 @@ const RequestButton = ({
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
active4kRequest &&
|
||||
(active4kRequest.requestedBy.id === user?.id ||
|
||||
(active4kRequests?.length === 1 &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS)))
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'active-4k-request',
|
||||
text: intl.formatMessage(messages.viewrequest4k),
|
||||
action: () => {
|
||||
setEditRequest(true);
|
||||
setShowRequest4kModal(true);
|
||||
},
|
||||
svg: <InformationCircleIcon />,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
active4kRequest &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) &&
|
||||
@@ -281,9 +234,7 @@ const RequestButton = ({
|
||||
svg: <XIcon />,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
} else if (
|
||||
active4kRequests &&
|
||||
active4kRequests.length > 0 &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) &&
|
||||
@@ -312,8 +263,31 @@ const RequestButton = ({
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Standard request button
|
||||
if (
|
||||
(!media || media.status === MediaStatus.UNKNOWN) &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST,
|
||||
mediaType === 'movie'
|
||||
? Permission.REQUEST_MOVIE
|
||||
: Permission.REQUEST_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
)
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request',
|
||||
text: intl.formatMessage(globalMessages.request),
|
||||
action: () => {
|
||||
setEditRequest(false);
|
||||
setShowRequestModal(true);
|
||||
},
|
||||
svg: <DownloadIcon />,
|
||||
});
|
||||
} else if (
|
||||
mediaType === 'tv' &&
|
||||
(!activeRequest || activeRequest.requestedBy.id !== user?.id) &&
|
||||
hasPermission([Permission.REQUEST, Permission.REQUEST_TV], {
|
||||
@@ -335,7 +309,31 @@ const RequestButton = ({
|
||||
});
|
||||
}
|
||||
|
||||
// 4K request button
|
||||
if (
|
||||
(!media || media.status4k === MediaStatus.UNKNOWN) &&
|
||||
hasPermission(
|
||||
[
|
||||
Permission.REQUEST_4K,
|
||||
mediaType === 'movie'
|
||||
? Permission.REQUEST_4K_MOVIE
|
||||
: Permission.REQUEST_4K_TV,
|
||||
],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
((settings.currentSettings.movie4kEnabled && mediaType === 'movie') ||
|
||||
(settings.currentSettings.series4kEnabled && mediaType === 'tv'))
|
||||
) {
|
||||
buttons.push({
|
||||
id: 'request4k',
|
||||
text: intl.formatMessage(globalMessages.request4k),
|
||||
action: () => {
|
||||
setEditRequest(false);
|
||||
setShowRequest4kModal(true);
|
||||
},
|
||||
svg: <DownloadIcon />,
|
||||
});
|
||||
} else if (
|
||||
mediaType === 'tv' &&
|
||||
(!active4kRequest || active4kRequest.requestedBy.id !== user?.id) &&
|
||||
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
|
||||
|
@@ -12,10 +12,7 @@ import { useInView } from 'react-intersection-observer';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR, { mutate } from 'swr';
|
||||
import {
|
||||
MediaRequestStatus,
|
||||
MediaStatus,
|
||||
} from '../../../server/constants/media';
|
||||
import { MediaRequestStatus } from '../../../server/constants/media';
|
||||
import type { MediaRequest } from '../../../server/entity/MediaRequest';
|
||||
import type { MovieDetails } from '../../../server/models/Movie';
|
||||
import type { TvDetails } from '../../../server/models/Tv';
|
||||
@@ -275,8 +272,7 @@ const RequestCard = ({ request, onTitleData }: RequestCardProps) => {
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.declined)}
|
||||
</Badge>
|
||||
) : requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
||||
MediaStatus.UNKNOWN ? (
|
||||
) : requestData.status === MediaRequestStatus.FAILED ? (
|
||||
<Badge
|
||||
badgeType="danger"
|
||||
href={`/${requestData.type}/${requestData.media.tmdbId}?manage=1`}
|
||||
@@ -305,9 +301,7 @@ const RequestCard = ({ request, onTitleData }: RequestCardProps) => {
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-1 items-end space-x-2">
|
||||
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
||||
MediaStatus.UNKNOWN &&
|
||||
requestData.status !== MediaRequestStatus.DECLINED &&
|
||||
{requestData.status === MediaRequestStatus.FAILED &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<Button
|
||||
buttonType="primary"
|
||||
|
@@ -12,10 +12,7 @@ import { useInView } from 'react-intersection-observer';
|
||||
import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import useSWR from 'swr';
|
||||
import {
|
||||
MediaRequestStatus,
|
||||
MediaStatus,
|
||||
} from '../../../../server/constants/media';
|
||||
import { MediaRequestStatus } from '../../../../server/constants/media';
|
||||
import type { MediaRequest } from '../../../../server/entity/MediaRequest';
|
||||
import type { MovieDetails } from '../../../../server/models/Movie';
|
||||
import type { TvDetails } from '../../../../server/models/Tv';
|
||||
@@ -273,9 +270,7 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => {
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.declined)}
|
||||
</Badge>
|
||||
) : requestData.media[
|
||||
requestData.is4k ? 'status4k' : 'status'
|
||||
] === MediaStatus.UNKNOWN ? (
|
||||
) : requestData.status === MediaRequestStatus.FAILED ? (
|
||||
<Badge
|
||||
badgeType="danger"
|
||||
href={`/${requestData.type}/${requestData.media.tmdbId}?manage=1`}
|
||||
@@ -402,9 +397,7 @@ const RequestItem = ({ request, revalidateList }: RequestItemProps) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="z-10 mt-4 flex w-full flex-col justify-center space-y-2 pl-4 pr-4 xl:mt-0 xl:w-96 xl:items-end xl:pl-0">
|
||||
{requestData.media[requestData.is4k ? 'status4k' : 'status'] ===
|
||||
MediaStatus.UNKNOWN &&
|
||||
requestData.status !== MediaRequestStatus.DECLINED &&
|
||||
{requestData.status === MediaRequestStatus.FAILED &&
|
||||
hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<Button
|
||||
className="w-full"
|
||||
|
@@ -33,6 +33,7 @@ enum Filter {
|
||||
PROCESSING = 'processing',
|
||||
AVAILABLE = 'available',
|
||||
UNAVAILABLE = 'unavailable',
|
||||
FAILED = 'failed',
|
||||
}
|
||||
|
||||
type Sort = 'added' | 'modified';
|
||||
@@ -158,6 +159,9 @@ const RequestList = () => {
|
||||
<option value="processing">
|
||||
{intl.formatMessage(globalMessages.processing)}
|
||||
</option>
|
||||
<option value="failed">
|
||||
{intl.formatMessage(globalMessages.failed)}
|
||||
</option>
|
||||
<option value="available">
|
||||
{intl.formatMessage(globalMessages.available)}
|
||||
</option>
|
||||
|
Reference in New Issue
Block a user