diff --git a/overseerr-api.yml b/overseerr-api.yml index 90b90d11db..6f51aad868 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -3453,6 +3453,8 @@ paths: summary: Get all requests description: | Returns all requests if the user has the `ADMIN` or `MANAGE_REQUESTS` permissions. Otherwise, only the logged-in user's requests are returned. + + If the `requestedBy` parameter is specified, only requests from that particular user ID will be returned. tags: - request parameters: @@ -3480,6 +3482,12 @@ paths: type: string enum: [added, modified] default: added + - in: query + name: requestedBy + schema: + type: number + nullable: true + example: 1 responses: '200': description: Requests returned @@ -4089,7 +4097,7 @@ paths: type: number /media: get: - summary: Return media + summary: Get media description: Returns all media (can be filtered and limited) in a JSON object. tags: - media diff --git a/server/routes/request.ts b/server/routes/request.ts index ec89a98311..cdc4a519d4 100644 --- a/server/routes/request.ts +++ b/server/routes/request.ts @@ -17,6 +17,9 @@ requestRoutes.get('/', async (req, res, next) => { try { const pageSize = req.query.take ? Number(req.query.take) : 10; const skip = req.query.skip ? Number(req.query.skip) : 0; + const requestedBy = req.query.requestedBy + ? Number(req.query.requestedBy) + : 0; let statusFilter: MediaRequestStatus[]; @@ -103,6 +106,10 @@ requestRoutes.get('/', async (req, res, next) => { query = query.andWhere('requestedBy.id = :id', { id: req.user?.id, }); + } else if (requestedBy) { + query = query.andWhere('requestedBy.id = :id', { + id: requestedBy, + }); } const [requests, requestCount] = await query diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx index 0be3bb0082..9e81a45f50 100644 --- a/src/components/RequestList/index.tsx +++ b/src/components/RequestList/index.tsx @@ -8,11 +8,13 @@ import Table from '../Common/Table'; import Button from '../Common/Button'; import { defineMessages, useIntl } from 'react-intl'; import PageTitle from '../Common/PageTitle'; +import { useRouter } from 'next/router'; +import { useUser } from '../../hooks/useUser'; const messages = defineMessages({ requests: 'Requests', mediaInfo: 'Media Info', - status: 'Status', + status: 'Media Status', requestedAt: 'Requested At', modifiedBy: 'Last Modified By', showingresults: @@ -35,16 +37,24 @@ type Filter = 'all' | 'pending' | 'approved' | 'processing' | 'available'; type Sort = 'added' | 'modified'; const RequestList: React.FC = () => { + const router = useRouter(); const intl = useIntl(); const [pageIndex, setPageIndex] = useState(0); - const [currentFilter, setCurrentFilter] = useState('pending'); + const { user } = useUser({ + id: Number(router.query.userId), + }); + const [currentFilter, setCurrentFilter] = useState( + router.query.userId ? 'all' : 'pending' + ); const [currentSort, setCurrentSort] = useState('added'); const [currentPageSize, setCurrentPageSize] = useState(10); const { data, error, revalidate } = useSWR( `/api/v1/request?take=${currentPageSize}&skip=${ pageIndex * currentPageSize - }&filter=${currentFilter}&sort=${currentSort}` + }&filter=${currentFilter}&sort=${currentSort}${ + user?.id && `&requestedBy=${user.id}` + }` ); if (!data && !error) { return ; @@ -59,9 +69,13 @@ const RequestList: React.FC = () => { return ( <> - +
-
{intl.formatMessage(messages.requests)}
+
+ {intl.formatMessage(messages.requests)} +
diff --git a/src/components/UserProfile/index.tsx b/src/components/UserProfile/index.tsx index 2596c974e4..03d0e878cc 100644 --- a/src/components/UserProfile/index.tsx +++ b/src/components/UserProfile/index.tsx @@ -13,6 +13,7 @@ import ImageFader from '../Common/ImageFader'; import PageTitle from '../Common/PageTitle'; import ProfileHeader from './ProfileHeader'; import { defineMessages, useIntl } from 'react-intl'; +import Link from 'next/link'; const messages = defineMessages({ recentrequests: 'Recent Requests', @@ -77,9 +78,25 @@ const UserProfile: React.FC = () => {
-
- {intl.formatMessage(messages.recentrequests)} -
+ + + {intl.formatMessage(messages.recentrequests)} + + + + +
diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index 082836caa7..cdb2cf19c3 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -180,7 +180,7 @@ "components.RequestList.showingresults": "Showing {from} to {to} of {total} results", "components.RequestList.sortAdded": "Request Date", "components.RequestList.sortModified": "Last Modified", - "components.RequestList.status": "Status", + "components.RequestList.status": "Media Status", "components.RequestModal.AdvancedRequester.advancedoptions": "Advanced Options", "components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.", "components.RequestModal.AdvancedRequester.default": "(Default)", diff --git a/src/pages/users/[userId]/requests.tsx b/src/pages/users/[userId]/requests.tsx new file mode 100644 index 0000000000..12cc92dac9 --- /dev/null +++ b/src/pages/users/[userId]/requests.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { NextPage } from 'next'; +import RequestList from '../../../components/RequestList'; +import useRouteGuard from '../../../hooks/useRouteGuard'; +import { Permission } from '../../../hooks/useUser'; + +const UserRequestsPage: NextPage = () => { + useRouteGuard(Permission.MANAGE_REQUESTS); + return ; +}; + +export default UserRequestsPage;