summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/admin/_recent_changes.html.erb24
-rw-r--r--app/views/admin/index.html.erb23
-rw-r--r--app/views/events/_rrule_builder.html.erb33
-rw-r--r--app/views/events/edit.html.erb28
-rw-r--r--app/views/events/new.html.erb5
-rw-r--r--app/views/node_actions/_action_row.html.erb18
-rw-r--r--app/views/node_actions/_change_details.html.erb27
-rw-r--r--app/views/node_actions/index.html.erb13
-rw-r--r--app/views/nodes/_recent_change_item.html.erb9
-rw-r--r--app/views/nodes/destroy.html.erb2
-rw-r--r--app/views/nodes/new.html.erb4
-rw-r--r--app/views/nodes/recent.html.erb6
-rw-r--r--app/views/nodes/show.html.erb64
-rw-r--r--app/views/nodes/trashed.html.erb42
14 files changed, 220 insertions, 78 deletions
diff --git a/app/views/admin/_recent_changes.html.erb b/app/views/admin/_recent_changes.html.erb
deleted file mode 100644
index 88b5e93..0000000
--- a/app/views/admin/_recent_changes.html.erb
+++ /dev/null
@@ -1,24 +0,0 @@
1<h2>Recent Changes</h2>
2<div id="draft_list">
3 <table>
4 <tr class="header">
5 <th>Title</th>
6 <th>path</th>
7 <th>user</th>
8 <th>date</th>
9 <th></th>
10 </tr>
11 <% @recent_changes.each do |node| %>
12 <tr>
13 <td><%= truncated_title_for_node node %></td>
14 <td><%= node.unique_name %></td>
15 <td><%= node.draft.user.login rescue "" %></td>
16 <td><%= node.updated_at.to_fs(:db) %></td>
17 <td class="actions">
18 <%= link_to 'Show', node_path(node) %>
19 <%= link_to "Revisions", revision_path(:id => node.id) %>
20 </td>
21 </tr>
22 <% end %>
23 </table>
24</div> \ No newline at end of file
diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb
index bdb555e..319530d 100644
--- a/app/views/admin/index.html.erb
+++ b/app/views/admin/index.html.erb
@@ -42,21 +42,12 @@
42 42
43 <div class="dashboard_widget"> 43 <div class="dashboard_widget">
44 <h3>Recent changes</h3> 44 <h3>Recent changes</h3>
45 <ul> 45 <table id="node_action_list">
46 <% @recent_changes.each do |node| %> 46 <%= render partial: "node_actions/action_row", collection: @actions, as: :action %>
47 <li> 47 </table>
48 <div> 48 <%= link_to "See all recent changes →", admin_log_path %>
49 <%= link_to title_for_node(node), node_path(node) %>
50 <span class="field_hint"><%= link_to_path("#{node.unique_name} ↗", node.unique_name) %></span>
51 </div>
52 <span class="dashboard_widget_meta">
53 <%= (editor = node_head_editor(node)) ? t("published_by", editor: editor) : t("published") %>, <%= relative_time_phrase(node.head.updated_at) %>
54 </span>
55 </li>
56 <% end %>
57 </ul>
58 <%= link_to "See all recent changes →", recent_nodes_path %>
59 </div> 49 </div>
50
60</div> 51</div>
61 52
62<div id="dashboard_housekeeping"> 53<div id="dashboard_housekeeping">
@@ -77,5 +68,9 @@
77 <%= link_to menu_items_path, class: "action_button" do %> 68 <%= link_to menu_items_path, class: "action_button" do %>
78 <%= icon("menu-2", library: "tabler", "aria-hidden": true) %> Navigation 69 <%= icon("menu-2", library: "tabler", "aria-hidden": true) %> Navigation
79 <% end %> 70 <% end %>
71 <% trash_count = Node.trash.children.count %>
72 <%= link_to trashed_nodes_path, class: "action_button" do %>
73 <%= icon("trash", library: "tabler", "aria-hidden": true) %> Trash<%= " (#{trash_count})" if trash_count > 0 %>
74 <% end %>
80 </div> 75 </div>
81</div> 76</div>
diff --git a/app/views/events/_rrule_builder.html.erb b/app/views/events/_rrule_builder.html.erb
new file mode 100644
index 0000000..1ffec0a
--- /dev/null
+++ b/app/views/events/_rrule_builder.html.erb
@@ -0,0 +1,33 @@
1<div id="rrule_builder">
2 <p>
3 <label><%= radio_button_tag "rrule_freq", "weekly", true %> Weekly</label>
4 <label><%= radio_button_tag "rrule_freq", "monthly" %> Monthly</label>
5 </p>
6 <div id="rrule_weekly_options">
7 <p><label><%= check_box_tag "rrule_biweekly" %> Every 2 weeks</label></p>
8 <p>
9 <% %w[MO TU WE TH FR SA SU].each do |code| %>
10 <label><%= check_box_tag "rrule_byday_#{code}" %> <%= RruleHumanizer::WEEKDAY_NAMES_ABBR[:de][code] %></label>
11 <% end %>
12 </p>
13 </div>
14 <div id="rrule_monthly_options" style="display: none;">
15 <p><label><%= check_box_tag "rrule_monthly_ordinal" %> On a specific weekday each month</label></p>
16 <p id="rrule_ordinal_fields" style="display: none;">
17 <%= select_tag "rrule_ordinal", options_for_select([["1.", 1], ["2.", 2], ["3.", 3], ["4.", 4], ["letzter", -1], ["vorletzter", -2], ["Selected weeks", "custom"]]) %>
18 <%= select_tag "rrule_ordinal_day", options_for_select(%w[MO TU WE TH FR SA SU].map { |c| [RruleHumanizer::WEEKDAY_NAMES[:de][c], c] }) %>
19 </p>
20 <p id="rrule_custom_ordinal_fields" style="display: none;">
21 Weeks of the month:
22 <% (1..5).each do |ordinal| %>
23 <label><%= check_box_tag "rrule_custom_ordinal_#{ordinal}" %> <%= ordinal %>.</label>
24 <% end %>
25 </p>
26 </div>
27 <p>
28 <label><%= check_box_tag "rrule_exclude_month" %> Except in one month</label>
29 <%= select_tag "rrule_excluded_month", options_for_select((1..12).map { |m| [RruleHumanizer::MONTH_NAMES[:de][m-1], m] }), style: "display: none;" %>
30 </p>
31 <span class="field_hint">Builds the field below automatically. If your pattern is more complex than this covers, just edit it directly below - these controls won't touch it unless you use them.</span>
32</div>
33<%= f.text_field :rrule, id: "event_rrule" %>
diff --git a/app/views/events/edit.html.erb b/app/views/events/edit.html.erb
index b6564a4..4532ff2 100644
--- a/app/views/events/edit.html.erb
+++ b/app/views/events/edit.html.erb
@@ -40,33 +40,7 @@
40 40
41 <div class="node_description">Recurrence</div> 41 <div class="node_description">Recurrence</div>
42 <div class="node_content"> 42 <div class="node_content">
43 <div id="rrule_builder"> 43 <%= render "rrule_builder", f: f %>
44 <p>
45 <label><%= radio_button_tag "rrule_freq", "weekly", true %> Weekly</label>
46 <label><%= radio_button_tag "rrule_freq", "monthly" %> Monthly</label>
47 </p>
48 <div id="rrule_weekly_options">
49 <p><label><%= check_box_tag "rrule_biweekly" %> Every 2 weeks</label></p>
50 <p>
51 <% %w[MO TU WE TH FR SA SU].each do |code| %>
52 <label><%= check_box_tag "rrule_byday_#{code}" %> <%= RruleHumanizer::WEEKDAY_NAMES_ABBR[:de][code] %></label>
53 <% end %>
54 </p>
55 </div>
56 <div id="rrule_monthly_options" style="display: none;">
57 <p><label><%= check_box_tag "rrule_monthly_ordinal" %> On a specific weekday each month</label></p>
58 <p id="rrule_ordinal_fields" style="display: none;">
59 <%= select_tag "rrule_ordinal", options_for_select([["1.", 1], ["2.", 2], ["3.", 3], ["4.", 4], ["letzter", -1], ["vorletzter", -2]]) %>
60 <%= select_tag "rrule_ordinal_day", options_for_select(%w[MO TU WE TH FR SA SU].map { |c| [RruleHumanizer::WEEKDAY_NAMES[:de][c], c] }) %>
61 </p>
62 </div>
63 <p>
64 <label><%= check_box_tag "rrule_exclude_month" %> Except in one month</label>
65 <%= select_tag "rrule_excluded_month", options_for_select((1..12).map { |m| [RruleHumanizer::MONTH_NAMES[:de][m-1], m] }), style: "display: none;" %>
66 </p>
67 <span class="field_hint">Builds the field below automatically. If your pattern is more complex than this covers, just edit it directly below - these controls won't touch it unless you use them.</span>
68 </div>
69 <%= f.text_field :rrule, id: "event_rrule" %>
70 </div> 44 </div>
71 45
72 <div class="node_description">Title</div> 46 <div class="node_description">Title</div>
diff --git a/app/views/events/new.html.erb b/app/views/events/new.html.erb
index 7a1ee7a..028fce7 100644
--- a/app/views/events/new.html.erb
+++ b/app/views/events/new.html.erb
@@ -21,8 +21,8 @@
21 <div class="node_description">End time</div> 21 <div class="node_description">End time</div>
22 <div class="node_content"><%= f.datetime_select :end_time %></div> 22 <div class="node_content"><%= f.datetime_select :end_time %></div>
23 23
24 <div class="node_description">Rrule</div> 24 <div class="node_description">Recurrence</div>
25 <div class="node_content"><%= f.text_field :rrule %></div> 25 <div class="node_content"><%= render "rrule_builder", f: f %></div>
26 26
27 <div class="node_description">Title</div> 27 <div class="node_description">Title</div>
28 <div class="node_content"> 28 <div class="node_content">
@@ -53,4 +53,3 @@
53 </div> 53 </div>
54 </div> 54 </div>
55<% end %> 55<% end %>
56
diff --git a/app/views/node_actions/_action_row.html.erb b/app/views/node_actions/_action_row.html.erb
new file mode 100644
index 0000000..c640f0d
--- /dev/null
+++ b/app/views/node_actions/_action_row.html.erb
@@ -0,0 +1,18 @@
1<tr class="node_action node_action--<%= action.action %>">
2 <td class="node_action_time">
3 <span class="node_action_date"><%= action.occurred_at.strftime("%Y-%m-%d") %></span>
4 <span class="node_action_clock"><%= action.occurred_at.strftime("%H:%M") %></span>
5 </td>
6 <td class="node_action_body">
7 <%= verb_icon(action) %>
8 <%= action_summary(action) %>
9 <% if action.node_id && params[:node_id].blank? %>
10 <%= link_to t("node_actions.node_history"), admin_log_path(:node_id => action.node_id), :class => "node_action_zoom" %>
11 <% end %>
12 <% if action.inferred_from %>
13 <span class="node_action_inferred" title="<%= action.inferred_from %>"><%= t("node_actions.backfilled") %></span>
14 <% end %>
15 <%= render "node_actions/change_details", :action_entry => action if action_details?(action) %>
16 </td>
17</tr>
18
diff --git a/app/views/node_actions/_change_details.html.erb b/app/views/node_actions/_change_details.html.erb
new file mode 100644
index 0000000..2583e8b
--- /dev/null
+++ b/app/views/node_actions/_change_details.html.erb
@@ -0,0 +1,27 @@
1<details class="node_action_details">
2 <summary><%= t("node_actions.show_changes") %></summary>
3 <table>
4 <% if (default_items = default_locale_changes(action_entry)).any? %>
5 <tr>
6 <th><%= I18n.default_locale.to_s.upcase %></th>
7 <td>
8 <%= safe_join(default_items, ", ") %>
9 <% if action_entry.page && action_entry.node %>
10 <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page) %>
11 <% end %>
12 </td>
13 </tr>
14 <% end %>
15 <% (action_entry.metadata["translation_diff"] || {}).each do |locale, diff| %>
16 <tr>
17 <th><%= locale.upcase %></th>
18 <td>
19 <%= safe_join(translation_changes(diff), ", ") %>
20 <% if action_entry.page && action_entry.node %>
21 <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page, :locale => locale) %>
22 <% end %>
23 </td>
24 </tr>
25 <% end %>
26 </table>
27</details>
diff --git a/app/views/node_actions/index.html.erb b/app/views/node_actions/index.html.erb
new file mode 100644
index 0000000..20ef5b3
--- /dev/null
+++ b/app/views/node_actions/index.html.erb
@@ -0,0 +1,13 @@
1<h1><%= t("node_actions.heading") %></h1>
2
3<% if params[:node_id].present? || params[:user_id].present? %>
4 <p><%= link_to t("node_actions.show_all"), admin_log_path %></p>
5<% end %>
6
7<%= will_paginate @actions %>
8
9<table id="node_action_list">
10 <%= render partial: "node_actions/action_row", collection: @actions, as: :action %>
11</table>
12
13<%= will_paginate @actions %>
diff --git a/app/views/nodes/_recent_change_item.html.erb b/app/views/nodes/_recent_change_item.html.erb
new file mode 100644
index 0000000..754a775
--- /dev/null
+++ b/app/views/nodes/_recent_change_item.html.erb
@@ -0,0 +1,9 @@
1<li>
2 <div>
3 <%= link_to title_for_node(node), node_path(node) %>
4 <span class="field_hint"><%= link_to_path("#{node.unique_name} ↗", node.unique_name) %></span>
5 </div>
6 <span class="dashboard_widget_meta">
7 <%= (editor = node_head_editor(node)) ? t("last_edited_by", editor: editor) : t("last_edited") %>, <%= relative_time_phrase(node.head.updated_at) %>
8 </span>
9</li>
diff --git a/app/views/nodes/destroy.html.erb b/app/views/nodes/destroy.html.erb
deleted file mode 100644
index 065cf1d..0000000
--- a/app/views/nodes/destroy.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
1<h1>Nodes#destroy</h1>
2<p>Find me in app/views/nodes/destroy.html.erb</p>
diff --git a/app/views/nodes/new.html.erb b/app/views/nodes/new.html.erb
index b63a606..890d46e 100644
--- a/app/views/nodes/new.html.erb
+++ b/app/views/nodes/new.html.erb
@@ -32,8 +32,8 @@
32 <div id="parent_search_field" style="<%= @selected_kind == "generic" ? "" : "display: none;" %>"> 32 <div id="parent_search_field" style="<%= @selected_kind == "generic" ? "" : "display: none;" %>">
33 <div class="node_description">Parent</div> 33 <div class="node_description">Parent</div>
34 <div class="node_content"> 34 <div class="node_content">
35 <%= text_field_tag :parent_search_term, @parent_name %> 35 <%= text_field_tag :parent_search_term, @parent&.title %>
36 <%= hidden_field_tag :parent_id, @parent_id %> 36 <%= hidden_field_tag :parent_id, @parent&.id, data: { unique_name: @parent&.computed_unique_name } %>
37 <div id="parent_search_results" class="search_results"></div> 37 <div id="parent_search_results" class="search_results"></div>
38 </div> 38 </div>
39 </div> 39 </div>
diff --git a/app/views/nodes/recent.html.erb b/app/views/nodes/recent.html.erb
index 3602775..d256253 100644
--- a/app/views/nodes/recent.html.erb
+++ b/app/views/nodes/recent.html.erb
@@ -1,3 +1,7 @@
1<h1>Recently changed</h1> 1<h1>Recently changed</h1>
2 2
3<%= render 'node_list' %> 3<%= will_paginate @nodes %>
4<ul id="recent_changes_full_list">
5 <%= render partial: "nodes/recent_change_item", collection: @nodes, as: :node %>
6</ul>
7<%= will_paginate @nodes %>
diff --git a/app/views/nodes/show.html.erb b/app/views/nodes/show.html.erb
index 66f04f9..af05778 100644
--- a/app/views/nodes/show.html.erb
+++ b/app/views/nodes/show.html.erb
@@ -46,7 +46,7 @@
46 <% end %> 46 <% end %>
47 47
48 <% unless locked_by_other %> 48 <% unless locked_by_other %>
49 <% if @node.draft && !@node.autosave %> 49 <% if @node.draft && !@node.autosave && !@node.in_trash? && !@node.trash_node? %>
50 <div class="node_info_item"> 50 <div class="node_info_item">
51 <%= button_to 'Publish', publish_node_path(@node), method: :put, 51 <%= button_to 'Publish', publish_node_path(@node), method: :put,
52 form: { data: { confirm: "Publish this draft?" }, class: 'button_to state_changing' } %> 52 form: { data: { confirm: "Publish this draft?" }, class: 'button_to state_changing' } %>
@@ -62,6 +62,15 @@
62 <% end %> 62 <% end %>
63 </div> 63 </div>
64 <% end %> 64 <% end %>
65 <% unless @node.trash_node? || @node.in_trash? || @node.root? %>
66 <div class="node_info_item">
67 <%= button_to trash_node_path(@node), method: :put,
68 form: { data: { confirm: "Move this page and everything beneath it to the Trash? All published content in it will go offline." }, class: 'button_to destructive' } do %>
69 <%= icon("trash", library: "tabler", "aria-hidden": true) %>
70 Move to Trash
71 <% end %>
72 </div>
73 <% end %>
65 <% end %> 74 <% end %>
66 </div> 75 </div>
67 76
@@ -70,6 +79,48 @@
70 <% end %> 79 <% end %>
71 </div> 80 </div>
72 81
82 <% if @node.in_trash? %>
83 <div class="node_description">Trash</div>
84 <div class="node_content node_info_group">
85 <div class="node_info_group_items">
86 <% if (entry = @node.last_trash_entry) && entry.metadata.dig("path", "from") %>
87 <div class="node_info_item">
88 <span class="node_info_label">Was at</span>
89 <%= entry.metadata.dig("path", "from") %>
90 </div>
91 <% end %>
92 <div class="node_info_item">
93 <span class="node_info_label">Restore to</span>
94 <% suggestion = @node.suggested_restore_parent %>
95 <%= form_tag restore_from_trash_node_path(@node), :method => :put, :class => "aligned_action_row" do %>
96 <div class="restore_picker">
97 <%= text_field_tag :restore_search_term,
98 suggestion && (suggestion.head&.title || suggestion.draft&.title || suggestion.slug),
99 :placeholder => "Search for a new parent…" %>
100 <div id="restore_search_results" class="search_results"></div>
101 </div>
102 <%= hidden_field_tag :parent_id, suggestion&.id %>
103 <%= submit_tag "Restore here", :class => "action_button action_button_no_margin_top" %>
104 <% end %>
105 <span class="field_hint">Restored pages come back unpublished. Republish each page deliberately.</span>
106 </div>
107 </div>
108 <div class="node_info_group_items">
109 <div class="node_info_item">
110 <% doomed_below = @node.descendants.count %>
111 <%= button_to node_path(@node), method: :delete,
112 form: { data: { confirm: doomed_below > 0 ?
113 "Delete this page and the #{doomed_below} pages beneath it permanently? This cannot be undone." :
114 "Delete this page permanently? This cannot be undone." },
115 class: 'button_to destructive' } do %>
116 <%= icon("trash-x", library: "tabler", "aria-hidden": true) %>
117 Delete permanently<%= " (including #{doomed_below} beneath)" if doomed_below > 0 %>
118 <% end %>
119 </div>
120 </div>
121 </div>
122 <% end %>
123
73 <div class="node_description">Translations</div> 124 <div class="node_description">Translations</div>
74 <div class="node_content node_info_group"> 125 <div class="node_content node_info_group">
75 <div class="node_info_group_items"> 126 <div class="node_info_group_items">
@@ -170,19 +221,22 @@
170 </div> 221 </div>
171 </div> 222 </div>
172 223
173 <div class="node_description">Revisions</div> 224 <div class="node_description">History</div>
174 <div class="node_content node_info_group"> 225 <div class="node_content node_info_group">
175 <details> 226 <details>
176 <summary> 227 <summary>
177 <%= pluralize(@node.pages.count, 'revision', 'revisions') %> 228 <%= pluralize(@node.pages.count, 'published revision', 'published revisions') %>
178 </summary> 229 </summary>
179 <ul> 230 <ul>
180 <% @node.pages.order(:revision).each do |page| %> 231 <% @node.pages.order(:revision).each do |page| %>
181 <li><%= link_to "##{page.revision} — #{page.title} (#{page.editor.try(:login)}, #{page.updated_at})", node_revision_path(@node, page) %></li> 232 <li>
233 <%= link_to "##{page.revision} — #{page.title} (#{page.editor.try(:login)}, #{page.updated_at})", node_revision_path(@node, page) %>
234 <span class="revision_lifecycle"><%= revision_lifecycle_badges(@page_actions[page.id]) %></span>
235 </li>
182 <% end %> 236 <% end %>
183 </ul> 237 </ul>
184 </details> 238 </details>
185 <p class="revisions_full_history_link"><%= link_to 'Full history (diff / restore)', node_revisions_path(@node) %></p> 239 <p class="revisions_full_history_link"><%= link_to 'Revision history (diff / restore)', node_revisions_path(@node) %> | <%= link_to t("node_actions.heading"), admin_log_path(:node_id => @node.id) %></p>
186 </div> 240 </div>
187 241
188 242
diff --git a/app/views/nodes/trashed.html.erb b/app/views/nodes/trashed.html.erb
new file mode 100644
index 0000000..9a4808e
--- /dev/null
+++ b/app/views/nodes/trashed.html.erb
@@ -0,0 +1,42 @@
1<h1>Trash</h1>
2
3<% if @nodes.empty? %>
4 <p class="field_hint">The Trash is empty.</p>
5<% else %>
6 <%= will_paginate @nodes %>
7 <table id="trashed_node_list">
8 <tr>
9 <th>Title</th>
10 <th>Was at</th>
11 <th>Trashed</th>
12 <th>Actions</th>
13 </tr>
14 <% @nodes.each do |node| %>
15 <% entry = node.last_trash_entry %>
16 <tr>
17 <% doomed_below = node.descendants.count %>
18 <td>
19 <%= link_to (node.draft&.title || node.slug), node_path(node) %><%= " (+ #{doomed_below} beneath)" if doomed_below > 0 %>
20 </td>
21 <td><%= entry&.metadata&.dig("path", "from") %></td>
22 <td>
23 <% if entry %>
24 <%= entry.occurred_at.strftime("%Y-%m-%d %H:%M") %> by <%= entry.actor_name %>
25 <% end %>
26 </td>
27 <td>
28 <%= button_to node_path(node), method: :delete,
29 form: { data: { confirm: doomed_below > 0 ?
30 "Delete \"#{node.draft&.title || node.slug}\" and the #{doomed_below} pages beneath it permanently? This cannot be undone." :
31 "Delete \"#{node.draft&.title || node.slug}\" permanently? This cannot be undone." },
32 class: 'button_to destructive' } do %>
33 <%= icon("trash-x", library: "tabler", "aria-hidden": true) %>
34 Delete permanently
35 <% end %>
36 </td>
37 </tr>
38 <% end %>
39 </table>
40 <%= will_paginate @nodes %>
41 <p class="field_hint">To restore a page, open it and pick a new parent in its Trash section.</p>
42<% end %>