Merge page and querystring abstraction
This commit is contained in:
parent
9570aebc5f
commit
0311790550
8 changed files with 48 additions and 48 deletions
|
@ -485,10 +485,8 @@ export function getOrderDirection(asc: boolean): OrderDirection {
|
||||||
return asc ? OrderDirection.ASC : OrderDirection.DESC;
|
return asc ? OrderDirection.ASC : OrderDirection.DESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getArrowDirection(
|
export function getArrowDirection(asc: boolean): TableCellHeaderArrowDirection {
|
||||||
order: OrderDirection
|
return asc ? "asc" : "desc";
|
||||||
): TableCellHeaderArrowDirection {
|
|
||||||
return order === OrderDirection.ASC ? "asc" : "desc";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseBoolean(a: string): boolean {
|
export function parseBoolean(a: string): boolean {
|
||||||
|
|
|
@ -31,8 +31,8 @@ import {
|
||||||
} from "@saleor/products/components/ProductListPage/utils";
|
} from "@saleor/products/components/ProductListPage/utils";
|
||||||
import { AvailableInGridAttributes_grid_edges_node } from "@saleor/products/types/AvailableInGridAttributes";
|
import { AvailableInGridAttributes_grid_edges_node } from "@saleor/products/types/AvailableInGridAttributes";
|
||||||
import { ProductList_products_edges_node } from "@saleor/products/types/ProductList";
|
import { ProductList_products_edges_node } from "@saleor/products/types/ProductList";
|
||||||
|
import { ProductListUrlSortField } from "@saleor/products/urls";
|
||||||
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
||||||
import { ProductOrder, ProductOrderField } from "@saleor/types/globalTypes";
|
|
||||||
import TDisplayColumn, {
|
import TDisplayColumn, {
|
||||||
DisplayColumnProps
|
DisplayColumnProps
|
||||||
} from "@saleor/utils/columns/DisplayColumn";
|
} from "@saleor/utils/columns/DisplayColumn";
|
||||||
|
@ -98,11 +98,10 @@ const DisplayColumn = TDisplayColumn as React.FunctionComponent<
|
||||||
interface ProductListProps
|
interface ProductListProps
|
||||||
extends ListProps<ProductListColumns>,
|
extends ListProps<ProductListColumns>,
|
||||||
ListActions,
|
ListActions,
|
||||||
SortPage<ProductOrderField>,
|
SortPage<ProductListUrlSortField>,
|
||||||
WithStyles<typeof styles> {
|
WithStyles<typeof styles> {
|
||||||
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
||||||
products: ProductList_products_edges_node[];
|
products: ProductList_products_edges_node[];
|
||||||
sort: ProductOrder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProductList = withStyles(styles, { name: "ProductList" })(
|
export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
|
@ -171,11 +170,11 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
[classes.colNameFixed]: settings.columns.length > 4
|
[classes.colNameFixed]: settings.columns.length > 4
|
||||||
})}
|
})}
|
||||||
direction={
|
direction={
|
||||||
sort.field === ProductOrderField.NAME
|
sort.sort === ProductListUrlSortField.name
|
||||||
? getArrowDirection(sort.direction)
|
? getArrowDirection(sort.asc)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
onClick={() => onSort(ProductOrderField.NAME)}
|
onClick={() => onSort(ProductListUrlSortField.name)}
|
||||||
>
|
>
|
||||||
<span className={classes.colNameHeader}>
|
<span className={classes.colNameHeader}>
|
||||||
<FormattedMessage defaultMessage="Name" description="product" />
|
<FormattedMessage defaultMessage="Name" description="product" />
|
||||||
|
@ -188,11 +187,11 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableCellHeader
|
<TableCellHeader
|
||||||
className={classes.colType}
|
className={classes.colType}
|
||||||
direction={
|
direction={
|
||||||
sort.field === ProductOrderField.TYPE
|
sort.sort === ProductListUrlSortField.productType
|
||||||
? getArrowDirection(sort.direction)
|
? getArrowDirection(sort.asc)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
onClick={() => onSort(ProductOrderField.TYPE)}
|
onClick={() => onSort(ProductListUrlSortField.productType)}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Type"
|
defaultMessage="Type"
|
||||||
|
@ -207,11 +206,11 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableCellHeader
|
<TableCellHeader
|
||||||
className={classes.colPublished}
|
className={classes.colPublished}
|
||||||
direction={
|
direction={
|
||||||
sort.field === ProductOrderField.PUBLISHED
|
sort.sort === ProductListUrlSortField.status
|
||||||
? getArrowDirection(sort.direction)
|
? getArrowDirection(sort.asc)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
onClick={() => onSort(ProductOrderField.PUBLISHED)}
|
onClick={() => onSort(ProductListUrlSortField.status)}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Published"
|
defaultMessage="Published"
|
||||||
|
@ -240,12 +239,12 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableCellHeader
|
<TableCellHeader
|
||||||
className={classes.colPrice}
|
className={classes.colPrice}
|
||||||
direction={
|
direction={
|
||||||
sort.field === ProductOrderField.PRICE
|
sort.sort === ProductListUrlSortField.price
|
||||||
? getArrowDirection(sort.direction)
|
? getArrowDirection(sort.asc)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
textAlign="right"
|
textAlign="right"
|
||||||
onClick={() => onSort(ProductOrderField.PRICE)}
|
onClick={() => onSort(ProductListUrlSortField.price)}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="Price"
|
defaultMessage="Price"
|
||||||
|
|
|
@ -24,8 +24,7 @@ import {
|
||||||
PageListProps,
|
PageListProps,
|
||||||
SortPage
|
SortPage
|
||||||
} from "@saleor/types";
|
} from "@saleor/types";
|
||||||
import { ProductOrder, ProductOrderField } from "@saleor/types/globalTypes";
|
import { ProductListUrlFilters, ProductListUrlSortField } from "../../urls";
|
||||||
import { ProductListUrlFilters } from "../../urls";
|
|
||||||
import ProductList from "../ProductList";
|
import ProductList from "../ProductList";
|
||||||
import ProductListFilter, { ProductFilterKeys } from "../ProductListFilter";
|
import ProductListFilter, { ProductFilterKeys } from "../ProductListFilter";
|
||||||
|
|
||||||
|
@ -34,13 +33,12 @@ export interface ProductListPageProps
|
||||||
ListActions,
|
ListActions,
|
||||||
FilterPageProps<ProductFilterKeys>,
|
FilterPageProps<ProductFilterKeys>,
|
||||||
FetchMoreProps,
|
FetchMoreProps,
|
||||||
SortPage<ProductOrderField> {
|
SortPage<ProductListUrlSortField> {
|
||||||
availableInGridAttributes: AvailableInGridAttributes_availableInGrid_edges_node[];
|
availableInGridAttributes: AvailableInGridAttributes_availableInGrid_edges_node[];
|
||||||
currencySymbol: string;
|
currencySymbol: string;
|
||||||
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
||||||
totalGridAttributes: number;
|
totalGridAttributes: number;
|
||||||
products: ProductList_products_edges_node[];
|
products: ProductList_products_edges_node[];
|
||||||
sort: ProductOrder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => ({
|
const useStyles = makeStyles((theme: Theme) => ({
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
|
||||||
import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||||
|
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { parseBoolean } from "@saleor/misc";
|
import { findInEnum, parseBoolean } from "@saleor/misc";
|
||||||
import { WindowTitle } from "../components/WindowTitle";
|
import { WindowTitle } from "../components/WindowTitle";
|
||||||
import {
|
import {
|
||||||
productAddPath,
|
productAddPath,
|
||||||
|
@ -12,6 +12,7 @@ import {
|
||||||
ProductImageUrlQueryParams,
|
ProductImageUrlQueryParams,
|
||||||
productListPath,
|
productListPath,
|
||||||
ProductListUrlQueryParams,
|
ProductListUrlQueryParams,
|
||||||
|
ProductListUrlSortField,
|
||||||
productPath,
|
productPath,
|
||||||
ProductUrlQueryParams,
|
ProductUrlQueryParams,
|
||||||
productVariantAddPath,
|
productVariantAddPath,
|
||||||
|
@ -31,7 +32,10 @@ const ProductList: React.StatelessComponent<RouteComponentProps<any>> = ({
|
||||||
const qs = parseQs(location.search.substr(1));
|
const qs = parseQs(location.search.substr(1));
|
||||||
const params: ProductListUrlQueryParams = {
|
const params: ProductListUrlQueryParams = {
|
||||||
...qs,
|
...qs,
|
||||||
asc: parseBoolean(qs.asc)
|
asc: parseBoolean(qs.asc),
|
||||||
|
sort: qs.sort
|
||||||
|
? findInEnum(qs.sort, ProductListUrlSortField)
|
||||||
|
: ProductListUrlSortField.name
|
||||||
};
|
};
|
||||||
return <ProductListComponent params={params} />;
|
return <ProductListComponent params={params} />;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,13 +30,13 @@ export enum ProductListUrlFiltersEnum {
|
||||||
query = "query"
|
query = "query"
|
||||||
}
|
}
|
||||||
export type ProductListUrlFilters = Filters<ProductListUrlFiltersEnum>;
|
export type ProductListUrlFilters = Filters<ProductListUrlFiltersEnum>;
|
||||||
export enum ProductListUrlSortFields {
|
export enum ProductListUrlSortField {
|
||||||
name = "name",
|
name = "name",
|
||||||
productType = "type",
|
productType = "productType",
|
||||||
status = "status",
|
status = "status",
|
||||||
price = "price"
|
price = "price"
|
||||||
}
|
}
|
||||||
export type ProductListUrlSort = Sort<ProductListUrlSortFields>;
|
export type ProductListUrlSort = Sort<ProductListUrlSortField>;
|
||||||
export type ProductListUrlQueryParams = BulkAction &
|
export type ProductListUrlQueryParams = BulkAction &
|
||||||
Dialog<ProductListUrlDialog> &
|
Dialog<ProductListUrlDialog> &
|
||||||
ProductListUrlFilters &
|
ProductListUrlFilters &
|
||||||
|
|
|
@ -229,16 +229,15 @@ export const ProductList: React.StatelessComponent<ProductListProps> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ProductListPage
|
<ProductListPage
|
||||||
sort={sort}
|
sort={{
|
||||||
|
asc: params.asc,
|
||||||
|
sort: params.sort
|
||||||
|
}}
|
||||||
onSort={field =>
|
onSort={field =>
|
||||||
navigate(
|
navigate(
|
||||||
productListUrl({
|
productListUrl({
|
||||||
...params,
|
...params,
|
||||||
...getSortUrlVariables(
|
...getSortUrlVariables(field, params)
|
||||||
field,
|
|
||||||
sort.field,
|
|
||||||
params
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,10 @@
|
||||||
import { getOrderDirection } from "@saleor/misc";
|
import { getOrderDirection } from "@saleor/misc";
|
||||||
import {
|
import {
|
||||||
ProductListUrlQueryParams,
|
ProductListUrlQueryParams,
|
||||||
ProductListUrlSortFields as ProductListUrlSortField
|
ProductListUrlSortField
|
||||||
} from "@saleor/products/urls";
|
} from "@saleor/products/urls";
|
||||||
import { Sort } from "@saleor/types";
|
import { Sort } from "@saleor/types";
|
||||||
import { ProductOrderField } from "@saleor/types/globalTypes";
|
import { ProductOrder, ProductOrderField } from "@saleor/types/globalTypes";
|
||||||
|
|
||||||
export function getSortQueryVariables(params: ProductListUrlQueryParams) {
|
|
||||||
return {
|
|
||||||
direction: getOrderDirection(params.asc),
|
|
||||||
field: getSortQueryField(params.sort)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getSortQueryField(
|
export function getSortQueryField(
|
||||||
sort: ProductListUrlSortField
|
sort: ProductListUrlSortField
|
||||||
|
@ -30,6 +23,15 @@ export function getSortQueryField(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSortQueryVariables(
|
||||||
|
params: ProductListUrlQueryParams
|
||||||
|
): ProductOrder {
|
||||||
|
return {
|
||||||
|
direction: getOrderDirection(params.asc),
|
||||||
|
field: getSortQueryField(params.sort)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function getSortUrlField(
|
export function getSortUrlField(
|
||||||
sort: ProductOrderField
|
sort: ProductOrderField
|
||||||
): ProductListUrlSortField {
|
): ProductListUrlSortField {
|
||||||
|
@ -48,19 +50,18 @@ export function getSortUrlField(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSortUrlVariables(
|
export function getSortUrlVariables(
|
||||||
field: ProductOrderField,
|
field: ProductListUrlSortField,
|
||||||
selectedField: ProductOrderField,
|
|
||||||
params: Sort<ProductListUrlSortField>
|
params: Sort<ProductListUrlSortField>
|
||||||
): Sort<ProductListUrlSortField> {
|
): Sort<ProductListUrlSortField> {
|
||||||
if (field === selectedField) {
|
if (field === params.sort) {
|
||||||
return {
|
return {
|
||||||
asc: !params.asc,
|
asc: !params.asc,
|
||||||
sort: getSortUrlField(field)
|
sort: field
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
asc: true,
|
asc: true,
|
||||||
sort: getSortUrlField(field)
|
sort: field
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ export interface ListProps<TColumns extends string = string> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SortPage<TSortKey extends string> {
|
export interface SortPage<TSortKey extends string> {
|
||||||
|
sort: Sort<TSortKey>;
|
||||||
onSort: (field: TSortKey) => void;
|
onSort: (field: TSortKey) => void;
|
||||||
}
|
}
|
||||||
export interface ListActionsWithoutToolbar {
|
export interface ListActionsWithoutToolbar {
|
||||||
|
|
Loading…
Reference in a new issue