summaryrefslogtreecommitdiff
path: root/app/views/revisions
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-13 23:33:11 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-13 23:33:11 +0200
commit8eab68f2c5a3c126e2fec2ecdfa7ace87ce0937b (patch)
treef446ebc26a7707c7b64a937aa51a155df146c80a /app/views/revisions
parent42714c697273a7117c6b355fab26c8c35e336ad1 (diff)
parentcdf5d9941ca866d437612d2f863eac6eb0b3db12 (diff)
Merge branch 'erdgeist-revive-events'
Diffstat (limited to 'app/views/revisions')
-rw-r--r--app/views/revisions/diff.html.erb177
-rw-r--r--app/views/revisions/index.html.erb112
-rw-r--r--app/views/revisions/show.html.erb90
3 files changed, 234 insertions, 145 deletions
diff --git a/app/views/revisions/diff.html.erb b/app/views/revisions/diff.html.erb
index b8d061d..7e7b729 100644
--- a/app/views/revisions/diff.html.erb
+++ b/app/views/revisions/diff.html.erb
@@ -1,65 +1,134 @@
1<% content_for :subnavigation do %>
2 <%= link_to 'Edit', edit_node_path(@node) %>
3 <%= link_to 'Revisions', node_revisions_path(@node) %>
4<% end %>
5
6<h1>Revisions#diff</h1> 1<h1>Revisions#diff</h1>
7 2
8<%= form_tag diff_node_revisions_path do %> 3<p class="node_action_bar standalone_action_bar">
9 <%= select_tag :start_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:start_revision].to_i) %> 4 <%= link_to 'Revisions', node_revisions_path(@node) %>
10 <%= select_tag :end_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:end_revision].to_i) %> 5</p>
11 <%= submit_tag 'Diff' %>
12<% end %>
13 6
14<div id="start_title" style="display: none;"> 7<p class="diff_comparison_label">
15 <%= h(@start.title) %> 8 Comparing <strong><%= describe_page_reference(params[:start_revision]) %></strong>
16</div> 9 against <strong><%= describe_page_reference(params[:end_revision]) %></strong>
10 — showing the <strong><%= @locale.to_s.upcase %></strong> translation
11</p>
17 12
18<div id="end_title" style="display: none;"> 13<% if @locale_summary.size > 1 %>
19 <%= h(@end.title) %> 14 <p class="diff_locale_toggle">
20</div> 15 Locale:
16 <% @locale_summary.each_with_index do |s, i| %>
17 <%= " &middot; ".html_safe if i > 0 %>
18 <% label = "#{s[:locale].to_s.upcase}#{' *' if s[:changed]}" %>
19 <% if s[:locale] == @locale %>
20 <strong><%= label %></strong>
21 <% else %>
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]) %>
23 <% end %>
24 <% end %>
25 </p>
26 <p class="field_hint">* has a difference between these two versions.</p>
27<% end %>
21 28
22<div id="start_abstract" style="display: none;"> 29<p class="diff_view_toggle">
23 <%= h(@start.abstract) %> 30 View:
24</div> 31 <% if @diff_view == :inline %>
32 <strong>Inline</strong>
33 <% else %>
34 <%= link_to '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>Side by side</strong>
39 <% else %>
40 <%= link_to '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>
25 43
26<div id="end_abstract" style="display: none;"> 44<% numeric_comparison = params[:start_revision].to_s =~ /\A\d+\z/ && params[:end_revision].to_s =~ /\A\d+\z/ %>
27 <%= h(@end.abstract) %>
28</div>
29 45
30<pre> 46<% if numeric_comparison %>
31 <div id="start_body" style="display: none;"> 47 <%= form_tag diff_node_revisions_path do %>
32 <%= (@start.body) %> 48 <%= select_tag :start_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:start_revision].to_i) %>
33 </div> 49 <%= select_tag :end_revision, options_for_select(@node.pages.map{|x| x.revision}, params[:end_revision].to_i) %>
34</pre> 50 <%= hidden_field_tag :view, @diff_view %>
35<pre> 51 <%= hidden_field_tag :locale, @locale %>
36 <div id="end_body" style="display: none;"> 52 <%= submit_tag 'Diff' %>
37 <%= (@end.body) %> 53 <% end %>
38 </div> 54<% else %>
39</pre> 55 <p class="node_action_bar standalone_action_bar"><%= link_to 'Compare two numbered revisions instead', node_revisions_path(@node) %></p>
56<% end %>
40 57
41<script src="/javascripts/cacycle_diff.js"></script> 58<% if @available_layer_pairs.present? %>
42<script type="text/javascript" charset="utf-8"> 59 <div class="node_action_bar standalone_action_bar">
43 window.onload = function() { 60 <% @available_layer_pairs.each do |pair| %>
44 title1 = document.getElementById('start_title').innerHTML; 61 <% next if [params[:start_revision].to_s, params[:end_revision].to_s].sort == pair.map(&:to_s).sort %>
45 title2 = document.getElementById('end_title').innerHTML; 62 <%= button_to "Diff #{pair.first.to_s.capitalize} vs. #{pair.last.to_s.capitalize}",
46 abstract1 = document.getElementById('start_abstract').innerHTML; 63 diff_node_revisions_path(@node),
47 abstract2 = document.getElementById('end_abstract').innerHTML; 64 method: :get,
48 body1 = document.getElementById('start_body').innerHTML; 65 params: { start_revision: pair.first, end_revision: pair.last, view: @diff_view, locale: @locale },
49 body2 = document.getElementById('end_body').innerHTML; 66 form: { class: 'button_to computation' } %>
50 document.getElementById('diffview_title').innerHTML = WDiffString(title1, title2); 67 <% end %>
51 document.getElementById('diffview_abstract').innerHTML = WDiffString(abstract1, abstract2); 68 <% if !@locked_by_other && (@node.autosave || @node.draft) %>
52 document.getElementById('diffview_body').innerHTML = WDiffString(body1, body2); 69 <%= button_to revert_node_path(@node), method: :put,
53 } 70 params: { return_to: request.fullpath },
54</script> 71 form: { data: { confirm: "This cannot be undone. Continue?" }, class: 'button_to destructive' } do %>
72 <%= icon("trash", library: "tabler", "aria-hidden": true) %>
73 <%= @node.draft && !@node.autosave ? "Destroy Draft" : "Discard Autosave" %>
74 <% end %>
75 <% end %>
76 </div>
77<% end %>
55 78
56<div id="diffview"> 79<div id="diffview">
57 <h3>Title</h3> 80 <% if @diff_view == :side_by_side %>
58 <p id="diffview_title"></p> 81 <div class="diff_side_by_side">
59 82 <div class="diff_column">
60 <h3>Abstract</h3> 83 <h3>Title</h3>
61 <p id="diffview_abstract"></p> 84 <p><%= raw @diff[:title][0] %></p>
62 85 <h3>Abstract</h3>
63 <h3>Body</h3> 86 <p><%= raw @diff[:abstract][0] %></p>
64 <p id="diffview_body"></p> 87 <h3>Body</h3>
88 <%= raw @diff[:body][0] %>
89 </div>
90 <div class="diff_column">
91 <h3>Title</h3>
92 <p><%= raw @diff[:title][1] %></p>
93 <h3>Abstract</h3>
94 <p><%= raw @diff[:abstract][1] %></p>
95 <h3>Body</h3>
96 <%= raw @diff[:body][1] %>
97 </div>
98 </div>
99 <% else %>
100 <h3>Title</h3>
101 <p><%= raw @diff[:title] %></p>
102 <h3>Abstract</h3>
103 <p><%= raw @diff[:abstract] %></p>
104 <h3>Body</h3>
105 <%= raw @diff[:body] %>
106 <% end %>
107
108 <h3>Tags</h3>
109 <% if @diff[:tags][:added].empty? && @diff[:tags][:removed].empty? %>
110 <p class="diff_unchanged">No change.</p>
111 <% else %>
112 <ul class="diff_set_list">
113 <% @diff[:tags][:added].each do |tag| %><li><ins><%= tag %></ins></li><% end %>
114 <% @diff[:tags][:removed].each do |tag| %><li><del><%= tag %></del></li><% end %>
115 </ul>
116 <% end %>
117
118 <h3>Template</h3>
119 <% if @diff[:template_name][:changed] %>
120 <p><del><%= @diff[:template_name][:from] || '(none)' %></del> <ins><%= @diff[:template_name][:to] || '(none)' %></ins></p>
121 <% else %>
122 <p class="diff_unchanged">No change.</p>
123 <% end %>
124
125 <h3>Assets</h3>
126 <% if @diff[:assets][:added].empty? && @diff[:assets][:removed].empty? %>
127 <p class="diff_unchanged">No change.</p>
128 <% else %>
129 <ul class="diff_set_list">
130 <% @diff[:assets][:added].each do |asset| %><li><ins><%= asset.upload_file_name %></ins></li><% end %>
131 <% @diff[:assets][:removed].each do |asset| %><li><del><%= asset.upload_file_name %></del></li><% end %>
132 </ul>
133 <% end %>
65</div> 134</div>
diff --git a/app/views/revisions/index.html.erb b/app/views/revisions/index.html.erb
index b875a4f..4680ae2 100644
--- a/app/views/revisions/index.html.erb
+++ b/app/views/revisions/index.html.erb
@@ -1,49 +1,80 @@
1<% content_for :subnavigation do %>
2 <%= link_to 'Edit', edit_node_path(@node) %>
3<% end %>
4
5<h2>Revisions for Node: <%= @node.unique_name %></h2> 1<h2>Revisions for Node: <%= @node.unique_name %></h2>
6 2
7<table id="revisions"> 3<p class="node_action_bar standalone_action_bar">
8 <tr class="header"> 4 <%= link_to 'Back to node', node_path(@node) %>
9 <th>First</th> 5</p>
10 <th>Last</th> 6
11 <th>Rev.</th> 7<table id="revisions" class="revisions_table">
12 <th>Title</th> 8 <thead>
13 <th>Editor</th> 9 <tr class="header">
14 <th>Date</th> 10 <th>First</th>
15 <th></th> 11 <th>Last</th>
16 <th></th> 12 <th>Rev.</th>
17 </tr> 13 <th>Title</th>
18<% (@pages || @node.pages.all).reverse.each do |page| %> 14 <th>Editor</th>
19 <tr> 15 <th>Date</th>
20 <td><%= radio_button_tag :start_revision, page.revision %></td> 16 <th></th>
21 <td><%= radio_button_tag :end_revision, page.revision %></td> 17 <th></th>
22 <td class="revision"><%= page.revision %></td> 18 </tr>
23 <td class="title"><%= page.title %></td> 19 <tr class="no_hover diff_sticky_bar">
24 <td class="user"><%= page.editor.try(:login) %></td> 20 <td colspan="8">
25 <td class="date"><%= page.updated_at %></td> 21 <%= button_to 'Diff revisions', diff_node_revisions_path(@node),
26 <td><%= link_to 'show', node_revision_path(@node, page) %></td> 22 method: :post,
27 <td> 23 form: { id: 'diff_form', class: 'button_to computation' },
28 <%= button_to 'restore', restore_node_revision_path(@node, page), 24 disabled: true %>
29 method: :put, 25 <span id="diff_selection_label"></span>
30 form: { data: { confirm: "Restore this revision?" } } %> 26 <label><%= radio_button_tag :view, 'inline', true %> Inline</label>
31 </td> 27 <label><%= radio_button_tag :view, 'side_by_side', false %> Side by side</label>
32 </tr> 28 </td>
33<% end %> 29 </tr>
34 <tr class="no_hover"> 30 </thead>
35 <td colspan="8" class="right"> 31 <tbody>
36 <%= button_to 'Diff revisions', diff_node_revisions_path(@node), 32 <% pages = (@pages || @node.pages.all).reverse %>
37 method: :post, 33 <% pages.each_with_index do |page, index| %>
38 form: { id: 'diff_form' } %> 34 <tr>
39 </td> 35 <td><%= radio_button_tag :start_revision, page.revision, index == 1 %></td>
40 </tr> 36 <td><%= radio_button_tag :end_revision, page.revision, index == 0 %></td>
37 <td class="revision"><%= page.revision %></td>
38 <td class="title"><%= page.title %></td>
39 <td class="user"><%= page.editor.try(:login) %></td>
40 <td class="date"><%= page.updated_at %></td>
41 <td><%= link_to 'show', node_revision_path(@node, page) %></td>
42 <td>
43 <%= button_to 'restore', restore_node_revision_path(@node, page),
44 method: :put,
45 form: { data: { confirm: "Restore this revision?" }, class: 'button_to state_changing' } %>
46 </td>
47 </tr>
48 <% end %>
49 </tbody>
41</table> 50</table>
42 51
43<script> 52<script>
53 function update_diff_button_state() {
54 var start = document.querySelector('input[name="start_revision"]:checked');
55 var end = document.querySelector('input[name="end_revision"]:checked');
56 var valid = start && end && start.value !== end.value;
57 document.querySelector('#diff_form button[type="submit"]').disabled = !valid;
58
59 var label = document.getElementById('diff_selection_label');
60 if (start && end) {
61 label.textContent = start.value + ' against ' + end.value;
62 } else if (start || end) {
63 label.textContent = (start || end).value + ' selected';
64 } else {
65 label.textContent = '';
66 }
67 }
68
69 document.querySelectorAll('input[name="start_revision"], input[name="end_revision"]')
70 .forEach(function(radio) { radio.addEventListener('change', update_diff_button_state); });
71
72 update_diff_button_state();
73
44 document.getElementById('diff_form').addEventListener('submit', function(e) { 74 document.getElementById('diff_form').addEventListener('submit', function(e) {
45 var start = document.querySelector('input[name="start_revision"]:checked'); 75 var start = document.querySelector('input[name="start_revision"]:checked');
46 var end = document.querySelector('input[name="end_revision"]:checked'); 76 var end = document.querySelector('input[name="end_revision"]:checked');
77 var view = document.querySelector('input[name="view"]:checked');
47 if (start) { 78 if (start) {
48 var s = document.createElement('input'); 79 var s = document.createElement('input');
49 s.type = 'hidden'; s.name = 'start_revision'; s.value = start.value; 80 s.type = 'hidden'; s.name = 'start_revision'; s.value = start.value;
@@ -54,5 +85,10 @@
54 en.type = 'hidden'; en.name = 'end_revision'; en.value = end.value; 85 en.type = 'hidden'; en.name = 'end_revision'; en.value = end.value;
55 this.appendChild(en); 86 this.appendChild(en);
56 } 87 }
88 if (view) {
89 var v = document.createElement('input');
90 v.type = 'hidden'; v.name = 'view'; v.value = view.value;
91 this.appendChild(v);
92 }
57 }); 93 });
58</script> 94</script>
diff --git a/app/views/revisions/show.html.erb b/app/views/revisions/show.html.erb
index f2a2895..92d959b 100644
--- a/app/views/revisions/show.html.erb
+++ b/app/views/revisions/show.html.erb
@@ -1,54 +1,38 @@
1<% content_for :subnavigation do %>
2 <%= link_to 'show all revisions', node_revisions_path(@node) %>
3<% end %>
4
5<div id="page_editor" class="show_node"> 1<div id="page_editor" class="show_node">
6 <table id="content"> 2 <h1>Revision <%= @page.revision %>: <%= @page.title %></h1>
7 <tr> 3
8 <td class="description">Path</td> 4 <div id="content">
9 <td><%= @page.public_link %></td> 5 <div class="node_description">Actions</div>
10 </tr> 6 <div class="node_content node_info_group">
11 <tr> 7 <div class="node_info_group_items">
12 <td class="description">Author</td> 8 <div class="node_info_item">
13 <td><%= @page.user.try(:login) %></td> 9 <%= link_to 'Show all revisions', node_revisions_path(@node) %>
14 </tr> 10 </div>
15 <tr> 11 </div>
16 <td class="description">Editor</td> 12 </div>
17 <td><%= @page.editor.try(:login) %></td> 13
18 </tr> 14 <div class="node_description">Path</div>
19 <% if @page.node.locked? %> 15 <div class="node_content"><%= @page.public_link %></div>
20 <tr> 16
21 <td class="description">Locked by</td> 17 <div class="node_description">Author</div>
22 <td><%= @page.node.lock_owner.login %></td> 18 <div class="node_content"><%= @page.user.try(:login) %></div>
23 </tr> 19
24 <% end %> 20 <div class="node_description">Editor</div>
25 <tr> 21 <div class="node_content"><%= @page.editor.try(:login) %></div>
26 <td class="description">Last updated</td> 22
27 <td><%= @page.updated_at %></td> 23 <div class="node_description">Last updated</div>
28 </tr> 24 <div class="node_content"><%= @page.updated_at %></div>
29 <tr> 25
30 <td class="description">Published at</td> 26 <div class="node_description">Published at</div>
31 <td><%= @page.published_at %></td> 27 <div class="node_content"><%= @page.published_at %></div>
32 </tr> 28
33 <tr> 29 <div class="node_description">Title</div>
34 <td class="description">Revision</td> 30 <div class="node_content"><%= @page.title %></div>
35 <td><%= @page.revision %></td> 31
36 </tr> 32 <div class="node_description">Abstract</div>
37 <tr> 33 <div class="node_content"><%= @page.abstract %></div>
38 <td class="description"><strong>Title</strong></td> 34
39 <td><%= @page.title %></td> 35 <div class="node_description">Body</div>
40 </tr> 36 <div class="node_content"><%= raw @page.body %></div>
41 <tr> 37 </div>
42 <td class="description"><strong>Abstract</strong></td> 38</div>
43 <td><%= @page.abstract %></td>
44 </tr>
45 <tr>
46 <td class="description"><strong>Body</strong></td>
47 <td><%= @page.body %></td>
48 </tr>
49 <tr>
50 <td></td>
51 <td class="right"></td>
52 </tr>
53 </table>
54</div> \ No newline at end of file