Sort orders by rank (#2114)

* Add rank sortfield to orders sort field enum

* Make useSortRedirects hook generic

* Add sorting by rank to orders list

* Move useSortRedirects to generic hooks dir

* Add hook description

* Add type parameters
This commit is contained in:
Michał Droń 2022-07-07 10:26:11 +02:00 committed by GitHub
parent 6bc7efc737
commit fba74ab7d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 48 deletions

View file

@ -0,0 +1,53 @@
import useNavigator from "@saleor/hooks/useNavigator";
import { Sort } from "@saleor/types";
import { useEffect } from "react";
export type SortByRankUrlQueryParams<T extends string> = Sort<T> & {
query?: string;
};
export interface UseSortRedirectsOpts<SortField extends string> {
params: SortByRankUrlQueryParams<SortField>;
defaultSortField: SortField;
urlFunc: (params: SortByRankUrlQueryParams<SortField>) => string;
resetToDefault?: boolean;
}
/**
* useSortRedirects is a hook that should be used in lists views
* where using search changes the sort field to "rank". Removing
* query changes sort field back to default one provided in params.
*/
export function useSortRedirects<SortField extends string>({
params,
defaultSortField,
urlFunc,
resetToDefault,
}: UseSortRedirectsOpts<SortField>) {
const navigate = useNavigator();
const hasQuery = !!params.query?.trim();
useEffect(() => {
const sortWithQuery = "rank" as SortField;
const sortWithoutQuery =
params.sort === "rank" ? defaultSortField : params.sort;
navigate(
urlFunc({
...params,
asc: hasQuery ? false : params.asc,
sort: hasQuery ? sortWithQuery : sortWithoutQuery,
}),
);
}, [params.query]);
useEffect(() => {
if (resetToDefault) {
navigate(
urlFunc({
...params,
sort: defaultSortField,
}),
);
}
}, [params]);
}

View file

@ -50,6 +50,7 @@ export enum OrderListUrlSortField {
fulfillment = "status",
payment = "payment",
total = "total",
rank = "rank",
}
export type OrderListUrlSort = Sort<OrderListUrlSortField>;
export type OrderListUrlQueryParams = BulkAction &

View file

@ -17,6 +17,7 @@ import usePaginator, {
createPaginationState,
PaginatorContext,
} from "@saleor/hooks/usePaginator";
import { useSortRedirects } from "@saleor/hooks/useSortRedirects";
import { getStringOrPlaceholder } from "@saleor/misc";
import { ListViews } from "@saleor/types";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
@ -32,6 +33,7 @@ import {
orderListUrl,
OrderListUrlDialog,
OrderListUrlQueryParams,
OrderListUrlSortField,
orderSettingsPath,
orderUrl,
} from "../../urls";
@ -45,7 +47,7 @@ import {
getFilterVariables,
saveFilterTab,
} from "./filters";
import { getSortQueryVariables } from "./sort";
import { DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
interface OrderListProps {
params: OrderListUrlQueryParams;
@ -148,6 +150,12 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
const handleSort = createSortHandler(navigate, orderListUrl, params);
useSortRedirects<OrderListUrlSortField>({
params,
defaultSortField: DEFAULT_SORT_KEY,
urlFunc: orderListUrl,
});
return (
<PaginatorContext.Provider value={paginationValues}>
<OrderListPage

View file

@ -2,6 +2,8 @@ import { OrderSortField } from "@saleor/graphql";
import { OrderListUrlSortField } from "@saleor/orders/urls";
import { createGetSortQueryVariables } from "@saleor/utils/sort";
export const DEFAULT_SORT_KEY = OrderListUrlSortField.number;
export function getSortQueryField(sort: OrderListUrlSortField): OrderSortField {
switch (sort) {
case OrderListUrlSortField.number:

View file

@ -65,6 +65,7 @@ import { getSortUrlVariables } from "@saleor/utils/sort";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useSortRedirects } from "../../../hooks/useSortRedirects";
import ProductListPage from "../../components/ProductListPage";
import {
deleteFilterTab,
@ -76,8 +77,7 @@ import {
getFilterVariables,
saveFilterTab,
} from "./filters";
import { getSortQueryVariables } from "./sort";
import { useSortRedirects } from "./useSortRedirects";
import { canBeSorted, DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
import { getAvailableProductKinds, getProductKindOpts } from "./utils";
interface ProductListProps {
@ -176,7 +176,12 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
channel => channel.slug === params.channel,
);
useSortRedirects(params, !!selectedChannel);
useSortRedirects<ProductListUrlSortField>({
params,
defaultSortField: DEFAULT_SORT_KEY,
urlFunc: productListUrl,
resetToDefault: !canBeSorted(params.sort, !!selectedChannel),
});
const [openModal, closeModal] = createDialogActionHandlers<
ProductListUrlDialog,

View file

@ -1,44 +0,0 @@
import useNavigator from "@saleor/hooks/useNavigator";
import {
productListUrl,
ProductListUrlQueryParams,
ProductListUrlSortField,
} from "@saleor/products/urls";
import { useEffect } from "react";
import { canBeSorted, DEFAULT_SORT_KEY } from "./sort";
export function useSortRedirects(
params: ProductListUrlQueryParams,
isChannelSelected: boolean,
) {
const navigate = useNavigator();
const hasQuery = !!params.query?.trim();
useEffect(() => {
const sortWithQuery = ProductListUrlSortField.rank;
const sortWithoutQuery =
params.sort === ProductListUrlSortField.rank
? DEFAULT_SORT_KEY
: params.sort;
navigate(
productListUrl({
...params,
asc: hasQuery ? false : params.asc,
sort: hasQuery ? sortWithQuery : sortWithoutQuery,
}),
);
}, [params.query]);
useEffect(() => {
if (!canBeSorted(params.sort, isChannelSelected)) {
navigate(
productListUrl({
...params,
sort: DEFAULT_SORT_KEY,
}),
);
}
}, [params]);
}