Skip to content

Commit

Permalink
Fix variant availability (#4607)
Browse files Browse the repository at this point in the history
* Fix improper availability on variant details page

* Fix improper availability on variant details page

* Fix strict typing

* Add changeset

* Fix multiple issues regarding availabilitiy channel list rendering

* Disable create variant when no name provided

* Simplify test

* Trigger deployment

* Fix naming

* Extract mapping outside filtering

* Remove unrelated messages
  • Loading branch information
Droniu committed Feb 1, 2024
1 parent c09ef4d commit 6473419
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 89 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-kings-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Fix variant availability
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
import {
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs,
} from "@dashboard/channels/utils";
import { Divider } from "@dashboard/components/Divider";
import { FormsetData } from "@dashboard/hooks/useFormset";
import React from "react";

import { Channel, ProductChannelListing } from "./../types";
import { ProductChannelListing } from "./../types";
import { ChannelsListItem } from "./ChannelsListItem";
import CardContainer from "./VariantDetailsChannelsAvailabilityCardContainer";

interface AvailabilityCardProps {
items: Channel[];
allAvailableListings: FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>;
productChannelListings: ProductChannelListing;
}

export const AvailabilityCard: React.FC<AvailabilityCardProps> = ({
items,
allAvailableListings,
productChannelListings,
children,
}) => {
if (items.length === 0) {
if (allAvailableListings.length === 0) {
return <CardContainer cardTitle={children}>{}</CardContainer>;
}

const listingIds = allAvailableListings.map(lst => lst.id);
const filteredListings: ProductChannelListing =
productChannelListings?.filter((channel: ProductChannelListing[0]) =>
listingIds.includes(channel.channel.id),
);

return (
<CardContainer cardTitle={children}>
{items.map(channel => (
{filteredListings.map((listing: ProductChannelListing[0]) => (
<ChannelsListItem
{...channel}
listings={productChannelListings}
key={channel.id}
{...listing}
id={listing.channel.id}
name={listing.channel.name}
key={listing.channel.id}
/>
))}
<Divider />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,24 @@ import React from "react";
import { useIntl } from "react-intl";

import { variantDetailsChannelsAvailabilityCardMessages as messages } from "./../messages";
import { Channel, ProductChannelListing } from "./../types";

type ChannelsListItemProps = Pick<Channel, "id" | "name"> & {
listings: ProductChannelListing;
};
interface ChannelsListItemProps {
id: string;
name: string;
isPublished: boolean;
publicationDate: string;
}

export const ChannelsListItem: React.FC<ChannelsListItemProps> = ({
id,
name,
listings,
isPublished,
publicationDate,
}) => {
const intl = useIntl();
const localizeDate = useDateLocalize();

const getItemSubtitle = (channelId: string) => {
const channelListing = listings.find(
({ channel }) => channel.id === channelId,
);

const { isPublished, publicationDate } = channelListing;

const getItemSubtitle = () => {
if (!isPublished) {
return intl.formatMessage(messages.itemSubtitleHidden);
}
Expand All @@ -53,7 +50,7 @@ export const ChannelsListItem: React.FC<ChannelsListItemProps> = ({
size="small"
data-test-id={`channels-variant-availability-item-subtitle-${id}`}
>
{getItemSubtitle(id)}
{getItemSubtitle()}
</Text>
</DashboardCard.Content>
</React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { variantDetailsChannelsAvailabilityCardMessages as messages } from "./..
interface CreateVariantTitleProps {
onManageClick: () => void;
disabled: boolean;
availabilityCount: Record<string, number>;
availabilityCount: Record<string, number | undefined>;
isEmpty: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import {
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs,
} from "@dashboard/channels/utils";
import {
ProductVariantCreateDataQuery,
ProductVariantFragment,
} from "@dashboard/graphql";
import { FormsetData } from "@dashboard/hooks/useFormset";

import {
getAvailabilityCountForProduct,
getAvailabilityCountForVariant,
} from "./availabilityCount";

const mockedListings = [
{
id: "1",
label: "Channel-PLN",
},
{
id: "2",
label: "Channel-USD",
},
] as unknown as FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>;

const mockedVariant = {
product: {
channelListings: [
{
channel: { id: "1" },
isPublished: true,
},
{
channel: { id: "2" },
isPublished: true,
},
],
},
} as unknown as ProductVariantFragment;

const mockedProduct = {
channelListings: [
{
channel: { id: "1" },
isPublished: true,
},
{
channel: { id: "2" },
isPublished: true,
},
],
} as unknown as ProductVariantCreateDataQuery["product"];

describe("getAvailabilityCountForVariant", () => {
it("should return correct counts when all channels are selected", () => {
// Arrange
const item = mockedVariant;
const listings = mockedListings;

// Act
const result = getAvailabilityCountForVariant(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 2,
availableChannelsCount: 2,
});
});

it("should return correct counts when some channels are selected", () => {
// Arrange
const item = mockedVariant;
const listings = mockedListings.slice(0, 1);

// Act
const result = getAvailabilityCountForVariant(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 1,
availableChannelsCount: 2,
});
});

it("should return correct counts when no channels are available", () => {
// Arrange
const item = mockedVariant;
const listings = [] as FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>;

// Act
const result = getAvailabilityCountForVariant(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 0,
availableChannelsCount: 2,
});
});
});

describe("getAvailabilityCountForProduct", () => {
it("should return correct counts when all channels are selected", () => {
// Arrange
const item = mockedProduct;
const listings = mockedListings;

// Act
const result = getAvailabilityCountForProduct(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 2,
availableChannelsCount: 2,
});
});

it("should return correct counts when some channels are selected", () => {
// Arrange
const item = mockedProduct;
const listings = mockedListings.slice(0, 1);

// Act
const result = getAvailabilityCountForProduct(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 1,
availableChannelsCount: 2,
});
});

it("should return correct counts when no channels are available", () => {
// Arrange
const item = mockedProduct;
const listings = [] as FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>;

// Act
const result = getAvailabilityCountForProduct(item, listings);

// Assert
expect(result).toEqual({
publishedInChannelsCount: 0,
availableChannelsCount: 2,
});
});
});
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
// @ts-strict-ignore
import {
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs,
} from "@dashboard/channels/utils";
import {
ProductVariantCreateDataQuery,
ProductVariantFragment,
} from "@dashboard/graphql";
import { FormsetData } from "@dashboard/hooks/useFormset";

export const getAvailabilityCountForVariant = (
item: ProductVariantFragment,
listings: FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>,
) => {
const variantChannelListingsChannelsIds = item.channelListings.map(
const allAvailableChannelsListings = item?.product?.channelListings?.map(
({ channel: { id } }) => id,
);

const allAvailableChannelsListings = item.product.channelListings.filter(
({ channel }) => variantChannelListingsChannelsIds.includes(channel.id),
);

const publishedInChannelsListings = allAvailableChannelsListings.filter(
({ isPublished }) => isPublished,
const selectedChannelListings = allAvailableChannelsListings?.filter(
listing => listings.some(lst => lst.id === listing),
);

return {
publishedInChannelsCount: publishedInChannelsListings.length,
availableChannelsCount: allAvailableChannelsListings.length,
publishedInChannelsCount: selectedChannelListings?.length,
availableChannelsCount: allAvailableChannelsListings?.length,
};
};

export const getAvailabilityCountForProduct = (
item: ProductVariantCreateDataQuery["product"],
listings: FormsetData<
ChannelPriceAndPreorderData,
IChannelPriceAndPreorderArgs
>,
) => {
const publishedInChannelsListings = item.channelListings.filter(
({ isPublished }) => isPublished,
const listingsIds = listings.map(({ id }) => id);
const publishedInChannelsListings = item?.channelListings?.filter(lst =>
listingsIds.includes(lst.channel.id),
);

return {
publishedInChannelsCount: publishedInChannelsListings.length,
availableChannelsCount: item.channelListings.length,
publishedInChannelsCount: publishedInChannelsListings?.length,
availableChannelsCount: item?.channelListings?.length,
};
};
Loading

0 comments on commit 6473419

Please sign in to comment.