summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/nodes_controller.rb45
-rw-r--r--app/models/node.rb22
-rw-r--r--app/views/nodes/_node_list.html.erb39
-rw-r--r--app/views/nodes/chapters.html.erb9
-rw-r--r--app/views/nodes/drafts.html.erb3
-rw-r--r--app/views/nodes/mine.html.erb3
-rw-r--r--app/views/nodes/recent.html.erb3
-rw-r--r--app/views/nodes/tags.html.erb3
8 files changed, 127 insertions, 0 deletions
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb
index 6fcd930c..ede91ad8 100644
--- a/app/controllers/nodes_controller.rb
+++ b/app/controllers/nodes_controller.rb
@@ -183,6 +183,39 @@ class NodesController < ApplicationController
183 render plain: slug_for(params[:title]) 183 render plain: slug_for(params[:title])
184 end 184 end
185 185
186 # Filter functions for admin views
187 def drafts
188 base = Node.where("draft_id IS NOT NULL OR autosave_id IS NOT NULL")
189 @nodes = index_matching(base)
190 end
191
192 def recent
193 base = Node.where(
194 "nodes.updated_at < ? AND nodes.updated_at > ? AND nodes.parent_id IS NOT NULL",
195 Time.now, Time.now - 14.days
196 )
197 @nodes = index_matching(base)
198 end
199
200 def mine
201 base = Node.joins(:pages)
202 .where("pages.user_id = ? or pages.editor_id = ?", current_user, current_user)
203 .distinct
204 @nodes = index_matching(base)
205 end
206
207 def chapters
208 @kind_keys = Array(params[:kinds]) & %w[erfa chaostreff]
209 @kind_keys = %w[erfa chaostreff] if @kind_keys.empty?
210 tags = @kind_keys.flat_map { |key| CccConventions::NODE_KINDS[key][:tags] }
211 @nodes = nodes_matching_tags(tags)
212 end
213
214 def tags
215 tags = params[:tags].to_s.split(',').map(&:strip).reject(&:blank?)
216 @nodes = nodes_matching_tags(tags)
217 end
218
186 private 219 private
187 220
188 def slug_for(title) 221 def slug_for(title)
@@ -214,4 +247,16 @@ class NodesController < ApplicationController
214 config && config[:parent] ? config[:parent].call.id : nil 247 config && config[:parent] ? config[:parent].call.id : nil
215 end 248 end
216 end 249 end
250
251 def nodes_matching_tags(tags)
252 matching_pages = Page.tagged_with(tags, any: true).reselect(:id)
253 base = Node.where(head_id: matching_pages).or(Node.where(draft_id: matching_pages))
254 index_matching(base)
255 end
256
257 def index_matching(base_scope)
258 scope = base_scope.includes(:head, :draft)
259 scope = scope.merge(Node.editor_search(params[:q])) if params[:q].present?
260 scope.order("nodes.updated_at desc").paginate(page: params[:page], per_page: 25)
261 end
217end 262end
diff --git a/app/models/node.rb b/app/models/node.rb
index 9cb48407..24f3cd09 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -345,6 +345,28 @@ class Node < ApplicationRecord
345 .distinct 345 .distinct
346 end 346 end
347 347
348 # This one is for admin-only views, where finding a draft is the point.
349 # Substring match on whichever of head/draft is present.
350 def self.editor_search(term)
351 words = term.to_s.split(/\s+/).reject(&:blank?)
352 return none if words.empty?
353
354 conditions = []
355 binds = {}
356
357 words.each_with_index do |word, i|
358 key = "term#{i}"
359 binds[key.to_sym] = "%#{sanitize_sql_like(word)}%"
360 conditions << "(head_translations.title ILIKE :#{key} OR head_translations.abstract ILIKE :#{key} " \
361 "OR draft_translations.title ILIKE :#{key} OR draft_translations.abstract ILIKE :#{key})"
362 end
363
364 joins("LEFT JOIN page_translations head_translations ON head_translations.page_id = nodes.head_id")
365 .joins("LEFT JOIN page_translations draft_translations ON draft_translations.page_id = nodes.draft_id")
366 .where(conditions.join(" AND "), binds)
367 .distinct
368 end
369
348 protected 370 protected
349 def lock_for! current_user 371 def lock_for! current_user
350 self.lock_owner = current_user 372 self.lock_owner = current_user
diff --git a/app/views/nodes/_node_list.html.erb b/app/views/nodes/_node_list.html.erb
new file mode 100644
index 00000000..03f38b4c
--- /dev/null
+++ b/app/views/nodes/_node_list.html.erb
@@ -0,0 +1,39 @@
1<%= form_tag url_for(controller: params[:controller], action: params[:action]), method: :get, class: "node_search_form" do %>
2 <% Array(params[:kinds]).each do |kind| %>
3 <%= hidden_field_tag "kinds[]", kind %>
4 <% end %>
5 <%= hidden_field_tag :tags, params[:tags] if params[:tags].present? %>
6 <%= text_field_tag :q, params[:q], placeholder: "Search title, abstract, body…" %>
7 <%= submit_tag "Search", class: "action_button" %>
8 <% if params[:q].present? || params[:kinds].present? || params[:tags].present? %>
9 <%= link_to "Reset", url_for(controller: params[:controller], action: params[:action]) %>
10 <% end %>
11<% end %>
12
13<%= will_paginate @nodes %>
14<table class="node_table">
15 <tr class="header">
16 <th class="node_id">ID</th>
17 <th class="title">Title</th>
18 <th class="actions">Actions</th>
19 <th class="editor">Locked by</th>
20 <th class="revision">Rev.</th>
21 </tr>
22 <% @nodes.each do |node| %>
23 <tr class="<%= cycle("even", "odd") %>">
24 <td class="node_id"><%= node.id %></td>
25 <td class="title">
26 <h4><%= link_to title_for_node(node), node_path(node) %></h4>
27 <p><%= link_to_path(node.unique_name, node.unique_name) %></p>
28 </td>
29 <td class="actions">
30 <%= link_to 'show', node_path(node) %>
31 <%= link_to 'edit', edit_node_path(node) %>
32 <%= link_to 'revisions', node_revisions_path(node) %>
33 </td>
34 <td><%= node.lock_owner.login if node.lock_owner %></td>
35 <td><%= node.draft ? node.draft.revision : (node.head ? node.head.revision : "EMPTY") %></td>
36 </tr>
37 <% end %>
38</table>
39<%= will_paginate @nodes %>
diff --git a/app/views/nodes/chapters.html.erb b/app/views/nodes/chapters.html.erb
new file mode 100644
index 00000000..939f19cd
--- /dev/null
+++ b/app/views/nodes/chapters.html.erb
@@ -0,0 +1,9 @@
1<h1>Chapters</h1>
2
3<%= form_tag chapters_nodes_path, method: :get do %>
4 <label><%= check_box_tag 'kinds[]', 'erfa', @kind_keys.include?('erfa') %> Erfa</label>
5 <label><%= check_box_tag 'kinds[]', 'chaostreff', @kind_keys.include?('chaostreff') %> Chaostreff</label>
6 <%= submit_tag "Filter", class: "action_button" %>
7<% end %>
8
9<%= render 'node_list' %>
diff --git a/app/views/nodes/drafts.html.erb b/app/views/nodes/drafts.html.erb
new file mode 100644
index 00000000..6d0830c9
--- /dev/null
+++ b/app/views/nodes/drafts.html.erb
@@ -0,0 +1,3 @@
1<h1>Nodes with drafts or autosaves</h1>
2
3<%= render 'node_list' %>
diff --git a/app/views/nodes/mine.html.erb b/app/views/nodes/mine.html.erb
new file mode 100644
index 00000000..fc5680a9
--- /dev/null
+++ b/app/views/nodes/mine.html.erb
@@ -0,0 +1,3 @@
1<h1>My work</h1>
2
3<%= render 'node_list' %>
diff --git a/app/views/nodes/recent.html.erb b/app/views/nodes/recent.html.erb
new file mode 100644
index 00000000..36027750
--- /dev/null
+++ b/app/views/nodes/recent.html.erb
@@ -0,0 +1,3 @@
1<h1>Recently changed</h1>
2
3<%= render 'node_list' %>
diff --git a/app/views/nodes/tags.html.erb b/app/views/nodes/tags.html.erb
new file mode 100644
index 00000000..0ebc6ce6
--- /dev/null
+++ b/app/views/nodes/tags.html.erb
@@ -0,0 +1,3 @@
1<h1>Nodes tagged: <%= params[:tags] %></h1>
2
3<%= render 'node_list' %>