
* Add assign warehouse section in channel page * Update data-test-ids on channel page * Update channel page form details * Update shipping zones and warehouses cards in chaannel page * Assigning warehouses by channel in product and variant pages (#2135) * Assigning warehouses by channel in product and variant pages * Disable warehouse assignment when no channel on variant page * Update products stocks section messages
272 lines
7.9 KiB
TypeScript
272 lines
7.9 KiB
TypeScript
import ChannelDeleteDialog from "@saleor/channels/components/ChannelDeleteDialog";
|
|
import { FormData } from "@saleor/channels/components/ChannelForm/ChannelForm";
|
|
import { getChannelsCurrencyChoices } from "@saleor/channels/utils";
|
|
import { Backlink } from "@saleor/components/Backlink";
|
|
import Container from "@saleor/components/Container";
|
|
import PageHeader from "@saleor/components/PageHeader";
|
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
|
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
|
import {
|
|
ChannelDeleteMutation,
|
|
ChannelErrorFragment,
|
|
ChannelUpdateMutation,
|
|
useChannelActivateMutation,
|
|
useChannelDeactivateMutation,
|
|
useChannelDeleteMutation,
|
|
useChannelQuery,
|
|
useChannelShippingZonesQuery,
|
|
useChannelsQuery,
|
|
useChannelUpdateMutation,
|
|
useChannelWarehousesQuery,
|
|
} from "@saleor/graphql";
|
|
import { getSearchFetchMoreProps } from "@saleor/hooks/makeTopLevelSearch/utils";
|
|
import useNavigator from "@saleor/hooks/useNavigator";
|
|
import useNotifier from "@saleor/hooks/useNotifier";
|
|
import { getDefaultNotifierSuccessErrorData } from "@saleor/hooks/useNotifier/utils";
|
|
import useShop from "@saleor/hooks/useShop";
|
|
import { sectionNames } from "@saleor/intl";
|
|
import { extractMutationErrors } from "@saleor/misc";
|
|
import useShippingZonesSearch from "@saleor/searches/useShippingZonesSearch";
|
|
import useWarehouseSearch from "@saleor/searches/useWarehouseSearch";
|
|
import getChannelsErrorMessage from "@saleor/utils/errors/channels";
|
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
|
import React from "react";
|
|
import { useIntl } from "react-intl";
|
|
|
|
import ChannelDetailsPage from "../../pages/ChannelDetailsPage";
|
|
import {
|
|
channelsListUrl,
|
|
channelUrl,
|
|
ChannelUrlDialog,
|
|
ChannelUrlQueryParams,
|
|
} from "../../urls";
|
|
|
|
interface ChannelDetailsProps {
|
|
id: string;
|
|
params: ChannelUrlQueryParams;
|
|
}
|
|
|
|
export const ChannelDetails: React.FC<ChannelDetailsProps> = ({
|
|
id,
|
|
params,
|
|
}) => {
|
|
const navigate = useNavigator();
|
|
const notify = useNotifier();
|
|
const intl = useIntl();
|
|
const shop = useShop();
|
|
|
|
const channelsListData = useChannelsQuery({ displayLoader: true });
|
|
|
|
const [openModal, closeModal] = createDialogActionHandlers<
|
|
ChannelUrlDialog,
|
|
ChannelUrlQueryParams
|
|
>(navigate, params => channelUrl(id, params), params);
|
|
|
|
const [updateChannel, updateChannelOpts] = useChannelUpdateMutation({
|
|
onCompleted: ({ channelUpdate: { errors } }: ChannelUpdateMutation) =>
|
|
notify(getDefaultNotifierSuccessErrorData(errors, intl)),
|
|
});
|
|
|
|
const { data, loading } = useChannelQuery({
|
|
displayLoader: true,
|
|
variables: { id },
|
|
});
|
|
|
|
const handleError = (error: ChannelErrorFragment) => {
|
|
notify({
|
|
status: "error",
|
|
text: getChannelsErrorMessage(error, intl),
|
|
});
|
|
};
|
|
|
|
const [activateChannel, activateChannelOpts] = useChannelActivateMutation({
|
|
onCompleted: data => {
|
|
const errors = data.channelActivate.errors;
|
|
if (errors.length) {
|
|
errors.forEach(error => handleError(error));
|
|
}
|
|
},
|
|
});
|
|
|
|
const [
|
|
deactivateChannel,
|
|
deactivateChannelOpts,
|
|
] = useChannelDeactivateMutation({
|
|
onCompleted: data => {
|
|
const errors = data.channelDeactivate.errors;
|
|
if (errors.length) {
|
|
errors.forEach(error => handleError(error));
|
|
}
|
|
},
|
|
});
|
|
|
|
const handleSubmit = ({
|
|
name,
|
|
slug,
|
|
shippingZonesIdsToRemove,
|
|
shippingZonesIdsToAdd,
|
|
warehousesIdsToRemove,
|
|
warehousesIdsToAdd,
|
|
defaultCountry,
|
|
}: FormData) =>
|
|
extractMutationErrors(
|
|
updateChannel({
|
|
variables: {
|
|
id: data?.channel.id,
|
|
input: {
|
|
name,
|
|
slug,
|
|
defaultCountry,
|
|
addShippingZones: shippingZonesIdsToAdd,
|
|
removeShippingZones: shippingZonesIdsToRemove,
|
|
addWarehouses: warehousesIdsToAdd,
|
|
removeWarehouses: warehousesIdsToRemove,
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
|
|
const onDeleteCompleted = (data: ChannelDeleteMutation) => {
|
|
const errors = data.channelDelete.errors;
|
|
if (errors.length === 0) {
|
|
notify({
|
|
status: "success",
|
|
text: intl.formatMessage({
|
|
id: "AkyGP2",
|
|
defaultMessage: "Channel deleted",
|
|
}),
|
|
});
|
|
closeModal();
|
|
navigate(channelsListUrl());
|
|
} else {
|
|
errors.map(error =>
|
|
notify({
|
|
status: "error",
|
|
text: getChannelsErrorMessage(error, intl),
|
|
}),
|
|
);
|
|
}
|
|
};
|
|
|
|
const [deleteChannel, deleteChannelOpts] = useChannelDeleteMutation({
|
|
onCompleted: onDeleteCompleted,
|
|
});
|
|
|
|
const channelsChoices = getChannelsCurrencyChoices(
|
|
id,
|
|
data?.channel,
|
|
channelsListData?.data?.channels,
|
|
);
|
|
|
|
const handleRemoveConfirm = (channelId?: string) => {
|
|
const data = channelId ? { id, input: { channelId } } : { id };
|
|
deleteChannel({ variables: data });
|
|
};
|
|
|
|
const {
|
|
data: channelShippingZonesData,
|
|
loading: channelsShippingZonesLoading,
|
|
} = useChannelShippingZonesQuery({
|
|
variables: {
|
|
filter: {
|
|
channels: [id],
|
|
},
|
|
},
|
|
});
|
|
|
|
const {
|
|
loadMore: fetchMoreShippingZones,
|
|
search: searchShippingZones,
|
|
result: searchShippingZonesResult,
|
|
} = useShippingZonesSearch({
|
|
variables: DEFAULT_INITIAL_SEARCH_DATA,
|
|
});
|
|
|
|
const {
|
|
data: channelWarehousesData,
|
|
loading: channelsWarehousesLoading,
|
|
} = useChannelWarehousesQuery({
|
|
variables: {
|
|
filter: {
|
|
channels: [id],
|
|
},
|
|
},
|
|
});
|
|
|
|
const {
|
|
loadMore: fetchMoreWarehouses,
|
|
search: searchWarehouses,
|
|
result: searchWarehousesResult,
|
|
} = useWarehouseSearch({
|
|
variables: DEFAULT_INITIAL_SEARCH_DATA,
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<WindowTitle
|
|
title={intl.formatMessage({
|
|
id: "D9Rg+F",
|
|
defaultMessage: "Channel details",
|
|
description: "window title",
|
|
})}
|
|
/>
|
|
<Container>
|
|
<Backlink href={channelsListUrl()}>
|
|
{intl.formatMessage(sectionNames.channels)}
|
|
</Backlink>
|
|
<PageHeader title={data?.channel?.name} />
|
|
<ChannelDetailsPage
|
|
channelShippingZones={channelShippingZonesData?.shippingZones?.edges?.map(
|
|
({ node }) => node,
|
|
)}
|
|
searchShippingZones={searchShippingZones}
|
|
searchShippingZonesData={searchShippingZonesResult.data}
|
|
fetchMoreShippingZones={getSearchFetchMoreProps(
|
|
searchShippingZonesResult,
|
|
fetchMoreShippingZones,
|
|
)}
|
|
channelWarehouses={channelWarehousesData?.warehouses?.edges?.map(
|
|
({ node }) => node,
|
|
)}
|
|
searchWarehouses={searchWarehouses}
|
|
searchWarehousesData={searchWarehousesResult.data}
|
|
fetchMoreWarehouses={getSearchFetchMoreProps(
|
|
searchWarehousesResult,
|
|
fetchMoreWarehouses,
|
|
)}
|
|
channel={data?.channel}
|
|
disabled={
|
|
updateChannelOpts.loading ||
|
|
loading ||
|
|
channelsShippingZonesLoading ||
|
|
channelsWarehousesLoading
|
|
}
|
|
disabledStatus={
|
|
activateChannelOpts.loading || deactivateChannelOpts.loading
|
|
}
|
|
errors={updateChannelOpts?.data?.channelUpdate?.errors || []}
|
|
onDelete={() => openModal("remove")}
|
|
onSubmit={handleSubmit}
|
|
updateChannelStatus={() =>
|
|
data?.channel?.isActive
|
|
? deactivateChannel({ variables: { id } })
|
|
: activateChannel({ variables: { id } })
|
|
}
|
|
saveButtonBarState={updateChannelOpts.status}
|
|
countries={shop?.countries || []}
|
|
/>
|
|
</Container>
|
|
<ChannelDeleteDialog
|
|
channelsChoices={channelsChoices}
|
|
hasOrders={data?.channel?.hasOrders}
|
|
open={params.action === "remove"}
|
|
confirmButtonState={deleteChannelOpts.status}
|
|
onBack={() => navigate(channelsListUrl())}
|
|
onClose={closeModal}
|
|
onConfirm={handleRemoveConfirm}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ChannelDetails;
|