import Button from "@material-ui/core/Button"; import CircularProgress from "@material-ui/core/CircularProgress"; import Dialog from "@material-ui/core/Dialog"; import DialogActions from "@material-ui/core/DialogActions"; import DialogContent from "@material-ui/core/DialogContent"; import DialogTitle from "@material-ui/core/DialogTitle"; 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 TableRow from "@material-ui/core/TableRow"; import TextField from "@material-ui/core/TextField"; import React from "react"; import * as InfiniteScroll from "react-infinite-scroller"; import Checkbox from "@saleor/components/Checkbox"; import ConfirmButton, { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton"; import Form from "@saleor/components/Form"; import Money from "@saleor/components/Money"; import TableCellAvatar from "@saleor/components/TableCellAvatar"; import i18n from "../../../i18n"; import { maybe, renderCollection } from "../../../misc"; import { SearchOrderVariant_products_edges_node, SearchOrderVariant_products_edges_node_variants } from "../../types/SearchOrderVariant"; export interface FormData { variants: SearchOrderVariant_products_edges_node_variants[]; query: string; } const styles = (theme: Theme) => createStyles({ avatar: { paddingLeft: 0 }, content: { maxHeight: 600, overflowY: "scroll" }, grayText: { color: theme.palette.text.disabled }, loadMoreLoaderContainer: { alignItems: "center", display: "flex", height: theme.spacing.unit * 3, justifyContent: "center" }, overflow: { overflowY: "visible" }, productCheckboxCell: { "&:first-child": { paddingLeft: 0, paddingRight: 0 } }, textRight: { textAlign: "right" }, variantCheckbox: { left: theme.spacing.unit, position: "relative" }, wideCell: { width: "100%" } }); interface OrderProductAddDialogProps extends WithStyles { confirmButtonState: ConfirmButtonTransitionState; open: boolean; products: SearchOrderVariant_products_edges_node[]; loading: boolean; hasMore: boolean; onClose: () => void; onFetch: (value: string) => void; onFetchMore: () => void; onSubmit: (data: FormData) => void; } const initialForm: FormData = { query: "", variants: [] }; function hasAllVariantsSelected( productVariants: SearchOrderVariant_products_edges_node_variants[], selectedVariants: SearchOrderVariant_products_edges_node_variants[] ): boolean { return productVariants.reduce( (acc, productVariant) => acc && !!selectedVariants.find( selectedVariant => selectedVariant.id === productVariant.id ), true ); } function isVariantSelected( variant: SearchOrderVariant_products_edges_node_variants, selectedVariants: SearchOrderVariant_products_edges_node_variants[] ): boolean { return !!selectedVariants.find( selectedVariant => selectedVariant.id === variant.id ); } const OrderProductAddDialog = withStyles(styles, { name: "OrderProductAddDialog" })( ({ classes, confirmButtonState, open, loading, hasMore, products, onFetch, onFetchMore, onClose, onSubmit }: OrderProductAddDialogProps) => (
{({ data, change }) => { const selectedVariants = products ? products.map(product => product.variants.map(variant => isVariantSelected(variant, data.variants) ) ) : []; const selectedProducts = products ? products.map(product => hasAllVariantsSelected(product.variants, data.variants) ) : []; const onProductAdd = ( product: SearchOrderVariant_products_edges_node, productIndex: number ) => selectedProducts[productIndex] ? change({ target: { name: "variants", value: data.variants.filter( selectedVariant => !product.variants.find( productVariant => productVariant.id === selectedVariant.id ) ) } } as any) : change({ target: { name: "variants", value: [ ...data.variants, ...product.variants.filter( productVariant => !data.variants.find( selectedVariant => selectedVariant.id === productVariant.id ) ) ] } } as any); const onVariantAdd = ( variant: SearchOrderVariant_products_edges_node_variants, variantIndex: number, productIndex: number ) => selectedVariants[productIndex][variantIndex] ? change({ target: { name: "variants", value: data.variants.filter( selectedVariant => selectedVariant.id !== variant.id ) } } as any) : change({ target: { name: "variants", value: [...data.variants, variant] } } as any); return ( <> {i18n.t("Add product")} change(event, () => onFetch(data.query))} label={i18n.t("Search Products", { context: "product search input label" })} placeholder={i18n.t( "Search by product name, attribute, product type etc...", { context: "product search input placeholder" } )} fullWidth InputProps={{ autoComplete: "off", endAdornment: loading && }} /> } threshold={10} > {renderCollection( products, (product, productIndex) => ( onProductAdd(product, productIndex) } /> product.thumbnail.url)} /> {maybe(() => product.name)} {maybe(() => product.variants, []).map( (variant, variantIndex) => ( onVariantAdd( variant, variantIndex, productIndex ) } />
{variant.name}
{i18n.t("SKU {{ sku }}", { sku: variant.sku })}
) )}
), () => ( {i18n.t("No products matching given query")} ) )}
{i18n.t("Confirm", { context: "button" })} ); }}
) ); OrderProductAddDialog.displayName = "OrderProductAddDialog"; export default OrderProductAddDialog;