Merge page and querystring abstraction

This commit is contained in:
dominik-zeglen 2019-09-13 16:17:12 +02:00
parent 9570aebc5f
commit 0311790550
8 changed files with 48 additions and 48 deletions

View file

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

View file

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

View file

@ -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) => ({

View file

@ -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} />;
}; };

View file

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

View file

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

View file

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

View file

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