mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-03 13:18:53 -05:00
feat(requestlist): sort direction (#1147)
* feat(requestlist): sort direction * style: quoted attributes * style: quoted attributes
This commit is contained in:
@@ -5438,6 +5438,12 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
enum: [added, modified]
|
enum: [added, modified]
|
||||||
default: added
|
default: added
|
||||||
|
- in: query
|
||||||
|
name: sortDirection
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [asc, desc]
|
||||||
|
default: desc
|
||||||
- in: query
|
- in: query
|
||||||
name: requestedBy
|
name: requestedBy
|
||||||
schema:
|
schema:
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ requestRoutes.get<Record<string, unknown>, RequestResultsResponse>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sortFilter: string;
|
let sortFilter: string;
|
||||||
|
let sortDirection: 'ASC' | 'DESC';
|
||||||
|
|
||||||
switch (req.query.sort) {
|
switch (req.query.sort) {
|
||||||
case 'modified':
|
case 'modified':
|
||||||
@@ -103,6 +104,14 @@ requestRoutes.get<Record<string, unknown>, RequestResultsResponse>(
|
|||||||
sortFilter = 'request.id';
|
sortFilter = 'request.id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (req.query.sortDirection) {
|
||||||
|
case 'asc':
|
||||||
|
sortDirection = 'ASC';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sortDirection = 'DESC';
|
||||||
|
}
|
||||||
|
|
||||||
let query = getRepository(MediaRequest)
|
let query = getRepository(MediaRequest)
|
||||||
.createQueryBuilder('request')
|
.createQueryBuilder('request')
|
||||||
.leftJoinAndSelect('request.media', 'media')
|
.leftJoinAndSelect('request.media', 'media')
|
||||||
@@ -142,7 +151,7 @@ requestRoutes.get<Record<string, unknown>, RequestResultsResponse>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [requests, requestCount] = await query
|
const [requests, requestCount] = await query
|
||||||
.orderBy(sortFilter, 'DESC')
|
.orderBy(sortFilter, sortDirection)
|
||||||
.take(pageSize)
|
.take(pageSize)
|
||||||
.skip(skip)
|
.skip(skip)
|
||||||
.getManyAndCount();
|
.getManyAndCount();
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import Button from '@app/components/Common/Button';
|
|||||||
import Header from '@app/components/Common/Header';
|
import Header from '@app/components/Common/Header';
|
||||||
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||||
import PageTitle from '@app/components/Common/PageTitle';
|
import PageTitle from '@app/components/Common/PageTitle';
|
||||||
|
import Tooltip from '@app/components/Common/Tooltip';
|
||||||
import RequestItem from '@app/components/RequestList/RequestItem';
|
import RequestItem from '@app/components/RequestList/RequestItem';
|
||||||
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
|
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
|
||||||
import { useUser } from '@app/hooks/useUser';
|
import { useUser } from '@app/hooks/useUser';
|
||||||
import globalMessages from '@app/i18n/globalMessages';
|
import globalMessages from '@app/i18n/globalMessages';
|
||||||
import defineMessages from '@app/utils/defineMessages';
|
import defineMessages from '@app/utils/defineMessages';
|
||||||
import {
|
import {
|
||||||
BarsArrowDownIcon,
|
ArrowDownIcon,
|
||||||
|
ArrowUpIcon,
|
||||||
|
Bars3BottomLeftIcon,
|
||||||
ChevronLeftIcon,
|
ChevronLeftIcon,
|
||||||
ChevronRightIcon,
|
ChevronRightIcon,
|
||||||
FunnelIcon,
|
FunnelIcon,
|
||||||
@@ -25,6 +28,7 @@ const messages = defineMessages('components.RequestList', {
|
|||||||
showallrequests: 'Show All Requests',
|
showallrequests: 'Show All Requests',
|
||||||
sortAdded: 'Most Recent',
|
sortAdded: 'Most Recent',
|
||||||
sortModified: 'Last Modified',
|
sortModified: 'Last Modified',
|
||||||
|
sortDirection: 'Toggle Sort Direction',
|
||||||
});
|
});
|
||||||
|
|
||||||
enum Filter {
|
enum Filter {
|
||||||
@@ -39,6 +43,8 @@ enum Filter {
|
|||||||
|
|
||||||
type Sort = 'added' | 'modified';
|
type Sort = 'added' | 'modified';
|
||||||
|
|
||||||
|
type SortDirection = 'asc' | 'desc';
|
||||||
|
|
||||||
const RequestList = () => {
|
const RequestList = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -48,6 +54,8 @@ const RequestList = () => {
|
|||||||
const { user: currentUser } = useUser();
|
const { user: currentUser } = useUser();
|
||||||
const [currentFilter, setCurrentFilter] = useState<Filter>(Filter.PENDING);
|
const [currentFilter, setCurrentFilter] = useState<Filter>(Filter.PENDING);
|
||||||
const [currentSort, setCurrentSort] = useState<Sort>('added');
|
const [currentSort, setCurrentSort] = useState<Sort>('added');
|
||||||
|
const [currentSortDirection, setCurrentSortDirection] =
|
||||||
|
useState<SortDirection>('desc');
|
||||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||||
|
|
||||||
const page = router.query.page ? Number(router.query.page) : 1;
|
const page = router.query.page ? Number(router.query.page) : 1;
|
||||||
@@ -61,7 +69,7 @@ const RequestList = () => {
|
|||||||
} = useSWR<RequestResultsResponse>(
|
} = useSWR<RequestResultsResponse>(
|
||||||
`/api/v1/request?take=${currentPageSize}&skip=${
|
`/api/v1/request?take=${currentPageSize}&skip=${
|
||||||
pageIndex * currentPageSize
|
pageIndex * currentPageSize
|
||||||
}&filter=${currentFilter}&sort=${currentSort}${
|
}&filter=${currentFilter}&sort=${currentSort}&sortDirection=${currentSortDirection}${
|
||||||
router.pathname.startsWith('/profile')
|
router.pathname.startsWith('/profile')
|
||||||
? `&requestedBy=${currentUser?.id}`
|
? `&requestedBy=${currentUser?.id}`
|
||||||
: router.query.userId
|
: router.query.userId
|
||||||
@@ -79,6 +87,7 @@ const RequestList = () => {
|
|||||||
|
|
||||||
setCurrentFilter(filterSettings.currentFilter);
|
setCurrentFilter(filterSettings.currentFilter);
|
||||||
setCurrentSort(filterSettings.currentSort);
|
setCurrentSort(filterSettings.currentSort);
|
||||||
|
setCurrentSortDirection(filterSettings.currentSortDirection);
|
||||||
setCurrentPageSize(filterSettings.currentPageSize);
|
setCurrentPageSize(filterSettings.currentPageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,10 +104,11 @@ const RequestList = () => {
|
|||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
currentFilter,
|
currentFilter,
|
||||||
currentSort,
|
currentSort,
|
||||||
|
currentSortDirection,
|
||||||
currentPageSize,
|
currentPageSize,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}, [currentFilter, currentSort, currentPageSize]);
|
}, [currentFilter, currentSort, currentSortDirection, currentPageSize]);
|
||||||
|
|
||||||
if (!data && !error) {
|
if (!data && !error) {
|
||||||
return <LoadingSpinner />;
|
return <LoadingSpinner />;
|
||||||
@@ -182,7 +192,7 @@ const RequestList = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mb-2 flex flex-grow sm:mb-0 lg:flex-grow-0">
|
<div className="mb-2 flex flex-grow sm:mb-0 lg:flex-grow-0">
|
||||||
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-gray-100 sm:text-sm">
|
||||||
<BarsArrowDownIcon className="h-6 w-6" />
|
<Bars3BottomLeftIcon className="h-6 w-6" />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
id="sort"
|
id="sort"
|
||||||
@@ -197,7 +207,7 @@ const RequestList = () => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
value={currentSort}
|
value={currentSort}
|
||||||
className="rounded-r-only"
|
className="rounded-none border-r-0"
|
||||||
>
|
>
|
||||||
<option value="added">
|
<option value="added">
|
||||||
{intl.formatMessage(messages.sortAdded)}
|
{intl.formatMessage(messages.sortAdded)}
|
||||||
@@ -206,6 +216,24 @@ const RequestList = () => {
|
|||||||
{intl.formatMessage(messages.sortModified)}
|
{intl.formatMessage(messages.sortModified)}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
<Tooltip content={intl.formatMessage(messages.sortDirection)}>
|
||||||
|
<Button
|
||||||
|
buttonType="ghost"
|
||||||
|
className="z-40 mr-2 rounded-l-none"
|
||||||
|
buttonSize="md"
|
||||||
|
onClick={() =>
|
||||||
|
setCurrentSortDirection(
|
||||||
|
currentSortDirection === 'asc' ? 'desc' : 'asc'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{currentSortDirection === 'asc' ? (
|
||||||
|
<ArrowUpIcon className="h-3" />
|
||||||
|
) : (
|
||||||
|
<ArrowDownIcon className="h-3" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -503,6 +503,7 @@
|
|||||||
"components.RequestList.requests": "Requests",
|
"components.RequestList.requests": "Requests",
|
||||||
"components.RequestList.showallrequests": "Show All Requests",
|
"components.RequestList.showallrequests": "Show All Requests",
|
||||||
"components.RequestList.sortAdded": "Most Recent",
|
"components.RequestList.sortAdded": "Most Recent",
|
||||||
|
"components.RequestList.sortDirection": "Toggle Sort Direction",
|
||||||
"components.RequestList.sortModified": "Last Modified",
|
"components.RequestList.sortModified": "Last Modified",
|
||||||
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced",
|
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced",
|
||||||
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
|
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
|
||||||
@@ -1099,7 +1100,7 @@
|
|||||||
"components.Setup.finishing": "Finishing…",
|
"components.Setup.finishing": "Finishing…",
|
||||||
"components.Setup.servertype": "Choose Server Type",
|
"components.Setup.servertype": "Choose Server Type",
|
||||||
"components.Setup.setup": "Setup",
|
"components.Setup.setup": "Setup",
|
||||||
"components.Setup.signin": "Sign in to your account",
|
"components.Setup.signin": "Sign In",
|
||||||
"components.Setup.signinMessage": "Get started by signing in",
|
"components.Setup.signinMessage": "Get started by signing in",
|
||||||
"components.Setup.signinWithEmby": "Enter your Emby details",
|
"components.Setup.signinWithEmby": "Enter your Emby details",
|
||||||
"components.Setup.signinWithJellyfin": "Enter your Jellyfin details",
|
"components.Setup.signinWithJellyfin": "Enter your Jellyfin details",
|
||||||
|
|||||||
Reference in New Issue
Block a user