From: Tom Hughes Date: Wed, 28 Aug 2024 18:03:53 +0000 (+0100) Subject: Merge remote-tracking branch 'upstream/pull/5126' X-Git-Tag: live~193 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/549a46c867002c974224bc86cc5933edd8acef94?hp=10a4c5cf6e1165a9db6e9b87d0fa19d7f97b51bf Merge remote-tracking branch 'upstream/pull/5126' --- diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index 5c7b2d26e..4f3c414f5 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -396,7 +396,7 @@ $(document).ready(function () { OSM.router.load(); $(document).on("click", "a", function (e) { - if (e.isDefaultPrevented() || e.isPropagationStopped()) { + if (e.isDefaultPrevented() || e.isPropagationStopped() || $(e.target).data("turbo")) { return; } diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index a5ddaf364..ba04b9a17 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -75,22 +75,33 @@ class ChangesetsController < ApplicationController end def show - @type = "changeset" @changeset = Changeset.find(params[:id]) - @comments = if current_user&.moderator? - @changeset.comments.unscope(:where => :visible).includes(:author) - else - @changeset.comments.includes(:author) - end - @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "node_page") - @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "way_page") - @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "relation_page") - if @changeset.user.active? && @changeset.user.data_public? - changesets = conditions_nonempty(@changeset.user.changesets) - @next_by_user = changesets.where("id > ?", @changeset.id).reorder(:id => :asc).first - @prev_by_user = changesets.where(:id => ...@changeset.id).reorder(:id => :desc).first + case turbo_frame_request_id + when "changeset_nodes" + @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "node_page") + render :partial => "elements", :locals => { :type => "node", :elements => @nodes, :pages => @node_pages } + when "changeset_ways" + @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "way_page") + render :partial => "elements", :locals => { :type => "way", :elements => @ways, :pages => @way_pages } + when "changeset_relations" + @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "relation_page") + render :partial => "elements", :locals => { :type => "relation", :elements => @relations, :pages => @relation_pages } + else + @comments = if current_user&.moderator? + @changeset.comments.unscope(:where => :visible).includes(:author) + else + @changeset.comments.includes(:author) + end + @node_pages, @nodes = paginate(:old_nodes, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "node_page") + @way_pages, @ways = paginate(:old_ways, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "way_page") + @relation_pages, @relations = paginate(:old_relations, :conditions => { :changeset_id => @changeset.id }, :per_page => 20, :parameter => "relation_page") + if @changeset.user.active? && @changeset.user.data_public? + changesets = conditions_nonempty(@changeset.user.changesets) + @next_by_user = changesets.where("id > ?", @changeset.id).reorder(:id => :asc).first + @prev_by_user = changesets.where(:id => ...@changeset.id).reorder(:id => :desc).first + end + render :layout => map_layout end - render :layout => map_layout rescue ActiveRecord::RecordNotFound render :template => "browse/not_found", :status => :not_found, :layout => map_layout end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index f53a8dad5..fe900d627 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -27,12 +27,11 @@ class IssuesController < ApplicationController # If search if params[:search_by_user].present? @find_user = User.find_by(:display_name => params[:search_by_user]) - if @find_user - @issues = @issues.where(:reported_user => @find_user) - else - @issues = @issues.none - flash.now[:warning] = t(".user_not_found") - end + @issues = if @find_user + @issues.where(:reported_user => @find_user) + else + @issues.none + end end @issues = @issues.where(:status => params[:status]) if params[:status].present? diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 658c43483..7d86796b1 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -88,6 +88,16 @@ class MessagesController < ApplicationController @title = @message.title + render :action => "new" + elsif message.sender == current_user + @message = Message.new( + :recipient => message.recipient, + :title => "Re: #{message.title.sub(/^Re:\s*/, '')}", + :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}" + ) + + @title = @message.title + render :action => "new" else flash[:notice] = t ".wrong_user", :user => current_user.display_name diff --git a/app/helpers/browse_helper.rb b/app/helpers/browse_helper.rb index c8fc8245c..0ea10e219 100644 --- a/app/helpers/browse_helper.rb +++ b/app/helpers/browse_helper.rb @@ -70,14 +70,14 @@ module BrowseHelper "nofollow" if object.tags.empty? end - def type_and_paginated_count(type, pages) + def type_and_paginated_count(type, pages, selected_page = pages.current_page) if pages.page_count == 1 t ".#{type.pluralize}", :count => pages.item_count else t ".#{type.pluralize}_paginated", - :x => pages.current_page.first_item, - :y => pages.current_page.last_item, + :x => selected_page.first_item, + :y => selected_page.last_item, :count => pages.item_count end end @@ -93,14 +93,14 @@ module BrowseHelper link_classes = ["page-link", { "px-1" => width > max_width_for_default_padding }] tag.ul :class => "pagination pagination-sm mb-1 ms-auto" do - pagination_items(pages, {}).each do |body, n| - linked = !(n.is_a? String) + pagination_items(pages, {}).each do |body, page_or_class| + linked = !(page_or_class.is_a? String) link = if linked - link_to body, url_for(page_param => n), :class => link_classes + link_to body, url_for(page_param => page_or_class.number), :class => link_classes, **yield(page_or_class) else tag.span body, :class => link_classes end - concat tag.li link, :class => ["page-item", { n => !linked }] + concat tag.li link, :class => ["page-item", { page_or_class => !linked }] end end end diff --git a/app/views/changesets/_elements.html.erb b/app/views/changesets/_elements.html.erb new file mode 100644 index 000000000..fd5dd8a26 --- /dev/null +++ b/app/views/changesets/_elements.html.erb @@ -0,0 +1,12 @@ +<%= turbo_frame_tag "changeset_#{type.pluralize}" do %> + <%= render :partial => "paging_nav", :locals => { :type => type, :pages => pages } %> + +<% end %> diff --git a/app/views/changesets/_paging_nav.html.erb b/app/views/changesets/_paging_nav.html.erb index aa7ee23b9..fbdf1d507 100644 --- a/app/views/changesets/_paging_nav.html.erb +++ b/app/views/changesets/_paging_nav.html.erb @@ -1,6 +1,11 @@

