diff --git a/overseerr-api.yml b/overseerr-api.yml
index 5c9ae45a6..dc1c5067e 100644
--- a/overseerr-api.yml
+++ b/overseerr-api.yml
@@ -2669,6 +2669,13 @@ paths:
description: Returns all users in a JSON array.
tags:
- users
+ parameters:
+ - in: query
+ name: sort
+ schema:
+ type: string
+ enum: [created, updated, requests, displayname]
+ default: created
responses:
'200':
description: A JSON array of all users
diff --git a/server/routes/user.ts b/server/routes/user.ts
index 45117247d..04e2c4c77 100644
--- a/server/routes/user.ts
+++ b/server/routes/user.ts
@@ -11,10 +11,35 @@ import { UserType } from '../constants/user';
const router = Router();
-router.get('/', async (_req, res) => {
- const userRepository = getRepository(User);
+router.get('/', async (req, res) => {
+ let query = getRepository(User).createQueryBuilder('user');
- const users = await userRepository.find();
+ switch (req.query.sort) {
+ case 'updated':
+ query = query.orderBy('user.updatedAt', 'DESC');
+ break;
+ case 'displayname':
+ query = query.orderBy(
+ '(CASE WHEN user.username IS NULL THEN user.plexUsername ELSE user.username END)',
+ 'ASC'
+ );
+ break;
+ case 'requests':
+ query = query
+ .addSelect((subQuery) => {
+ return subQuery
+ .select('COUNT(request.id)', 'requestCount')
+ .from(MediaRequest, 'request')
+ .where('request.requestedBy.id = user.id');
+ }, 'requestCount')
+ .orderBy('requestCount', 'DESC');
+ break;
+ default:
+ query = query.orderBy('user.id', 'ASC');
+ break;
+ }
+
+ const users = await query.getMany();
return res.status(200).json(User.filterMany(users));
});
diff --git a/src/components/RequestList/index.tsx b/src/components/RequestList/index.tsx
index 39dca9124..741729f3e 100644
--- a/src/components/RequestList/index.tsx
+++ b/src/components/RequestList/index.tsx
@@ -56,11 +56,11 @@ const RequestList: React.FC = () => {
return (
<>
-
+
{intl.formatMessage(messages.requests)}
-
-
-
+
+
+
-
-
+
+