From 5aebbe410285475f271c8b01fa67a52604760255 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Bellet Date: Tue, 27 Jun 2023 11:44:36 +0200 Subject: [PATCH] use `beforeFetch` and `afterFetch` lifecycle methods + Move outside `Admin` module the reflex Therefore, this reflex should be _equivalent_ to its javascript controller: `ProductsV3` (relation is made through names) Remove unwanted line Actually call StimulusJS controller instead of calling the reflex itself In order to have this "showLoading", "hideLoading" behavior. It seems to be possible to directly use the Reflex itself (use `data-reflex` instead of `data-action`) but I can't make it work: the `stimulus-controller:after` event is never broadcasted/catched (but `stimulus-controller:before` yes...) Documentation: https://docs.stimulusreflex.com/guide/reflexes.html#understanding-stimulusreflex-controllers https://docs.stimulusreflex.com/guide/lifecycle.html#generic-life-cycle-methods Maybe @dacook if you want to have a look... --- app/reflexes/admin/products_v3_reflex.rb | 51 ------------------- app/reflexes/products_v3_reflex.rb | 49 ++++++++++++++++++ .../admin/products_v3/_content.html.haml | 2 +- app/views/admin/shared/v3/_pagy.html.haml | 6 +-- .../controllers/productsV3_controller.js | 19 +++++-- 5 files changed, 68 insertions(+), 59 deletions(-) delete mode 100644 app/reflexes/admin/products_v3_reflex.rb create mode 100644 app/reflexes/products_v3_reflex.rb diff --git a/app/reflexes/admin/products_v3_reflex.rb b/app/reflexes/admin/products_v3_reflex.rb deleted file mode 100644 index 0bfc63431a..0000000000 --- a/app/reflexes/admin/products_v3_reflex.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -module Admin - class ProductsV3Reflex < ApplicationReflex - include Pagy::Backend - - def fetch - fetch_products(element.dataset.page || 1) - - cable_ready.replace( - selector: "#products-content", - html: render(partial: "admin/products_v3/content", - locals: { products: @products, pagy: @pagy }) - ).broadcast - - morph :nothing - end - - private - - # copied from ProductsTableComponent - def fetch_products(page) - product_query = OpenFoodNetwork::Permissions.new(current_user) - .editable_products.merge(product_scope) - @pagy, @products = pagy(product_query.order(:name), items: 15, page:) - end - - def product_scope - scope = if current_user.has_spree_role?("admin") || current_user.enterprises.present? - Spree::Product - else - Spree::Product.active - end - - scope.includes(product_query_includes) - end - - # Optimise by pre-loading required columns - def product_query_includes - # TODO: add other fields used in columns? (eg supplier: [:name]) - [ - # variants: [ - # :default_price, - # :stock_locations, - # :stock_items, - # :variant_overrides - # ] - ] - end - end -end diff --git a/app/reflexes/products_v3_reflex.rb b/app/reflexes/products_v3_reflex.rb new file mode 100644 index 0000000000..79e7a6055e --- /dev/null +++ b/app/reflexes/products_v3_reflex.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +class ProductsV3Reflex < ApplicationReflex + include Pagy::Backend + + def fetch + fetch_products(element.dataset.page || 1, element.dataset.per_page || 15) + + cable_ready.replace( + selector: "#products-content", + html: render(partial: "admin/products_v3/content", + locals: { products: @products, pagy: @pagy }) + ).broadcast + + morph :nothing + end + + private + + # copied from ProductsTableComponent + def fetch_products(page, per_page) + product_query = OpenFoodNetwork::Permissions.new(current_user) + .editable_products.merge(product_scope) + @pagy, @products = pagy(product_query.order(:name), items: per_page, page:) + end + + def product_scope + scope = if current_user.has_spree_role?("admin") || current_user.enterprises.present? + Spree::Product + else + Spree::Product.active + end + + scope.includes(product_query_includes) + end + + # Optimise by pre-loading required columns + def product_query_includes + # TODO: add other fields used in columns? (eg supplier: [:name]) + [ + # variants: [ + # :default_price, + # :stock_locations, + # :stock_items, + # :variant_overrides + # ] + ] + end +end diff --git a/app/views/admin/products_v3/_content.html.haml b/app/views/admin/products_v3/_content.html.haml index 8ac13d94eb..fd94e0fd91 100644 --- a/app/views/admin/products_v3/_content.html.haml +++ b/app/views/admin/products_v3/_content.html.haml @@ -4,7 +4,7 @@ .sixteen.columns = render partial: 'sort', locals: { pagy: pagy } = render partial: 'table', locals: { products: products } - = render partial: 'admin/shared/v3/pagy', locals: { pagy: pagy, reflex: "click->Admin::ProductsV3#fetch" } + = render partial: 'admin/shared/v3/pagy', locals: { pagy: pagy, action: "click->productsV3#fetch" } - else #no-products = t('.no_products_found') diff --git a/app/views/admin/shared/v3/_pagy.html.haml b/app/views/admin/shared/v3/_pagy.html.haml index 016b1c2f2f..03a1c65016 100644 --- a/app/views/admin/shared/v3/_pagy.html.haml +++ b/app/views/admin/shared/v3/_pagy.html.haml @@ -1,20 +1,20 @@ %nav.pagy_nav.pagination{"aria-label" => "pager", :role => "navigation"} - if pagy.prev - %a.page.previous{ href: "#", "data-reflex": reflex, "data-page": pagy.prev || 1, "aria-label": "previous"} + %a.page.prev{ href: "#", "data-action": action, "data-page": pagy.prev || 1, "aria-label": "previous"} %i.icon-chevron-left - else %span.page.prev.disabled %i.icon-chevron-left - pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] - if item.is_a?(Integer) # page link - %a.page{ href: "#", "data-reflex": reflex, "data-page": item, "aria-label": "page #{item}"} + %a.page{ href: "#", "data-action": action, "data-page": item, "aria-label": "page #{item}"} = item - elsif item.is_a?(String) # current page %span.page.current= item - elsif item == :gap # page gap %span.page.gap … - if pagy.next - %a.page.next{ href: "#", "data-reflex": reflex, "data-page": pagy.next || pagy.last, "aria-label": "next"} + %a.page.next{ href: "#", "data-action": action, "data-page": pagy.next || pagy.last, "aria-label": "next"} %i.icon-chevron-right - else %span.page.next.disabled diff --git a/app/webpacker/controllers/productsV3_controller.js b/app/webpacker/controllers/productsV3_controller.js index 9a034b69e0..4e783f26c3 100644 --- a/app/webpacker/controllers/productsV3_controller.js +++ b/app/webpacker/controllers/productsV3_controller.js @@ -6,12 +6,15 @@ export default class extends ApplicationController { connect() { super.connect(); // Fetch the products on page load - this.load(); + this.fetch(); } - load = () => { - this.showLoading(); - this.stimulate("Admin::ProductsV3#fetch").then(() => this.hideLoading()); + fetch = (event = {}) => { + if (event && event.target) { + this.stimulate("ProductsV3#fetch", event.target); + return; + } + this.stimulate("ProductsV3#fetch"); }; hideLoading = () => { @@ -21,4 +24,12 @@ export default class extends ApplicationController { showLoading = () => { this.loadingTarget.classList.remove("hidden"); }; + + beforeFetch(element, reflex, noop, reflexId) { + this.showLoading(); + } + + afterFetch(element, reflex, noop, reflexId) { + this.hideLoading(); + } }