<%= type_and_paginated_count(type, pages) %>

<% if pages.page_count > 1 %> - <%= sidebar_classic_pagination(pages, "#{type}_page") %> + <%= sidebar_classic_pagination(pages, "#{type}_page") do |page| + { + :title => type_and_paginated_count(type, pages, page), + :data => { :turbo => "true" } + } + end %> <% end %>
diff --git a/app/views/changesets/show.html.erb b/app/views/changesets/show.html.erb index 915b0ef35..13f40ce50 100644 --- a/app/views/changesets/show.html.erb +++ b/app/views/changesets/show.html.erb @@ -90,42 +90,15 @@ <% end %> <% unless @ways.empty? %> - <%= render :partial => "paging_nav", :locals => { :type => "way", :pages => @way_pages } %> - + <%= render :partial => "elements", :locals => { :type => "way", :elements => @ways, :pages => @way_pages } %> <% end %> <% unless @relations.empty? %> - <%= render :partial => "paging_nav", :locals => { :type => "relation", :pages => @relation_pages } %> - + <%= render :partial => "elements", :locals => { :type => "relation", :elements => @relations, :pages => @relation_pages } %> <% end %> <% unless @nodes.empty? %> - <%= render :partial => "paging_nav", :locals => { :type => "node", :pages => @node_pages } %> - + <%= render :partial => "elements", :locals => { :type => "node", :elements => @nodes, :pages => @node_pages } %> <% end %> diff --git a/app/views/issues/_page.html.erb b/app/views/issues/_page.html.erb index 2c0340c11..b46b1798c 100644 --- a/app/views/issues/_page.html.erb +++ b/app/views/issues/_page.html.erb @@ -1,36 +1,44 @@ - - - - - - - - - - - - <% @issues.each do |issue| %> + <% if @issues.length == 0 %> + <% if params[:search_by_user].present? && !@find_user %> +

<%= t ".user_not_found" %>

+ <% else %> +

<%= t ".issues_not_found" %>

+ <% end %> + <% else %> +
<%= t ".status" %><%= t ".reports" %><%= t ".reported_item" %><%= t ".reported_user" %><%= t ".last_updated" %>
+ - - - - - + + + + + - <% end %> - -
<%= t ".states.#{issue.status}" %><%= link_to t(".reports_count", :count => issue.reports_count), issue %><%= link_to reportable_title(issue.reportable), reportable_url(issue.reportable) %><%= link_to issue.reported_user.display_name, issue.reported_user if issue.reported_user %> - <% 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 %> - <%= t ".status" %><%= t ".reports" %><%= t ".reported_item" %><%= t ".reported_user" %><%= t ".last_updated" %>
- <%= render "shared/pagination", - :newer_key => "issues.page.newer_issues", - :older_key => "issues.page.older_issues", - :newer_id => @newer_issues_id, - :older_id => @older_issues_id %> + + + <% @issues.each do |issue| %> + + <%= t ".states.#{issue.status}" %> + <%= link_to t(".reports_count", :count => issue.reports_count), issue %> + <%= link_to reportable_title(issue.reportable), reportable_url(issue.reportable) %> + <%= link_to issue.reported_user.display_name, issue.reported_user if issue.reported_user %> + + <% 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 %> + + + <% end %> + + + <%= render "shared/pagination", + :newer_key => "issues.page.newer_issues", + :older_key => "issues.page.older_issues", + :newer_id => @newer_issues_id, + :older_id => @older_issues_id %> + <% end %>
diff --git a/app/views/issues/index.html.erb b/app/views/issues/index.html.erb index 6234f755f..95dfbf6f2 100644 --- a/app/views/issues/index.html.erb +++ b/app/views/issues/index.html.erb @@ -4,7 +4,7 @@

