import DialogContentText from "@material-ui/core/DialogContentText"; import { useChannelsList } from "@saleor/channels/queries"; import ActionDialog from "@saleor/components/ActionDialog"; import useAppChannel from "@saleor/components/AppLayout/AppChannelContext"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import { PAGINATE_BY } from "@saleor/config"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { createPaginationState } from "@saleor/hooks/usePaginator"; import useShop from "@saleor/hooks/useShop"; import { commonMessages } from "@saleor/intl"; import { getById } from "@saleor/orders/components/OrderReturnPage/utils"; import useWarehouseSearch from "@saleor/searches/useWarehouseSearch"; import DeleteShippingRateDialog from "@saleor/shipping/components/DeleteShippingRateDialog"; import ShippingZoneAddWarehouseDialog from "@saleor/shipping/components/ShippingZoneAddWarehouseDialog"; import ShippingZoneCountriesAssignDialog from "@saleor/shipping/components/ShippingZoneCountriesAssignDialog"; import { useShippingRateDelete, useShippingZoneDelete, useShippingZoneUpdate } from "@saleor/shipping/mutations"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler"; import { mapEdgesToItems } from "@saleor/utils/maps"; import { useMetadataUpdate, usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; import { useWarehouseCreate } from "@saleor/warehouses/mutations"; import { diff } from "fast-array-diff"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { findValueInEnum, getStringOrPlaceholder } from "../../../misc"; import { CountryCode } from "../../../types/globalTypes"; import ShippingZoneDetailsPage from "../../components/ShippingZoneDetailsPage"; import { FormData } from "../../components/ShippingZoneDetailsPage/types"; import { useShippingZone } from "../../queries"; import { shippingPriceRatesEditUrl, shippingPriceRatesUrl, shippingWeightRatesEditUrl, shippingWeightRatesUrl, shippingZonesListUrl, shippingZoneUrl, ShippingZoneUrlDialog, ShippingZoneUrlQueryParams } from "../../urls"; export interface ShippingZoneDetailsProps { id: string; params: ShippingZoneUrlQueryParams; } const ShippingZoneDetails: React.FC = ({ id, params }) => { const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); const shop = useShop(); const paginationState = createPaginationState(PAGINATE_BY, params); const { result: searchWarehousesOpts, loadMore, search } = useWarehouseSearch( { variables: DEFAULT_INITIAL_SEARCH_DATA } ); const { data: channelsList } = useChannelsList({}); const { data, loading } = useShippingZone({ displayLoader: true, variables: { id, ...paginationState } }); const { channel } = useAppChannel(); const [openModal, closeModal] = createDialogActionHandlers< ShippingZoneUrlDialog, ShippingZoneUrlQueryParams >(navigate, params => shippingZoneUrl(id, params), params); const rate = data?.shippingZone?.shippingMethods?.find(getById(params.id)); const [deleteShippingRate, deleteShippingRateOpts] = useShippingRateDelete({ onCompleted: data => { if (data.shippingPriceDelete.errors.length === 0) { notify({ status: "success", text: intl.formatMessage(commonMessages.savedChanges) }); closeModal(); } } }); const [deleteShippingZone, deleteShippingZoneOpts] = useShippingZoneDelete({ onCompleted: data => { if (data.shippingZoneDelete.errors.length === 0) { notify({ status: "success", text: intl.formatMessage(commonMessages.savedChanges) }); navigate(shippingZonesListUrl(), true); } } }); const [updateShippingZone, updateShippingZoneOpts] = useShippingZoneUpdate({ onCompleted: data => { if (data.shippingZoneUpdate.errors.length === 0) { notify({ status: "success", text: intl.formatMessage(commonMessages.savedChanges) }); closeModal(); } } }); const [createWarehouse, createWarehouseOpts] = useWarehouseCreate({ onCompleted: data => { if (data.createWarehouse.errors.length === 0) { notify({ status: "success", text: intl.formatMessage(commonMessages.savedChanges) }); closeModal(); } } }); const [updateMetadata] = useMetadataUpdate({}); const [updatePrivateMetadata] = usePrivateMetadataUpdate({}); const updateData = async (submitData: FormData) => { const warehouseDiff = diff( data.shippingZone.warehouses.map(warehouse => warehouse.id), submitData.warehouses ); const channelsDiff = diff( data.shippingZone.channels.map(channel => channel.id), submitData.channels ); const result = await updateShippingZone({ variables: { id, input: { addWarehouses: warehouseDiff.added, addChannels: channelsDiff.added, removeChannels: channelsDiff.removed, description: submitData.description, name: submitData.name, removeWarehouses: warehouseDiff.removed } } }); return result.data.shippingZoneUpdate.errors; }; const handleSubmit = createMetadataUpdateHandler( data?.shippingZone, updateData, variables => updateMetadata({ variables }), variables => updatePrivateMetadata({ variables }) ); if (data?.shippingZone === null) { return navigate(shippingZonesListUrl())} />; } return ( <> navigate(shippingZonesListUrl())} onCountryAdd={() => openModal("assign-country")} onCountryRemove={code => openModal("unassign-country", { id: code }) } onDelete={() => openModal("remove")} onPriceRateAdd={() => navigate(shippingPriceRatesUrl(id))} onPriceRateEdit={rateId => navigate(shippingPriceRatesEditUrl(id, rateId)) } onRateRemove={rateId => openModal("remove-rate", { id: rateId }) } onSubmit={handleSubmit} allChannels={channelsList?.channels} onWarehouseAdd={() => openModal("add-warehouse")} onWeightRateAdd={() => navigate(shippingWeightRatesUrl(id))} onWeightRateEdit={rateId => navigate(shippingWeightRatesEditUrl(id, rateId)) } saveButtonBarState={updateShippingZoneOpts.status} shippingZone={data?.shippingZone} warehouses={mapEdgesToItems(searchWarehousesOpts?.data?.search)} hasMore={searchWarehousesOpts.data?.search.pageInfo.hasNextPage} loading={searchWarehousesOpts.loading} onFetchMore={loadMore} onSearchChange={search} selectedChannelId={channel.id} /> deleteShippingRate({ variables: { id: params.id } }) } name={rate?.name} open={params.action === "remove-rate"} /> deleteShippingZone({ variables: { id } }) } open={params.action === "remove"} title={intl.formatMessage({ defaultMessage: "Delete Shipping Zone", description: "dialog header" })} variant="delete" > {getStringOrPlaceholder(data?.shippingZone.name)} ) }} /> country.code) || [] } isDefault={data?.shippingZone?.default} onClose={closeModal} onConfirm={formData => updateShippingZone({ variables: { id, input: { countries: formData.countries, default: formData.restOfTheWorld } } }) } open={params.action === "assign-country"} /> updateShippingZone({ variables: { id, input: { countries: data.shippingZone.countries .filter(country => country.code !== params.id) .map(country => country.code) } } }) } open={params.action === "unassign-country"} title={intl.formatMessage({ defaultMessage: "Delete from Shipping Zone", description: "unassign country, dialog header" })} variant="delete" > {getStringOrPlaceholder( data?.shippingZone?.countries.find( country => country.code === params.id )?.country )} ) }} /> createWarehouse({ variables: { input: { address: { city: data.city, cityArea: data.cityArea, country: findValueInEnum(data.country, CountryCode), countryArea: data.countryArea, phone: data.phone, postalCode: data.postalCode, streetAddress1: data.streetAddress1, streetAddress2: data.streetAddress2 }, companyName: data.companyName, name: data.name } } }) } /> ); }; export default ShippingZoneDetails;