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:
parent
6bc7efc737
commit
fba74ab7d3
6 changed files with 73 additions and 48 deletions
53
src/hooks/useSortRedirects.ts
Normal file
53
src/hooks/useSortRedirects.ts
Normal 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]);
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ export enum OrderListUrlSortField {
|
||||||
fulfillment = "status",
|
fulfillment = "status",
|
||||||
payment = "payment",
|
payment = "payment",
|
||||||
total = "total",
|
total = "total",
|
||||||
|
rank = "rank",
|
||||||
}
|
}
|
||||||
export type OrderListUrlSort = Sort<OrderListUrlSortField>;
|
export type OrderListUrlSort = Sort<OrderListUrlSortField>;
|
||||||
export type OrderListUrlQueryParams = BulkAction &
|
export type OrderListUrlQueryParams = BulkAction &
|
||||||
|
|
|
@ -17,6 +17,7 @@ import usePaginator, {
|
||||||
createPaginationState,
|
createPaginationState,
|
||||||
PaginatorContext,
|
PaginatorContext,
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
|
import { useSortRedirects } from "@saleor/hooks/useSortRedirects";
|
||||||
import { getStringOrPlaceholder } from "@saleor/misc";
|
import { getStringOrPlaceholder } from "@saleor/misc";
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
|
@ -32,6 +33,7 @@ import {
|
||||||
orderListUrl,
|
orderListUrl,
|
||||||
OrderListUrlDialog,
|
OrderListUrlDialog,
|
||||||
OrderListUrlQueryParams,
|
OrderListUrlQueryParams,
|
||||||
|
OrderListUrlSortField,
|
||||||
orderSettingsPath,
|
orderSettingsPath,
|
||||||
orderUrl,
|
orderUrl,
|
||||||
} from "../../urls";
|
} from "../../urls";
|
||||||
|
@ -45,7 +47,7 @@ import {
|
||||||
getFilterVariables,
|
getFilterVariables,
|
||||||
saveFilterTab,
|
saveFilterTab,
|
||||||
} from "./filters";
|
} from "./filters";
|
||||||
import { getSortQueryVariables } from "./sort";
|
import { DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
|
||||||
|
|
||||||
interface OrderListProps {
|
interface OrderListProps {
|
||||||
params: OrderListUrlQueryParams;
|
params: OrderListUrlQueryParams;
|
||||||
|
@ -148,6 +150,12 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
|
||||||
|
|
||||||
const handleSort = createSortHandler(navigate, orderListUrl, params);
|
const handleSort = createSortHandler(navigate, orderListUrl, params);
|
||||||
|
|
||||||
|
useSortRedirects<OrderListUrlSortField>({
|
||||||
|
params,
|
||||||
|
defaultSortField: DEFAULT_SORT_KEY,
|
||||||
|
urlFunc: orderListUrl,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PaginatorContext.Provider value={paginationValues}>
|
<PaginatorContext.Provider value={paginationValues}>
|
||||||
<OrderListPage
|
<OrderListPage
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { OrderSortField } from "@saleor/graphql";
|
||||||
import { OrderListUrlSortField } from "@saleor/orders/urls";
|
import { OrderListUrlSortField } from "@saleor/orders/urls";
|
||||||
import { createGetSortQueryVariables } from "@saleor/utils/sort";
|
import { createGetSortQueryVariables } from "@saleor/utils/sort";
|
||||||
|
|
||||||
|
export const DEFAULT_SORT_KEY = OrderListUrlSortField.number;
|
||||||
|
|
||||||
export function getSortQueryField(sort: OrderListUrlSortField): OrderSortField {
|
export function getSortQueryField(sort: OrderListUrlSortField): OrderSortField {
|
||||||
switch (sort) {
|
switch (sort) {
|
||||||
case OrderListUrlSortField.number:
|
case OrderListUrlSortField.number:
|
||||||
|
|
|
@ -65,6 +65,7 @@ import { getSortUrlVariables } from "@saleor/utils/sort";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import { useSortRedirects } from "../../../hooks/useSortRedirects";
|
||||||
import ProductListPage from "../../components/ProductListPage";
|
import ProductListPage from "../../components/ProductListPage";
|
||||||
import {
|
import {
|
||||||
deleteFilterTab,
|
deleteFilterTab,
|
||||||
|
@ -76,8 +77,7 @@ import {
|
||||||
getFilterVariables,
|
getFilterVariables,
|
||||||
saveFilterTab,
|
saveFilterTab,
|
||||||
} from "./filters";
|
} from "./filters";
|
||||||
import { getSortQueryVariables } from "./sort";
|
import { canBeSorted, DEFAULT_SORT_KEY, getSortQueryVariables } from "./sort";
|
||||||
import { useSortRedirects } from "./useSortRedirects";
|
|
||||||
import { getAvailableProductKinds, getProductKindOpts } from "./utils";
|
import { getAvailableProductKinds, getProductKindOpts } from "./utils";
|
||||||
|
|
||||||
interface ProductListProps {
|
interface ProductListProps {
|
||||||
|
@ -176,7 +176,12 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
channel => channel.slug === params.channel,
|
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<
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
ProductListUrlDialog,
|
ProductListUrlDialog,
|
||||||
|
|
|
@ -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]);
|
|
||||||
}
|
|
Loading…
Reference in a new issue