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-26 13:59:32 +00:00
import { FormattedMessage , useIntl } from "react-intl" ;
2019-06-19 14:40:52 +00:00
import ActionDialog from "@saleor/components/ActionDialog" ;
import AssignCategoriesDialog from "@saleor/components/AssignCategoryDialog" ;
import AssignCollectionDialog from "@saleor/components/AssignCollectionDialog" ;
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" ;
import useShop from "@saleor/hooks/useShop" ;
2019-08-26 13:59:32 +00:00
import { commonMessages , sectionNames } from "@saleor/intl" ;
2019-11-19 15:47:12 +00:00
import useCategorySearch from "@saleor/searches/useCategorySearch" ;
2019-11-19 16:04:53 +00:00
import useCollectionSearch from "@saleor/searches/useCollectionSearch" ;
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" ;
2019-06-19 14:40:52 +00:00
import { categoryUrl } from "../../categories/urls" ;
import { collectionUrl } from "../../collections/urls" ;
2019-12-06 17:11:46 +00:00
import { decimal , joinDateTime , maybe } from "../../misc" ;
2019-06-19 14:40:52 +00:00
import { productUrl } from "../../products/urls" ;
import { DiscountValueTypeEnum , SaleType } from "../../types/globalTypes" ;
import SaleDetailsPage , {
SaleDetailsPageTab
} from "../components/SaleDetailsPage" ;
import {
TypedSaleCataloguesAdd ,
TypedSaleCataloguesRemove ,
TypedSaleDelete ,
TypedSaleUpdate
} from "../mutations" ;
import { TypedSaleDetails } from "../queries" ;
import { SaleCataloguesAdd } from "../types/SaleCataloguesAdd" ;
import { SaleCataloguesRemove } from "../types/SaleCataloguesRemove" ;
import { SaleDelete } from "../types/SaleDelete" ;
import { SaleUpdate } from "../types/SaleUpdate" ;
import {
saleListUrl ,
saleUrl ,
2019-12-06 14:58:28 +00:00
SaleUrlQueryParams ,
SaleUrlDialog
2019-06-19 14:40:52 +00:00
} from "../urls" ;
interface SaleDetailsProps {
id : string ;
params : SaleUrlQueryParams ;
}
function discountValueTypeEnum ( type : SaleType ) : DiscountValueTypeEnum {
return type . toString ( ) === DiscountValueTypeEnum . FIXED
? DiscountValueTypeEnum . FIXED
: DiscountValueTypeEnum . PERCENTAGE ;
}
2019-11-07 11:34:54 +00:00
export const SaleDetails : React.FC < SaleDetailsProps > = ( { id , params } ) = > {
2019-06-19 14:40:52 +00:00
const navigate = useNavigator ( ) ;
const paginate = usePaginator ( ) ;
const notify = useNotifier ( ) ;
const shop = useShop ( ) ;
const { isSelected , listElements , reset , toggle , toggleAll } = useBulkActions (
params . ids
) ;
2019-08-26 13:59:32 +00:00
const intl = useIntl ( ) ;
2019-11-19 15:47:12 +00:00
const {
search : searchCategories ,
result : searchCategoriesOpts
} = useCategorySearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-11-19 16:04:53 +00:00
const {
search : searchCollections ,
result : searchCollectionsOpts
} = useCollectionSearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-11-19 16:50:40 +00:00
const {
search : searchProducts ,
result : searchProductsOpts
} = useProductSearch ( {
variables : DEFAULT_INITIAL_SEARCH_DATA
} ) ;
2019-06-19 14:40:52 +00:00
const paginationState = createPaginationState ( PAGINATE_BY , params ) ;
const changeTab = ( tab : SaleDetailsPageTab ) = > {
reset ( ) ;
navigate (
saleUrl ( id , {
activeTab : tab
} )
) ;
} ;
const handleSaleDelete = ( data : SaleDelete ) = > {
if ( data . saleDelete . errors . length === 0 ) {
notify ( {
2019-08-26 13:59:32 +00:00
text : intl.formatMessage ( {
defaultMessage : "Removed sale"
2019-06-19 14:40:52 +00:00
} )
} ) ;
navigate ( saleListUrl ( ) , true ) ;
}
} ;
const handleSaleUpdate = ( data : SaleUpdate ) = > {
if ( data . saleUpdate . errors . length === 0 ) {
notify ( {
2019-08-26 13:59:32 +00:00
text : intl.formatMessage ( commonMessages . savedChanges )
2019-06-19 14:40:52 +00:00
} ) ;
}
} ;
2019-12-06 14:58:28 +00:00
const [ openModal , closeModal ] = createDialogActionHandlers <
SaleUrlDialog ,
SaleUrlQueryParams
> ( navigate , params = > saleUrl ( id , params ) , params ) ;
2019-06-19 14:40:52 +00:00
const handleCatalogueAdd = ( data : SaleCataloguesAdd ) = > {
if ( data . saleCataloguesAdd . errors . length === 0 ) {
closeModal ( ) ;
}
} ;
const handleCatalogueRemove = ( data : SaleCataloguesRemove ) = > {
if ( data . saleCataloguesRemove . errors . length === 0 ) {
closeModal ( ) ;
reset ( ) ;
}
} ;
2019-08-26 13:59:32 +00:00
const canOpenBulkActionDialog = maybe ( ( ) = > params . ids . length > 0 ) ;
2019-06-19 14:40:52 +00:00
return (
< TypedSaleCataloguesRemove onCompleted = { handleCatalogueRemove } >
{ ( saleCataloguesRemove , saleCataloguesRemoveOpts ) = > (
< TypedSaleCataloguesAdd onCompleted = { handleCatalogueAdd } >
{ ( saleCataloguesAdd , saleCataloguesAddOpts ) = > (
< TypedSaleUpdate onCompleted = { handleSaleUpdate } >
{ ( saleUpdate , saleUpdateOpts ) = > (
< TypedSaleDelete onCompleted = { handleSaleDelete } >
{ ( saleDelete , saleDeleteOpts ) = > (
< TypedSaleDetails
displayLoader
variables = { { id , . . . paginationState } }
>
{ ( { data , loading } ) = > {
const tabPageInfo =
params . activeTab === SaleDetailsPageTab . categories
? maybe ( ( ) = > data . sale . categories . pageInfo )
: params . activeTab ===
SaleDetailsPageTab . collections
? maybe ( ( ) = > data . sale . collections . pageInfo )
: maybe ( ( ) = > data . sale . products . pageInfo ) ;
const handleCategoriesUnassign = ( ids : string [ ] ) = >
saleCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
categories : ids
}
}
} ) ;
const handleCollectionsUnassign = ( ids : string [ ] ) = >
saleCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
collections : ids
}
}
} ) ;
const handleProductsUnassign = ( ids : string [ ] ) = >
saleCataloguesRemove ( {
variables : {
. . . paginationState ,
id ,
input : {
products : ids
}
}
} ) ;
const {
loadNextPage ,
loadPreviousPage ,
pageInfo
} = paginate ( tabPageInfo , paginationState , params ) ;
return (
< >
2019-08-26 13:59:32 +00:00
< WindowTitle
title = { intl . formatMessage ( sectionNames . sales ) }
/ >
2019-06-19 14:40:52 +00:00
< SaleDetailsPage
defaultCurrency = { maybe (
( ) = > shop . defaultCurrency
) }
sale = { maybe ( ( ) = > data . sale ) }
disabled = {
loading || saleCataloguesRemoveOpts . loading
}
errors = { maybe (
( ) = > saleUpdateOpts . data . saleUpdate . errors
) }
pageInfo = { pageInfo }
onNextPage = { loadNextPage }
onPreviousPage = { loadPreviousPage }
onCategoryAssign = { ( ) = >
openModal ( "assign-category" )
}
onCategoryClick = { id = > ( ) = >
navigate ( categoryUrl ( id ) ) }
onCollectionAssign = { ( ) = >
openModal ( "assign-collection" )
}
onCollectionUnassign = { collectionId = >
handleCollectionsUnassign ( [ collectionId ] )
}
onCategoryUnassign = { categoryId = >
handleCategoriesUnassign ( [ categoryId ] )
}
onCollectionClick = { id = > ( ) = >
navigate ( collectionUrl ( id ) ) }
onProductAssign = { ( ) = >
openModal ( "assign-product" )
}
onProductUnassign = { productId = >
handleProductsUnassign ( [ productId ] )
}
onProductClick = { id = > ( ) = >
navigate ( productUrl ( id ) ) }
activeTab = { params . activeTab }
onBack = { ( ) = > navigate ( saleListUrl ( ) ) }
onTabClick = { changeTab }
onSubmit = { formData = >
saleUpdate ( {
variables : {
id ,
input : {
2019-10-10 13:33:50 +00:00
endDate : formData.hasEndDate
? joinDateTime (
formData . endDate ,
formData . endTime
)
: null ,
2019-06-19 14:40:52 +00:00
name : formData.name ,
2019-10-10 13:33:50 +00:00
startDate : joinDateTime (
formData . startDate ,
formData . startTime
) ,
2019-06-19 14:40:52 +00:00
type : discountValueTypeEnum (
formData . type
) ,
value : decimal ( formData . value )
}
}
} )
}
onRemove = { ( ) = > openModal ( "remove" ) }
2019-12-06 17:17:44 +00:00
saveButtonBarState = { saleUpdateOpts . status }
2019-06-19 14:40:52 +00:00
categoryListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-category" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign category from sale, button"
id = "saleDetailsUnassignCategory"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
collectionListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-collection" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign collection from sale, button"
id = "saleDetailsUnassignCollection"
/ >
2019-06-19 14:40:52 +00:00
< / Button >
}
productListToolbar = {
< Button
color = "primary"
onClick = { ( ) = >
2019-12-06 14:58:28 +00:00
openModal ( "unassign-product" , {
ids : listElements
} )
2019-06-19 14:40:52 +00:00
}
>
2019-08-26 13:59:32 +00:00
< FormattedMessage
defaultMessage = "Unassign"
description = "unassign product from sale, button"
id = "saleDetailsUnassignProduct"
/ >
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 = { saleCataloguesAddOpts . status }
2019-11-19 16:50:40 +00:00
open = { params . action === "assign-product" }
onFetch = { searchProducts }
loading = { searchProductsOpts . loading }
onClose = { closeModal }
onSubmit = { products = >
saleCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
products : products.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 16:50:40 +00:00
}
}
} )
}
products = { maybe ( ( ) = >
searchProductsOpts . 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-11-19 15:47:12 +00:00
< AssignCategoriesDialog
categories = { maybe ( ( ) = >
searchCategoriesOpts . data . search . edges
. map ( edge = > edge . node )
. filter (
suggestedCategory = > suggestedCategory . id
)
) }
2019-12-06 17:17:44 +00:00
confirmButtonState = { saleCataloguesAddOpts . status }
2019-11-19 15:47:12 +00:00
open = { params . action === "assign-category" }
onFetch = { searchCategories }
loading = { searchCategoriesOpts . loading }
onClose = { closeModal }
onSubmit = { categories = >
saleCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
categories : categories.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 15:47:12 +00:00
}
2019-06-19 14:40:52 +00:00
}
2019-11-19 15:47:12 +00:00
} )
}
/ >
2019-11-19 16:04:53 +00:00
< AssignCollectionDialog
collections = { maybe ( ( ) = >
searchCollectionsOpts . data . search . edges
. map ( edge = > edge . node )
. filter (
suggestedCategory = > suggestedCategory . id
)
) }
2019-12-06 17:17:44 +00:00
confirmButtonState = { saleCataloguesAddOpts . status }
2019-11-19 16:04:53 +00:00
open = { params . action === "assign-collection" }
onFetch = { searchCollections }
loading = { searchCollectionsOpts . loading }
onClose = { closeModal }
onSubmit = { collections = >
saleCataloguesAdd ( {
variables : {
. . . paginationState ,
id ,
input : {
collections : collections.map (
product = > product . id
2019-06-19 14:40:52 +00:00
)
2019-11-19 16:04:53 +00:00
}
2019-06-19 14:40:52 +00:00
}
2019-11-19 16:04:53 +00:00
} )
}
/ >
2019-06-19 14:40:52 +00:00
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-category" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage : "Unassign Categories From Sale" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
saleCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleCategoriesUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this category?} other{Are you sure you want to unassign {displayQuantity} categories?}}"
2019-08-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-collection" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage :
"Unassign Collections From Sale" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
saleCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleCollectionsUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< DialogContentText >
< FormattedMessage
2020-02-13 11:14:16 +00:00
defaultMessage = "{counter,plural,one{Are you sure you want to unassign this collection?} other{Are you sure you want to unassign {displayQuantity} collections?}}"
2019-08-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
2019-08-26 13:59:32 +00:00
open = {
params . action === "unassign-product" &&
canOpenBulkActionDialog
}
title = { intl . formatMessage ( {
defaultMessage : "Unassign Products From Sale" ,
description : "dialog header"
} ) }
2019-12-06 17:11:46 +00:00
confirmButtonState = {
2019-12-06 17:17:44 +00:00
saleCataloguesRemoveOpts . status
2019-12-06 17:11:46 +00:00
}
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
onConfirm = { ( ) = >
handleProductsUnassign ( params . ids )
}
>
2019-08-26 13:59:32 +00:00
{ canOpenBulkActionDialog && (
< 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-26 13:59:32 +00:00
description = "dialog content"
values = { {
counter : params.ids.length ,
displayQuantity : (
< strong > { params . ids . length } < / strong >
2019-06-19 14:40:52 +00:00
)
2019-08-26 13:59:32 +00:00
} }
/ >
< / DialogContentText >
) }
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< ActionDialog
open = { params . action === "remove" }
2019-08-26 13:59:32 +00:00
title = { intl . formatMessage ( {
defaultMessage : "Delete Sale" ,
description : "dialog header"
} ) }
2019-12-06 17:17:44 +00:00
confirmButtonState = { saleDeleteOpts . status }
2019-06-19 14:40:52 +00:00
onClose = { closeModal }
variant = "delete"
onConfirm = { ( ) = >
saleDelete ( {
variables : { id }
} )
}
>
2019-08-26 13:59:32 +00:00
< DialogContentText >
< FormattedMessage
defaultMessage = "Are you sure you want to delete {saleName}?"
description = "dialog content"
values = { {
saleName : (
< strong >
{ maybe ( ( ) = > data . sale . name , "..." ) }
< / strong >
)
} }
/ >
< / DialogContentText >
2019-06-19 14:40:52 +00:00
< / ActionDialog >
< / >
) ;
} }
< / TypedSaleDetails >
) }
< / TypedSaleDelete >
) }
< / TypedSaleUpdate >
) }
< / TypedSaleCataloguesAdd >
) }
< / TypedSaleCataloguesRemove >
) ;
} ;
export default SaleDetails ;