- <%= select_tag 'per_page',
- options_for_select(per_page_options, index_params[:per_page]),
- class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
- data: {
- 'turbo-frame': turbo_frame,
- 'per-page-target': 'selector',
- action: 'change->per-page#reload'
- }
- %> <%= t('avo.per_page').downcase %>
-
- <% per_page_options.each do |option| %>
- <%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
- <% end %>
+
+
+
+
+
+
+ <%= select_tag 'per_page',
+ options_for_select(per_page_options, index_params[:per_page]),
+ class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
+ data: {
+ 'turbo-frame': turbo_frame,
+ 'per-page-target': 'selector',
+ action: 'change->per-page#reload'
+ }
+ %> <%= t('avo.per_page').downcase %>
+ <% per_page_options.each do |option| %>
+ <%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
+ <% end %>
-
-
- <% if @pagy.count > 0 %>
-
<%== helpers.pagy_info @pagy %>
- <% end %>
+
+
+
+ <% if @resource.pagination_type.default? %>
+
<%== helpers.pagy_info @pagy %>
+ <% end %>
- <% if @pagy.pages > 1 %>
- <%# @todo: add first & last page. make the first and last buttons rounded %>
- <%== helpers.pagy_nav @pagy %>
- <% end %>
-
+ <% if pagy.pages > 1 %>
+ <%# @todo: add first & last page. make the first and last buttons rounded %>
+ <%== helpers.pagy_nav @pagy %>
+ <% end %>
-<% end %>
+
diff --git a/app/components/avo/paginator_component.rb b/app/components/avo/paginator_component.rb
index edf55c5a2e..851c4ca9f9 100644
--- a/app/components/avo/paginator_component.rb
+++ b/app/components/avo/paginator_component.rb
@@ -24,4 +24,22 @@ def change_items_per_page_url(option)
helpers.resources_path(resource: resource, per_page: option, keep_query_params: true, page: 1)
end
end
+
+ def render?
+ return false if discreet_pagination && pagy.pages <= 1
+
+ @pagy.items > 0
+ end
+
+ def per_page_options
+ @per_page_options ||= begin
+ options = [*Avo.configuration.per_page_steps, Avo.configuration.per_page.to_i, index_params[:per_page].to_i]
+
+ if parent_model.present?
+ options.prepend Avo.configuration.via_per_page
+ end
+
+ options.sort.uniq
+ end
+ end
end
diff --git a/app/controllers/avo/application_controller.rb b/app/controllers/avo/application_controller.rb
index a7d583001f..7d7431134f 100644
--- a/app/controllers/avo/application_controller.rb
+++ b/app/controllers/avo/application_controller.rb
@@ -6,7 +6,6 @@ class ApplicationController < ::ActionController::Base
Avo::ApplicationController.include Pundit
end
- include Pagy::Backend
include Avo::ApplicationHelper
include Avo::UrlHelpers
include Avo::Concerns::Breadcrumbs
diff --git a/app/controllers/avo/base_controller.rb b/app/controllers/avo/base_controller.rb
index a47bb034d7..75a6a5521e 100644
--- a/app/controllers/avo/base_controller.rb
+++ b/app/controllers/avo/base_controller.rb
@@ -65,14 +65,7 @@ def index
).apply_query request, @query, filter_value
end
- extra_pagy_params = {}
-
- # Reset open filters when a user navigates to a new page
- extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
- "0"
- end
-
- @pagy, @models = pagy(@query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1], params: extra_pagy_params)
+ apply_pagination
# Create resources for each model
@resources = @models.map do |model|
@@ -543,5 +536,9 @@ def is_associated_record?
def set_pagy_locale
@pagy_locale = locale.to_s || Avo.configuration.locale || "en"
end
+
+ def apply_pagination
+ @pagy, @models = @resource.apply_pagination(index_params: @index_params, query: @query)
+ end
end
end
diff --git a/config/initializers/pagy.rb b/config/initializers/pagy.rb
index 0e5e2ce89e..85cf452c35 100644
--- a/config/initializers/pagy.rb
+++ b/config/initializers/pagy.rb
@@ -1,4 +1,5 @@
require "pagy/extras/trim"
+require "pagy/extras/countless"
# For locales without native pagy i18n support
def pagy_locale_path(file_name)
diff --git a/lib/avo/base_resource.rb b/lib/avo/base_resource.rb
index 6ef1b1aeee..4f61188ad6 100644
--- a/lib/avo/base_resource.rb
+++ b/lib/avo/base_resource.rb
@@ -8,6 +8,7 @@ class BaseResource
include Avo::Concerns::HasEditableControls
include Avo::Concerns::HasStimulusControllers
include Avo::Concerns::ModelClassConstantized
+ include Avo::Concerns::Pagination
delegate :view_context, to: ::Avo::App
delegate :current_user, to: ::Avo::App
diff --git a/lib/avo/concerns/pagination.rb b/lib/avo/concerns/pagination.rb
new file mode 100644
index 0000000000..f99cd172e9
--- /dev/null
+++ b/lib/avo/concerns/pagination.rb
@@ -0,0 +1,53 @@
+module Avo
+ module Concerns
+ module Pagination
+ extend ActiveSupport::Concern
+
+ included do
+ include Pagy::Backend
+
+ class_attribute :pagination, default: {}
+
+ PAGINATION_METHOD = {
+ default: :pagy,
+ countless: :pagy_countless,
+ } unless defined? PAGINATION_METHOD
+
+ PAGINATION_DEFAULTS = {
+ type: :default,
+ size: [1, 2, 2, 1],
+ } unless defined? PAGINATION_DEFAULTS
+ end
+
+ def pagination_type
+ @pagination_type ||= ActiveSupport::StringInquirer.new(pagination_hash[:type].to_s)
+ end
+
+ def apply_pagination(index_params:, query:)
+ extra_pagy_params = {}
+
+ # Reset open filters when a user navigates to a new page
+ extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
+ "0"
+ end
+
+ send PAGINATION_METHOD[pagination_type.to_sym],
+ query,
+ items: index_params[:per_page],
+ link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"",
+ params: extra_pagy_params,
+ size: pagination_hash[:size]
+ end
+
+ private
+
+ def pagination_hash
+ @pagination ||= PAGINATION_DEFAULTS.merge Avo::ExecutionContext.new(
+ target: pagination,
+ resource: self,
+ view: @view
+ ).handle
+ end
+ end
+ end
+end
diff --git a/lib/generators/avo/templates/locales/avo.en.yml b/lib/generators/avo/templates/locales/avo.en.yml
index d9e318088f..b41a6859fc 100644
--- a/lib/generators/avo/templates/locales/avo.en.yml
+++ b/lib/generators/avo/templates/locales/avo.en.yml
@@ -80,6 +80,7 @@ en:
to_top: Move record to top
per_page: Per page
prev_page: Previous page
+ records_selected_from_all_pages_html: All records selected from all pages
remove_selection: Remove selection
reset_filters: Reset filters
resource_created: Record created
@@ -121,4 +122,5 @@ en:
zero: no more items
x_records_selected_from_a_total_of_x_html:
%{selected} records selected on this page from a total of
%{count}
x_records_selected_from_all_pages_html:
%{count} records selected from all pages
+ x_records_selected_from_page_html:
%{selected} records selected on this page
you_missed_something_check_form: You might have missed something. Please check the form.
diff --git a/lib/generators/avo/templates/locales/avo.fr.yml b/lib/generators/avo/templates/locales/avo.fr.yml
index 404263ed48..a52270cdbf 100644
--- a/lib/generators/avo/templates/locales/avo.fr.yml
+++ b/lib/generators/avo/templates/locales/avo.fr.yml
@@ -80,6 +80,7 @@ fr:
to_top: Déplacer tout en haut
per_page: Par page
prev_page: Page précédente
+ records_selected_from_all_pages_html: tous les éléments sélectionnés de toutes les pages
remove_selection: Supprimer la sélection
reset_filters: Réinitialiser les filtres
resource_created: Ressource créee
@@ -117,4 +118,5 @@ fr:
zero: aucun élément supplémentaire
x_records_selected_from_a_total_of_x_html:
%{selected} enregistrements sélectionnés sur cette page sur un total de
%{count}
x_records_selected_from_all_pages_html:
%{count} enregistrements sélectionnés dans toutes les pages
+ x_records_selected_from_page_html:
%{selected} éléments sélectionnés de cette page
you_missed_something_check_form: Vous avez peut-être oublié quelque chose. Veuillez vérifier le formulaire
diff --git a/lib/generators/avo/templates/locales/avo.pt-BR.yml b/lib/generators/avo/templates/locales/avo.pt-BR.yml
index 95713d55ef..e0963466f3 100644
--- a/lib/generators/avo/templates/locales/avo.pt-BR.yml
+++ b/lib/generators/avo/templates/locales/avo.pt-BR.yml
@@ -80,6 +80,7 @@ pt-BR:
to_top: Mover registro para cima
per_page: Por página
prev_page: Página anterior
+ records_selected_from_all_pages_html: Todos os registros de todas as páginas selecionados
remove_selection: Remover seleção
reset_filters: Limpar filtros
resource_created: Recurso criado
@@ -117,4 +118,5 @@ pt-BR:
zero: mais nenhum item
x_records_selected_from_a_total_of_x_html:
%{selected} registros selecionados nesta página de um total de
%{count}
x_records_selected_from_all_pages_html:
%{count} registros selecionados de todas as páginas
+ x_records_selected_from_page_html:
%{selected} registros selecionados nesta página
you_missed_something_check_form: Você pode ter esquecido algo. Por favor, cheque o formulário.
diff --git a/lib/generators/avo/templates/locales/avo.pt.yml b/lib/generators/avo/templates/locales/avo.pt.yml
index 2e02198f5a..512adafcd2 100644
--- a/lib/generators/avo/templates/locales/avo.pt.yml
+++ b/lib/generators/avo/templates/locales/avo.pt.yml
@@ -80,6 +80,7 @@ pt:
to_top: Mover recurso para o topo
per_page: Por página
prev_page: Página anterior
+ records_selected_from_all_pages_html: Todos os itens de todas as páginas selecionados
remove_selection: Remover seleção
reset_filters: Limpar filtros
resource_created: Recurso criado
@@ -117,4 +118,5 @@ pt:
zero: mais nenhum item
x_records_selected_from_a_total_of_x_html:
%{selected} itens selecionados nesta página de um total de
%{count}
x_records_selected_from_all_pages_html:
%{count} itens selecionados de todas as páginas
+ x_records_selected_from_page_html:
%{selected} itens selecionados nesta página
you_missed_something_check_form: Pode ter-se esquecido algo. Por favor, verifique o formulário.
diff --git a/lib/generators/avo/templates/locales/avo.ro.yml b/lib/generators/avo/templates/locales/avo.ro.yml
index 27508de16a..fe5449c7cc 100644
--- a/lib/generators/avo/templates/locales/avo.ro.yml
+++ b/lib/generators/avo/templates/locales/avo.ro.yml
@@ -80,6 +80,7 @@ ro:
to_top: Mutați înregistrarea sus de tot
per_page: Pe pagină
prev_page: Pagina anterioara
+ records_selected_from_all_pages_html: Toate selectate din toate paginile
remove_selection: Șterge selecția
reset_filters: Resetați filtrele
resource_created: Resursă creata
@@ -117,4 +118,5 @@ ro:
zero: zero articole
x_records_selected_from_a_total_of_x_html:
%{selected} selectate dintr-un total de
%{count}
x_records_selected_from_all_pages_html:
%{count} selectate din toate paginile
+ x_records_selected_from_page_html:
%{selected} selectate
you_missed_something_check_form: S-ar putea să fi omis ceva. Vă rugăm să verificați formularul.
diff --git a/spec/system/avo/select_all_spec.rb b/spec/system/avo/select_all_spec.rb
index 74459c2639..683626065d 100644
--- a/spec/system/avo/select_all_spec.rb
+++ b/spec/system/avo/select_all_spec.rb
@@ -37,68 +37,115 @@
expect(page).to have_text "#{total_fish} fish released with message '' by ."
end
+ end
- context "press undo" do
- it "releases the fish from the selected page" do
- visit url
+ context "press undo" do
+ it "releases the fish from the selected page" do
+ visit url
- check_select_all
- expect_all_message
+ check_select_all
+ expect_all_message
- click_on "Select all matching"
- expect_all_matching_message
+ click_on "Select all matching"
+ expect_all_matching_message
- click_on "Undo"
- expect_all_message
+ click_on "Undo"
+ expect_all_message
- release_fish
+ release_fish
- expect(page).to have_text "#{per_page} fish released with message '' by ."
- end
+ expect(page).to have_text "#{per_page} fish released with message '' by ."
end
+ end
- context "uncheck one of them" do
- it "releases the fish from the selected page - 1" do
- visit url
+ context "uncheck one of them" do
+ it "releases the fish from the selected page - 1" do
+ visit url
- check_select_all
- expect_all_message
+ check_select_all
+ expect_all_message
- click_on "Select all matching"
- expect_all_matching_message
+ click_on "Select all matching"
+ expect_all_matching_message
- uncheck_first_record
- release_fish
+ uncheck_first_record
+ release_fish
- expect(page).to have_text "#{per_page - 1} fish released with message '' by ."
- end
+ expect(page).to have_text "#{per_page - 1} fish released with message '' by ."
end
end
+ end
+
+ describe "with applyed filters" do
+ context "select all" do
+ it "releases all fish from applyed filter" do
+ visit url
+
+ open_filters_menu
+ expect(page).to have_text "Name filter"
+ fill_in "avo_filters_name_filter", with: "Spec Salmon"
+ click_on "Filter by name"
+ wait_for_loaded
+
+ check_select_all
+ expect(page).to have_text "#{per_page} records selected on this page from a total of #{spec_salmon_number}"
+
+ click_on "Select all matching"
- describe "with applyed filters" do
+ expect(page).to have_text "#{spec_salmon_number} records selected from all pages"
+ release_fish
+
+ expect(page).to have_text "#{spec_salmon_number} fish released with message '' by ."
+ end
+ end
+
+ describe "countless resource" do
context "select all" do
- it "releases all fish from applyed filter" do
+ it "display contless messages" do
+ pagination = FishResource.pagination
+ FishResource.pagination = -> do
+ {
+ type: :countless
+ }
+ end
+
visit url
- open_filters_menu
- expect(page).to have_text "Name filter"
- fill_in "avo_filters_name_filter", with: "Spec Salmon"
- click_on "Filter by name"
- wait_for_loaded
+ within('nav.pagy-nav.pagination') do
+ expect(page).to have_css('span.page.active', text: '1')
+ expect(page).to have_css('span.page', text: '2')
+ end
check_select_all
- expect(page).to have_text "#{per_page} records selected on this page from a total of #{spec_salmon_number}"
+ expect(page).to have_text "2 records selected on this page"
click_on "Select all matching"
+ expect(page).to have_text "All records selected from all pages"
+
+ FishResource.pagination = -> do
+ {
+ type: :countless,
+ size: []
+ }
+ end
+
+ visit url
- expect(page).to have_text "#{spec_salmon_number} records selected from all pages"
- release_fish
+ within('nav.pagy-nav.pagination') do
+ expect(page).not_to have_css('span.page.active', text: '1')
+ expect(page).not_to have_css('span.page', text: '2')
+ end
- expect(page).to have_text "#{spec_salmon_number} fish released with message '' by ."
+ check_select_all
+ expect(page).to have_text "2 records selected on this page"
+
+ click_on "Select all matching"
+ expect(page).to have_text "All records selected from all pages"
+
+ FishResource.pagination = pagination
end
end
end
-
end
end