diff --git a/_includes/cart_controller.html b/_includes/cart_controller.html index 115249b..424c86d 100644 --- a/_includes/cart_controller.html +++ b/_includes/cart_controller.html @@ -1,5 +1,6 @@ data-controller="cart" data-target="stock.product" +data-sku="{{ include.product.sku }}" data-cart-url="{{ include.product.url }}" data-cart-variant-id="{{ include.product.variant_id }}" data-cart-image="{{ include.product.image.path | thumbnail: 212, 300 }}" diff --git a/_layouts/default.html b/_layouts/default.html index 69665ef..834dba4 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -52,7 +52,7 @@ {%- include_cached menu.html active_cache_key=page.layout %} -
+
{{ content }}
diff --git a/_packs/controllers/stock_controller.js b/_packs/controllers/stock_controller.js index b8cea93..d716913 100644 --- a/_packs/controllers/stock_controller.js +++ b/_packs/controllers/stock_controller.js @@ -12,59 +12,84 @@ export default class extends Controller { static targets = [ 'product' ] async connect () { - if (this.variant_ids.length === 0) return + const all_skus = this.skus - const ids = this.variant_ids.join(',') - const filter = { ids } - let response = await window.spree.products.list({ filter }) + if (all_skus.length === 0) return - // TODO: Gestionar errores - if (response.isFail()) { - console.error(response.fail()) - return - } + // El paginado es para prevenir que la petición se haga muy grande y + // falle entera. + const pages = Math.ceil(all_skus.length / this.per_page) - this.update_local_products(response.success().data) + let start = 0 + let end = this.per_page - // Recorrer todas las páginas - // XXX: Podríamos usar next pero la página 1 siempre se devuelve a - // sí misma y entraríamos en un loop infinito. - for (let page = 2; page <= response.success().meta.total_pages; page++) { - response = await window.spree.products.list({ filter, page }) + for (let local_page = 1; local_page <= pages; local_page++) { + const skus = all_skus.slice(start, end).join(',') + + start = this.per_page * local_page + end = start + this.per_page + + const filter = { skus } + let response = await window.spree.products.list({ filter }) - // TODO: Gestionar errores if (response.isFail()) { console.error(response.fail()) - continue + return } this.update_local_products(response.success().data) + + // Recorrer todas las páginas + // XXX: Podríamos usar next pero la página 1 siempre se devuelve a + // sí misma y entraríamos en un loop infinito. + for (let page = 2; page <= response.success().meta.total_pages; page++) { + response = await window.spree.products.list({ filter, page }) + + if (response.isFail()) { + console.error(response.fail()) + continue + } + + this.update_local_products(response.success().data) + } } } /* * La lista de todas las variantes incluidas en el controlador que no - * estén vacías. + * estén vacías. Usamos los SKUs porque no tenemos forma de filtrar + * por ID. * * @return [Array] */ - get variant_ids () { - if (!this._variant_ids) this._variant_ids = [...new Set(this.productTargets.map(p=> p.dataset.cartVariantId).filter(x => x.length > 0))] + get skus () { + return [...new Set(this.productTargets.map(p=> p.dataset.sku).filter(x => x.length > 0))] + } - return this._variant_ids + /* + * La cantidad de productos por página que vamos a pedir + */ + get per_page () { + if (!this._per_page) { + this._per_page = parseInt(this.element.dataset.perPage) + if (isNaN(this._per_page)) this._per_page = 100 + } + + return this._per_page } /* * Los productos pueden estar duplicados así que buscamos todos. */ update_local_products (products) { - for (const product of products) { - for (const local of this.productTargets.filter(local => local.dataset.cartVariantId === product.id)) { + for (const local of this.productTargets) { + for (const product of products.filter(p => local.dataset.cartVariantId === p.relationships.default_variant.data.id)) { local.dataset.cartInStock = product.attributes.in_stock local.dataset.cartPrice = product.attributes.price local.querySelectorAll('[data-stock-add]').forEach(button => button.disabled = !product.attributes.in_stock) - local.querySelectorAll('[data-stock-price]').forEach(price => price.innerText = product.attributes.display_price) + local.querySelectorAll('[data-stock-price]').forEach(price => price.innerText = parseInt(product.attributes.price)) + local.querySelectorAll('[data-stock-currency]').forEach(currency => currency.innerText = product.attributes.currency) } } }