diff --git a/.changeset/strange-ladybugs-judge.md b/.changeset/strange-ladybugs-judge.md new file mode 100644 index 00000000000..e5651b430a7 --- /dev/null +++ b/.changeset/strange-ladybugs-judge.md @@ -0,0 +1,5 @@ +--- +"saleor-dashboard": patch +--- + +Add check if channel listing array is undefined before call filter on it to prevent Dashboard crash diff --git a/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/AvailabilityCard.tsx b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/AvailabilityCard.tsx index 834b65eaba2..f6c7eaf34a0 100644 --- a/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/AvailabilityCard.tsx +++ b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/AvailabilityCard.tsx @@ -8,6 +8,7 @@ import React from "react"; import { ProductChannelListing } from "./../types"; import { ChannelsListItem } from "./ChannelsListItem"; +import { useFilteredChannelListing } from "./useFilteredChannelListing"; import CardContainer from "./VariantDetailsChannelsAvailabilityCardContainer"; interface AvailabilityCardProps { @@ -15,7 +16,7 @@ interface AvailabilityCardProps { ChannelPriceAndPreorderData, IChannelPriceAndPreorderArgs >; - productChannelListings: ProductChannelListing; + productChannelListings: ProductChannelListing | undefined; } export const AvailabilityCard: React.FC = ({ @@ -23,16 +24,15 @@ export const AvailabilityCard: React.FC = ({ productChannelListings, children, }) => { + const filteredListings = useFilteredChannelListing({ + allAvailableListings, + channelListing: productChannelListings, + }); + if (allAvailableListings.length === 0) { - return {}; + return {null}; } - const listingIds = allAvailableListings.map(lst => lst.id); - const filteredListings: ProductChannelListing = - productChannelListings?.filter((channel: ProductChannelListing[0]) => - listingIds.includes(channel.channel.id), - ); - return ( {filteredListings.map((listing: ProductChannelListing[0]) => ( diff --git a/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.test.ts b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.test.ts new file mode 100644 index 00000000000..1eede0ded6b --- /dev/null +++ b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.test.ts @@ -0,0 +1,40 @@ +import { useFilteredChannelListing } from "./useFilteredChannelListing"; + +describe("useFilteredChannelListing", () => { + it("should return empty array if channelListing is null or undefined", () => { + // Arrange + const allAvailableListings = [{ id: "1" }, { id: "2" }]; + const channelListing = null; + + // Act + const result = useFilteredChannelListing({ + allAvailableListings, + channelListing, + }); + + // Assert + expect(result).toEqual([]); + }); + + it("should return array with filtered channel listings", () => { + // Arrange + const allAvailableListings = [{ id: "1" }, { id: "2" }, { id: "3" }]; + const channelListing = [ + { channel: { id: "1" } }, + { channel: { id: "3" } }, + { channel: { id: "4" } }, + ]; + + // Act + const result = useFilteredChannelListing({ + allAvailableListings, + channelListing, + }); + + // Assert + expect(result).toEqual([ + { channel: { id: "1" } }, + { channel: { id: "3" } }, + ]); + }); +}); diff --git a/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.ts b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.ts new file mode 100644 index 00000000000..931eff25bf6 --- /dev/null +++ b/src/products/components/ProductVariantChannels/ChannelsAvailabilityCard/useFilteredChannelListing.ts @@ -0,0 +1,23 @@ +interface ChannelListing { + channel: { + id: string; + }; +} + +export const useFilteredChannelListing = ({ + channelListing, + allAvailableListings, +}: { + allAvailableListings: Array<{ id: string }>; + channelListing: ChannelListing[] | null | undefined; +}) => { + if (!channelListing) { + return []; + } + + const listingIds = allAvailableListings.map(lst => lst.id); + + return channelListing.filter(channel => + listingIds.includes(channel.channel.id), + ); +};