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:
parent
e831791493
commit
b024a0fde6
10 changed files with 201 additions and 17 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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']",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from "./ProductVariantCreateDialog";
|
||||
export * from "./ProductVariantCreateDialog";
|
|
@ -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"
|
||||
}
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
export enum ProductVariantCreateOptionEnum {
|
||||
MULTIPLE = "multiple",
|
||||
SINGLE = "single"
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue