Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-orphaned-sales-channel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/dashboard": patch
---

fix(admin): handle null sales channel references in product list and detail views
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,45 @@ export const SalesChannelsCell = ({
}: SalesChannelsCellProps) => {
const { t } = useTranslation()

if (!salesChannels || !salesChannels.length) {
// Filter out null/undefined entries that can occur when a sales channel
// is deleted but the product association is not cleaned up
const validChannels = salesChannels?.filter(
(sc): sc is SalesChannelDTO => sc != null
)

if (!validChannels || !validChannels.length) {
return <PlaceholderCell />
}

if (salesChannels.length > 2) {
if (validChannels.length > 2) {
return (
<div className="flex h-full w-full items-center gap-x-1 overflow-hidden">
<span className="truncate">
{salesChannels
{validChannels
.slice(0, 2)
.map((sc) => sc.name)
.join(", ")}
</span>
<Tooltip
content={
<ul>
{salesChannels.slice(2).map((sc) => (
{validChannels.slice(2).map((sc) => (
<li key={sc.id}>{sc.name}</li>
))}
</ul>
}
>
<span className="text-xs">
{t("general.plusCountMore", {
count: salesChannels.length - 2,
count: validChannels.length - 2,
})}
</span>
</Tooltip>
</div>
)
}

const channels = salesChannels.map((sc) => sc.name).join(", ")
const channels = validChannels.map((sc) => sc.name).join(", ")

return (
<div className="flex h-full w-full items-center overflow-hidden max-w-[250px]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ export const ProductSalesChannelSection = ({
const { count } = useSalesChannels()
const { t } = useTranslation()

// Filter out null/undefined entries that can occur when a sales channel
// is deleted but the product association is not cleaned up
const availableInSalesChannels =
product.sales_channels?.map((sc) => ({
id: sc.id,
name: sc.name,
})) ?? []
product.sales_channels
?.filter((sc) => sc != null)
.map((sc) => ({
id: sc.id,
name: sc.name,
})) ?? []

const firstChannels = availableInSalesChannels.slice(0, 3)
const restChannels = availableInSalesChannels.slice(3)
Expand Down
Loading