diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx index 183ba56af..112a45bdc 100644 --- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx +++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx @@ -46,6 +46,7 @@ import { commonMessages, sectionNames } from "@saleor/intl"; import useCategorySearch from "@saleor/searches/useCategorySearch"; import useCollectionSearch from "@saleor/searches/useCollectionSearch"; import useProductSearch from "@saleor/searches/useProductSearch"; +import { arrayDiff } from "@saleor/utils/arrays"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler"; import { mapEdgesToItems } from "@saleor/utils/maps"; @@ -53,7 +54,7 @@ import { useMetadataUpdate, usePrivateMetadataUpdate } from "@saleor/utils/metadata/updateMetadata"; -import React from "react"; +import React, { useMemo } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { categoryUrl } from "../../../categories/urls"; @@ -132,9 +133,11 @@ export const VoucherDetails: React.FC = ({ data?.voucher, availableChannels ); - const voucherChannelsChoices: ChannelVoucherData[] = createSortedChannelsDataFromVoucher( - data?.voucher + const voucherChannelsChoices: ChannelVoucherData[] = useMemo( + () => createSortedChannelsDataFromVoucher(data?.voucher), + [data?.voucher] ); + const { channelListElements, channelsToggle, @@ -151,12 +154,6 @@ export const VoucherDetails: React.FC = ({ openModal }); - React.useEffect(() => { - if (!currentChannels.length && voucherChannelsChoices.length) { - setCurrentChannels(voucherChannelsChoices); - } - }, [voucherChannelsChoices]); - const [updateChannels, updateChannelsOpts] = useVoucherChannelListingUpdate( {} ); @@ -198,12 +195,21 @@ export const VoucherDetails: React.FC = ({ const canOpenBulkActionDialog = maybe(() => params.ids.length > 0); + const hasArrChanged = () => { + const { added, removed } = arrayDiff( + voucherChannelsChoices.map(choice => choice.id), + currentChannels.map(choice => choice.id) + ); + + return added.length !== 0 || removed.length !== 0; + }; + return ( <> {!!allChannels?.length && ( = ({ voucher={data?.voucher} allChannelsCount={allChannels?.length} channelListings={currentChannels} - hasChannelChanged={ - voucherChannelsChoices?.length !== - currentChannels?.length - } + hasChannelChanged={hasArrChanged()} disabled={ loading || voucherCataloguesRemoveOpts.loading || diff --git a/src/hooks/useChannels.test.ts b/src/hooks/useChannels.test.ts new file mode 100644 index 000000000..84446bde4 --- /dev/null +++ b/src/hooks/useChannels.test.ts @@ -0,0 +1,89 @@ +import { ChannelData } from "@saleor/channels/utils"; +import { act, renderHook } from "@testing-library/react-hooks"; + +import useChannels from "./useChannels"; + +const channels: ChannelData[] = [ + { + id: "channel1", + name: "Channel 1", + variantsIds: ["variant1", "variant2"] + }, + { + id: "channel2", + name: "Channel 2", + variantsIds: [] + } +]; + +describe("useChannels", () => { + it("properly toggles channels", () => { + // Given + const { result } = renderHook(() => + useChannels(channels, "", { + closeModal: jest.fn, + openModal: jest.fn + }) + ); + + // When + act(() => { + result.current.channelsToggle(channels[0]); + }); + + act(() => { + result.current.handleChannelsConfirm(); + }); + + // Then + expect(result.current.currentChannels).toStrictEqual([channels[1]]); + expect(result.current.currentChannels[0].id).toBe(channels[1].id); + }); + it("properly removes channels", () => { + // Given + const { result } = renderHook(() => + useChannels(channels, "", { + closeModal: jest.fn, + openModal: jest.fn + }) + ); + + // When + act(() => { + result.current.channelsToggle(channels[0]); + }); + + act(() => { + result.current.channelsToggle(channels[1]); + }); + + act(() => { + result.current.handleChannelsConfirm(); + }); + + // Then + expect(result.current.currentChannels).toStrictEqual([]); + }); + + it("doesn't not save changes if closed without confirm", () => { + // Given + const { result } = renderHook(() => + useChannels(channels, "", { + closeModal: jest.fn, + openModal: jest.fn + }) + ); + + // When + act(() => { + result.current.channelsToggle(channels[0]); + }); + + act(() => { + result.current.handleChannelsModalClose(); + }); + + // Then + expect(result.current.currentChannels).toStrictEqual(channels); + }); +}); diff --git a/src/shipping/views/PriceRatesCreate/PriceRatesCreate.tsx b/src/shipping/views/PriceRatesCreate/PriceRatesCreate.tsx index 4f84fd0fd..6ab32717f 100644 --- a/src/shipping/views/PriceRatesCreate/PriceRatesCreate.tsx +++ b/src/shipping/views/PriceRatesCreate/PriceRatesCreate.tsx @@ -131,7 +131,6 @@ export const PriceRatesCreate: React.FC = ({ {!!allChannels?.length && ( = ({ {!!allChannels?.length && ( = ({ {!!allChannels?.length && ( = ({ {!!allChannels?.length && (