summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/revisions_controller.rb22
-rw-r--r--app/helpers/revisions_helper.rb17
-rw-r--r--app/views/layouts/_nav_controls.html.erb3
-rw-r--r--app/views/node_actions/_change_details.html.erb4
-rw-r--r--app/views/page_translations/edit.html.erb2
-rw-r--r--app/views/page_translations/show.html.erb2
-rw-r--r--app/views/revisions/diff.html.erb84
-rw-r--r--app/views/revisions/index.html.erb10
-rw-r--r--app/views/revisions/show.html.erb6
-rw-r--r--public/stylesheets/admin.css13
-rw-r--r--test/controllers/revisions_controller_test.rb4
11 files changed, 97 insertions, 70 deletions
diff --git a/app/controllers/revisions_controller.rb b/app/controllers/revisions_controller.rb
index cddb9e72..b8e66218 100644
--- a/app/controllers/revisions_controller.rb
+++ b/app/controllers/revisions_controller.rb
@@ -8,9 +8,9 @@ class RevisionsController < ApplicationController
8 layout 'admin' 8 layout 'admin'
9 9
10 def index 10 def index
11 @node = Node.find(params[:node_id]) 11 @node = Node.find(params[:node_id])
12 @pages = @node.pages.all 12 @pages = @node.pages.all
13 @locale = resolve_locale(params[:locale]) 13 @translation_locale = resolve_locale(params[:translation_locale])
14 end 14 end
15 15
16 def diff 16 def diff
@@ -31,21 +31,21 @@ class RevisionsController < ApplicationController
31 redirect_to(node_path(@node)) and return 31 redirect_to(node_path(@node)) and return
32 end 32 end
33 33
34 @locale_summary = @end.locale_diff_summary(@start) 34 @locale_summary = @end.locale_diff_summary(@start)
35 requested_locale = params[:locale].presence&.to_sym 35 requested_locale = params[:translation_locale].presence&.to_sym
36 default_locale = @locale_summary.find { |s| s[:changed] }&.dig(:locale) || I18n.default_locale 36 default_locale = @locale_summary.find { |s| s[:changed] }&.dig(:locale) || I18n.default_locale
37 @locale = @locale_summary.any? { |s| s[:locale] == requested_locale } ? requested_locale : default_locale 37 @translation_locale = @locale_summary.any? { |s| s[:locale] == requested_locale } ? requested_locale : default_locale
38 38
39 @diff_view = params[:view] == "side_by_side" ? :side_by_side : :inline 39 @diff_view = params[:view] == "side_by_side" ? :side_by_side : :inline
40 @diff = @end.diff_against(@start, view: @diff_view, locale: @locale) 40 @diff = @end.diff_against(@start, view: @diff_view, locale: @translation_locale)
41 @available_layer_pairs = @node.available_layer_pairs 41 @available_layer_pairs = @node.available_layer_pairs
42 @locked_by_other = @node.locked? && @node.lock_owner != current_user 42 @locked_by_other = @node.locked? && @node.lock_owner != current_user
43 end 43 end
44 44
45 def show 45 def show
46 @node = Node.find(params[:node_id]) 46 @node = Node.find(params[:node_id])
47 @page = @node.pages.find(params[:id]) 47 @page = @node.pages.find(params[:id])
48 @locale = resolve_locale(params[:locale]) 48 @translation_locale = resolve_locale(params[:translation_locale])
49 end 49 end
50 50
51 def restore 51 def restore
diff --git a/app/helpers/revisions_helper.rb b/app/helpers/revisions_helper.rb
index a6290133..25a2aa38 100644
--- a/app/helpers/revisions_helper.rb
+++ b/app/helpers/revisions_helper.rb
@@ -4,4 +4,21 @@ module RevisionsHelper
4 def describe_page_reference(ref) 4 def describe_page_reference(ref)
5 %w[head draft autosave].include?(ref.to_s) ? ref.to_s.capitalize : "revision #{ref}" 5 %w[head draft autosave].include?(ref.to_s) ? ref.to_s.capitalize : "revision #{ref}"
6 end 6 end
7
8 def neighbour_revision_pairs node, start_ref, end_ref
9 return [nil, nil] unless start_ref.to_s.match?(/\A\d+\z/) &&
10 end_ref.to_s.match?(/\A\d+\z/)
11
12 a, b = start_ref.to_i, end_ref.to_i
13 return [nil, nil] unless (a - b).abs == 1
14
15 lo, hi = [a, b].minmax
16 forward = a < b
17 earlier = forward ? [lo - 1, lo] : [lo, lo - 1]
18 later = forward ? [hi, hi + 1] : [hi + 1, hi]
19
20 [earlier, later].map do |pair|
21 pair if pair.all? { |rev| node.pages.exists?(:revision => rev) }
22 end
23 end
7end 24end
diff --git a/app/views/layouts/_nav_controls.html.erb b/app/views/layouts/_nav_controls.html.erb
index bae1082b..70d5130c 100644
--- a/app/views/layouts/_nav_controls.html.erb
+++ b/app/views/layouts/_nav_controls.html.erb
@@ -9,7 +9,8 @@
9<% end %> 9<% end %>
10 10
11<span class="nav_group"> 11<span class="nav_group">
12 <%= link_to url_for(locale: (:en unless I18n.locale == :en)), 12 <% locale_target = request.query_parameters.symbolize_keys.except(:controller, :action, :only_path, :host, :port, :protocol, :anchor, :script_name).merge(:locale => (:en unless I18n.locale == :en)) %>
13 <%= link_to url_for(locale_target),
13 class: "nav_toggle nav_locale", 14 class: "nav_toggle nav_locale",
14 "aria-label" => t(".switch_locale"), title: t(".switch_locale") do %> 15 "aria-label" => t(".switch_locale"), title: t(".switch_locale") do %>
15 <%= I18n.locale == :en ? "DE" : "EN" %> 16 <%= I18n.locale == :en ? "DE" : "EN" %>
diff --git a/app/views/node_actions/_change_details.html.erb b/app/views/node_actions/_change_details.html.erb
index 19e2fe29..2da8bfd5 100644
--- a/app/views/node_actions/_change_details.html.erb
+++ b/app/views/node_actions/_change_details.html.erb
@@ -25,9 +25,9 @@
25 <br/> 25 <br/>
26 <% if action_entry.page && action_entry.node %> 26 <% if action_entry.page && action_entry.node %>
27 <% if (diff_params = action_entry.diff_link_params) %> 27 <% if (diff_params = action_entry.diff_link_params) %>
28 <%= link_to t("node_actions.view_diff"), diff_node_revisions_path(action_entry.node, diff_params.merge(:locale => locale)) %> 28 <%= link_to t("node_actions.view_diff"), diff_node_revisions_path(action_entry.node, diff_params.merge(:translation_locale => locale)) %>
29 <% else %> 29 <% else %>
30 <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page, :locale => locale) %> 30 <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page, :translation_locale => locale) %>
31 <% end %> 31 <% end %>
32 <% end %> 32 <% end %>
33 </td> 33 </td>
diff --git a/app/views/page_translations/edit.html.erb b/app/views/page_translations/edit.html.erb
index f398a544..fb879568 100644
--- a/app/views/page_translations/edit.html.erb
+++ b/app/views/page_translations/edit.html.erb
@@ -2,7 +2,7 @@
2 <%= t(".editing_prefix") %> <strong><%= @locale.to_s.upcase %></strong> <%= t(".translation_of") %> <strong><%= title_for_node(@node) %></strong>. 2 <%= t(".editing_prefix") %> <strong><%= @locale.to_s.upcase %></strong> <%= t(".translation_of") %> <strong><%= title_for_node(@node) %></strong>.
3</div> 3</div>
4 4
5<p class="node_action_bar standalone_action_bar"><%= link_to t("page_translations.revision_history_link"), node_revisions_path(@node, :locale => @locale) %></p> 5<p class="node_action_bar standalone_action_bar"><%= link_to t("page_translations.revision_history_link"), node_revisions_path(@node, :translation_locale => @locale) %></p>
6 6
7<p class="field_hint"> 7<p class="field_hint">
8 <%= t(".metadata_hint_prefix") %> <%= link_to t(".metadata_hint_link"), edit_node_path(@node) %>. 8 <%= t(".metadata_hint_prefix") %> <%= link_to t(".metadata_hint_link"), edit_node_path(@node) %>.
diff --git a/app/views/page_translations/show.html.erb b/app/views/page_translations/show.html.erb
index 0fbcd0b6..5f94ac38 100644
--- a/app/views/page_translations/show.html.erb
+++ b/app/views/page_translations/show.html.erb
@@ -1,6 +1,6 @@
1<h1><%= t(".title") %> — <%= title_for_node(@node) %></h1> 1<h1><%= t(".title") %> — <%= title_for_node(@node) %></h1>
2 2
3<p class="node_action_bar standalone_action_bar"><%= link_to t("page_translations.revision_history_link"), node_revisions_path(@node, :locale => @locale) %></p> 3<p class="node_action_bar standalone_action_bar"><%= link_to t("page_translations.revision_history_link"), node_revisions_path(@node, :translation_locale => @locale) %></p>
4 4
5<div class="translation_compare"> 5<div class="translation_compare">
6 <div class="translation_compare_column"> 6 <div class="translation_compare_column">
diff --git a/app/views/revisions/diff.html.erb b/app/views/revisions/diff.html.erb
index 1318bd37..ba320365 100644
--- a/app/views/revisions/diff.html.erb
+++ b/app/views/revisions/diff.html.erb
@@ -4,57 +4,51 @@
4 <%= link_to t(".revisions_link"), node_revisions_path(@node) %> 4 <%= link_to t(".revisions_link"), node_revisions_path(@node) %>
5</p> 5</p>
6 6
7<p class="diff_comparison_label"> 7<% numeric_comparison = params[:start_revision].to_s =~ /\A\d+\z/ && params[:end_revision].to_s =~ /\A\d+\z/ %>
8 <%= t(".comparing") %> <strong><%= describe_page_reference(params[:start_revision]) %></strong> 8<% start_control = numeric_comparison ?
9 <%= t(".against") %> <strong><%= describe_page_reference(params[:end_revision]) %></strong> 9 select_tag(:start_revision, options_for_select(@node.pages.map(&:revision), params[:start_revision].to_i)) :
10 <%= t(".showing_prefix") %> <strong><%= @locale.to_s.upcase %></strong> <%= t(".translation_suffix") %> 10 content_tag(:strong, describe_page_reference(params[:start_revision])) + hidden_field_tag(:start_revision, params[:start_revision]) %>
11</p> 11<% end_control = numeric_comparison ?
12 select_tag(:end_revision, options_for_select(@node.pages.map(&:revision), params[:end_revision].to_i)) :
13 content_tag(:strong, describe_page_reference(params[:end_revision])) + hidden_field_tag(:end_revision, params[:end_revision]) %>
14<% locale_control = select_tag(:translation_locale, options_for_select(
15 @locale_summary.map { |s| [s[:changed] ? t("revisions.locale_changed", :lang => s[:locale].to_s.upcase) : s[:locale].to_s.upcase, s[:locale]] },
16 @translation_locale)) %>
17<% view_control = select_tag(:view, options_for_select(
18 [[t("revisions.inline"), "inline"], [t("revisions.side_by_side"), "side_by_side"]], @diff_view.to_s)) %>
19<% earlier, later = neighbour_revision_pairs(@node, params[:start_revision], params[:end_revision]) %>
12 20
13<% if @locale_summary.size > 1 %> 21<%= form_tag diff_node_revisions_path(@node), :method => :get, :class => "diff_controls" do %>
14 <p class="diff_locale_toggle"> 22 <p class="diff_comparison_label">
15 <%= t("revisions.locale_label") %> 23 <%= t(".comparing_html", :start => start_control, :end => end_control,
16 <% @locale_summary.each_with_index do |s, i| %> 24 :lang => locale_control, :view => view_control) %>
17 <%= " &middot; ".html_safe if i > 0 %> 25 </p>
18 <% label = "#{s[:locale].to_s.upcase}#{' *' if s[:changed]}" %> 26 <p class="node_action_bar standalone_action_bar diff_step_bar">
19 <% if s[:locale] == @locale %> 27 <% if earlier %>
20 <strong><%= label %></strong> 28 <%= link_to t(".pair_link", :from => earlier.first, :to => earlier.last), diff_node_revisions_path(@node,
21 <% else %> 29 start_revision: earlier.first, end_revision: earlier.last,
22 <%= link_to label, diff_node_revisions_path(@node, start_revision: params[:start_revision], end_revision: params[:end_revision], view: @diff_view, locale: s[:locale]) %> 30 view: @diff_view, translation_locale: @translation_locale) %>
23 <% end %> 31 <% else %>
32 <span class="disabled_action">&mdash;</span>
33 <% end %>
34 <%= submit_tag t(".diff_button") %>
35 <% if later %>
36 <%= link_to t(".pair_link", :from => later.first, :to => later.last), diff_node_revisions_path(@node,
37 start_revision: later.first, end_revision: later.last,
38 view: @diff_view, translation_locale: @translation_locale) %>
39 <% else %>
40 <span class="disabled_action">&mdash;</span>
24 <% end %> 41 <% end %>
25 </p> 42 </p>
26 <p class="field_hint"><%= t(".changed_hint") %></p>
27<% end %> 43<% end %>
28 44
29<p class="diff_view_toggle"> 45<% unless numeric_comparison %>
30 <%= t(".view_label") %> 46 <p class="node_action_bar standalone_action_bar">
31 <% if @diff_view == :inline %> 47 <%= link_to t(".compare_numbered"), node_revisions_path(@node) %>
32 <strong><%= t("revisions.inline") %></strong> 48 </p>
33 <% else %>
34 <%= link_to t("revisions.inline"), diff_node_revisions_path(@node, start_revision: params[:start_revision], end_revision: params[:end_revision], view: 'inline', locale: @locale) %>
35 <% end %>
36 &middot;
37 <% if @diff_view == :side_by_side %>
38 <strong><%= t("revisions.side_by_side") %></strong>
39 <% else %>
40 <%= link_to t("revisions.side_by_side"), diff_node_revisions_path(@node, start_revision: params[:start_revision], end_revision: params[:end_revision], view: 'side_by_side', locale: @locale) %>
41 <% end %>
42</p>
43
44<% numeric_comparison = params[:start_revision].to_s =~ /\A\d+\z/ && params[:end_revision].to_s =~ /\A\d+\z/ %>
45
46<% if numeric_comparison %>
47 <%= form_tag diff_node_revisions_path do %>
48 <%= select_tag :start_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:start_revision].to_i) %>
49 <%= select_tag :end_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:end_revision].to_i) %>
50 <%= hidden_field_tag :view, @diff_view %>
51 <%= hidden_field_tag :locale, @locale %>
52 <%= submit_tag t(".diff_button") %>
53 <% end %>
54<% else %>
55 <p class="node_action_bar standalone_action_bar"><%= link_to t(".compare_numbered"), node_revisions_path(@node) %></p>
56<% end %> 49<% end %>
57 50
51
58<% if @available_layer_pairs.present? %> 52<% if @available_layer_pairs.present? %>
59 <div class="node_action_bar standalone_action_bar"> 53 <div class="node_action_bar standalone_action_bar">
60 <% @available_layer_pairs.each do |pair| %> 54 <% @available_layer_pairs.each do |pair| %>
@@ -62,7 +56,7 @@
62 <%= button_to t("nodes.show.diff_layers", :from => t("nodes.show.layer_#{pair.first}"), :to => t("nodes.show.layer_#{pair.last}")), 56 <%= button_to t("nodes.show.diff_layers", :from => t("nodes.show.layer_#{pair.first}"), :to => t("nodes.show.layer_#{pair.last}")),
63 diff_node_revisions_path(@node), 57 diff_node_revisions_path(@node),
64 method: :get, 58 method: :get,
65 params: { start_revision: pair.first, end_revision: pair.last, view: @diff_view, locale: @locale }, 59 params: { start_revision: pair.first, end_revision: pair.last, view: @diff_view, translation_locale: @translation_locale },
66 form: { class: 'button_to computation' } %> 60 form: { class: 'button_to computation' } %>
67 <% end %> 61 <% end %>
68 <% if !@locked_by_other && (@node.autosave || @node.draft) %> 62 <% if !@locked_by_other && (@node.autosave || @node.draft) %>
diff --git a/app/views/revisions/index.html.erb b/app/views/revisions/index.html.erb
index 6bcf1820..d118f96a 100644
--- a/app/views/revisions/index.html.erb
+++ b/app/views/revisions/index.html.erb
@@ -9,10 +9,10 @@
9 <%= t("revisions.locale_label") %> 9 <%= t("revisions.locale_label") %>
10 <% ([I18n.default_locale] + Page.non_default_locales).each_with_index do |locale, i| %> 10 <% ([I18n.default_locale] + Page.non_default_locales).each_with_index do |locale, i| %>
11 <%= " &middot; ".html_safe if i > 0 %> 11 <%= " &middot; ".html_safe if i > 0 %>
12 <% if locale == @locale %> 12 <% if locale == @translation_locale %>
13 <strong><%= locale.to_s.upcase %></strong> 13 <strong><%= locale.to_s.upcase %></strong>
14 <% else %> 14 <% else %>
15 <%= link_to locale.to_s.upcase, node_revisions_path(@node, :locale => locale) %> 15 <%= link_to locale.to_s.upcase, node_revisions_path(@node, :translation_locale => locale) %>
16 <% end %> 16 <% end %>
17 <% end %> 17 <% end %>
18 </p> 18 </p>
@@ -34,7 +34,7 @@
34 <td colspan="8"> 34 <td colspan="8">
35 <%= button_to t(".diff_revisions"), diff_node_revisions_path(@node), 35 <%= button_to t(".diff_revisions"), diff_node_revisions_path(@node),
36 method: :post, 36 method: :post,
37 params: { locale: @locale }, 37 params: { translation_locale: @translation_locale },
38 form: { id: 'diff_form', class: 'button_to computation' }, 38 form: { id: 'diff_form', class: 'button_to computation' },
39 disabled: true %> 39 disabled: true %>
40 <span id="diff_selection_label" data-against="<%= t(".against_word") %>" data-selected="<%= t(".selected_word") %>"></span> 40 <span id="diff_selection_label" data-against="<%= t(".against_word") %>" data-selected="<%= t(".selected_word") %>"></span>
@@ -50,10 +50,10 @@
50 <td><%= radio_button_tag :start_revision, page.revision, index == 1 %></td> 50 <td><%= radio_button_tag :start_revision, page.revision, index == 1 %></td>
51 <td><%= radio_button_tag :end_revision, page.revision, index == 0 %></td> 51 <td><%= radio_button_tag :end_revision, page.revision, index == 0 %></td>
52 <td class="revision"><%= page.revision %></td> 52 <td class="revision"><%= page.revision %></td>
53 <td class="title"><%= page.translations.find_by(:locale => @locale)&.title || "—" %></td> 53 <td class="title"><%= page.translations.find_by(:locale => @translation_locale)&.title || "—" %></td>
54 <td class="user"><%= page.editor.try(:login) %></td> 54 <td class="user"><%= page.editor.try(:login) %></td>
55 <td class="date"><%= page.updated_at %></td> 55 <td class="date"><%= page.updated_at %></td>
56 <td><%= link_to t(".show_link"), node_revision_path(@node, page, :locale => @locale) %></td> 56 <td><%= link_to t(".show_link"), node_revision_path(@node, page, :translation_locale => @translation_locale) %></td>
57 <td> 57 <td>
58 <%= button_to t(".restore_link"), restore_node_revision_path(@node, page), 58 <%= button_to t(".restore_link"), restore_node_revision_path(@node, page),
59 method: :put, 59 method: :put,
diff --git a/app/views/revisions/show.html.erb b/app/views/revisions/show.html.erb
index a39071c6..addcfa1a 100644
--- a/app/views/revisions/show.html.erb
+++ b/app/views/revisions/show.html.erb
@@ -1,13 +1,13 @@
1<% translation = @page.translations.find_by(:locale => @locale) %> 1<% translation = @page.translations.find_by(:locale => @translation_locale) %>
2<div id="admin_layout" class="show_node"> 2<div id="admin_layout" class="show_node">
3 <h1><%= t(".title", :rev => @page.revision) %>: <%= translation&.title %> <small>(<%= @locale.to_s.upcase %>)</small></h1> 3 <h1><%= t(".title", :rev => @page.revision) %>: <%= translation&.title %> <small>(<%= @translation_locale.to_s.upcase %>)</small></h1>
4 4
5 <div id="content"> 5 <div id="content">
6 <div class="layout_row_label"><%= t("admin.columns.actions") %></div> 6 <div class="layout_row_label"><%= t("admin.columns.actions") %></div>
7 <div class="layout_row_content info_group"> 7 <div class="layout_row_content info_group">
8 <div class="info_group_items"> 8 <div class="info_group_items">
9 <div class="info_item"> 9 <div class="info_item">
10 <%= link_to t(".show_all"), node_revisions_path(@node, :locale => @locale) %> 10 <%= link_to t(".show_all"), node_revisions_path(@node, :translation_locale => @translation_locale) %>
11 </div> 11 </div>
12 </div> 12 </div>
13 </div> 13 </div>
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css
index f415379a..39badaa6 100644
--- a/public/stylesheets/admin.css
+++ b/public/stylesheets/admin.css
@@ -1019,6 +1019,19 @@ div.layout_row_content {
1019 height: 1.25rem; 1019 height: 1.25rem;
1020} 1020}
1021 1021
1022.diff_step_bar .disabled_action {
1023 border: none;
1024 padding: 0;
1025 font-weight: normal;
1026}
1027
1028.diff_step_bar > a,
1029.diff_step_bar .disabled_action {
1030 display: inline-flex;
1031 justify-content: center;
1032 min-width: 8ch;
1033}
1034
1022.info_group_items { 1035.info_group_items {
1023 display: flex; 1036 display: flex;
1024 flex-wrap: wrap; 1037 flex-wrap: wrap;
diff --git a/test/controllers/revisions_controller_test.rb b/test/controllers/revisions_controller_test.rb
index 8311735c..34f00a4f 100644
--- a/test/controllers/revisions_controller_test.rb
+++ b/test/controllers/revisions_controller_test.rb
@@ -146,7 +146,9 @@ class RevisionsControllerTest < ActionController::TestCase
146 146
147 post(:diff, params: { :node_id => @node.id, :start_revision => "head", :end_revision => "draft" }) 147 post(:diff, params: { :node_id => @node.id, :start_revision => "head", :end_revision => "draft" })
148 assert_response :success 148 assert_response :success
149 assert_select "a", I18n.t("revisions.side_by_side") 149 assert_select "select[name='view'] option", :text => I18n.t("revisions.side_by_side")
150 assert_select "input[type='hidden'][name='start_revision'][value='head']"
151 assert_select "input[type='hidden'][name='end_revision'][value='draft']"
150 end 152 end
151 153
152 test "diffing two revisions also shows tag, template, and asset changes" do 154 test "diffing two revisions also shows tag, template, and asset changes" do