Remove ProductUpdateOperations component

This commit is contained in:
dominik-zeglen 2020-08-24 11:50:55 +02:00
parent 8f66954590
commit 7726bacb77
4 changed files with 267 additions and 424 deletions

View file

@ -1,153 +0,0 @@
import React from "react";
import { getMutationProviderData, maybe } from "../../misc";
import { PartialMutationProviderOutput } from "../../types";
import {
TypedProductDeleteMutation,
TypedProductImageCreateMutation,
TypedProductImageDeleteMutation,
TypedProductUpdateMutation,
TypedProductVariantBulkDeleteMutation,
TypedSimpleProductUpdateMutation
} from "../mutations";
import { ProductDelete, ProductDeleteVariables } from "../types/ProductDelete";
import { ProductDetails_product } from "../types/ProductDetails";
import {
ProductImageCreate,
ProductImageCreateVariables
} from "../types/ProductImageCreate";
import {
ProductImageDelete,
ProductImageDeleteVariables
} from "../types/ProductImageDelete";
import {
ProductImageReorder,
ProductImageReorderVariables
} from "../types/ProductImageReorder";
import { ProductUpdate, ProductUpdateVariables } from "../types/ProductUpdate";
import {
ProductVariantBulkDelete,
ProductVariantBulkDeleteVariables
} from "../types/ProductVariantBulkDelete";
import {
SimpleProductUpdate,
SimpleProductUpdateVariables
} from "../types/SimpleProductUpdate";
import ProductImagesReorderProvider from "./ProductImagesReorder";
interface ProductUpdateOperationsProps {
product: ProductDetails_product;
children: (props: {
bulkProductVariantDelete: PartialMutationProviderOutput<
ProductVariantBulkDelete,
ProductVariantBulkDeleteVariables
>;
createProductImage: PartialMutationProviderOutput<
ProductImageCreate,
ProductImageCreateVariables
>;
deleteProduct: PartialMutationProviderOutput<
ProductDelete,
ProductDeleteVariables
>;
deleteProductImage: PartialMutationProviderOutput<
ProductImageDelete,
ProductImageDeleteVariables
>;
reorderProductImages: PartialMutationProviderOutput<
ProductImageReorder,
ProductImageReorderVariables
>;
updateProduct: PartialMutationProviderOutput<
ProductUpdate,
ProductUpdateVariables
>;
updateSimpleProduct: PartialMutationProviderOutput<
SimpleProductUpdate,
SimpleProductUpdateVariables
>;
}) => React.ReactNode;
onBulkProductVariantDelete?: (data: ProductVariantBulkDelete) => void;
onDelete?: (data: ProductDelete) => void;
onImageCreate?: (data: ProductImageCreate) => void;
onImageDelete?: (data: ProductImageDelete) => void;
onImageReorder?: (data: ProductImageReorder) => void;
onUpdate?: (data: ProductUpdate) => void;
}
const ProductUpdateOperations: React.FC<ProductUpdateOperationsProps> = ({
product,
children,
onBulkProductVariantDelete,
onDelete,
onImageDelete,
onImageCreate,
onImageReorder,
onUpdate
}) => {
const productId = product ? product.id : "";
return (
<TypedProductUpdateMutation onCompleted={onUpdate}>
{(...updateProduct) => (
<ProductImagesReorderProvider
productId={productId}
productImages={maybe(() => product.images, [])}
onCompleted={onImageReorder}
>
{(...reorderProductImages) => (
<TypedProductImageCreateMutation onCompleted={onImageCreate}>
{(...createProductImage) => (
<TypedProductDeleteMutation onCompleted={onDelete}>
{(...deleteProduct) => (
<TypedProductImageDeleteMutation
onCompleted={onImageDelete}
>
{(...deleteProductImage) => (
<TypedSimpleProductUpdateMutation
onCompleted={onUpdate}
>
{(...updateSimpleProduct) => (
<TypedProductVariantBulkDeleteMutation
onCompleted={onBulkProductVariantDelete}
>
{(...bulkProductVariantDelete) =>
children({
bulkProductVariantDelete: getMutationProviderData(
...bulkProductVariantDelete
),
createProductImage: getMutationProviderData(
...createProductImage
),
deleteProduct: getMutationProviderData(
...deleteProduct
),
deleteProductImage: getMutationProviderData(
...deleteProductImage
),
reorderProductImages: getMutationProviderData(
...reorderProductImages
),
updateProduct: getMutationProviderData(
...updateProduct
),
updateSimpleProduct: getMutationProviderData(
...updateSimpleProduct
)
})
}
</TypedProductVariantBulkDeleteMutation>
)}
</TypedSimpleProductUpdateMutation>
)}
</TypedProductImageDeleteMutation>
)}
</TypedProductDeleteMutation>
)}
</TypedProductImageCreateMutation>
)}
</ProductImagesReorderProvider>
)}
</TypedProductUpdateMutation>
);
};
export default ProductUpdateOperations;

