Add variant create options dialog (#1238)

* Add variant create options dialog

* Update e2e tests

* Update option field name

* Refactor

* Use macaw UI in Variant create dialog

* Update messages
This commit is contained in:
Dawid Tarasiuk 2021-07-22 11:56:13 +02:00 committed by GitHub
parent e831791493
commit b024a0fde6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 201 additions and 17 deletions

View file

@ -68,6 +68,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Fix list pagination crash on search - #1230 by @orzechdev
- Fix positive float number input validation - #1233 by @orzechdev
- Use MacawUI - #1229 by @dominik-zeglen
- Add variant create options dialog - #1238 by @orzechdev
# 2.11.1

View file

@ -9,6 +9,10 @@ export const PRODUCT_DETAILS = {
visibleRadioBtn: "[name='isPublished']",
channelAvailabilityItem: "[data-test='channel-availability-item']",
addVariantsButton: "[data-test*='button-add-variant']",
addVariantsOptionDialog: {
optionMultiple: '[data-test-id="variant-create-option-multiple"]',
optionSingle: '[data-test-id="variant-create-option-single"]'
},
descriptionInput: "[data-test-id='description']",
ratingInput: "[name='rating']",
skuInput: "[name='sku']",

View file

@ -16,6 +16,8 @@ export function variantsShouldBeVisible({ name, price }) {
}
export function createFirstVariant({ sku, warehouseId, price, attribute }) {
cy.get(PRODUCT_DETAILS.addVariantsButton).click();
cy.get(PRODUCT_DETAILS.addVariantsOptionDialog.optionMultiple).click();
cy.get(BUTTON_SELECTORS.submit).click();
cy.get(VARIANTS_SELECTORS.valueContainer)
.click()
.contains(attribute)

View file

@ -2038,10 +2038,6 @@
"src_dot_components_dot_CompanyAddressInput_dot_944851093": {
"string": "Country area"
},
"src_dot_components_dot_ConfirmButton_dot_2845142593": {
"context": "button",
"string": "Error"
},
"src_dot_components_dot_CountryList_dot_2460766407": {
"context": "number of countries",
"string": "{number} Countries"
@ -2466,18 +2462,6 @@
"context": "weight",
"string": "{value} {unit}"
},
"src_dot_components_dot_messages_dot_1219076963": {
"context": "snackbar expand",
"string": "Expand"
},
"src_dot_components_dot_messages_dot_2473863536": {
"context": "snackbar button undo",
"string": "Undo"
},
"src_dot_components_dot_messages_dot_3444275093": {
"context": "snackbar collapse",
"string": "Collapse"
},
"src_dot_configuration": {
"context": "configuration section name",
"string": "Configuration"
@ -3369,6 +3353,9 @@
"src_dot_endHour": {
"string": "End Hour"
},
"src_dot_error": {
"string": "Error"
},
"src_dot_exchangeRates": {
"context": "Manage and Update your warehouse information",
"string": "Exchange Rates"
@ -5560,6 +5547,30 @@
"context": "product label",
"string": "Published"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_description": {
"context": "create product variants",
"string": "How would you like to create variants:"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_optionMultipleDescription": {
"context": "option description",
"string": "Use variant creator to create matrix of selected attribute values to create variants"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_optionMultipleTitle": {
"context": "option",
"string": "Create multiple variant via variant creator"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_optionSingleDescription": {
"context": "option description",
"string": "Create new variant using variant details view"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_optionSingleTitle": {
"context": "option",
"string": "Create single variant"
},
"src_dot_products_dot_components_dot_ProductVariantCreateDialog_dot_title": {
"context": "dialog header",
"string": "Create Variants"
},
"src_dot_products_dot_components_dot_ProductVariantCreatePage_dot_attributesHeader": {
"context": "attributes, section header",
"string": "Variant Attributes"

View file

@ -0,0 +1,121 @@
import {
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Typography
} from "@material-ui/core";
import ConfirmButton from "@saleor/components/ConfirmButton";
import Form from "@saleor/components/Form";
import FormSpacer from "@saleor/components/FormSpacer";
import RadioGroupField from "@saleor/components/RadioGroupField";
import { buttonMessages } from "@saleor/intl";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { FormattedMessage } from "react-intl";
import { messages } from "./messages";
import { ProductVariantCreateOptionEnum } from "./types";
const useStyles = makeStyles(
theme => ({
option: {
marginBottom: theme.spacing(2),
width: 400
}
}),
{ name: "ProductVariantCreateDialog" }
);
interface ProductVariantCreateDialogForm {
option: ProductVariantCreateOptionEnum;
}
export interface ProductVariantCreateDialogProps {
open: boolean;
onClose: () => void;
onConfirm: (option: ProductVariantCreateOptionEnum) => void;
}
const ProductVariantCreateDialog: React.FC<ProductVariantCreateDialogProps> = props => {
const { open, onConfirm, onClose } = props;
const classes = useStyles(props);
const initialForm = {
option: ProductVariantCreateOptionEnum.MULTIPLE
};
const handleSubmit = (form: ProductVariantCreateDialogForm) => {
onConfirm(form.option);
};
const options = [
{
title: messages.optionMultipleTitle,
subtitle: messages.optionMultipleDescription,
type: ProductVariantCreateOptionEnum.MULTIPLE
},
{
title: messages.optionSingleTitle,
subtitle: messages.optionSingleDescription,
type: ProductVariantCreateOptionEnum.SINGLE
}
];
return (
<Dialog onClose={onClose} open={open}>
<Form initial={initialForm} onSubmit={handleSubmit}>
{({ change, data }) => (
<>
<DialogTitle>
<FormattedMessage {...messages.title} />
</DialogTitle>
<DialogContent>
<Typography variant="body2">
<FormattedMessage {...messages.description} />
</Typography>
<FormSpacer />
<RadioGroupField
alignTop
choices={options.map(option => ({
label: (
<div
className={classes.option}
data-test-id={`variant-create-option-${option.type}`}
>
<Typography variant="body1">
<FormattedMessage {...option.title} />
</Typography>
<Typography color="textSecondary" variant="caption">
<FormattedMessage {...option.subtitle} />
</Typography>
</div>
),
value: option.type
}))}
name="option"
value={data.option}
onChange={change}
/>
</DialogContent>
<DialogActions>
<ConfirmButton
transitionState="default"
color="primary"
variant="contained"
type="submit"
data-test-id="submit"
data-test="submit"
>
<FormattedMessage {...buttonMessages.create} />
</ConfirmButton>
</DialogActions>
</>
)}
</Form>
</Dialog>
);
};
ProductVariantCreateDialog.displayName = "ProductVariantCreateDialog";
export default ProductVariantCreateDialog;

View file

@ -0,0 +1,2 @@
export { default } from "./ProductVariantCreateDialog";
export * from "./ProductVariantCreateDialog";

View file

@ -0,0 +1,29 @@
import { defineMessages } from "react-intl";
export const messages = defineMessages({
title: {
defaultMessage: "Create Variants",
description: "dialog header"
},
description: {
defaultMessage: "How would you like to create variants:",
description: "create product variants"
},
optionMultipleTitle: {
defaultMessage: "Create multiple variant via variant creator",
description: "option"
},
optionMultipleDescription: {
defaultMessage:
"Use variant creator to create matrix of selected attribute values to create variants",
description: "option description"
},
optionSingleTitle: {
defaultMessage: "Create single variant",
description: "option"
},
optionSingleDescription: {
defaultMessage: "Create new variant using variant details view",
description: "option description"
}
});

View file

@ -0,0 +1,4 @@
export enum ProductVariantCreateOptionEnum {
MULTIPLE = "multiple",
SINGLE = "single"
}

View file

@ -67,6 +67,7 @@ export const productListUrl = (params?: ProductListUrlQueryParams): string =>
export const productPath = (id: string) => urlJoin(productSection + id);
export type ProductUrlDialog =
| "add-variants"
| "remove"
| "remove-variants"
| "assign-attribute-value"

View file

@ -28,6 +28,7 @@ import useNotifier from "@saleor/hooks/useNotifier";
import useOnSetDefaultVariant from "@saleor/hooks/useOnSetDefaultVariant";
import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl";
import ProductVariantCreateDialog from "@saleor/products/components/ProductVariantCreateDialog";
import {
useProductChannelListingUpdate,
useProductDeleteMutation,
@ -369,6 +370,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
return <NotFoundPage onBack={handleBack} />;
}
const handleVariantAdd = () => navigate(productVariantAddUrl(id));
const handleVariantsAdd = () => navigate(productVariantCreatorUrl(id));
const handleImageDelete = (id: string) => () =>
deleteProductImage({ variables: { id } });
@ -563,7 +565,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
}}
onWarehouseConfigure={() => navigate(warehouseAddPath)}
onVariantAdd={handleVariantAdd}
onVariantsAdd={() => navigate(productVariantCreatorUrl(id))}
onVariantsAdd={() => openModal("add-variants")}
onVariantShow={variantId => () =>
navigate(productVariantEditUrl(product.id, variantId))}
onVariantReorder={handleVariantReorder}
@ -643,6 +645,13 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
/>
</DialogContentText>
</ActionDialog>
<ProductVariantCreateDialog
open={params.action === "add-variants"}
onClose={closeModal}
onConfirm={option =>
option === "multiple" ? handleVariantsAdd() : handleVariantAdd()
}
/>
</>
);
};