feat(requestlist): sort direction (#1147)

* feat(requestlist): sort direction

* style: quoted attributes

* style: quoted attributes
This commit is contained in:
Guillaume Chau
2024-12-17 10:59:03 +01:00
committed by GitHub
parent 7c734bc873
commit 66a5ab41ab
4 changed files with 51 additions and 7 deletions

View File

@@ -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:

View File

@@ -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();

View File

@@ -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>

View File

@@ -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",