mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
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...
This commit is contained in:
@@ -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
|
||||
49
app/reflexes/products_v3_reflex.rb
Normal file
49
app/reflexes/products_v3_reflex.rb
Normal file
@@ -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
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user