Merge pull request #186 from mirumee/tc/fix-products
Fix product testcafe tags
This commit is contained in:
commit
116d952bea
5 changed files with 265 additions and 352 deletions
|
@ -1,344 +0,0 @@
|
||||||
import {
|
|
||||||
createStyles,
|
|
||||||
Theme,
|
|
||||||
withStyles,
|
|
||||||
WithStyles
|
|
||||||
} from "@material-ui/core/styles";
|
|
||||||
import Table from "@material-ui/core/Table";
|
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
|
||||||
import TableFooter from "@material-ui/core/TableFooter";
|
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import React from "react";
|
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
|
||||||
|
|
||||||
import TableCellAvatar, {
|
|
||||||
AVATAR_MARGIN
|
|
||||||
} from "@saleor/components/TableCellAvatar";
|
|
||||||
import { ProductListColumns } from "@saleor/config";
|
|
||||||
import { 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 Checkbox from "../Checkbox";
|
|
||||||
import Money from "../Money";
|
|
||||||
import Skeleton from "../Skeleton";
|
|
||||||
import StatusLabel from "../StatusLabel";
|
|
||||||
import TableHead from "../TableHead";
|
|
||||||
import TablePagination from "../TablePagination";
|
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
|
||||||
createStyles({
|
|
||||||
[theme.breakpoints.up("lg")]: {
|
|
||||||
colName: {
|
|
||||||
width: "auto"
|
|
||||||
},
|
|
||||||
colPrice: {
|
|
||||||
width: 200
|
|
||||||
},
|
|
||||||
colPublished: {
|
|
||||||
width: 200
|
|
||||||
},
|
|
||||||
colType: {
|
|
||||||
width: 200
|
|
||||||
}
|
|
||||||
},
|
|
||||||
colAttribute: {
|
|
||||||
width: 150
|
|
||||||
},
|
|
||||||
colFill: {
|
|
||||||
padding: 0,
|
|
||||||
width: "100%"
|
|
||||||
},
|
|
||||||
colName: {
|
|
||||||
"&$colNameFixed": {
|
|
||||||
width: 250
|
|
||||||
},
|
|
||||||
paddingLeft: 0
|
|
||||||
},
|
|
||||||
colNameFixed: {},
|
|
||||||
colNameHeader: {
|
|
||||||
marginLeft: AVATAR_MARGIN
|
|
||||||
},
|
|
||||||
colPrice: {
|
|
||||||
textAlign: "right"
|
|
||||||
},
|
|
||||||
colPublished: {},
|
|
||||||
colType: {},
|
|
||||||
link: {
|
|
||||||
cursor: "pointer"
|
|
||||||
},
|
|
||||||
table: {
|
|
||||||
tableLayout: "fixed"
|
|
||||||
},
|
|
||||||
tableContainer: {
|
|
||||||
overflowX: "scroll"
|
|
||||||
},
|
|
||||||
textLeft: {
|
|
||||||
textAlign: "left"
|
|
||||||
},
|
|
||||||
textRight: {
|
|
||||||
textAlign: "right"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
interface ProductListProps
|
|
||||||
extends ListProps<ProductListColumns>,
|
|
||||||
ListActions,
|
|
||||||
WithStyles<typeof styles> {
|
|
||||||
gridAttributes: AvailableInGridAttributes_grid_edges_node[];
|
|
||||||
products: ProductList_products_edges_node[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ProductList = withStyles(styles, { name: "ProductList" })(
|
|
||||||
({
|
|
||||||
classes,
|
|
||||||
settings,
|
|
||||||
disabled,
|
|
||||||
isChecked,
|
|
||||||
gridAttributes,
|
|
||||||
pageInfo,
|
|
||||||
products,
|
|
||||||
selected,
|
|
||||||
toggle,
|
|
||||||
toggleAll,
|
|
||||||
toolbar,
|
|
||||||
onNextPage,
|
|
||||||
onPreviousPage,
|
|
||||||
onUpdateListSettings,
|
|
||||||
onRowClick
|
|
||||||
}: ProductListProps) => {
|
|
||||||
const intl = useIntl();
|
|
||||||
|
|
||||||
const DisplayColumn: React.FC<{ column: ProductListColumns }> = props => (
|
|
||||||
<TDisplayColumn displayColumns={settings.columns} {...props} />
|
|
||||||
);
|
|
||||||
|
|
||||||
const gridAttributesFromSettings = settings.columns.filter(
|
|
||||||
isAttributeColumnValue
|
|
||||||
);
|
|
||||||
const numberOfColumns = 2 + settings.columns.length;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={classes.tableContainer}>
|
|
||||||
<Table className={classes.table}>
|
|
||||||
<colgroup>
|
|
||||||
<col />
|
|
||||||
<col className={classes.colName} />
|
|
||||||
<DisplayColumn column="productType">
|
|
||||||
<col className={classes.colType} />
|
|
||||||
</DisplayColumn>
|
|
||||||
<DisplayColumn column="isPublished">
|
|
||||||
<col className={classes.colPublished} />
|
|
||||||
</DisplayColumn>
|
|
||||||
{gridAttributesFromSettings.map(gridAttribute => (
|
|
||||||
<col className={classes.colAttribute} key={gridAttribute} />
|
|
||||||
))}
|
|
||||||
<DisplayColumn column="price">
|
|
||||||
<col className={classes.colPrice} />
|
|
||||||
</DisplayColumn>
|
|
||||||
</colgroup>
|
|
||||||
<TableHead
|
|
||||||
colSpan={numberOfColumns}
|
|
||||||
selected={selected}
|
|
||||||
disabled={disabled}
|
|
||||||
items={products}
|
|
||||||
toggleAll={toggleAll}
|
|
||||||
toolbar={toolbar}
|
|
||||||
>
|
|
||||||
<TableCell
|
|
||||||
className={classNames(classes.colName, {
|
|
||||||
[classes.colNameFixed]: settings.columns.length > 4
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<span className={classes.colNameHeader}>
|
|
||||||
<FormattedMessage defaultMessage="Name" description="product" />
|
|
||||||
</span>
|
|
||||||
</TableCell>
|
|
||||||
<DisplayColumn column="productType">
|
|
||||||
<TableCell className={classes.colType}>
|
|
||||||
<FormattedMessage defaultMessage="Type" description="product" />
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
<DisplayColumn column="isPublished">
|
|
||||||
<TableCell className={classes.colPublished}>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Published"
|
|
||||||
description="product status"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
{gridAttributesFromSettings.map(gridAttributeFromSettings => (
|
|
||||||
<TableCell
|
|
||||||
className={classes.colAttribute}
|
|
||||||
key={gridAttributeFromSettings}
|
|
||||||
>
|
|
||||||
{maybe<React.ReactNode>(
|
|
||||||
() =>
|
|
||||||
gridAttributes.find(
|
|
||||||
gridAttribute =>
|
|
||||||
getAttributeIdFromColumnValue(
|
|
||||||
gridAttributeFromSettings
|
|
||||||
) === gridAttribute.id
|
|
||||||
).name,
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
<DisplayColumn column="price">
|
|
||||||
<TableCell className={classes.colPrice}>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Price"
|
|
||||||
description="product"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
</TableHead>
|
|
||||||
<TableFooter>
|
|
||||||
<TableRow>
|
|
||||||
<TablePagination
|
|
||||||
colSpan={numberOfColumns}
|
|
||||||
settings={settings}
|
|
||||||
hasNextPage={
|
|
||||||
pageInfo && !disabled ? pageInfo.hasNextPage : false
|
|
||||||
}
|
|
||||||
onNextPage={onNextPage}
|
|
||||||
onUpdateListSettings={onUpdateListSettings}
|
|
||||||
hasPreviousPage={
|
|
||||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
|
||||||
}
|
|
||||||
onPreviousPage={onPreviousPage}
|
|
||||||
/>
|
|
||||||
</TableRow>
|
|
||||||
</TableFooter>
|
|
||||||
<TableBody>
|
|
||||||
{renderCollection(
|
|
||||||
products,
|
|
||||||
product => {
|
|
||||||
const isSelected = product ? isChecked(product.id) : false;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableRow
|
|
||||||
selected={isSelected}
|
|
||||||
hover={!!product}
|
|
||||||
key={product ? product.id : "skeleton"}
|
|
||||||
onClick={product && onRowClick(product.id)}
|
|
||||||
className={classes.link}
|
|
||||||
data-tc={product ? `product-${product.id}` : undefined}
|
|
||||||
>
|
|
||||||
<TableCell padding="checkbox">
|
|
||||||
<Checkbox
|
|
||||||
checked={isSelected}
|
|
||||||
disabled={disabled}
|
|
||||||
disableClickPropagation
|
|
||||||
onChange={() => toggle(product.id)}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCellAvatar
|
|
||||||
className={classes.colName}
|
|
||||||
thumbnail={maybe(() => product.thumbnail.url)}
|
|
||||||
data-tc="name"
|
|
||||||
>
|
|
||||||
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
|
||||||
</TableCellAvatar>
|
|
||||||
<DisplayColumn column="productType">
|
|
||||||
<TableCell
|
|
||||||
className={classes.colType}
|
|
||||||
data-tc="product-type"
|
|
||||||
>
|
|
||||||
{product && product.productType ? (
|
|
||||||
product.productType.name
|
|
||||||
) : (
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
<DisplayColumn column="isPublished">
|
|
||||||
<TableCell
|
|
||||||
className={classes.colPublished}
|
|
||||||
data-tc="isPublished"
|
|
||||||
data-tc-is-published={maybe(() => product.isAvailable)}
|
|
||||||
>
|
|
||||||
{product &&
|
|
||||||
maybe(() => product.isAvailable !== undefined) ? (
|
|
||||||
<StatusLabel
|
|
||||||
label={
|
|
||||||
product.isAvailable
|
|
||||||
? intl.formatMessage({
|
|
||||||
defaultMessage: "Published",
|
|
||||||
description: "product status"
|
|
||||||
})
|
|
||||||
: intl.formatMessage({
|
|
||||||
defaultMessage: "Not published",
|
|
||||||
description: "product status"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
status={product.isAvailable ? "success" : "error"}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
{gridAttributesFromSettings.map(gridAttribute => {
|
|
||||||
const attribute = maybe(() =>
|
|
||||||
product.attributes.find(
|
|
||||||
attribute =>
|
|
||||||
attribute.attribute.id ===
|
|
||||||
getAttributeIdFromColumnValue(gridAttribute)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const attributeValues = attribute
|
|
||||||
? attribute.values.map(value => value.name).join(", ")
|
|
||||||
: "-";
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TableCell
|
|
||||||
className={classes.colAttribute}
|
|
||||||
key={gridAttribute}
|
|
||||||
data-tc="attribute"
|
|
||||||
data-tc-attribute={maybe(
|
|
||||||
() => attribute.attribute.id
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{attribute ? attributeValues : <Skeleton />}
|
|
||||||
</TableCell>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
<DisplayColumn column="price">
|
|
||||||
<TableCell className={classes.colPrice}>
|
|
||||||
{maybe(() => product.basePrice) &&
|
|
||||||
maybe(() => product.basePrice.amount) !== undefined &&
|
|
||||||
maybe(() => product.basePrice.currency) !==
|
|
||||||
undefined ? (
|
|
||||||
<Money money={product.basePrice} />
|
|
||||||
) : (
|
|
||||||
<Skeleton />
|
|
||||||
)}
|
|
||||||
</TableCell>
|
|
||||||
</DisplayColumn>
|
|
||||||
</TableRow>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
() => (
|
|
||||||
<TableRow>
|
|
||||||
<TableCell colSpan={numberOfColumns}>
|
|
||||||
<FormattedMessage defaultMessage="No products found" />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
ProductList.displayName = "ProductList";
|
|
||||||
export default ProductList;
|
|
|
@ -1 +0,0 @@
|
||||||
export { default } from "./ProductList";
|
|
|
@ -52,9 +52,10 @@ const TableCellAvatar = withStyles(styles, { name: "TableCellAvatar" })(
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
avatarProps
|
avatarProps,
|
||||||
|
...props
|
||||||
}: TableCellAvatarProps) => (
|
}: TableCellAvatarProps) => (
|
||||||
<TableCell className={classNames(classes.root, className)}>
|
<TableCell className={classNames(classes.root, className)} {...props}>
|
||||||
<div className={classes.content}>
|
<div className={classes.content}>
|
||||||
{thumbnail === undefined ? (
|
{thumbnail === undefined ? (
|
||||||
<Avatar className={classNames(classes.avatar, avatarProps)}>
|
<Avatar className={classNames(classes.avatar, avatarProps)}>
|
||||||
|
|
|
@ -284,6 +284,8 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
key={product ? product.id : "skeleton"}
|
key={product ? product.id : "skeleton"}
|
||||||
onClick={product && onRowClick(product.id)}
|
onClick={product && onRowClick(product.id)}
|
||||||
className={classes.link}
|
className={classes.link}
|
||||||
|
data-tc="id"
|
||||||
|
data-tc-id={maybe(() => product.id)}
|
||||||
>
|
>
|
||||||
<TableCell padding="checkbox">
|
<TableCell padding="checkbox">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
@ -296,6 +298,7 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableCellAvatar
|
<TableCellAvatar
|
||||||
className={classes.colName}
|
className={classes.colName}
|
||||||
thumbnail={maybe(() => product.thumbnail.url)}
|
thumbnail={maybe(() => product.thumbnail.url)}
|
||||||
|
data-tc="name"
|
||||||
>
|
>
|
||||||
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
||||||
</TableCellAvatar>
|
</TableCellAvatar>
|
||||||
|
@ -303,7 +306,10 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
column="productType"
|
column="productType"
|
||||||
displayColumns={settings.columns}
|
displayColumns={settings.columns}
|
||||||
>
|
>
|
||||||
<TableCell className={classes.colType}>
|
<TableCell
|
||||||
|
className={classes.colType}
|
||||||
|
data-tc="product-type"
|
||||||
|
>
|
||||||
{product && product.productType ? (
|
{product && product.productType ? (
|
||||||
product.productType.name
|
product.productType.name
|
||||||
) : (
|
) : (
|
||||||
|
@ -315,7 +321,11 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
column="isPublished"
|
column="isPublished"
|
||||||
displayColumns={settings.columns}
|
displayColumns={settings.columns}
|
||||||
>
|
>
|
||||||
<TableCell className={classes.colPublished}>
|
<TableCell
|
||||||
|
className={classes.colPublished}
|
||||||
|
data-tc="isPublished"
|
||||||
|
data-tc-is-published={maybe(() => product.isAvailable)}
|
||||||
|
>
|
||||||
{product &&
|
{product &&
|
||||||
maybe(() => product.isAvailable !== undefined) ? (
|
maybe(() => product.isAvailable !== undefined) ? (
|
||||||
<StatusLabel
|
<StatusLabel
|
||||||
|
@ -323,12 +333,11 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
product.isAvailable
|
product.isAvailable
|
||||||
? intl.formatMessage({
|
? intl.formatMessage({
|
||||||
defaultMessage: "Published",
|
defaultMessage: "Published",
|
||||||
description: "product",
|
description: "product status"
|
||||||
id: "productStatusLabel"
|
|
||||||
})
|
})
|
||||||
: intl.formatMessage({
|
: intl.formatMessage({
|
||||||
defaultMessage: "Not published",
|
defaultMessage: "Not published",
|
||||||
description: "product"
|
description: "product status"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
status={product.isAvailable ? "success" : "error"}
|
status={product.isAvailable ? "success" : "error"}
|
||||||
|
@ -342,6 +351,10 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableCell
|
<TableCell
|
||||||
className={classes.colAttribute}
|
className={classes.colAttribute}
|
||||||
key={gridAttribute}
|
key={gridAttribute}
|
||||||
|
data-tc="attribute"
|
||||||
|
data-tc-attribute={getAttributeIdFromColumnValue(
|
||||||
|
gridAttribute
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{maybe<React.ReactNode>(() => {
|
{maybe<React.ReactNode>(() => {
|
||||||
const attribute = product.attributes.find(
|
const attribute = product.attributes.find(
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue