diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index c24054f77f..f26764db3a 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -1,4 +1,6 @@ class IssuesController < ApplicationController + include PaginationMethods + layout "site" before_action :authorize_web @@ -11,14 +13,17 @@ class IssuesController < ApplicationController before_action :check_database_writable, :only => [:resolve, :ignore, :reopen] def index + @params = params.permit(:before, :after, :limit, :status, :search_by_user, :issue_type, :last_updated_by) + @params[:limit] ||= 50 @title = t ".title" + @user_not_found = false @issue_types = [] @issue_types.push("Note", "User") if current_user.moderator? @issue_types.push("DiaryEntry", "DiaryComment", "User") if current_user.administrator? @users = User.joins(:roles).where(:user_roles => { :role => current_user.roles.map(&:role) }).distinct - @issues = Issue.visible_to(current_user).order(:updated_at => :desc) + @issues = Issue.visible_to(current_user) # If search if params[:search_by_user].present? @@ -27,7 +32,7 @@ def index @issues = @issues.where(:reported_user => @find_user) else @issues = @issues.none - flash.now[:warning] = t(".user_not_found") + @user_not_found = true end end @@ -39,6 +44,8 @@ def index last_updated_by = params[:last_updated_by].to_s == "nil" ? nil : params[:last_updated_by].to_i @issues = @issues.where(:updated_by => last_updated_by) end + + @issues, @newer_issues_id, @older_issues_id = get_page_items(@issues, :limit => @params[:limit]) end def show diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 523f90846a..044d41d7e0 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -4,72 +4,81 @@ <p><%= t ".search_guidance" %></p> -<%= form_tag(issues_path, :method => :get) do %> - <div class="row gx-1"> - <div class="mb-3 col-md-auto"> - <%= select_tag :status, - options_for_select(Issue.aasm.states.map(&:name).map { |state| [t(".states.#{state}"), state] }, params[:status]), - :include_blank => t(".select_status"), - :data => { :behavior => "category_dropdown" }, - :class => "form-select" %> +<turbo-frame> + <%= form_tag(issues_path, :method => :get, :data => { :turbo_frame => "pagination" }) do %> + <div class="row gx-1"> + <div class="mb-3 col-md-auto"> + <%= select_tag :status, + options_for_select(Issue.aasm.states.map(&:name).map { |state| [t(".states.#{state}"), state] }, params[:status]), + :include_blank => t(".select_status"), + :data => { :behavior => "category_dropdown" }, + :class => "form-select" %> + </div> + <div class="mb-3 col-md-auto"> + <%= select_tag :issue_type, + options_for_select(@issue_types, params[:issue_type]), + :include_blank => t(".select_type"), + :data => { :behavior => "category_dropdown" }, + :class => "form-select" %> + </div> + <div class="mb-3 col-md"> + <%= text_field_tag :search_by_user, + params[:search_by_user], + :placeholder => t(".reported_user"), + :autocomplete => "on", + :class => "form-control" %> + </div> + <div class="mb-3 col-md-auto"> + <%= select_tag :last_updated_by, + options_for_select(@users.all.collect { |f| [f.display_name, f.id] } << [t(".not_updated"), "nil"], params[:last_updated_by]), + :include_blank => t(".select_last_updated_by"), + :data => { :behavior => "category_dropdown" }, + :class => "form-select" %> + </div> + <div class="mb-3 col-md-auto"> + <%= submit_tag t(".search"), :name => nil, :class => "btn btn-primary" %> + </div> </div> - <div class="mb-3 col-md-auto"> - <%= select_tag :issue_type, - options_for_select(@issue_types, params[:issue_type]), - :include_blank => t(".select_type"), - :data => { :behavior => "category_dropdown" }, - :class => "form-select" %> - </div> - <div class="mb-3 col-md"> - <%= text_field_tag :search_by_user, - params[:search_by_user], - :placeholder => t(".reported_user"), - :autocomplete => "on", - :class => "form-control" %> - </div> - <div class="mb-3 col-md-auto"> - <%= select_tag :last_updated_by, - options_for_select(@users.all.collect { |f| [f.display_name, f.id] } << [t(".not_updated"), "nil"], params[:last_updated_by]), - :include_blank => t(".select_last_updated_by"), - :data => { :behavior => "category_dropdown" }, - :class => "form-select" %> - </div> - <div class="mb-3 col-md-auto"> - <%= submit_tag t(".search"), :name => nil, :class => "btn btn-primary" %> - </div> - </div> -<% end %> + <% end %> +</turbo-frame> -<% if @issues.length == 0 %> - <p><%= t ".issues_not_found" %></p> -<% else %> - <table class="table table-sm"> - <thead> - <tr> - <th><%= t ".status" %></th> - <th><%= t ".reports" %></th> - <th><%= t ".reported_item" %></th> - <th><%= t ".reported_user" %></th> - <th><%= t ".last_updated" %></th> - </tr> - </thead> - <tbody> - <% @issues.each do |issue| %> +<turbo-frame id="pagination" data-turbo-action="advance"> + <% if @issues.length == 0 %> + <p><%= t(@user_not_found ? ".user_not_found" : ".issues_not_found") %></p> + <% else %> + <table class="table table-sm"> + <thead> <tr> - <td><%= t ".states.#{issue.status}" %></td> - <td class="text-nowrap"><%= link_to t(".reports_count", :count => issue.reports_count), issue %></td> - <td><%= link_to reportable_title(issue.reportable), reportable_url(issue.reportable) %></td> - <td><%= link_to issue.reported_user.display_name, issue.reported_user if issue.reported_user %></td> - <td> - <% if issue.user_updated %> - <%= t ".last_updated_time_ago_user_html", :user => link_to(issue.user_updated.display_name, issue.user_updated), - :time_ago => friendly_date_ago(issue.updated_at) %> - <% else %> - <%= friendly_date_ago(issue.updated_at) %> - <% end %> - </td> + <th><%= t ".status" %></th> + <th><%= t ".reports" %></th> + <th><%= t ".reported_item" %></th> + <th><%= t ".reported_user" %></th> + <th><%= t ".last_updated" %></th> </tr> - <% end %> - </tbody> - </table> -<% end %> + </thead> + <tbody> + <% @issues.each do |issue| %> + <tr> + <td><%= t ".states.#{issue.status}" %></td> + <td class="text-nowrap"><%= link_to t(".reports_count", :count => issue.reports_count), issue, "data-turbo-frame" => "_top" %></td> + <td><%= link_to reportable_title(issue.reportable), reportable_url(issue.reportable), "data-turbo-frame" => "_top" %></td> + <td><%= link_to issue.reported_user.display_name, issue.reported_user, "data-turbo-frame" => "_top" if issue.reported_user %></td> + <td> + <% if issue.user_updated %> + <%= t ".last_updated_time_ago_user_html", :user => link_to(issue.user_updated.display_name, issue.user_updated, "data-turbo-frame" => "_top"), + :time_ago => friendly_date_ago(issue.updated_at) %> + <% else %> + <%= friendly_date_ago(issue.updated_at) %> + <% end %> + </td> + </tr> + <% end %> + </tbody> + </table> + <%= render "shared/pagination", + :newer_key => "issues.index.newer_issues", + :older_key => "issues.index.older_issues", + :newer_id => @newer_issues_id, + :older_id => @older_issues_id %> + <% end %> +</turbo-frame> diff --git a/config/locales/en.yml b/config/locales/en.yml index dc7f1a1c0e..68ea34ae91 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1480,6 +1480,8 @@ en: ignored: Ignored open: Open resolved: Resolved + older_issues: Older Issues + newer_issues: Newer Issues show: title: "%{status} Issue #%{issue_id}" reports: diff --git a/test/system/issues_test.rb b/test/system/issues_test.rb index b9b989c075..ce26258a2c 100644 --- a/test/system/issues_test.rb +++ b/test/system/issues_test.rb @@ -89,7 +89,7 @@ def test_search_issues_by_user fill_in "search_by_user", :with => "Nonexistent User" click_on "Search" assert_content I18n.t("issues.index.user_not_found") - assert_content I18n.t("issues.index.issues_not_found") + assert_no_content I18n.t("issues.index.issues_not_found") # Find Issue against bad_user visit issues_path @@ -161,4 +161,32 @@ def test_issue_index_with_multiple_roles assert_link I18n.t("issues.index.reports_count", :count => issue1.reports_count), :href => issue_path(issue1) assert_link I18n.t("issues.index.reports_count", :count => issue2.reports_count), :href => issue_path(issue2) end + + def test_issues_pagination + 1.upto(80).each do + user = create(:user) + create(:issue, :reportable => user, :reported_user => user, :assigned_role => "administrator") + end + + sign_in_as(create(:administrator_user)) + + visit issues_path + + # First Page + assert_no_content I18n.t("issues.index.user_not_found") + assert_no_content I18n.t("issues.index.issues_not_found") + assert_css "tr", :count => 51 + + # Second Page + click_on I18n.t("issues.index.older_issues") + assert_no_content I18n.t("issues.index.user_not_found") + assert_no_content I18n.t("issues.index.issues_not_found") + assert_css "tr", :count => 31, :wait => 1 + + # Back to First Page + click_on I18n.t("issues.index.newer_issues") + assert_no_content I18n.t("issues.index.user_not_found") + assert_no_content I18n.t("issues.index.issues_not_found") + assert_css "tr", :count => 51, :wait => 1 + end end