diff --git a/src/products/containers/ProductUpdateOperations.tsx b/src/products/containers/ProductUpdateOperations.tsx deleted file mode 100644 index a2e79a952..000000000 --- a/src/products/containers/ProductUpdateOperations.tsx +++ /dev/null @@ -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 = ({ - product, - children, - onBulkProductVariantDelete, - onDelete, - onImageDelete, - onImageCreate, - onImageReorder, - onUpdate -}) => { - const productId = product ? product.id : ""; - return ( - - {(...updateProduct) => ( - product.images, [])} - onCompleted={onImageReorder} - > - {(...reorderProductImages) => ( - - {(...createProductImage) => ( - - {(...deleteProduct) => ( - - {(...deleteProductImage) => ( - - {(...updateSimpleProduct) => ( - - {(...bulkProductVariantDelete) => - children({ - bulkProductVariantDelete: getMutationProviderData( - ...bulkProductVariantDelete - ), - createProductImage: getMutationProviderData( - ...createProductImage - ), - deleteProduct: getMutationProviderData( - ...deleteProduct - ), - deleteProductImage: getMutationProviderData( - ...deleteProductImage - ), - reorderProductImages: getMutationProviderData( - ...reorderProductImages - ), - updateProduct: getMutationProviderData( - ...updateProduct - ), - updateSimpleProduct: getMutationProviderData( - ...updateSimpleProduct - ) - }) - } - - )} - - )} - - )} - - )} - - )} - - )} - - ); -}; -export default ProductUpdateOperations; diff --git a/src/products/mutations.ts b/src/products/mutations.ts index 7a8927b9e..87dbe40b4 100644 --- a/src/products/mutations.ts +++ b/src/products/mutations.ts @@ -13,7 +13,6 @@ import { import makeMutation from "@saleor/hooks/makeMutation"; import gql from "graphql-tag"; -import { TypedMutation } from "../mutations"; import { productBulkDelete, productBulkDeleteVariables @@ -80,7 +79,7 @@ export const productImageCreateMutation = gql` } } `; -export const TypedProductImageCreateMutation = TypedMutation< +export const useProductImageCreateMutation = makeMutation< ProductImageCreate, ProductImageCreateVariables >(productImageCreateMutation); @@ -98,7 +97,7 @@ export const productDeleteMutation = gql` } } `; -export const TypedProductDeleteMutation = TypedMutation< +export const useProductDeleteMutation = makeMutation< ProductDelete, ProductDeleteVariables >(productDeleteMutation); @@ -122,7 +121,7 @@ export const productImagesReorder = gql` } } `; -export const TypedProductImagesReorder = TypedMutation< +export const useProductImagesReorder = makeMutation< ProductImageReorder, ProductImageReorderVariables >(productImagesReorder); @@ -167,7 +166,7 @@ export const productUpdateMutation = gql` } } `; -export const TypedProductUpdateMutation = TypedMutation< +export const useProductUpdateMutation = makeMutation< ProductUpdate, ProductUpdateVariables >(productUpdateMutation); @@ -263,7 +262,7 @@ export const simpleProductUpdateMutation = gql` } } `; -export const TypedSimpleProductUpdateMutation = TypedMutation< +export const useSimpleProductUpdateMutation = makeMutation< SimpleProductUpdate, SimpleProductUpdateVariables >(simpleProductUpdateMutation); @@ -316,7 +315,7 @@ export const productCreateMutation = gql` } } `; -export const TypedProductCreateMutation = TypedMutation< +export const useProductCreateMutation = makeMutation< ProductCreate, ProductCreateVariables >(productCreateMutation); @@ -334,7 +333,7 @@ export const variantDeleteMutation = gql` } } `; -export const TypedVariantDeleteMutation = TypedMutation< +export const useVariantDeleteMutation = makeMutation< VariantDelete, VariantDeleteVariables >(variantDeleteMutation); @@ -406,7 +405,7 @@ export const variantUpdateMutation = gql` } } `; -export const TypedVariantUpdateMutation = TypedMutation< +export const useVariantUpdateMutation = makeMutation< VariantUpdate, VariantUpdateVariables >(variantUpdateMutation); @@ -425,7 +424,7 @@ export const variantCreateMutation = gql` } } `; -export const TypedVariantCreateMutation = TypedMutation< +export const useVariantCreateMutation = makeMutation< VariantCreate, VariantCreateVariables >(variantCreateMutation); @@ -446,7 +445,7 @@ export const productImageDeleteMutation = gql` } } `; -export const TypedProductImageDeleteMutation = TypedMutation< +export const useProductImageDeleteMutation = makeMutation< ProductImageDelete, ProductImageDeleteVariables >(productImageDeleteMutation); @@ -465,7 +464,7 @@ export const productImageUpdateMutation = gql` } } `; -export const TypedProductImageUpdateMutation = TypedMutation< +export const useProductImageUpdateMutation = makeMutation< ProductImageUpdate, ProductImageUpdateVariables >(productImageUpdateMutation); @@ -484,7 +483,7 @@ export const variantImageAssignMutation = gql` } } `; -export const TypedVariantImageAssignMutation = TypedMutation< +export const useVariantImageAssignMutation = makeMutation< VariantImageAssign, VariantImageAssignVariables >(variantImageAssignMutation); @@ -503,7 +502,7 @@ export const variantImageUnassignMutation = gql` } } `; -export const TypedVariantImageUnassignMutation = TypedMutation< +export const useVariantImageUnassignMutation = makeMutation< VariantImageUnassign, VariantImageUnassignVariables >(variantImageUnassignMutation); @@ -518,7 +517,7 @@ export const productBulkDeleteMutation = gql` } } `; -export const TypedProductBulkDeleteMutation = TypedMutation< +export const useProductBulkDeleteMutation = makeMutation< productBulkDelete, productBulkDeleteVariables >(productBulkDeleteMutation); @@ -533,7 +532,7 @@ export const productBulkPublishMutation = gql` } } `; -export const TypedProductBulkPublishMutation = TypedMutation< +export const useProductBulkPublishMutation = makeMutation< productBulkPublish, productBulkPublishVariables >(productBulkPublishMutation); @@ -566,7 +565,7 @@ export const ProductVariantBulkDeleteMutation = gql` } } `; -export const TypedProductVariantBulkDeleteMutation = TypedMutation< +export const useProductVariantBulkDeleteMutation = makeMutation< ProductVariantBulkDelete, ProductVariantBulkDeleteVariables >(ProductVariantBulkDeleteMutation); diff --git a/src/products/queries.ts b/src/products/queries.ts index 80d5d8a1f..4eab8904b 100644 --- a/src/products/queries.ts +++ b/src/products/queries.ts @@ -174,7 +174,7 @@ const productDetailsQuery = gql` } } `; -export const TypedProductDetailsQuery = TypedQuery< +export const useProductDetails = makeQuery< ProductDetails, ProductDetailsVariables >(productDetailsQuery); diff --git a/src/products/views/ProductUpdate/ProductUpdate.tsx b/src/products/views/ProductUpdate/ProductUpdate.tsx index 77b4ea440..e25e4df6b 100644 --- a/src/products/views/ProductUpdate/ProductUpdate.tsx +++ b/src/products/views/ProductUpdate/ProductUpdate.tsx @@ -11,6 +11,15 @@ import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import useShop from "@saleor/hooks/useShop"; import { commonMessages } from "@saleor/intl"; +import { + useProductDeleteMutation, + useProductImageCreateMutation, + useProductImageDeleteMutation, + useProductImagesReorder, + useProductUpdateMutation, + useProductVariantBulkDeleteMutation, + useSimpleProductUpdateMutation +} from "@saleor/products/mutations"; import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; @@ -20,14 +29,9 @@ import { FormattedMessage, useIntl } from "react-intl"; import { getMutationState, maybe } from "../../../misc"; import ProductUpdatePage from "../../components/ProductUpdatePage"; -import ProductUpdateOperations from "../../containers/ProductUpdateOperations"; -import { TypedProductDetailsQuery } from "../../queries"; -import { - ProductImageCreate, - ProductImageCreateVariables -} from "../../types/ProductImageCreate"; +import { useProductDetails } from "../../queries"; +import { ProductImageCreateVariables } from "../../types/ProductImageCreate"; import { ProductUpdate as ProductUpdateMutationResult } from "../../types/ProductUpdate"; -import { ProductVariantBulkDelete } from "../../types/ProductVariantBulkDelete"; import { productImageUrl, productListUrl, @@ -78,6 +82,86 @@ export const ProductUpdate: React.FC = ({ id, params }) => { }); const shop = useShop(); + const { data, loading, refetch } = useProductDetails({ + displayLoader: true, + variables: { + id + } + }); + + const handleUpdate = (data: ProductUpdateMutationResult) => { + if (data.productUpdate.errors.length === 0) { + notify({ + status: "success", + text: intl.formatMessage(commonMessages.savedChanges) + }); + } + }; + const [updateProduct, updateProductOpts] = useProductUpdateMutation({ + onCompleted: handleUpdate + }); + const [ + updateSimpleProduct, + updateSimpleProductOpts + ] = useSimpleProductUpdateMutation({ + onCompleted: handleUpdate + }); + + 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( + error => error.field === ("image" as keyof ProductImageCreateVariables) + ); + if (imageError) { + notify({ + status: "error", + text: intl.formatMessage(commonMessages.somethingWentWrong) + }); + } + } + }); + + const [deleteProductImage] = useProductImageDeleteMutation({ + onCompleted: () => + notify({ + status: "success", + text: intl.formatMessage(commonMessages.savedChanges) + }) + }); + + const [ + bulkProductVariantDelete, + bulkProductVariantDeleteOpts + ] = useProductVariantBulkDeleteMutation({ + onCompleted: data => { + if (data.productVariantBulkDelete.errors.length === 0) { + closeModal(); + reset(); + refetch(); + } + } + }); + const [openModal, closeModal] = createDialogActionHandlers< ProductUrlDialog, ProductUrlQueryParams @@ -85,256 +169,169 @@ export const ProductUpdate: React.FC = ({ id, params }) => { const handleBack = () => navigate(productListUrl()); + const product = data?.product; + + if (product === null) { + return ; + } + + const handleVariantAdd = () => navigate(productVariantAddUrl(id)); + + const handleImageDelete = (id: string) => () => + deleteProductImage({ variables: { id } }); + const handleImageEdit = (imageId: string) => () => + navigate(productImageUrl(id, imageId)); + const handleSubmit = createUpdateHandler( + product, + variables => updateProduct({ variables }), + variables => updateSimpleProduct({ variables }) + ); + const handleImageUpload = createImageUploadHandler(id, variables => + createProductImage({ variables }) + ); + const handleImageReorder = createImageReorderHandler(product, variables => + reorderProductImages({ variables }) + ); + + const disableFormSave = + createProductImageOpts.loading || + deleteProductOpts.loading || + reorderProductImagesOpts.loading || + updateProductOpts.loading || + loading; + const formTransitionState = getMutationState( + updateProductOpts.called || updateSimpleProductOpts.called, + updateProductOpts.loading || updateSimpleProductOpts.loading, + maybe(() => updateProductOpts.data.productUpdate.errors), + maybe(() => updateSimpleProductOpts.data.productUpdate.errors), + maybe(() => updateSimpleProductOpts.data.productVariantUpdate.errors) + ); + + const categories = maybe( + () => searchCategoriesOpts.data.search.edges, + [] + ).map(edge => edge.node); + const collections = maybe( + () => searchCollectionsOpts.data.search.edges, + [] + ).map(edge => edge.node); + const errors = [ + ...maybe(() => updateProductOpts.data.productUpdate.errors, []), + ...maybe(() => updateSimpleProductOpts.data.productUpdate.errors, []) + ]; + return ( - - {({ data, loading, refetch }) => { - const product = data?.product; - - if (product === null) { - return ; + <> + data.product.name)} /> + data.product.images)} + header={maybe(() => product.name)} + placeholderImage={placeholderImg} + product={product} + warehouses={ + warehouses.data?.warehouses.edges.map(edge => edge.node) || [] } - - const handleDelete = () => { - notify({ - status: "success", - text: intl.formatMessage({ - defaultMessage: "Product removed" - }) - }); - navigate(productListUrl()); - }; - const handleUpdate = (data: ProductUpdateMutationResult) => { - if (data.productUpdate.errors.length === 0) { - notify({ - status: "success", - text: intl.formatMessage(commonMessages.savedChanges) - }); - } - }; - - const handleImageCreate = (data: ProductImageCreate) => { - const imageError = data.productImageCreate.errors.find( - error => - error.field === ("image" as keyof ProductImageCreateVariables) - ); - if (imageError) { - notify({ - status: "error", - text: intl.formatMessage(commonMessages.somethingWentWrong) - }); - } - }; - const handleImageDeleteSuccess = () => - notify({ - status: "success", - text: intl.formatMessage(commonMessages.savedChanges) - }); - const handleVariantAdd = () => navigate(productVariantAddUrl(id)); - - const handleBulkProductVariantDelete = ( - data: ProductVariantBulkDelete - ) => { - if (data.productVariantBulkDelete.errors.length === 0) { - closeModal(); - reset(); - refetch(); - } - }; - - return ( - product.variants)} + onBack={handleBack} + onDelete={() => openModal("remove")} + onImageReorder={handleImageReorder} + onSubmit={handleSubmit} + onVariantAdd={handleVariantAdd} + onVariantsAdd={() => navigate(productVariantCreatorUrl(id))} + onVariantShow={variantId => () => + navigate(productVariantEditUrl(product.id, variantId))} + onImageUpload={handleImageUpload} + onImageEdit={handleImageEdit} + onImageDelete={handleImageDelete} + toolbar={ + + openModal("remove-variants", { + ids: listElements + }) + } > - {({ - bulkProductVariantDelete, - createProductImage, - deleteProduct, - deleteProductImage, - reorderProductImages, - updateProduct, - updateSimpleProduct - }) => { - const handleImageDelete = (id: string) => () => - deleteProductImage.mutate({ id }); - const handleImageEdit = (imageId: string) => () => - navigate(productImageUrl(id, imageId)); - const handleSubmit = createUpdateHandler( - product, - updateProduct.mutate, - updateSimpleProduct.mutate - ); - const handleImageUpload = createImageUploadHandler( - id, - createProductImage.mutate - ); - const handleImageReorder = createImageReorderHandler( - product, - reorderProductImages.mutate - ); - - const disableFormSave = - createProductImage.opts.loading || - deleteProduct.opts.loading || - reorderProductImages.opts.loading || - updateProduct.opts.loading || - loading; - const formTransitionState = getMutationState( - updateProduct.opts.called || updateSimpleProduct.opts.called, - updateProduct.opts.loading || updateSimpleProduct.opts.loading, - maybe(() => updateProduct.opts.data.productUpdate.errors), - maybe(() => updateSimpleProduct.opts.data.productUpdate.errors), - maybe( - () => - updateSimpleProduct.opts.data.productVariantUpdate.errors - ) - ); - - const categories = maybe( - () => searchCategoriesOpts.data.search.edges, - [] - ).map(edge => edge.node); - const collections = maybe( - () => searchCollectionsOpts.data.search.edges, - [] - ).map(edge => edge.node); - const errors = [ - ...maybe( - () => updateProduct.opts.data.productUpdate.errors, - [] - ), - ...maybe( - () => updateSimpleProduct.opts.data.productUpdate.errors, - [] - ) - ]; - - return ( - <> - data.product.name)} /> - data.product.images)} - header={maybe(() => product.name)} - placeholderImage={placeholderImg} - product={product} - warehouses={ - warehouses.data?.warehouses.edges.map( - edge => edge.node - ) || [] - } - variants={maybe(() => product.variants)} - onBack={handleBack} - onDelete={() => openModal("remove")} - onImageReorder={handleImageReorder} - onSubmit={handleSubmit} - onVariantAdd={handleVariantAdd} - onVariantsAdd={() => navigate(productVariantCreatorUrl(id))} - onVariantShow={variantId => () => - navigate(productVariantEditUrl(product.id, variantId))} - onImageUpload={handleImageUpload} - onImageEdit={handleImageEdit} - onImageDelete={handleImageDelete} - toolbar={ - - openModal("remove-variants", { - ids: listElements - }) - } - > - - - } - isChecked={isSelected} - selected={listElements.length} - toggle={toggle} - toggleAll={toggleAll} - fetchMoreCategories={{ - hasMore: maybe( - () => - searchCategoriesOpts.data.search.pageInfo.hasNextPage - ), - loading: searchCategoriesOpts.loading, - onFetchMore: loadMoreCategories - }} - fetchMoreCollections={{ - hasMore: maybe( - () => - searchCollectionsOpts.data.search.pageInfo.hasNextPage - ), - loading: searchCollectionsOpts.loading, - onFetchMore: loadMoreCollections - }} - /> - deleteProduct.mutate({ id })} - variant="delete" - title={intl.formatMessage({ - defaultMessage: "Delete Product", - description: "dialog header" - })} - > - - - - - - bulkProductVariantDelete.mutate({ - ids: params.ids - }) - } - variant="delete" - title={intl.formatMessage({ - defaultMessage: "Delete Product Variants", - description: "dialog header" - })} - > - - params.ids.length), - displayQuantity: ( - {maybe(() => params.ids.length)} - ) - }} - /> - - - - ); + + + } + isChecked={isSelected} + selected={listElements.length} + toggle={toggle} + toggleAll={toggleAll} + fetchMoreCategories={{ + hasMore: maybe( + () => searchCategoriesOpts.data.search.pageInfo.hasNextPage + ), + loading: searchCategoriesOpts.loading, + onFetchMore: loadMoreCategories + }} + fetchMoreCollections={{ + hasMore: maybe( + () => searchCollectionsOpts.data.search.pageInfo.hasNextPage + ), + loading: searchCollectionsOpts.loading, + onFetchMore: loadMoreCollections + }} + /> + deleteProduct({ variables: { id } })} + variant="delete" + title={intl.formatMessage({ + defaultMessage: "Delete Product", + description: "dialog header" + })} + > + + - ); - }} - + /> + + + + bulkProductVariantDelete({ + variables: { + ids: params.ids + } + }) + } + variant="delete" + title={intl.formatMessage({ + defaultMessage: "Delete Product Variants", + description: "dialog header" + })} + > + + params.ids.length), + displayQuantity: {maybe(() => params.ids.length)} + }} + /> + + + ); }; export default ProductUpdate;