2019-06-19 14:40:52 +00:00
import Button from "@material-ui/core/Button" ;
import DialogContentText from "@material-ui/core/DialogContentText" ;
2019-08-09 10:26:22 +00:00
import React from "react" ;
2019-08-21 12:31:55 +00:00
import { FormattedMessage , useIntl } from "react-intl" ;
2019-06-19 14:40:52 +00:00
import ActionDialog from "@saleor/components/ActionDialog" ;
import AssignProductDialog from "@saleor/components/AssignProductDialog" ;
import { WindowTitle } from "@saleor/components/WindowTitle" ;
2019-11-21 14:59:06 +00:00
import { DEFAULT_INITIAL_SEARCH_DATA , PAGINATE_BY } from "@saleor/config" ;
2019-06-19 14:40:52 +00:00
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" ;
2019-08-21 12:31:55 +00:00
import { commonMessages } from "@saleor/intl" ;
2019-11-19 16:50:40 +00:00
import useProductSearch from "@saleor/searches/useProductSearch" ;
2019-12-06 14:58:28 +00:00
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers" ;
2020-02-20 14:18:22 +00:00
import NotFoundPage from "@saleor/components/NotFoundPage" ;
2019-06-19 14:40:52 +00:00
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 ,
2019-12-06 14:58:28 +00:00
CollectionUrlQueryParams ,
CollectionUrlDialog
2019-06-19 14:40:52 +00:00
} from "../urls" ;
2020-03-05 17:48:54 +00:00
import { CollectionUpdateWithHomepage } from "../types/CollectionUpdateWithHomepage" ;
2019-06-19 14:40:52 +00:00
interface CollectionDetailsProps {
id : string ;
params : CollectionUrlQueryParams ;
}
2019-11-07 11:34:54 +00:00
export const CollectionDetails : React.FC < CollectionDetailsProps > = ( {
id ,
params
} ) = > {
2019-06-19 14:40:52 +00:00
const navigate = useNavigator ( ) ;
const notify = useNotifier ( ) ;
const { isSelected , listElements , reset , toggle , toggleAll } = useBulkActions (
params . ids
) ;
const paginate = usePaginator ( ) ;
2019-08-21 12:31:55 +00:00
const intl = useIntl ( ) ;
2019-11-19 16:50:40 +00:00
const { search , result } = useProductSearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-06-19 14:40:52 +00:00
2019-12-06 14:58:28 +00:00
const [ openModal , closeModal ] = createDialogActionHandlers <
CollectionUrlDialog ,
CollectionUrlQueryParams
> ( navigate , params = > collectionUrl ( id , params ) , params ) ;
2019-06-19 14:40:52 +00:00
const paginationState = createPaginationState ( PAGINATE_BY , params ) ;
2020-02-20 14:18:22 +00:00
const handleBack = ( ) = > navigate ( collectionListUrl ( ) ) ;
2019-06-19 14:40:52 +00:00
return (
< TypedCollectionDetailsQuery
displayLoader
variables = { { id , . . . paginationState } }
>
{ ( { data , loading } ) = > {
2020-02-20 14:18:22 +00:00
const collection = data ? . collection ;
if ( collection === null ) {
return < NotFoundPage onBack = { handleBack } / > ;
}
2019-06-19 14:40:52 +00:00
const handleCollectionUpdate = ( data : CollectionUpdate ) = > {
if ( data . collectionUpdate . errors . length === 0 ) {
notify ( {
2019-08-21 12:31:55 +00:00
text : intl.formatMessage ( commonMessages . savedChanges )
2019-06-19 14:40:52 +00:00
} ) ;
navigate ( collectionUrl ( id ) ) ;
} else {
const backgroundImageError = data . collectionUpdate . errors . find (
error = >
error . field === ( "backgroundImage" as keyof CollectionInput )
) ;
if ( backgroundImageError ) {
notify ( {
2020-03-05 14:59:55 +00:00
text : intl.formatMessage ( commonMessages . somethingWentWrong )
2019-06-19 14:40:52 +00:00
} ) ;
}
}
} ;
2020-03-05 17:48:54 +00:00
const handleCollectioUpdateWithHomepage = (
data : CollectionUpdateWithHomepage
) = > {
if ( data . homepageCollectionUpdate . errors . length === 0 ) {
handleCollectionUpdate ( data ) ;
}
} ;
2019-06-19 14:40:52 +00:00
const handleProductAssign = ( data : CollectionAssignProduct ) = > {
if ( data . collectionAddProducts . errors . length === 0 ) {
notify ( {
2019-08-21 12:31:55 +00:00
text : intl.formatMessage ( {
2019-08-22 16:19:16 +00:00
defaultMessage : "Added product to collection"
2019-06-19 14:40:52 +00:00
} )
} ) ;
navigate ( collectionUrl ( id ) , true ) ;
}
} ;
const handleProductUnassign = ( data : UnassignCollectionProduct ) = > {
if ( data . collectionRemoveProducts . errors . length === 0 ) {
notify ( {
2019-08-21 12:31:55 +00:00
text : intl.formatMessage ( {
2019-08-22 16:19:16 +00:00
defaultMessage : "Deleted product from collection"
2019-06-19 14:40:52 +00:00
} )
} ) ;
reset ( ) ;
closeModal ( ) ;
}
} ;
const handleCollectionRemove = ( data : RemoveCollection ) = > {
if ( data . collectionDelete . errors . length === 0 ) {
notify ( {
2019-08-21 12:31:55 +00:00
text : intl.formatMessage ( {
2019-08-22 16:19:16 +00:00
defaultMessage : "Deleted collection"
2019-06-19 14:40:52 +00:00
} )
} ) ;
navigate ( collectionListUrl ( ) ) ;
}
} ;
return (
< CollectionOperations
onUpdate = { handleCollectionUpdate }
2020-03-05 17:48:54 +00:00
onUpdateWithCollection = { handleCollectioUpdateWithHomepage }
2019-06-19 14:40:52 +00:00
onProductAssign = { handleProductAssign }
onProductUnassign = { handleProductUnassign }
onRemove = { handleCollectionRemove }
>
{ ( {
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 { loadNextPage , loadPreviousPage , pageInfo } = paginate (
maybe ( ( ) = > data . collection . products . pageInfo ) ,
paginationState ,
params
) ;
return (
< >
< WindowTitle title = { maybe ( ( ) = > data . collection . name ) } / >
< CollectionDetailsPage
onAdd = { ( ) = > openModal ( "assign" ) }
2020-02-20 14:18:22 +00:00
onBack = { handleBack }
2019-06-19 14:40:52 +00:00
disabled = { loading }
2020-03-05 14:59:55 +00:00
collection = { data ? . collection }
2020-02-24 14:14:48 +00:00
errors = {
updateCollection . opts ? . data ? . collectionUpdate . errors || [ ]
}
2019-06-19 14:40:52 +00:00
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 = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-21 12:31:55 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign product from collection, button"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
isChecked = { isSelected }
selected = { listElements . length }
toggle = { toggle }
toggleAll = { toggleAll }
/ >
2019-11-19 16:50:40 +00:00
< AssignProductDialog
2019-12-06 17:17:44 +00:00
confirmButtonState = { assignProduct . opts . status }
2019-11-19 16:50:40 +00:00
open = { params . action === "assign" }
onFetch = { search }
loading = { result . loading }
onClose = { closeModal }
onSubmit = { products = >
assignProduct . mutate ( {
. . . paginationState ,
collectionId : id ,
productIds : products.map ( product = > product . id )
} )
}
products = { maybe ( ( ) = >
result . data . search . edges
. map ( edge = > edge . node )
. filter ( suggestedProduct = > suggestedProduct . id )
2019-06-19 14:40:52 +00:00
) }
2019-11-19 16:50:40 +00:00
/ >
2019-06-19 14:40:52 +00:00
< ActionDialog
2019-12-06 17:17:44 +00:00
confirmButtonState = { removeCollection . opts . status }
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = > removeCollection . mutate ( { id } ) }
open = { params . action === "remove" }
2019-08-21 12:31:55 +00:00
title = { intl . formatMessage ( {
defaultMessage : "Delete Collection" ,
2019-08-22 16:19:16 +00:00
description : "dialog title"
2019-06-19 14:40:52 +00:00
} ) }
variant = "delete"
>
2019-08-21 12:31:55 +00:00
< DialogContentText >
< FormattedMessage
defaultMessage = "Are you sure you want to delete {collectionName}?"
values = { {
collectionName : (
< strong >
{ maybe ( ( ) = > data . collection . name , "..." ) }
< / strong >
)
} }
/ >
< / DialogContentText >
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-12-06 17:17:44 +00:00
confirmButtonState = { unassignProduct . opts . status }
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
unassignProduct . mutate ( {
. . . paginationState ,
collectionId : id ,
productIds : params.ids
} )
}
open = { params . action === "unassign" }
2019-08-21 12:31:55 +00:00
title = { intl . formatMessage ( {
defaultMessage : "Unassign products from collection" ,
2019-08-22 16:19:16 +00:00
description : "dialog title"
2019-06-19 14:40:52 +00:00
} ) }
>
2019-08-21 12:31:55 +00:00
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this product?} other{Are you sure you want to unassign {displayQuantity} products?}}"
2019-08-21 12:31:55 +00:00
values = { {
2019-08-21 12:44:29 +00:00
counter : maybe ( ( ) = > params . ids . length ) ,
displayQuantity : (
< strong > { maybe ( ( ) = > params . ids . length ) } < / strong >
)
2019-08-21 12:31:55 +00:00
} }
/ >
< / DialogContentText >
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-12-06 17:17:44 +00:00
confirmButtonState = { updateCollection . opts . status }
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
updateCollection . mutate ( {
id ,
input : {
backgroundImage : null
}
} )
}
open = { params . action === "removeImage" }
2019-08-21 12:31:55 +00:00
title = { intl . formatMessage ( {
defaultMessage : "Delete image" ,
2019-08-22 16:19:16 +00:00
description : "dialog title"
2019-06-19 14:40:52 +00:00
} ) }
variant = "delete"
>
< DialogContentText >
2019-08-22 16:19:16 +00:00
< FormattedMessage defaultMessage = "Are you sure you want to delete collection's image?" / >
2019-06-19 14:40:52 +00:00
< / DialogContentText >
< / ActionDialog >
< / >
) ;
} }
< / CollectionOperations >
) ;
} }
< / TypedCollectionDetailsQuery >
) ;
} ;
export default CollectionDetails ;