diff --git a/src/products/views/ProductCreate/ProductCreate.tsx b/src/products/views/ProductCreate/ProductCreate.tsx index 669e59927..ce9893b02 100644 --- a/src/products/views/ProductCreate/ProductCreate.tsx +++ b/src/products/views/ProductCreate/ProductCreate.tsx @@ -7,7 +7,6 @@ import useChannels from "@saleor/hooks/useChannels"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import useShop from "@saleor/hooks/useShop"; -import { getMutationStatus } from "@saleor/misc"; import ProductCreatePage from "@saleor/products/components/ProductCreatePage"; import { useProductChannelListingUpdate, @@ -135,41 +134,29 @@ export const ProductCreateView: React.FC = () => { }); const handleSubmit = async data => { - await createMetadataCreateHandler( + const result = await createMetadataCreateHandler( createHandler( productTypes, variables => productCreate({ variables }), variables => productVariantCreate({ variables }), updateChannels, - updateVariantChannels + updateVariantChannels, + deleteProduct ), updateMetadata, updatePrivateMetadata )(data); - setProductCreateComplete(true); + if (result) { + setProductCreateComplete(true); + } }; React.useEffect(() => { const productId = productCreateOpts.data?.productCreate?.product?.id; - // INFO: All these mutations contain required fields in Product Create UI - const statuses = [ - getMutationStatus(productCreateOpts), - getMutationStatus(productVariantCreateOpts), - getMutationStatus(updateChannelsOpts) - ]; - if (productId && productCreateComplete) { - if (statuses.every(s => s === "success")) { - handleSuccess(productId); - } else { - /* - INFO: This is a stop-gap solution, where we delete products that didn't meet all required data in the create form - A more robust solution would require merging create and update form into one to persist form state across redirects - */ - setProductCreateComplete(false); - deleteProduct({ variables: { id: productId } }); - } + if (productCreateComplete && productId) { + handleSuccess(productId); } }, [productCreateComplete]); diff --git a/src/products/views/ProductCreate/handlers.ts b/src/products/views/ProductCreate/handlers.ts index 024033cb4..96e26f8b5 100644 --- a/src/products/views/ProductCreate/handlers.ts +++ b/src/products/views/ProductCreate/handlers.ts @@ -9,6 +9,10 @@ import { ProductCreate, ProductCreateVariables } from "@saleor/products/types/ProductCreate"; +import { + ProductDelete, + ProductDeleteVariables +} from "@saleor/products/types/ProductDelete"; import { ProductVariantChannelListingUpdate, ProductVariantChannelListingUpdateVariables @@ -59,7 +63,10 @@ export function createHandler( }) => Promise>, updateVariantChannels: (options: { variables: ProductVariantChannelListingUpdateVariables; - }) => Promise> + }) => Promise>, + productDelete: (options: { + variables: ProductDeleteVariables; + }) => Promise> ) { return async (formData: ProductCreateData) => { const productVariables: ProductCreateVariables = { @@ -85,6 +92,7 @@ export function createHandler( }; const result = await productCreate(productVariables); + let hasErrors = false; const hasVariants = productTypes.find( product => product.id === formData.productType.id @@ -98,7 +106,13 @@ export function createHandler( ), productVariantCreate(getSimpleProductVariables(formData, productId)) ]); - const variantErrors = result[1].data.productVariantCreate.errors; + const channelErrors = result[0].data?.productChannelListingUpdate?.errors; + const variantErrors = result[1].data?.productVariantCreate?.errors; + + if ([...(channelErrors || []), ...(variantErrors || [])].length > 0) { + hasErrors = true; + } + const variantId = result[1].data.productVariantCreate.productVariant?.id; if (variantErrors.length === 0 && variantId) { updateVariantChannels({ @@ -113,7 +127,23 @@ export function createHandler( }); } } else { - updateChannels(getChannelsVariables(productId, formData.channelListings)); + const result = await updateChannels( + getChannelsVariables(productId, formData.channelListings) + ); + + if (result.data?.productChannelListingUpdate?.errors.length > 0) { + hasErrors = true; + } + } + + /* + INFO: This is a stop-gap solution, where we delete products that didn't meet all required data in the create form + A more robust solution would require merging create and update form into one to persist form state across redirects + */ + if (productId && hasErrors) { + productDelete({ variables: { id: productId } }); + + return null; } return productId || null; };