<%= t ".search_guidance" %>

-<%= form_tag(issues_path, :method => :get) do %> +<%= form_tag(issues_path, :method => :get, :data => { "turbo" => true, "turbo-frame" => "pagination", "turbo-action" => "advance" }) do %>
<%= select_tag :status, @@ -40,8 +40,4 @@
<% end %> -<% if @issues.length == 0 %> -

<%= t ".issues_not_found" %>

-<% else %> - <%= render :partial => "page" %> -<% end %> +<%= render :partial => "page" %> diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index 8fe508469..99d6d0435 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -18,8 +18,8 @@
<%= @message.body.to_html %>
+ <%= link_to t(".reply_button"), message_reply_path(@message), :class => "btn btn-primary" %> <% if current_user == @message.recipient %> - <%= link_to t(".reply_button"), message_reply_path(@message), :class => "btn btn-primary" %> <%= link_to t(".unread_button"), message_mark_path(@message, :mark => "unread"), :method => "post", :class => "btn btn-primary" %> <%= link_to t(".destroy_button"), message_path(@message), :method => "delete", :class => "btn btn-danger" %> <% else %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a435eb8a4..dfad0230e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1468,14 +1468,14 @@ en: not_updated: Not Updated search: Search search_guidance: "Search Issues:" - user_not_found: User does not exist - issues_not_found: No such issues found link_to_reports: View Reports states: ignored: Ignored open: Open resolved: Resolved page: + user_not_found: User does not exist + issues_not_found: No such issues found reported_user: Reported User status: Status reports: Reports diff --git a/lib/classic_pagination/pagination_helper.rb b/lib/classic_pagination/pagination_helper.rb index 72d16fc98..c450de4e1 100644 --- a/lib/classic_pagination/pagination_helper.rb +++ b/lib/classic_pagination/pagination_helper.rb @@ -145,7 +145,7 @@ module ActionView items = [] if always_show_anchors && !(wp_first = window_pages[0]).first? - items.push [first.number.to_s, first.number] + items.push [first.number.to_s, first] items.push ["...", "disabled"] if wp_first.number - first.number > 1 end @@ -153,13 +153,13 @@ module ActionView if current_page == page && !link_to_current_page items.push [page.number.to_s, "active"] else - items.push [page.number.to_s, page.number] + items.push [page.number.to_s, page] end end if always_show_anchors && !(wp_last = window_pages[-1]).last? items.push ["...", "disabled"] if last.number - wp_last.number > 1 - items.push [last.number.to_s, last.number] + items.push [last.number.to_s, last] end items diff --git a/test/controllers/messages_controller_test.rb b/test/controllers/messages_controller_test.rb index b39aed77b..52a856beb 100644 --- a/test/controllers/messages_controller_test.rb +++ b/test/controllers/messages_controller_test.rb @@ -263,6 +263,21 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest end assert Message.find(message.id).message_read + # Login as the sending user + session_for(user) + + # Check that the message reply page loads + get message_reply_path(message) + assert_response :success + assert_template "new" + assert_select "title", "Re: #{message.title} | OpenStreetMap" + assert_select "form[action='/messages']", :count => 1 do + assert_select "input[type='hidden'][name='display_name'][value='#{recipient_user.display_name}']" + assert_select "input#message_title[value='Re: #{message.title}']", :count => 1 + assert_select "textarea#message_body", :count => 1 + assert_select "input[type='submit'][value='Send']", :count => 1 + end + # Asking to reply to a message with a bogus ID should fail get message_reply_path(99999) assert_response :not_found @@ -292,21 +307,23 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest # Login as the message sender session_for(user) - # Check that the message sender can read the message + # Check that the message sender can read the message and that Reply button is available get message_path(message) assert_response :success assert_template "show" assert_select "a[href='#{user_path recipient_user}']", :text => recipient_user.display_name + assert_select "a.btn.btn-primary", :text => "Reply" assert_not Message.find(message.id).message_read # Login as the message recipient session_for(recipient_user) - # Check that the message recipient can read the message + # Check that the message recipient can read the message and that Reply button is available get message_path(message) assert_response :success assert_template "show" assert_select "a[href='#{user_path user}']", :text => user.display_name + assert_select "a.btn.btn-primary", :text => "Reply" assert Message.find(message.id).message_read # Asking to read a message with a bogus ID should fail diff --git a/test/system/changeset_elements_test.rb b/test/system/changeset_elements_test.rb new file mode 100644 index 000000000..9e65f5be2 --- /dev/null +++ b/test/system/changeset_elements_test.rb @@ -0,0 +1,75 @@ +require "application_system_test_case" + +class ChangesetElementsTest < ApplicationSystemTestCase + test "can navigate between element subpages without losing comment input" do + element_page_size = 20 + changeset = create(:changeset, :closed) + ways = create_list(:way, element_page_size + 1, :with_history, :changeset => changeset) + way_paths = ways.map { |way| way_path(way) } + nodes = create_list(:node, element_page_size + 1, :with_history, :changeset => changeset) + node_paths = nodes.map { |node| node_path(node) } + + sign_in_as(create(:user)) + visit changeset_path(changeset) + + within_sidebar do + next_page_way_path = assert_one_missing_link way_paths + assert_no_link "Ways (1-20 of 21)" + assert_link "Ways (21-21 of 21)" + + assert_one_missing_link node_paths + assert_no_link "Nodes (1-20 of 21)" + assert_link "Nodes (21-21 of 21)" + + fill_in "text", :with => "Comment text we don't want to lose" + + click_on "Ways (21-21 of 21)" + + assert_one_present_link way_paths, next_page_way_path + assert_link "Ways (1-20 of 21)" + assert_no_link "Ways (21-21 of 21)" + + next_page_node_path = assert_one_missing_link node_paths + assert_no_link "Nodes (1-20 of 21)" + assert_link "Nodes (21-21 of 21)" + + assert_field "text", :with => "Comment text we don't want to lose" + + click_on "Nodes (21-21 of 21)" + + assert_one_present_link way_paths, next_page_way_path + assert_link "Ways (1-20 of 21)" + assert_no_link "Ways (21-21 of 21)" + + assert_one_present_link node_paths, next_page_node_path + assert_link "Nodes (1-20 of 21)" + assert_no_link "Nodes (21-21 of 21)" + + assert_field "text", :with => "Comment text we don't want to lose" + end + end + + private + + def assert_one_missing_link(hrefs) + missing_href = nil + hrefs.each do |href| + missing = true + assert_link :href => href, :minimum => 0, :maximum => 1 do + missing = false + end + if missing + assert_nil missing_href, "unexpected extra missing link '#{href}'" + missing_href = href + end + end + assert_not_nil missing_href, "expected one link missing but all are present" + missing_href + end + + def assert_one_present_link(hrefs, present_href) + hrefs.each do |href| + assert_link :href => href, :count => (href == present_href ? 1 : 0) + end + end +end diff --git a/test/system/issues_test.rb b/test/system/issues_test.rb index 4d58b9cfc..ab2330e31 100644 --- a/test/system/issues_test.rb +++ b/test/system/issues_test.rb @@ -19,7 +19,7 @@ class IssuesTest < ApplicationSystemTestCase sign_in_as(create(:moderator_user)) visit issues_path - assert_content I18n.t("issues.index.issues_not_found") + assert_content I18n.t("issues.page.issues_not_found") end def test_view_issues @@ -81,22 +81,22 @@ class IssuesTest < ApplicationSystemTestCase visit issues_path fill_in "search_by_user", :with => good_user.display_name click_on "Search" - assert_no_content I18n.t("issues.index.user_not_found") - assert_content I18n.t("issues.index.issues_not_found") + assert_no_content I18n.t("issues.page.user_not_found") + assert_content I18n.t("issues.page.issues_not_found") # User doesn't exist visit issues_path 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_content I18n.t("issues.page.user_not_found") + assert_no_content I18n.t("issues.page.issues_not_found") # Find Issue against bad_user visit issues_path fill_in "search_by_user", :with => bad_user.display_name click_on "Search" - assert_no_content I18n.t("issues.index.user_not_found") - assert_no_content I18n.t("issues.index.issues_not_found") + assert_no_content I18n.t("issues.page.user_not_found") + assert_no_content I18n.t("issues.page.issues_not_found") end def test_commenting @@ -173,20 +173,20 @@ class IssuesTest < ApplicationSystemTestCase 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_no_content I18n.t("issues.page.user_not_found") + assert_no_content I18n.t("issues.page.issues_not_found") assert_css "tr", :count => 51 # Second Page click_on I18n.t("issues.page.older_issues") - assert_no_content I18n.t("issues.index.user_not_found") - assert_no_content I18n.t("issues.index.issues_not_found") + assert_no_content I18n.t("issues.page.user_not_found") + assert_no_content I18n.t("issues.page.issues_not_found") assert_css "tr", :count => 31 # Back to First Page click_on I18n.t("issues.page.newer_issues") - assert_no_content I18n.t("issues.index.user_not_found") - assert_no_content I18n.t("issues.index.issues_not_found") + assert_no_content I18n.t("issues.page.user_not_found") + assert_no_content I18n.t("issues.page.issues_not_found") assert_css "tr", :count => 51 end end