Add optional channel selection in price and weight rates view + voucher view (#1531)
* Add useChannels test * Fix unnecessary re-render that caused overwrite of form list * Change array diff check * Channel selection in price and weight rates is optional
This commit is contained in:
parent
925e723c35
commit
f9a090ee47
6 changed files with 106 additions and 18 deletions
|
@ -46,6 +46,7 @@ import { commonMessages, sectionNames } from "@saleor/intl";
|
||||||
import useCategorySearch from "@saleor/searches/useCategorySearch";
|
import useCategorySearch from "@saleor/searches/useCategorySearch";
|
||||||
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
|
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
|
||||||
import useProductSearch from "@saleor/searches/useProductSearch";
|
import useProductSearch from "@saleor/searches/useProductSearch";
|
||||||
|
import { arrayDiff } from "@saleor/utils/arrays";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
import createMetadataUpdateHandler from "@saleor/utils/handlers/metadataUpdateHandler";
|
||||||
import { mapEdgesToItems } from "@saleor/utils/maps";
|
import { mapEdgesToItems } from "@saleor/utils/maps";
|
||||||
|
@ -53,7 +54,7 @@ import {
|
||||||
useMetadataUpdate,
|
useMetadataUpdate,
|
||||||
usePrivateMetadataUpdate
|
usePrivateMetadataUpdate
|
||||||
} from "@saleor/utils/metadata/updateMetadata";
|
} from "@saleor/utils/metadata/updateMetadata";
|
||||||
import React from "react";
|
import React, { useMemo } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { categoryUrl } from "../../../categories/urls";
|
import { categoryUrl } from "../../../categories/urls";
|
||||||
|
@ -132,9 +133,11 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
|
||||||
data?.voucher,
|
data?.voucher,
|
||||||
availableChannels
|
availableChannels
|
||||||
);
|
);
|
||||||
const voucherChannelsChoices: ChannelVoucherData[] = createSortedChannelsDataFromVoucher(
|
const voucherChannelsChoices: ChannelVoucherData[] = useMemo(
|
||||||
data?.voucher
|
() => createSortedChannelsDataFromVoucher(data?.voucher),
|
||||||
|
[data?.voucher]
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
channelListElements,
|
channelListElements,
|
||||||
channelsToggle,
|
channelsToggle,
|
||||||
|
@ -151,12 +154,6 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
|
||||||
openModal
|
openModal
|
||||||
});
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!currentChannels.length && voucherChannelsChoices.length) {
|
|
||||||
setCurrentChannels(voucherChannelsChoices);
|
|
||||||
}
|
|
||||||
}, [voucherChannelsChoices]);
|
|
||||||
|
|
||||||
const [updateChannels, updateChannelsOpts] = useVoucherChannelListingUpdate(
|
const [updateChannels, updateChannelsOpts] = useVoucherChannelListingUpdate(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
@ -198,12 +195,21 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
|
||||||
|
|
||||||
const canOpenBulkActionDialog = maybe(() => params.ids.length > 0);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
{!!allChannels?.length && (
|
{!!allChannels?.length && (
|
||||||
<ChannelsAvailabilityDialog
|
<ChannelsAvailabilityDialog
|
||||||
isSelected={isChannelSelected}
|
isSelected={isChannelSelected}
|
||||||
disabled={!channelListElements.length}
|
disabled={false}
|
||||||
channels={allChannels}
|
channels={allChannels}
|
||||||
onChange={channelsToggle}
|
onChange={channelsToggle}
|
||||||
onClose={handleChannelsModalClose}
|
onClose={handleChannelsModalClose}
|
||||||
|
@ -295,10 +301,7 @@ export const VoucherDetails: React.FC<VoucherDetailsProps> = ({
|
||||||
voucher={data?.voucher}
|
voucher={data?.voucher}
|
||||||
allChannelsCount={allChannels?.length}
|
allChannelsCount={allChannels?.length}
|
||||||
channelListings={currentChannels}
|
channelListings={currentChannels}
|
||||||
hasChannelChanged={
|
hasChannelChanged={hasArrChanged()}
|
||||||
voucherChannelsChoices?.length !==
|
|
||||||
currentChannels?.length
|
|
||||||
}
|
|
||||||
disabled={
|
disabled={
|
||||||
loading ||
|
loading ||
|
||||||
voucherCataloguesRemoveOpts.loading ||
|
voucherCataloguesRemoveOpts.loading ||
|
||||||
|
|
89
src/hooks/useChannels.test.ts
Normal file
89
src/hooks/useChannels.test.ts
Normal file
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
|
@ -131,7 +131,6 @@ export const PriceRatesCreate: React.FC<PriceRatesCreateProps> = ({
|
||||||
{!!allChannels?.length && (
|
{!!allChannels?.length && (
|
||||||
<ChannelsAvailabilityDialog
|
<ChannelsAvailabilityDialog
|
||||||
isSelected={isChannelSelected}
|
isSelected={isChannelSelected}
|
||||||
disabled={!channelListElements.length}
|
|
||||||
channels={allChannels}
|
channels={allChannels}
|
||||||
onChange={channelsToggle}
|
onChange={channelsToggle}
|
||||||
onClose={handleChannelsModalClose}
|
onClose={handleChannelsModalClose}
|
||||||
|
|
|
@ -304,7 +304,6 @@ export const PriceRatesUpdate: React.FC<PriceRatesUpdateProps> = ({
|
||||||
{!!allChannels?.length && (
|
{!!allChannels?.length && (
|
||||||
<ChannelsAvailabilityDialog
|
<ChannelsAvailabilityDialog
|
||||||
isSelected={isChannelSelected}
|
isSelected={isChannelSelected}
|
||||||
disabled={!channelListElements.length}
|
|
||||||
channels={allChannels}
|
channels={allChannels}
|
||||||
onChange={channelsToggle}
|
onChange={channelsToggle}
|
||||||
onClose={handleChannelsModalClose}
|
onClose={handleChannelsModalClose}
|
||||||
|
|
|
@ -137,7 +137,6 @@ export const WeightRatesCreate: React.FC<WeightRatesCreateProps> = ({
|
||||||
{!!allChannels?.length && (
|
{!!allChannels?.length && (
|
||||||
<ChannelsAvailabilityDialog
|
<ChannelsAvailabilityDialog
|
||||||
isSelected={isChannelSelected}
|
isSelected={isChannelSelected}
|
||||||
disabled={!channelListElements.length}
|
|
||||||
channels={allChannels}
|
channels={allChannels}
|
||||||
onChange={channelsToggle}
|
onChange={channelsToggle}
|
||||||
onClose={handleChannelsModalClose}
|
onClose={handleChannelsModalClose}
|
||||||
|
|
|
@ -303,7 +303,6 @@ export const WeightRatesUpdate: React.FC<WeightRatesUpdateProps> = ({
|
||||||
{!!allChannels?.length && (
|
{!!allChannels?.length && (
|
||||||
<ChannelsAvailabilityDialog
|
<ChannelsAvailabilityDialog
|
||||||
isSelected={isChannelSelected}
|
isSelected={isChannelSelected}
|
||||||
disabled={!channelListElements.length}
|
|
||||||
channels={allChannels}
|
channels={allChannels}
|
||||||
onChange={channelsToggle}
|
onChange={channelsToggle}
|
||||||
onClose={handleChannelsModalClose}
|
onClose={handleChannelsModalClose}
|
||||||
|
|
Loading…
Reference in a new issue