GlobalData.Settings.EnableMyProductMixselectItem when a product is clicked{
"items": [
{
"productId": "Product Id",
"productVariantId": "Variant Id",
"title": "Sample product title",
"sku": "Sample text",
"imageUrl": "https://example.com/media/sample.jpg",
"alias": "sample-product-alias",
"dimension1Name": "Sample text",
"dimension1Value": "Sample text",
"dimension2Name": "Sample text",
"dimension2Value": "Sample text",
"lastPurchasedPrice": 0,
"lastPurchasedQuantity": 1,
"lastPurchasedAtUtc": "2026-01-01T00:00:00.0000000+00:00",
"lastPurchasedTotal": 0,
"lastPurchasedTotalText": "Sample price text",
"currentPrice": 0,
"canOrder": false,
"minOrderQuantity": 1,
"maxOrderQuantity": 99,
"orderQuantityStep": 1,
"sellOutOfStock": true,
"stock": 0,
"quantityConstraints": {
"additive": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
},
"absolute": {
"minimum": 1,
"maximum": 999999,
"step": 1,
"isValid": true
}
}
},
"..."
],
"currentPage": 1,
"totalPages": 2,
"totalCount": 23,
"pageSize": 20,
"name": "ProductMixList",
"view": "Default",
"section": "SectionA",
"settings": {
"id": "Component Id",
"section": "SectionA",
"type": "NoirProductMixList",
"name": "ProductMixList",
"configuredInContentApi": true,
"view": "Default",
"displayName": "",
"cssClass": ""
},
"translations": {
"myProductMix": "Sample text",
"noProducts": "Sample text",
"noProductsDescription": "Sample text",
"...": "..."
}
}settings.iditems[]currentPage, totalPages, totalCount, pageSizesettings.cssClassimageUrl (falls back to global no-image)dimension1Name, dimension1Value, dimension2Name, dimension2ValuequantityConstraints.*minOrderQuantity, maxOrderQuantity, orderQuantitySteptranslations.*Components/ProductMixList/Default.js exposes:<section
x-data='productmixlistdefault.initComponent(items, currentPage, totalPages, totalCount, pageSize, errorMessages)'
>currentPage, pageSize, totalCount, totalPages, currentSort) and the errorMessages mapping.debounceMap, cancelTokenMap) used by quantity updates.item._qty from quantityConstraints.additive.minimum (fallback 0).generatePages().items whose productVariantId matches the given id._qty) for a variant id as a number (0 when missing).selectItem event for a clicked product, using prepareListProducts(...) plus the provided list name and position.el-GR "day month year" string via Intl.DateTimeFormat. Returns an empty string for missing/invalid dates.servicesreusabledefault.fetchProductMixProducts(params).page, pageSize, and orderBy (current sort) as query params.items, re-seeds _qty, updates pagination from paginationDTO, and rebuilds pages.currentSort and refetches starting at page 1.newPage is passed (within range and different from the current page), calls fetchList(newPage) and scrolls to top.pages array used by the pagination UI.totalPages <= 7; otherwise uses a condensed window with "..." placeholders around the current page._qty by quantityConstraints.additive.step (clamped to maximum), then schedules a debounced update via debounceUpdateProduct(...)._qty by quantityConstraints.additive.step (clamped to minimum), then schedules a debounced update via debounceUpdateProduct(...).updateQuantity(..., false)._qty immediately for UI feedback.useDebounce is true, delegates to debounceUpdateProduct(...) and returns.servicesreusabledefault.updateProductQuantity(data, cancelToken), and on success sets _qty from response.data.additiveQuantity.value; on failure it shows a toast.servicesreusabledefault.addToCart(...).lineFailures, maps each failure to translated messages via getLineFailureMessages(...) and shows them as toasts._qty / quantityConstraints from the added cart item.GET /api/product-mix/my-list?page=<n>&pageSize=<n>&orderBy=<sort>servicesreusabledefault.fetchProductMixProducts(params)GET /api/product-mix/my-list?... used by fetchList.servicesreusabledefault.updateProductQuantity({ productId, productVariantId, requestedQuantity }, cancelToken)servicesreusabledefault.addToCart(productId, productVariantId, quantity, currentPrice, originalPrice)fetch (for list paging)prepareListProducts(...)sendGAEvent(...)toastservicesreusabledefault.addToCart(...) for add-to-cart.GlobalData.Settings.EnableMyProductMix.generatePages()), so they must stay in sync.{% for item in items %}<template x-for="..."> after any fetch/update (updateFlag).errorMessages JSON string in Liquid and passes it to initComponent(...).items is empty.quantityConstraints.additive.isValid == false.GlobalData.Settings.noImage (fallback to theme Assets/images/no-image.svg).--loading modifier class is applied.