Add sorting ability to product list
This commit is contained in:
parent
5dea135b2e
commit
87fca41f07
13 changed files with 270 additions and 41 deletions
|
@ -24,6 +24,12 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
display: "flex",
|
||||
height: 24
|
||||
},
|
||||
labelContainerCenter: {
|
||||
justifyContent: "center"
|
||||
},
|
||||
labelContainerRight: {
|
||||
justifyContent: "flex-end"
|
||||
},
|
||||
root: {
|
||||
cursor: "pointer"
|
||||
}
|
||||
|
@ -31,18 +37,31 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
|
||||
export type TableCellHeaderArrowDirection = "asc" | "desc";
|
||||
export type TableCellHeaderArrowPosition = "left" | "right";
|
||||
export interface TableCellHeader extends TableCellProps {
|
||||
export interface TableCellHeaderProps extends TableCellProps {
|
||||
arrowPosition?: TableCellHeaderArrowPosition;
|
||||
direction?: TableCellHeaderArrowDirection;
|
||||
textAlign?: "left" | "center" | "right";
|
||||
}
|
||||
|
||||
const TableCellHeader: React.FC<TableCellHeader> = props => {
|
||||
const TableCellHeader: React.FC<TableCellHeaderProps> = props => {
|
||||
const classes = useStyles(props);
|
||||
const { arrowPosition, children, className, direction, ...rest } = props;
|
||||
const {
|
||||
arrowPosition,
|
||||
children,
|
||||
className,
|
||||
direction,
|
||||
textAlign,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<TableCell {...rest} className={classNames(className, classes.root)}>
|
||||
<div className={classes.labelContainer}>
|
||||
<TableCell {...rest} className={classNames(classes.root, className)}>
|
||||
<div
|
||||
className={classNames(classes.labelContainer, {
|
||||
[classes.labelContainerCenter]: textAlign === "center",
|
||||
[classes.labelContainerRight]: textAlign === "right"
|
||||
})}
|
||||
>
|
||||
{!!direction && arrowPosition === "left" && (
|
||||
<ArrowSort
|
||||
className={classNames(classes.arrow, classes.arrowLeft, {
|
||||
|
@ -65,6 +84,7 @@ const TableCellHeader: React.FC<TableCellHeader> = props => {
|
|||
|
||||
TableCellHeader.displayName = "TableCellHeader";
|
||||
TableCellHeader.defaultProps = {
|
||||
arrowPosition: "left"
|
||||
arrowPosition: "left",
|
||||
textAlign: "left"
|
||||
};
|
||||
export default TableCellHeader;
|
||||
|
|
16
src/misc.ts
16
src/misc.ts
|
@ -4,11 +4,13 @@ import urlJoin from "url-join";
|
|||
|
||||
import { defineMessages, IntlShape } from "react-intl";
|
||||
import { ConfirmButtonTransitionState } from "./components/ConfirmButton/ConfirmButton";
|
||||
import { TableCellHeaderArrowDirection } from "./components/TableCellHeader";
|
||||
import { APP_MOUNT_URI } from "./config";
|
||||
import { AddressType } from "./customers/types";
|
||||
import { PartialMutationProviderOutput, UserError } from "./types";
|
||||
import {
|
||||
AuthorizationKeyType,
|
||||
OrderDirection,
|
||||
OrderStatus,
|
||||
PaymentChargeStatusEnum,
|
||||
TaxRateType
|
||||
|
@ -478,3 +480,17 @@ export function findInEnum<TEnum extends object>(
|
|||
|
||||
throw new Error(`Key ${needle} not found in enum`);
|
||||
}
|
||||
|
||||
export function getOrderDirection(asc: boolean): OrderDirection {
|
||||
return asc ? OrderDirection.ASC : OrderDirection.DESC;
|
||||
}
|
||||
|
||||
export function getArrowDirection(
|
||||
order: OrderDirection
|
||||
): TableCellHeaderArrowDirection {
|
||||
return order === OrderDirection.ASC ? "asc" : "desc";
|
||||
}
|
||||
|
||||
export function parseBoolean(a: string): boolean {
|
||||
return a === "true";
|
||||
}
|
||||
|
|
|
@ -20,18 +20,22 @@ import StatusLabel from "@saleor/components/StatusLabel";
|
|||
import TableCellAvatar, {
|
||||
AVATAR_MARGIN
|
||||
} from "@saleor/components/TableCellAvatar";
|
||||
import TableCellHeader from "@saleor/components/TableCellHeader";
|
||||
import TableHead from "@saleor/components/TableHead";
|
||||
import TablePagination from "@saleor/components/TablePagination";
|
||||
import { ProductListColumns } from "@saleor/config";
|
||||
import { maybe, renderCollection } from "@saleor/misc";
|
||||
import { getArrowDirection, maybe, renderCollection } from "@saleor/misc";
|
||||
import {
|
||||
getAttributeIdFromColumnValue,
|
||||
isAttributeColumnValue
|
||||
} from "@saleor/products/components/ProductListPage/utils";
|
||||
import { AvailableInGridAttributes_grid_edges_node } from "@saleor/products/types/AvailableInGridAttributes";
|
||||
import { ProductList_products_edges_node } from "@saleor/products/types/ProductList";
|
||||
import { ListActions, ListProps } from "@saleor/types";
|
||||
import TDisplayColumn from "@saleor/utils/columns/DisplayColumn";
|
||||
import { ListActions, ListProps, SortPage } from "@saleor/types";
|
||||
import { ProductOrder, ProductOrderField } from "@saleor/types/globalTypes";
|
||||
import TDisplayColumn, {
|
||||
DisplayColumnProps
|
||||
} from "@saleor/utils/columns/DisplayColumn";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
|
@ -87,12 +91,18 @@ const styles = (theme: Theme) =>
|
|||
}
|
||||
});
|
||||
|
||||
const DisplayColumn = TDisplayColumn as React.FunctionComponent<
|
||||
DisplayColumnProps<ProductListColumns>
|
||||
>;
|
||||
|
||||
interface ProductListProps
|
||||
extends ListProps<ProductListColumns>,
|
||||
ListActions,
|
||||
SortPage<ProductOrderField>,
|
||||
WithStyles<typeof styles> {
|
||||
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
||||
products: ProductList_products_edges_node[];
|
||||
sort: ProductOrder;
|
||||
}
|
||||
|
||||
export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||
|
@ -105,19 +115,18 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
pageInfo,
|
||||
products,
|
||||
selected,
|
||||
sort,
|
||||
toggle,
|
||||
toggleAll,
|
||||
toolbar,
|
||||
onNextPage,
|
||||
onPreviousPage,
|
||||
onUpdateListSettings,
|
||||
onRowClick
|
||||
onRowClick,
|
||||
onSort
|
||||
}: ProductListProps) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const DisplayColumn: React.FC<{ column: ProductListColumns }> = props => (
|
||||
<TDisplayColumn displayColumns={settings.columns} {...props} />
|
||||
);
|
||||
const gridAttributesFromSettings = settings.columns.filter(
|
||||
isAttributeColumnValue
|
||||
);
|
||||
|
@ -129,16 +138,22 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
<colgroup>
|
||||
<col />
|
||||
<col className={classes.colName} />
|
||||
<DisplayColumn column="productType">
|
||||
<DisplayColumn
|
||||
column="productType"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<col className={classes.colType} />
|
||||
</DisplayColumn>
|
||||
<DisplayColumn column="isPublished">
|
||||
<DisplayColumn
|
||||
column="isPublished"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<col className={classes.colPublished} />
|
||||
</DisplayColumn>
|
||||
{gridAttributesFromSettings.map(gridAttribute => (
|
||||
<col className={classes.colAttribute} key={gridAttribute} />
|
||||
))}
|
||||
<DisplayColumn column="price">
|
||||
<DisplayColumn column="price" displayColumns={settings.columns}>
|
||||
<col className={classes.colPrice} />
|
||||
</DisplayColumn>
|
||||
</colgroup>
|
||||
|
@ -150,30 +165,59 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell
|
||||
<TableCellHeader
|
||||
arrowPosition="right"
|
||||
className={classNames(classes.colName, {
|
||||
[classes.colNameFixed]: settings.columns.length > 4
|
||||
})}
|
||||
direction={
|
||||
sort.field === ProductOrderField.NAME
|
||||
? getArrowDirection(sort.direction)
|
||||
: undefined
|
||||
}
|
||||
onClick={() => onSort(ProductOrderField.NAME)}
|
||||
>
|
||||
<span className={classes.colNameHeader}>
|
||||
<FormattedMessage defaultMessage="Name" description="product" />
|
||||
</span>
|
||||
</TableCell>
|
||||
<DisplayColumn column="productType">
|
||||
<TableCell className={classes.colType}>
|
||||
</TableCellHeader>
|
||||
<DisplayColumn
|
||||
column="productType"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<TableCellHeader
|
||||
className={classes.colType}
|
||||
direction={
|
||||
sort.field === ProductOrderField.TYPE
|
||||
? getArrowDirection(sort.direction)
|
||||
: undefined
|
||||
}
|
||||
onClick={() => onSort(ProductOrderField.TYPE)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Type"
|
||||
description="product type"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableCellHeader>
|
||||
</DisplayColumn>
|
||||
<DisplayColumn column="isPublished">
|
||||
<TableCell className={classes.colPublished}>
|
||||
<DisplayColumn
|
||||
column="isPublished"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<TableCellHeader
|
||||
className={classes.colPublished}
|
||||
direction={
|
||||
sort.field === ProductOrderField.PUBLISHED
|
||||
? getArrowDirection(sort.direction)
|
||||
: undefined
|
||||
}
|
||||
onClick={() => onSort(ProductOrderField.PUBLISHED)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Published"
|
||||
description="product status"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableCellHeader>
|
||||
</DisplayColumn>
|
||||
{gridAttributesFromSettings.map(gridAttributeFromSettings => (
|
||||
<TableCell
|
||||
|
@ -192,13 +236,22 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
)}
|
||||
</TableCell>
|
||||
))}
|
||||
<DisplayColumn column="price">
|
||||
<TableCell className={classes.colPrice}>
|
||||
<DisplayColumn column="price" displayColumns={settings.columns}>
|
||||
<TableCellHeader
|
||||
className={classes.colPrice}
|
||||
direction={
|
||||
sort.field === ProductOrderField.PRICE
|
||||
? getArrowDirection(sort.direction)
|
||||
: undefined
|
||||
}
|
||||
textAlign="right"
|
||||
onClick={() => onSort(ProductOrderField.PRICE)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Price"
|
||||
description="product price"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableCellHeader>
|
||||
</DisplayColumn>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
|
@ -246,7 +299,10 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
>
|
||||
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
||||
</TableCellAvatar>
|
||||
<DisplayColumn column="productType">
|
||||
<DisplayColumn
|
||||
column="productType"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<TableCell className={classes.colType}>
|
||||
{product && product.productType ? (
|
||||
product.productType.name
|
||||
|
@ -255,7 +311,10 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
)}
|
||||
</TableCell>
|
||||
</DisplayColumn>
|
||||
<DisplayColumn column="isPublished">
|
||||
<DisplayColumn
|
||||
column="isPublished"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<TableCell className={classes.colPublished}>
|
||||
{product &&
|
||||
maybe(() => product.isAvailable !== undefined) ? (
|
||||
|
@ -299,7 +358,10 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|||
}, <Skeleton />)}
|
||||
</TableCell>
|
||||
))}
|
||||
<DisplayColumn column="price">
|
||||
<DisplayColumn
|
||||
column="price"
|
||||
displayColumns={settings.columns}
|
||||
>
|
||||
<TableCell className={classes.colPrice}>
|
||||
{maybe(() => product.basePrice) &&
|
||||
maybe(() => product.basePrice.amount) !== undefined &&
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
@ -22,8 +21,11 @@ import {
|
|||
FetchMoreProps,
|
||||
FilterPageProps,
|
||||
ListActions,
|
||||
PageListProps
|
||||
PageListProps,
|
||||
SortPage
|
||||
} from "@saleor/types";
|
||||
import { ProductOrder, ProductOrderField } from "@saleor/types/globalTypes";
|
||||
import { ProductListUrlFilters } from "../../urls";
|
||||
import ProductList from "../ProductList";
|
||||
import ProductListFilter, { ProductFilterKeys } from "../ProductListFilter";
|
||||
|
||||
|
@ -31,12 +33,14 @@ export interface ProductListPageProps
|
|||
extends PageListProps<ProductListColumns>,
|
||||
ListActions,
|
||||
FilterPageProps<ProductFilterKeys>,
|
||||
FetchMoreProps {
|
||||
FetchMoreProps,
|
||||
SortPage<ProductOrderField> {
|
||||
availableInGridAttributes: AvailableInGridAttributes_availableInGrid_edges_node[];
|
||||
currencySymbol: string;
|
||||
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
||||
totalGridAttributes: number;
|
||||
products: ProductList_products_edges_node[];
|
||||
sort: ProductOrder;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useIntl } from "react-intl";
|
|||
import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { parseBoolean } from "@saleor/misc";
|
||||
import { WindowTitle } from "../components/WindowTitle";
|
||||
import {
|
||||
productAddPath,
|
||||
|
@ -28,7 +29,10 @@ const ProductList: React.StatelessComponent<RouteComponentProps<any>> = ({
|
|||
location
|
||||
}) => {
|
||||
const qs = parseQs(location.search.substr(1));
|
||||
const params: ProductListUrlQueryParams = qs;
|
||||
const params: ProductListUrlQueryParams = {
|
||||
...qs,
|
||||
asc: parseBoolean(qs.asc)
|
||||
};
|
||||
return <ProductListComponent params={params} />;
|
||||
};
|
||||
|
||||
|
|
|
@ -218,6 +218,7 @@ const productListQuery = gql`
|
|||
$last: Int
|
||||
$before: String
|
||||
$filter: ProductFilterInput
|
||||
$sort: ProductOrder
|
||||
) {
|
||||
products(
|
||||
before: $before
|
||||
|
@ -225,6 +226,7 @@ const productListQuery = gql`
|
|||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
sortBy: $sort
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { ProductFilterInput } from "./../../types/globalTypes";
|
||||
import { ProductFilterInput, ProductOrder } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: ProductList
|
||||
|
@ -82,4 +82,5 @@ export interface ProductListVariables {
|
|||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: ProductFilterInput | null;
|
||||
sort?: ProductOrder | null;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
Dialog,
|
||||
Filters,
|
||||
Pagination,
|
||||
Sort,
|
||||
TabActionDialog
|
||||
} from "../types";
|
||||
|
||||
|
@ -29,9 +30,17 @@ export enum ProductListUrlFiltersEnum {
|
|||
query = "query"
|
||||
}
|
||||
export type ProductListUrlFilters = Filters<ProductListUrlFiltersEnum>;
|
||||
export enum ProductListUrlSortFields {
|
||||
name = "name",
|
||||
productType = "type",
|
||||
status = "status",
|
||||
price = "price"
|
||||
}
|
||||
export type ProductListUrlSort = Sort<ProductListUrlSortFields>;
|
||||
export type ProductListUrlQueryParams = BulkAction &
|
||||
Dialog<ProductListUrlDialog> &
|
||||
ProductListUrlFilters &
|
||||
ProductListUrlSort &
|
||||
Pagination &
|
||||
ActiveTab;
|
||||
export const productListUrl = (params?: ProductListUrlQueryParams): string =>
|
||||
|
|
|
@ -22,6 +22,7 @@ import usePaginator, {
|
|||
import useShop from "@saleor/hooks/useShop";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { getMutationState, maybe } from "@saleor/misc";
|
||||
import { ProductListVariables } from "@saleor/products/types/ProductList";
|
||||
import { ListViews } from "@saleor/types";
|
||||
import ProductListPage from "../../components/ProductListPage";
|
||||
import {
|
||||
|
@ -52,6 +53,7 @@ import {
|
|||
getFilterVariables,
|
||||
saveFilterTab
|
||||
} from "./filters";
|
||||
import { getSortUrlVariables, getSortQueryVariables } from "./sort";
|
||||
|
||||
interface ProductListProps {
|
||||
params: ProductListUrlQueryParams;
|
||||
|
@ -152,10 +154,13 @@ export const ProductList: React.StatelessComponent<ProductListProps> = ({
|
|||
|
||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
const currencySymbol = maybe(() => shop.defaultCurrency, "USD");
|
||||
const queryVariables = React.useMemo(
|
||||
const filter = getFilterVariables(params);
|
||||
const sort = getSortQueryVariables(params);
|
||||
const queryVariables = React.useMemo<ProductListVariables>(
|
||||
() => ({
|
||||
...paginationState,
|
||||
filter: getFilterVariables(params)
|
||||
filter,
|
||||
sort
|
||||
}),
|
||||
[params, settings.rowNumber]
|
||||
);
|
||||
|
@ -224,6 +229,19 @@ export const ProductList: React.StatelessComponent<ProductListProps> = ({
|
|||
return (
|
||||
<>
|
||||
<ProductListPage
|
||||
sort={sort}
|
||||
onSort={field =>
|
||||
navigate(
|
||||
productListUrl({
|
||||
...params,
|
||||
...getSortUrlVariables(
|
||||
field,
|
||||
sort.field,
|
||||
params
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
availableInGridAttributes={maybe(
|
||||
() =>
|
||||
attributes.data.availableInGrid.edges.map(
|
||||
|
|
66
src/products/views/ProductList/sort.ts
Normal file
66
src/products/views/ProductList/sort.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { getOrderDirection } from "@saleor/misc";
|
||||
import {
|
||||
ProductListUrlQueryParams,
|
||||
ProductListUrlSortFields as ProductListUrlSortField
|
||||
} from "@saleor/products/urls";
|
||||
import { Sort } from "@saleor/types";
|
||||
import { ProductOrderField } from "@saleor/types/globalTypes";
|
||||
|
||||
export function getSortQueryVariables(params: ProductListUrlQueryParams) {
|
||||
return {
|
||||
direction: getOrderDirection(params.asc),
|
||||
field: getSortQueryField(params.sort)
|
||||
};
|
||||
}
|
||||
|
||||
export function getSortQueryField(
|
||||
sort: ProductListUrlSortField
|
||||
): ProductOrderField {
|
||||
switch (sort) {
|
||||
case ProductListUrlSortField.name:
|
||||
return ProductOrderField.NAME;
|
||||
case ProductListUrlSortField.price:
|
||||
return ProductOrderField.PRICE;
|
||||
case ProductListUrlSortField.productType:
|
||||
return ProductOrderField.TYPE;
|
||||
case ProductListUrlSortField.status:
|
||||
return ProductOrderField.PUBLISHED;
|
||||
default:
|
||||
return ProductOrderField.NAME;
|
||||
}
|
||||
}
|
||||
|
||||
export function getSortUrlField(
|
||||
sort: ProductOrderField
|
||||
): ProductListUrlSortField {
|
||||
switch (sort) {
|
||||
case ProductOrderField.NAME:
|
||||
return ProductListUrlSortField.name;
|
||||
case ProductOrderField.PRICE:
|
||||
return ProductListUrlSortField.price;
|
||||
case ProductOrderField.TYPE:
|
||||
return ProductListUrlSortField.productType;
|
||||
case ProductOrderField.PUBLISHED:
|
||||
return ProductListUrlSortField.status;
|
||||
default:
|
||||
return ProductListUrlSortField.name;
|
||||
}
|
||||
}
|
||||
|
||||
export function getSortUrlVariables(
|
||||
field: ProductOrderField,
|
||||
selectedField: ProductOrderField,
|
||||
params: Sort<ProductListUrlSortField>
|
||||
): Sort<ProductListUrlSortField> {
|
||||
if (field === selectedField) {
|
||||
return {
|
||||
asc: !params.asc,
|
||||
sort: getSortUrlField(field)
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
asc: true,
|
||||
sort: getSortUrlField(field)
|
||||
};
|
||||
}
|
|
@ -47,6 +47,10 @@ export interface ListProps<TColumns extends string = string> {
|
|||
) => void;
|
||||
onListSettingsReset?: () => void;
|
||||
}
|
||||
|
||||
export interface SortPage<TSortKey extends string> {
|
||||
onSort: (field: TSortKey) => void;
|
||||
}
|
||||
export interface ListActionsWithoutToolbar {
|
||||
toggle: (id: string) => void;
|
||||
toggleAll: (items: React.ReactNodeArray, selected: number) => void;
|
||||
|
@ -131,6 +135,10 @@ export type FiltersWithMultipleValues<TFilters extends string> = Partial<
|
|||
export type SingleAction = Partial<{
|
||||
id: string;
|
||||
}>;
|
||||
export type Sort<TSort extends string = string> = Partial<{
|
||||
asc: boolean;
|
||||
sort: TSort;
|
||||
}>;
|
||||
export type BulkAction = Partial<{
|
||||
ids: string[];
|
||||
}>;
|
||||
|
|
|
@ -112,6 +112,11 @@ export enum OrderAction {
|
|||
VOID = "VOID",
|
||||
}
|
||||
|
||||
export enum OrderDirection {
|
||||
ASC = "ASC",
|
||||
DESC = "DESC",
|
||||
}
|
||||
|
||||
export enum OrderEventsEmailsEnum {
|
||||
DIGITAL_LINKS = "DIGITAL_LINKS",
|
||||
FULFILLMENT_CONFIRMATION = "FULFILLMENT_CONFIRMATION",
|
||||
|
@ -187,6 +192,15 @@ export enum PermissionEnum {
|
|||
MANAGE_USERS = "MANAGE_USERS",
|
||||
}
|
||||
|
||||
export enum ProductOrderField {
|
||||
DATE = "DATE",
|
||||
MINIMAL_PRICE = "MINIMAL_PRICE",
|
||||
NAME = "NAME",
|
||||
PRICE = "PRICE",
|
||||
PUBLISHED = "PUBLISHED",
|
||||
TYPE = "TYPE",
|
||||
}
|
||||
|
||||
export enum ProductTypeConfigurable {
|
||||
CONFIGURABLE = "CONFIGURABLE",
|
||||
SIMPLE = "SIMPLE",
|
||||
|
@ -574,6 +588,11 @@ export interface ProductFilterInput {
|
|||
minimalPrice?: PriceRangeInput | null;
|
||||
}
|
||||
|
||||
export interface ProductOrder {
|
||||
field: ProductOrderField;
|
||||
direction: OrderDirection;
|
||||
}
|
||||
|
||||
export interface ProductTypeFilterInput {
|
||||
search?: string | null;
|
||||
configurable?: ProductTypeConfigurable | null;
|
||||
|
|
|
@ -12,12 +12,12 @@ const DisplayColumn: React.FC<DisplayColumnProps> = ({
|
|||
children,
|
||||
column
|
||||
}) => {
|
||||
const displayColumn = React.useCallback(
|
||||
(column: string) => isSelected(column, displayColumns, (a, b) => a === b),
|
||||
[displayColumns]
|
||||
const display = React.useMemo(
|
||||
() => isSelected(column, displayColumns, (a, b) => a === b),
|
||||
[column, displayColumns]
|
||||
);
|
||||
|
||||
return <>{displayColumn(column) && children}</>;
|
||||
return <>{display && children}</>;
|
||||
};
|
||||
|
||||
DisplayColumn.displayName = "DisplayColumn";
|
||||
|
|
Loading…
Reference in a new issue