View file

@ -13,7 +13,6 @@ import {
import makeMutation from "@saleor/hooks/makeMutation"; import makeMutation from "@saleor/hooks/makeMutation";
import gql from "graphql-tag"; import gql from "graphql-tag";
import { TypedMutation } from "../mutations";
import { import {
productBulkDelete, productBulkDelete,
productBulkDeleteVariables productBulkDeleteVariables
@ -80,7 +79,7 @@ export const productImageCreateMutation = gql`
} }
} }
`; `;
export const TypedProductImageCreateMutation = TypedMutation< export const useProductImageCreateMutation = makeMutation<
ProductImageCreate, ProductImageCreate,
ProductImageCreateVariables ProductImageCreateVariables
>(productImageCreateMutation); >(productImageCreateMutation);
@ -98,7 +97,7 @@ export const productDeleteMutation = gql`
} }
} }
`; `;
export const TypedProductDeleteMutation = TypedMutation< export const useProductDeleteMutation = makeMutation<
ProductDelete, ProductDelete,
ProductDeleteVariables ProductDeleteVariables
>(productDeleteMutation); >(productDeleteMutation);
@ -122,7 +121,7 @@ export const productImagesReorder = gql`
} }
} }
`; `;
export const TypedProductImagesReorder = TypedMutation< export const useProductImagesReorder = makeMutation<
ProductImageReorder, ProductImageReorder,
ProductImageReorderVariables ProductImageReorderVariables
>(productImagesReorder); >(productImagesReorder);
@ -167,7 +166,7 @@ export const productUpdateMutation = gql`
} }
} }
`; `;
export const TypedProductUpdateMutation = TypedMutation< export const useProductUpdateMutation = makeMutation<
ProductUpdate, ProductUpdate,
ProductUpdateVariables ProductUpdateVariables
>(productUpdateMutation); >(productUpdateMutation);
@ -263,7 +262,7 @@ export const simpleProductUpdateMutation = gql`
} }
} }
`; `;
export const TypedSimpleProductUpdateMutation = TypedMutation< export const useSimpleProductUpdateMutation = makeMutation<
SimpleProductUpdate, SimpleProductUpdate,
SimpleProductUpdateVariables SimpleProductUpdateVariables
>(simpleProductUpdateMutation); >(simpleProductUpdateMutation);
@ -316,7 +315,7 @@ export const productCreateMutation = gql`
} }
} }
`; `;
export const TypedProductCreateMutation = TypedMutation< export const useProductCreateMutation = makeMutation<
ProductCreate, ProductCreate,
ProductCreateVariables ProductCreateVariables
>(productCreateMutation); >(productCreateMutation);
@ -334,7 +333,7 @@ export const variantDeleteMutation = gql`
} }
} }
`; `;
export const TypedVariantDeleteMutation = TypedMutation< export const useVariantDeleteMutation = makeMutation<
VariantDelete, VariantDelete,
VariantDeleteVariables VariantDeleteVariables
>(variantDeleteMutation); >(variantDeleteMutation);
@ -406,7 +405,7 @@ export const variantUpdateMutation = gql`
} }
} }
`; `;
export const TypedVariantUpdateMutation = TypedMutation< export const useVariantUpdateMutation = makeMutation<
VariantUpdate, VariantUpdate,
VariantUpdateVariables VariantUpdateVariables
>(variantUpdateMutation); >(variantUpdateMutation);
@ -425,7 +424,7 @@ export const variantCreateMutation = gql`
} }
} }
`; `;
export const TypedVariantCreateMutation = TypedMutation< export const useVariantCreateMutation = makeMutation<
VariantCreate, VariantCreate,
VariantCreateVariables VariantCreateVariables
>(variantCreateMutation); >(variantCreateMutation);
@ -446,7 +445,7 @@ export const productImageDeleteMutation = gql`
} }
} }
`; `;
export const TypedProductImageDeleteMutation = TypedMutation< export const useProductImageDeleteMutation = makeMutation<
ProductImageDelete, ProductImageDelete,
ProductImageDeleteVariables ProductImageDeleteVariables
>(productImageDeleteMutation); >(productImageDeleteMutation);
@ -465,7 +464,7 @@ export const productImageUpdateMutation = gql`
} }
} }
`; `;
export const TypedProductImageUpdateMutation = TypedMutation< export const useProductImageUpdateMutation = makeMutation<
ProductImageUpdate, ProductImageUpdate,
ProductImageUpdateVariables ProductImageUpdateVariables
>(productImageUpdateMutation); >(productImageUpdateMutation);
@ -484,7 +483,7 @@ export const variantImageAssignMutation = gql`
} }
} }
`; `;
export const TypedVariantImageAssignMutation = TypedMutation< export const useVariantImageAssignMutation = makeMutation<
VariantImageAssign, VariantImageAssign,
VariantImageAssignVariables VariantImageAssignVariables
>(variantImageAssignMutation); >(variantImageAssignMutation);
@ -503,7 +502,7 @@ export const variantImageUnassignMutation = gql`
} }
} }
`; `;
export const TypedVariantImageUnassignMutation = TypedMutation< export const useVariantImageUnassignMutation = makeMutation<
VariantImageUnassign, VariantImageUnassign,
VariantImageUnassignVariables VariantImageUnassignVariables
>(variantImageUnassignMutation); >(variantImageUnassignMutation);
@ -518,7 +517,7 @@ export const productBulkDeleteMutation = gql`
} }
} }
`; `;
export const TypedProductBulkDeleteMutation = TypedMutation< export const useProductBulkDeleteMutation = makeMutation<
productBulkDelete, productBulkDelete,
productBulkDeleteVariables productBulkDeleteVariables
>(productBulkDeleteMutation); >(productBulkDeleteMutation);
@ -533,7 +532,7 @@ export const productBulkPublishMutation = gql`
} }
} }
`; `;
export const TypedProductBulkPublishMutation = TypedMutation< export const useProductBulkPublishMutation = makeMutation<
productBulkPublish, productBulkPublish,
productBulkPublishVariables productBulkPublishVariables
>(productBulkPublishMutation); >(productBulkPublishMutation);
@ -566,7 +565,7 @@ export const ProductVariantBulkDeleteMutation = gql`
} }
} }
`; `;
export const TypedProductVariantBulkDeleteMutation = TypedMutation< export const useProductVariantBulkDeleteMutation = makeMutation<
ProductVariantBulkDelete, ProductVariantBulkDelete,
ProductVariantBulkDeleteVariables ProductVariantBulkDeleteVariables
>(ProductVariantBulkDeleteMutation); >(ProductVariantBulkDeleteMutation);

