summaryrefslogtreecommitdiff
path: root/app/controllers
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-11 23:43:02 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-11 23:43:02 +0200
commit92c394b43a0603743b914c6298aab986805ca990 (patch)
tree39308770fbae5558d98a7def3d25802ed8083d81 /app/controllers
parent47beb3fe6ed6fdb75c2dd3a55362ad1aba3bbc3b (diff)
Add drafts/recent/mine/chapters admin node views
Four NodesController actions -- drafts, recent, mine, chapters -- each building its own base scope, sharing one private method (index_matching) for search narrowing and pagination. Wizard rewrite to link into these instead of rendering its own tables is a separate, later step. Node.editor_search backs the shared "q" narrowing: an ILIKE substring match against title/abstract on whichever of head or draft is present, splitting the term on whitespace and requiring every word to match somewhere independently, not as one phrase, since real words can end up separated by markup in the underlying HTML. Deliberately separate from Node.search, the public content search, which stays tsvector-based and head-only. chapters generalizes into /admin/nodes/tags/:tags for an arbitrary tag list (OR'd, not AND'd), sharing the controller action but rendering its own template rather than branching inside one view.
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/nodes_controller.rb45
1 files changed, 45 insertions, 0 deletions
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb
index 6fcd930..ede91ad 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