import React from 'react' import Button from '../Button/Button' import Icon from '../Icons/Icon' import Image from '../Image/Image' import Tag from '../Tag/Tag' import { toast } from '../Toast/Toast' import Tooltip from '../Tooltip/Tooltip' import TrimText from '../TrimText/TrimText' import { useIsMobileView } from '../../hooks/useIsMobileView/useIsMobileView' import type { ImageProps } from '../Image/Image' import type { TagProps } from '../Tag/Tag' import styles from './_primary-cell.module.scss' import { c } from '../../translations/LibraryTranslationService' import SellingInfoTooltip from './SellingInfoTooltip' interface Marketplace { name: string link?: string } interface BaseProps { /** sortBy prop object which must include the `prop` value in order to highlight selected sort */ sortBy: { prop: string; order?: 'asc' | 'desc' } /** the sold_by_iserve and/or sold_by_threepn values as an object */ soldBy?: { iserve?: boolean threepn?: boolean } /** an array of tag objects which include the text, color and (if applicable) solid values */ tags?: TagProps[] /** the main display text */ title: string /** the main display text trim length */ titleTrimTextLimit?: number /** the prop string associated with the title value in the product object (for sorting) */ titleProp?: string /** id props: the id value, the label to display (such as `ID` or `asin`) and the prop associated with the id value in the product object (for sorting) */ uniqId: { id: string | number idLabel: string idName: string enableCopyIdButton?: boolean } /** the image prop object which includes {alt, url} and custom classes and image styles */ imageProps?: ImageProps /** product description text */ description?: string /** Optional prop to add a test id to the PrimaryTableCell for QA testing */ qaTestId?: string } type CellWithLink = BaseProps & { /** URL that goes to the product information page for the selected product */ productLink: string /** Router component (e.g. Using Link from react-router-dom) */ routerComponent: React.ElementType /** Allow any props to be passed in */ routerProp: string } type CellWithoutLink = BaseProps & { productLink?: never routerComponent?: never routerProp?: never } type PrimaryTableLinkAndBaseProps = CellWithLink | CellWithoutLink type LegacyMarketplaceProps = { /** @deprecated Use marketplaces prop instead. */ externalLink?: string /** @deprecated Use marketplaces prop instead. */ marketplaceNames?: string[] | string /** Cannot be used with legacy marketplace props */ marketplaces?: never } type NewMarketplaceProps = { /** @deprecated Use marketplaces prop instead. Cannot be used with marketplaces prop */ externalLink?: never /** @deprecated Use marketplaces prop instead. Cannot be used with marketplaces prop */ marketplaceNames?: never /** Array of marketplace objects with name and individual links */ marketplaces?: Marketplace[] } export type PrimaryTableCellProps = PrimaryTableLinkAndBaseProps & (LegacyMarketplaceProps | NewMarketplaceProps) const PrimaryTableCell = (props: PrimaryTableCellProps): React.JSX.Element => { const { imageProps, title, titleProp = 'name', titleTrimTextLimit = 60, tags, externalLink, marketplaceNames, uniqId, sortBy, soldBy, description, routerComponent, routerProp, productLink, qaTestId = 'primary-table-cell', } = props const isMobileView = useIsMobileView() const RouterComponent = routerComponent const marketplaces = 'marketplaces' in props ? props.marketplaces : undefined const { id, idLabel, idName, enableCopyIdButton } = uniqId const productImage = () => { return } const productTitle = () => { return (
) } const productMarketplaces = () => { const baseClassName = ['marketplace_name', 'marketplace_names'].includes( sortBy.prop, ) ? styles.semibold : '' if (marketplaces && marketplaces.length > 0) { if (marketplaces.length === 1) { const marketplace = marketplaces[0] return ( {marketplace.link ? ( { // This is to prevent any parent events to trigger when this external link is clicked. e.stopPropagation() }} > {marketplace.name} ) : ( {marketplace.name} )} ) } else { // Multiple marketplaces: render with variations format like the original // Show only first 3 marketplaces in main display, but keep total count const displayMarketplaces = marketplaces.slice(0, 3) const totalCount = marketplaces.length // Only show variations text when there are more than 3 marketplaces let variationsText = '' if (totalCount > 3) { // Use translation to get the proper format const marketplaceNamesString = displayMarketplaces .map((m) => m.name) .join(', ') const translatedText = c('marketplaceVariations', { marketplaceNames: marketplaceNamesString, numberVariations: totalCount, }) // Extract the " - X Variations" part from the translation variationsText = translatedText.replace(marketplaceNamesString, '') } // Create tooltip content for all marketplaces if more than 3 const tooltipContent = totalCount > 3 ? (
{marketplaces.map((marketplace) => marketplace.link ? ( { e.stopPropagation() }} > {marketplace.name} ) : ( {marketplace.name} ), )}
) : null return ( {displayMarketplaces.map((marketplace, index) => ( {marketplace.link ? ( { // This is to prevent any parent events to trigger when this external link is clicked. e.stopPropagation() }} > {marketplace.name} ) : ( {marketplace.name} )} {index < displayMarketplaces.length - 1 ? ', ' : null} ))} {variationsText && (tooltipContent ? ( {variationsText} ) : ( variationsText ))} ) } } // Fallback to original logic return ( {Array.isArray(marketplaceNames) ? marketplaceNames.length === 1 ? marketplaceNames[0] : c('marketplaceVariations', { marketplaceNames: marketplaceNames.join(', '), numberVariations: marketplaceNames.length, }) : marketplaceNames} ) } const routerComponentProps = routerProp && productLink ? { [routerProp]: productLink, } : {} return (
{/* PREFIX CONTAINER */}
{productLink && RouterComponent ? ( {productImage()} ) : ( productImage() )}
{/* BODY CONTAINER */}
{/* TITLE */} {productLink && RouterComponent ? ( {productTitle()} ) : ( productTitle() )}
{/* ID */} {id && ( <>
{`${idLabel}: ${id}`} {enableCopyIdButton ? ( ) : null}
{/* DIVIDER */} {((marketplaceNames && marketplaceNames.length > 0) || (marketplaces && marketplaces.length > 0)) && ( | )} )}
{/* MARKETPLACES */} {marketplaces && marketplaces.length > 0 ? ( productMarketplaces() ) : externalLink ? ( { // This is to prevent any parent events to trigger when this external link is clicked. e.stopPropagation() }} > {productMarketplaces()} ) : ( // No external link productMarketplaces() )} {/* SOLD BY */} {(soldBy?.iserve || soldBy?.threepn) && ( <> | )}
{description && ( )} {/* TAGS */} {!!tags && (
{tags?.map((tag, i) => ( // using index as key because it could be possible to have duplicate tag names ))}
)}
) } export default PrimaryTableCell