View file

@ -174,7 +174,7 @@ const productDetailsQuery = gql`
} }
} }
`; `;
export const TypedProductDetailsQuery = TypedQuery< export const useProductDetails = makeQuery<
ProductDetails, ProductDetails,
ProductDetailsVariables ProductDetailsVariables
>(productDetailsQuery); >(productDetailsQuery);

View file

@ -11,6 +11,15 @@ import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier"; import useNotifier from "@saleor/hooks/useNotifier";
import useShop from "@saleor/hooks/useShop"; import useShop from "@saleor/hooks/useShop";
import { commonMessages } from "@saleor/intl"; import { commonMessages } from "@saleor/intl";
import {
useProductDeleteMutation,
useProductImageCreateMutation,
useProductImageDeleteMutation,
useProductImagesReorder,
useProductUpdateMutation,
useProductVariantBulkDeleteMutation,
useSimpleProductUpdateMutation
} from "@saleor/products/mutations";
import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCategorySearch from "@saleor/searches/useCategorySearch";
import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch";
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
@ -20,14 +29,9 @@ import { FormattedMessage, useIntl } from "react-intl";
import { getMutationState, maybe } from "../../../misc"; import { getMutationState, maybe } from "../../../misc";
import ProductUpdatePage from "../../components/ProductUpdatePage"; import ProductUpdatePage from "../../components/ProductUpdatePage";
import ProductUpdateOperations from "../../containers/ProductUpdateOperations"; import { useProductDetails } from "../../queries";
import { TypedProductDetailsQuery } from "../../queries"; import { ProductImageCreateVariables } from "../../types/ProductImageCreate";
import {
ProductImageCreate,
ProductImageCreateVariables
} from "../../types/ProductImageCreate";
import { ProductUpdate as ProductUpdateMutationResult } from "../../types/ProductUpdate"; import { ProductUpdate as ProductUpdateMutationResult } from "../../types/ProductUpdate";
import { ProductVariantBulkDelete } from "../../types/ProductVariantBulkDelete";
import { import {
productImageUrl, productImageUrl,
productListUrl, productListUrl,
@ -78,31 +82,13 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
}); });
const shop = useShop(); const shop = useShop();
const [openModal, closeModal] = createDialogActionHandlers< const { data, loading, refetch } = useProductDetails({
ProductUrlDialog, displayLoader: true,
ProductUrlQueryParams variables: {
>(navigate, params => productUrl(id, params), params); id
const handleBack = () => navigate(productListUrl());
return (
<TypedProductDetailsQuery displayLoader variables={{ id }}>
{({ data, loading, refetch }) => {
const product = data?.product;
if (product === null) {
return <NotFoundPage onBack={handleBack} />;
} }
const handleDelete = () => {
notify({
status: "success",
text: intl.formatMessage({
defaultMessage: "Product removed"
})
}); });
navigate(productListUrl());
};
const handleUpdate = (data: ProductUpdateMutationResult) => { const handleUpdate = (data: ProductUpdateMutationResult) => {
if (data.productUpdate.errors.length === 0) { if (data.productUpdate.errors.length === 0) {
notify({ notify({
@ -111,11 +97,40 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
}); });
} }
}; };
const [updateProduct, updateProductOpts] = useProductUpdateMutation({
onCompleted: handleUpdate
});
const [
updateSimpleProduct,
updateSimpleProductOpts
] = useSimpleProductUpdateMutation({
onCompleted: handleUpdate
});
const handleImageCreate = (data: ProductImageCreate) => { const [
reorderProductImages,
reorderProductImagesOpts
] = useProductImagesReorder({});
const [deleteProduct, deleteProductOpts] = useProductDeleteMutation({
onCompleted: () => {
notify({
status: "success",
text: intl.formatMessage({
defaultMessage: "Product removed"
})
});
navigate(productListUrl());
}
});
const [
createProductImage,
createProductImageOpts
] = useProductImageCreateMutation({
onCompleted: data => {
const imageError = data.productImageCreate.errors.find( const imageError = data.productImageCreate.errors.find(
error => error => error.field === ("image" as keyof ProductImageCreateVariables)
error.field === ("image" as keyof ProductImageCreateVariables)
); );
if (imageError) { if (imageError) {
notify({ notify({
@ -123,75 +138,73 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
text: intl.formatMessage(commonMessages.somethingWentWrong) text: intl.formatMessage(commonMessages.somethingWentWrong)
}); });
} }
}; }
const handleImageDeleteSuccess = () => });
const [deleteProductImage] = useProductImageDeleteMutation({
onCompleted: () =>
notify({ notify({
status: "success", status: "success",
text: intl.formatMessage(commonMessages.savedChanges) text: intl.formatMessage(commonMessages.savedChanges)
})
}); });
const handleVariantAdd = () => navigate(productVariantAddUrl(id));
const handleBulkProductVariantDelete = ( const [
data: ProductVariantBulkDelete bulkProductVariantDelete,
) => { bulkProductVariantDeleteOpts
] = useProductVariantBulkDeleteMutation({
onCompleted: data => {
if (data.productVariantBulkDelete.errors.length === 0) { if (data.productVariantBulkDelete.errors.length === 0) {
closeModal(); closeModal();
reset(); reset();
refetch(); refetch();
} }
}; }
});
const [openModal, closeModal] = createDialogActionHandlers<
ProductUrlDialog,
ProductUrlQueryParams
>(navigate, params => productUrl(id, params), params);
const handleBack = () => navigate(productListUrl());
const product = data?.product;
if (product === null) {
return <NotFoundPage onBack={handleBack} />;
}
const handleVariantAdd = () => navigate(productVariantAddUrl(id));
return (
<ProductUpdateOperations
product={product}
onBulkProductVariantDelete={handleBulkProductVariantDelete}
onDelete={handleDelete}
onImageCreate={handleImageCreate}
onImageDelete={handleImageDeleteSuccess}
onUpdate={handleUpdate}
>
{({
bulkProductVariantDelete,
createProductImage,
deleteProduct,
deleteProductImage,
reorderProductImages,
updateProduct,
updateSimpleProduct
}) => {
const handleImageDelete = (id: string) => () => const handleImageDelete = (id: string) => () =>
deleteProductImage.mutate({ id }); deleteProductImage({ variables: { id } });
const handleImageEdit = (imageId: string) => () => const handleImageEdit = (imageId: string) => () =>
navigate(productImageUrl(id, imageId)); navigate(productImageUrl(id, imageId));
const handleSubmit = createUpdateHandler( const handleSubmit = createUpdateHandler(
product, product,
updateProduct.mutate, variables => updateProduct({ variables }),
updateSimpleProduct.mutate variables => updateSimpleProduct({ variables })
); );
const handleImageUpload = createImageUploadHandler( const handleImageUpload = createImageUploadHandler(id, variables =>
id, createProductImage({ variables })
createProductImage.mutate
); );
const handleImageReorder = createImageReorderHandler( const handleImageReorder = createImageReorderHandler(product, variables =>
product, reorderProductImages({ variables })
reorderProductImages.mutate
); );
const disableFormSave = const disableFormSave =
createProductImage.opts.loading || createProductImageOpts.loading ||
deleteProduct.opts.loading || deleteProductOpts.loading ||
reorderProductImages.opts.loading || reorderProductImagesOpts.loading ||
updateProduct.opts.loading || updateProductOpts.loading ||
loading; loading;
const formTransitionState = getMutationState( const formTransitionState = getMutationState(
updateProduct.opts.called || updateSimpleProduct.opts.called, updateProductOpts.called || updateSimpleProductOpts.called,
updateProduct.opts.loading || updateSimpleProduct.opts.loading, updateProductOpts.loading || updateSimpleProductOpts.loading,
maybe(() => updateProduct.opts.data.productUpdate.errors), maybe(() => updateProductOpts.data.productUpdate.errors),
maybe(() => updateSimpleProduct.opts.data.productUpdate.errors), maybe(() => updateSimpleProductOpts.data.productUpdate.errors),
maybe( maybe(() => updateSimpleProductOpts.data.productVariantUpdate.errors)
() =>
updateSimpleProduct.opts.data.productVariantUpdate.errors
)
); );
const categories = maybe( const categories = maybe(
@ -203,14 +216,8 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
[] []
).map(edge => edge.node); ).map(edge => edge.node);
const errors = [ const errors = [
...maybe( ...maybe(() => updateProductOpts.data.productUpdate.errors, []),
() => updateProduct.opts.data.productUpdate.errors, ...maybe(() => updateSimpleProductOpts.data.productUpdate.errors, [])
[]
),
...maybe(
() => updateSimpleProduct.opts.data.productUpdate.errors,
[]
)
]; ];
return ( return (
@ -230,9 +237,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
placeholderImage={placeholderImg} placeholderImage={placeholderImg}
product={product} product={product}
warehouses={ warehouses={
warehouses.data?.warehouses.edges.map( warehouses.data?.warehouses.edges.map(edge => edge.node) || []
edge => edge.node
) || []
} }
variants={maybe(() => product.variants)} variants={maybe(() => product.variants)}
onBack={handleBack} onBack={handleBack}
@ -264,16 +269,14 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
toggleAll={toggleAll} toggleAll={toggleAll}
fetchMoreCategories={{ fetchMoreCategories={{
hasMore: maybe( hasMore: maybe(
() => () => searchCategoriesOpts.data.search.pageInfo.hasNextPage
searchCategoriesOpts.data.search.pageInfo.hasNextPage
), ),
loading: searchCategoriesOpts.loading, loading: searchCategoriesOpts.loading,
onFetchMore: loadMoreCategories onFetchMore: loadMoreCategories
}} }}
fetchMoreCollections={{ fetchMoreCollections={{
hasMore: maybe( hasMore: maybe(
() => () => searchCollectionsOpts.data.search.pageInfo.hasNextPage
searchCollectionsOpts.data.search.pageInfo.hasNextPage
), ),
loading: searchCollectionsOpts.loading, loading: searchCollectionsOpts.loading,
onFetchMore: loadMoreCollections onFetchMore: loadMoreCollections
@ -282,8 +285,8 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
<ActionDialog <ActionDialog
open={params.action === "remove"} open={params.action === "remove"}
onClose={closeModal} onClose={closeModal}
confirmButtonState={deleteProduct.opts.status} confirmButtonState={deleteProductOpts.status}
onConfirm={() => deleteProduct.mutate({ id })} onConfirm={() => deleteProduct({ variables: { id } })}
variant="delete" variant="delete"
title={intl.formatMessage({ title={intl.formatMessage({
defaultMessage: "Delete Product", defaultMessage: "Delete Product",
@ -303,10 +306,12 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
<ActionDialog <ActionDialog
open={params.action === "remove-variants"} open={params.action === "remove-variants"}
onClose={closeModal} onClose={closeModal}
confirmButtonState={bulkProductVariantDelete.opts.status} confirmButtonState={bulkProductVariantDeleteOpts.status}
onConfirm={() => onConfirm={() =>
bulkProductVariantDelete.mutate({ bulkProductVariantDelete({
variables: {
ids: params.ids ids: params.ids
}
}) })
} }
variant="delete" variant="delete"
@ -321,20 +326,12 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
description="dialog content" description="dialog content"
values={{ values={{
counter: maybe(() => params.ids.length), counter: maybe(() => params.ids.length),
displayQuantity: ( displayQuantity: <strong>{maybe(() => params.ids.length)}</strong>
<strong>{maybe(() => params.ids.length)}</strong>
)
}} }}
/> />
</DialogContentText> </DialogContentText>
</ActionDialog> </ActionDialog>
</> </>
); );
}}
</ProductUpdateOperations>
);
}}
</TypedProductDetailsQuery>
);
}; };
export default ProductUpdate; export default ProductUpdate;