import Button from "@material-ui/core/Button"; import DialogContentText from "@material-ui/core/DialogContentText"; import * as React from "react"; import ActionDialog from "@saleor/components/ActionDialog"; import AssignProductDialog from "@saleor/components/AssignProductDialog"; import { WindowTitle } from "@saleor/components/WindowTitle"; import useBulkActions from "@saleor/hooks/useBulkActions"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import usePaginator, { createPaginationState } from "@saleor/hooks/usePaginator"; import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "../../config"; import SearchProducts from "../../containers/SearchProducts"; import i18n from "../../i18n"; import { getMutationState, maybe } from "../../misc"; import { productUrl } from "../../products/urls"; import { CollectionInput } from "../../types/globalTypes"; import CollectionDetailsPage, { CollectionDetailsPageFormData } from "../components/CollectionDetailsPage/CollectionDetailsPage"; import CollectionOperations from "../containers/CollectionOperations"; import { TypedCollectionDetailsQuery } from "../queries"; import { CollectionAssignProduct } from "../types/CollectionAssignProduct"; import { CollectionUpdate } from "../types/CollectionUpdate"; import { RemoveCollection } from "../types/RemoveCollection"; import { UnassignCollectionProduct } from "../types/UnassignCollectionProduct"; import { collectionListUrl, collectionUrl, CollectionUrlDialog, CollectionUrlQueryParams } from "../urls"; interface CollectionDetailsProps { id: string; params: CollectionUrlQueryParams; } export const CollectionDetails: React.StatelessComponent< CollectionDetailsProps > = ({ id, params }) => { const navigate = useNavigator(); const notify = useNotifier(); const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions( params.ids ); const paginate = usePaginator(); const closeModal = () => navigate( collectionUrl(id, { ...params, action: undefined }), true ); const openModal = (action: CollectionUrlDialog) => navigate( collectionUrl(id, { ...params, action }), false ); const paginationState = createPaginationState(PAGINATE_BY, params); return ( {({ data, loading }) => { const handleCollectionUpdate = (data: CollectionUpdate) => { if (data.collectionUpdate.errors.length === 0) { notify({ text: i18n.t("Updated collection", { context: "notification" }) }); navigate(collectionUrl(id)); } else { const backgroundImageError = data.collectionUpdate.errors.find( error => error.field === ("backgroundImage" as keyof CollectionInput) ); if (backgroundImageError) { notify({ text: backgroundImageError.message }); } } }; const handleProductAssign = (data: CollectionAssignProduct) => { if (data.collectionAddProducts.errors.length === 0) { notify({ text: i18n.t("Added product to collection", { context: "notification" }) }); navigate(collectionUrl(id), true); } }; const handleProductUnassign = (data: UnassignCollectionProduct) => { if (data.collectionRemoveProducts.errors.length === 0) { notify({ text: i18n.t("Removed product from collection", { context: "notification" }) }); reset(); closeModal(); } }; const handleCollectionRemove = (data: RemoveCollection) => { if (data.collectionDelete.errors.length === 0) { notify({ text: i18n.t("Removed collection", { context: "notification" }) }); navigate(collectionListUrl()); } }; return ( {({ updateCollection, updateCollectionWithHomepage, assignProduct, unassignProduct, removeCollection }) => { const handleSubmit = ( formData: CollectionDetailsPageFormData ) => { const input: CollectionInput = { backgroundImageAlt: formData.backgroundImageAlt, descriptionJson: JSON.stringify(formData.description), isPublished: formData.isPublished, name: formData.name, publicationDate: formData.publicationDate, seo: { description: formData.seoDescription, title: formData.seoTitle } }; const isFeatured = data.shop.homepageCollection ? data.shop.homepageCollection.id === data.collection.id : false; if (formData.isFeatured !== isFeatured) { updateCollectionWithHomepage.mutate({ homepageId: formData.isFeatured ? id : null, id, input }); } else { updateCollection.mutate({ id, input }); } }; const formTransitionState = getMutationState( updateCollection.opts.called || updateCollectionWithHomepage.opts.called, updateCollection.opts.loading || updateCollectionWithHomepage.opts.loading, maybe(() => updateCollection.opts.data.collectionUpdate.errors), maybe( () => updateCollectionWithHomepage.opts.data.collectionUpdate .errors ), maybe( () => updateCollectionWithHomepage.opts.data .homepageCollectionUpdate.errors ) ); const assignTransitionState = getMutationState( assignProduct.opts.called, assignProduct.opts.loading, maybe( () => assignProduct.opts.data.collectionAddProducts.errors ) ); const unassignTransitionState = getMutationState( unassignProduct.opts.called, unassignProduct.opts.loading, maybe( () => unassignProduct.opts.data.collectionRemoveProducts.errors ) ); const removeTransitionState = getMutationState( removeCollection.opts.called, removeCollection.opts.loading, maybe(() => removeCollection.opts.data.collectionDelete.errors) ); const imageRemoveTransitionState = getMutationState( updateCollection.opts.called, updateCollection.opts.loading, maybe(() => updateCollection.opts.data.collectionUpdate.errors) ); const { loadNextPage, loadPreviousPage, pageInfo } = paginate( maybe(() => data.collection.products.pageInfo), paginationState, params ); return ( <> data.collection.name)} /> openModal("assign")} onBack={() => navigate(collectionListUrl())} disabled={loading} collection={data.collection} isFeatured={maybe( () => data.shop.homepageCollection.id === data.collection.id, false )} onCollectionRemove={() => openModal("remove")} onImageDelete={() => openModal("removeImage")} onImageUpload={file => updateCollection.mutate({ id, input: { backgroundImage: file } }) } onSubmit={handleSubmit} onNextPage={loadNextPage} onPreviousPage={loadPreviousPage} pageInfo={pageInfo} onProductUnassign={(productId, event) => { event.stopPropagation(); unassignProduct.mutate({ collectionId: id, productIds: [productId], ...paginationState }); }} onRowClick={id => () => navigate(productUrl(id))} saveButtonBarState={formTransitionState} toolbar={ } isChecked={isSelected} selected={listElements.length} toggle={toggle} toggleAll={toggleAll} /> {({ search, result }) => ( navigate(collectionUrl(id), true, true)} onSubmit={formData => assignProduct.mutate({ ...paginationState, collectionId: id, productIds: formData.products.map( product => product.id ) }) } products={maybe(() => result.data.products.edges .map(edge => edge.node) .filter(suggestedProduct => suggestedProduct.id) )} /> )} removeCollection.mutate({ id })} open={params.action === "remove"} title={i18n.t("Remove collection", { context: "modal title" })} variant="delete" > {{ collectionName }}?", { collectionName: maybe( () => data.collection.name, "..." ), context: "modal" } ) }} /> unassignProduct.mutate({ ...paginationState, collectionId: id, productIds: params.ids }) } open={params.action === "unassign"} title={i18n.t("Unassign products from collection", { context: "modal title" })} > {{ number }} products?", { context: "modal", number: maybe( () => params.ids.length.toString(), "..." ) } ) }} /> updateCollection.mutate({ id, input: { backgroundImage: null } }) } open={params.action === "removeImage"} title={i18n.t("Remove image", { context: "modal title" })} variant="delete" > {i18n.t( "Are you sure you want to remove collection's image?" )} ); }} ); }} ); }; export default CollectionDetails;