mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat: media delete option in manage media slideover
This commit is contained in:
@@ -2106,6 +2106,23 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/MediaInfo'
|
||||
/media/{mediaId}:
|
||||
delete:
|
||||
summary: Delete a media item
|
||||
description: Removes a media item. The `MANAGE_REQUESTS` permission is required to perform this action.
|
||||
tags:
|
||||
- media
|
||||
parameters:
|
||||
- in: path
|
||||
name: mediaId
|
||||
description: Media ID
|
||||
required: true
|
||||
example: 1
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: Succesfully removed media item
|
||||
|
||||
security:
|
||||
- cookieAuth: []
|
||||
|
@@ -31,6 +31,7 @@ export class MediaRequest {
|
||||
|
||||
@ManyToOne(() => Media, (media) => media.requests, {
|
||||
eager: true,
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
public media: Media;
|
||||
|
||||
|
@@ -2,6 +2,9 @@ import { Router } from 'express';
|
||||
import { getRepository, FindOperator, FindOneOptions } from 'typeorm';
|
||||
import Media from '../entity/Media';
|
||||
import { MediaStatus } from '../constants/media';
|
||||
import logger from '../logger';
|
||||
import { isAuthenticated } from '../middleware/auth';
|
||||
import { Permission } from '../lib/permissions';
|
||||
|
||||
export interface MediaResultsResponse {
|
||||
pageInfo: {
|
||||
@@ -78,4 +81,28 @@ mediaRoutes.get('/', async (req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
mediaRoutes.delete(
|
||||
'/:id',
|
||||
isAuthenticated(Permission.MANAGE_REQUESTS),
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const mediaRepository = getRepository(Media);
|
||||
|
||||
const media = await mediaRepository.findOneOrFail({
|
||||
where: { id: req.params.id },
|
||||
});
|
||||
|
||||
await mediaRepository.remove(media);
|
||||
|
||||
return res.status(204).send();
|
||||
} catch (e) {
|
||||
logger.error('Something went wrong fetching media in delete request', {
|
||||
label: 'Media',
|
||||
message: e.message,
|
||||
});
|
||||
next({ status: 404, message: 'Media not found' });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default mediaRoutes;
|
||||
|
@@ -21,7 +21,7 @@ const Button: React.FC<ButtonProps> = ({
|
||||
...props
|
||||
}) => {
|
||||
const buttonStyle = [
|
||||
'inline-flex items-center border border-transparent leading-5 font-medium rounded-md focus:outline-none transition ease-in-out duration-150',
|
||||
'inline-flex items-center justify-center border border-transparent leading-5 font-medium rounded-md focus:outline-none transition ease-in-out duration-150',
|
||||
];
|
||||
switch (buttonType) {
|
||||
case 'primary':
|
||||
@@ -73,7 +73,7 @@ const Button: React.FC<ButtonProps> = ({
|
||||
}
|
||||
return (
|
||||
<button className={buttonStyle.join(' ')} {...props}>
|
||||
{children}
|
||||
<span className="flex items-center">{children}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
@@ -113,6 +113,13 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const deleteMedia = async () => {
|
||||
if (data?.mediaInfo?.id) {
|
||||
await axios.delete(`/api/v1/media/${data?.mediaInfo?.id}`);
|
||||
revalidate();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="bg-cover bg-center -mx-4 -mt-2 px-4 sm:px-8 pt-4 "
|
||||
@@ -155,6 +162,22 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
{data?.mediaInfo && (
|
||||
<div className="mt-8">
|
||||
<Button
|
||||
buttonType="danger"
|
||||
className="w-full text-center"
|
||||
onClick={() => deleteMedia()}
|
||||
>
|
||||
Clear All Media Data
|
||||
</Button>
|
||||
<div className="text-sm text-cool-gray-400 mt-2">
|
||||
This will remove all media data including all requests for this
|
||||
item. This action is irreversible. If this item exists in your
|
||||
Plex library, the media information will be recreated next sync.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
<div className="flex flex-col items-center md:flex-row md:items-end pt-4">
|
||||
<div className="mr-4 flex-shrink-0">
|
||||
|
@@ -116,6 +116,13 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
revalidate();
|
||||
};
|
||||
|
||||
const deleteMedia = async () => {
|
||||
if (data?.mediaInfo?.id) {
|
||||
await axios.delete(`/api/v1/media/${data?.mediaInfo?.id}`);
|
||||
revalidate();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="bg-cover bg-center -mx-4 -mt-2 px-4 sm:px-8 pt-4 "
|
||||
@@ -158,6 +165,22 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
{data?.mediaInfo && (
|
||||
<div className="mt-8">
|
||||
<Button
|
||||
buttonType="danger"
|
||||
className="w-full text-center"
|
||||
onClick={() => deleteMedia()}
|
||||
>
|
||||
Clear All Media Data
|
||||
</Button>
|
||||
<div className="text-sm text-cool-gray-400 mt-2">
|
||||
This will remove all media data including all requests for this
|
||||
item. This action is irreversible. If this item exists in your
|
||||
Plex library, the media information will be recreated next sync.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
<div className="flex flex-col items-center md:flex-row md:items-end pt-4">
|
||||
<div className="mr-4 flex-shrink-0">
|
||||
|
Reference in New Issue
Block a user