diff options
| -rw-r--r-- | app/controllers/nodes_controller.rb | 1 | ||||
| -rw-r--r-- | app/helpers/nodes_helper.rb | 5 | ||||
| -rw-r--r-- | app/views/nodes/new.html.erb | 4 | ||||
| -rw-r--r-- | app/views/nodes/show.html.erb | 29 | ||||
| -rw-r--r-- | lib/ccc_conventions.rb | 61 | ||||
| -rw-r--r-- | public/javascripts/admin_search.js | 18 | ||||
| -rw-r--r-- | public/stylesheets/admin.css | 8 |
7 files changed, 82 insertions, 44 deletions
diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb index 69aa268..a72be68 100644 --- a/app/controllers/nodes_controller.rb +++ b/app/controllers/nodes_controller.rb | |||
| @@ -22,6 +22,7 @@ class NodesController < ApplicationController | |||
| 22 | 22 | ||
| 23 | def new | 23 | def new |
| 24 | @node = Node.new node_params | 24 | @node = Node.new node_params |
| 25 | @selected_kind = CccConventions::NODE_KINDS.key?(params[:kind]) ? params[:kind] : "generic" | ||
| 25 | if params.has_key?(:parent_id) | 26 | if params.has_key?(:parent_id) |
| 26 | @parent_id = params[:parent_id] | 27 | @parent_id = params[:parent_id] |
| 27 | @parent_name = Node.find(@parent_id).title | 28 | @parent_name = Node.find(@parent_id).title |
diff --git a/app/helpers/nodes_helper.rb b/app/helpers/nodes_helper.rb index 2baf813..a89f879 100644 --- a/app/helpers/nodes_helper.rb +++ b/app/helpers/nodes_helper.rb | |||
| @@ -58,4 +58,9 @@ module NodesHelper | |||
| 58 | t(:event_schedule_none) | 58 | t(:event_schedule_none) |
| 59 | end | 59 | end |
| 60 | end | 60 | end |
| 61 | |||
| 62 | def matching_node_kinds(node) | ||
| 63 | path = node.unique_path | ||
| 64 | CccConventions::NODE_KINDS.select { |_, config| config[:parent_match]&.call(path) } | ||
| 65 | end | ||
| 61 | end | 66 | end |
diff --git a/app/views/nodes/new.html.erb b/app/views/nodes/new.html.erb index 0a05325..71f2fbf 100644 --- a/app/views/nodes/new.html.erb +++ b/app/views/nodes/new.html.erb | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | <div class="node_content"> | 13 | <div class="node_content"> |
| 14 | <% CccConventions::NODE_KINDS.each do |kind, config| %> | 14 | <% CccConventions::NODE_KINDS.each do |kind, config| %> |
| 15 | <p> | 15 | <p> |
| 16 | <%= radio_button_tag :kind, kind, kind == "generic", | 16 | <%= radio_button_tag :kind, kind, kind == @selected_kind, |
| 17 | data: { path_prefix: resolve_kind_text(config[:path_prefix]) } %> | 17 | data: { path_prefix: resolve_kind_text(config[:path_prefix]) } %> |
| 18 | <%= resolve_kind_text(config[:label]) %> | 18 | <%= resolve_kind_text(config[:label]) %> |
| 19 | <% if config[:hint] %> | 19 | <% if config[:hint] %> |
| @@ -29,7 +29,7 @@ | |||
| 29 | <span class="field_hint">A URL slug will be generated from this automatically. You can review or adjust it afterward under the "metadata" section's Slug field.</span> | 29 | <span class="field_hint">A URL slug will be generated from this automatically. You can review or adjust it afterward under the "metadata" section's Slug field.</span> |
| 30 | </div> | 30 | </div> |
| 31 | 31 | ||
| 32 | <div id="parent_search_field"> | 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_name %> |
diff --git a/app/views/nodes/show.html.erb b/app/views/nodes/show.html.erb index 189adb8..963bc37 100644 --- a/app/views/nodes/show.html.erb +++ b/app/views/nodes/show.html.erb | |||
| @@ -101,17 +101,30 @@ | |||
| 101 | <%= link_to 'add event', new_event_path(node_id: @node.id, tag_list: mapping&.last, auto_tag_source: mapping&.first, return_to: request.path) %> | 101 | <%= link_to 'add event', new_event_path(node_id: @node.id, tag_list: mapping&.last, auto_tag_source: mapping&.first, return_to: request.path) %> |
| 102 | </div> | 102 | </div> |
| 103 | 103 | ||
| 104 | <% if @node.children.any? %> | 104 | <% matches = matching_node_kinds(@node) %> |
| 105 | <% if @node.children.any? || matches.any? %> | ||
| 105 | <div class="node_description">Children</div> | 106 | <div class="node_description">Children</div> |
| 106 | <div class="node_content node_info_group"> | 107 | <div class="node_content node_info_group"> |
| 107 | <details> | 108 | <% if @node.children.any? %> |
| 108 | <summary><%= pluralize(@node.children.count, 'child', 'children') %></summary> | 109 | <details> |
| 109 | <ul> | 110 | <summary><%= pluralize(@node.children.count, 'child', 'children') %></summary> |
| 110 | <% @node.children.order(:slug).each do |child| %> | 111 | <ul> |
| 111 | <li><%= link_to (child.head&.title || child.draft&.title || child.slug), node_path(child) %></li> | 112 | <% @node.children.order(:slug).each do |child| %> |
| 113 | <li><%= link_to (child.head&.title || child.draft&.title || child.slug), node_path(child) %></li> | ||
| 114 | <% end %> | ||
| 115 | </ul> | ||
| 116 | </details> | ||
| 117 | <% end %> | ||
| 118 | <% if matches.any? %> | ||
| 119 | <p class="add_child_links"> | ||
| 120 | <% matches.each_with_index do |(kind, config), index| %> | ||
| 121 | <%= " · ".html_safe if index > 0 %> | ||
| 122 | <% link_params = { kind: kind } %> | ||
| 123 | <% link_params[:parent_id] = @node.id if kind == "generic" %> | ||
| 124 | <%= link_to "add '#{resolve_kind_text(config[:label])}' child", new_node_path(link_params) %> | ||
| 112 | <% end %> | 125 | <% end %> |
| 113 | </ul> | 126 | </p> |
| 114 | </details> | 127 | <% end %> |
| 115 | </div> | 128 | </div> |
| 116 | <% end %> | 129 | <% end %> |
| 117 | 130 | ||
diff --git a/lib/ccc_conventions.rb b/lib/ccc_conventions.rb index c0f9943..b420452 100644 --- a/lib/ccc_conventions.rb +++ b/lib/ccc_conventions.rb | |||
| @@ -4,44 +4,49 @@ module CccConventions | |||
| 4 | 4 | ||
| 5 | NODE_KINDS = { | 5 | NODE_KINDS = { |
| 6 | "top_level" => { | 6 | "top_level" => { |
| 7 | parent: -> { Node.root }, | 7 | parent: -> { Node.root }, |
| 8 | path_prefix: "", | 8 | parent_match: ->(path) { path == [] }, |
| 9 | label: "Top Level" | 9 | path_prefix: "", |
| 10 | label: "Top Level" | ||
| 10 | }, | 11 | }, |
| 11 | "generic" => { | 12 | "generic" => { |
| 12 | label: "Generic", | 13 | parent_match: ->(path) { true }, |
| 13 | hint: "Can be created anywhere - choose the parent below." | 14 | label: "Generic", |
| 14 | # no path_prefix - depends on whatever parent gets chosen; see below | 15 | hint: "Can be created anywhere - choose the parent below." |
| 15 | }, | 16 | }, |
| 16 | "update" => { | 17 | "update" => { |
| 17 | parent: -> { Update.find_or_create_parent }, | 18 | parent: -> { Update.find_or_create_parent }, |
| 18 | tags: ["update"], | 19 | parent_match: ->(path) { path[0] == "updates" && (path.length == 1 || path[1] =~ /\A\d{4}\z/) }, |
| 19 | path_prefix: -> { "updates/#{Time.now.year}" }, | 20 | tags: ["update"], |
| 20 | label: "Update", | 21 | path_prefix: -> { "updates/#{Time.now.year}" }, |
| 21 | hint: -> { "Automatically created in /updates/#{Time.now.year}/, gets tag \"update\", and inherits the update template." } | 22 | label: "Update", |
| 23 | hint: -> { "Automatically created in /updates/#{Time.now.year}/, gets tag \"update\", and inherits the update template." } | ||
| 22 | }, | 24 | }, |
| 23 | "press_release" => { | 25 | "press_release" => { |
| 24 | parent: -> { Update.find_or_create_parent }, | 26 | parent: -> { Update.find_or_create_parent }, |
| 25 | tags: ["update", "pressemitteilung"], | 27 | parent_match: ->(path) { path[0] == "updates" && (path.length == 1 || path[1] =~ /\A\d{4}\z/) }, |
| 26 | path_prefix: -> { "updates/#{Time.now.year}" }, | 28 | tags: ["update", "pressemitteilung"], |
| 27 | label: "Pressemitteilung", | 29 | path_prefix: -> { "updates/#{Time.now.year}" }, |
| 28 | hint: -> { "Automatically created in /updates/#{Time.now.year}/, gets tags \"update, pressemitteilung\", and inherits the update template." } | 30 | label: "Pressemitteilung", |
| 31 | hint: -> { "Automatically created in /updates/#{Time.now.year}/, gets tags \"update, pressemitteilung\", and inherits the update template." } | ||
| 29 | }, | 32 | }, |
| 30 | "erfa" => { | 33 | "erfa" => { |
| 31 | parent: -> { Node.find_by_unique_name!(ERFA_PARENT_NAME) }, | 34 | parent: -> { Node.find_by_unique_name!(ERFA_PARENT_NAME) }, |
| 32 | tags: ["erfa-detail"], | 35 | parent_match: ->(path) { path == ["club", "erfas"] }, |
| 33 | template: "chapter_detail", | 36 | tags: ["erfa-detail"], |
| 34 | path_prefix: ERFA_PARENT_NAME, | 37 | template: "chapter_detail", |
| 35 | label: "Erfa", | 38 | path_prefix: ERFA_PARENT_NAME, |
| 36 | hint: "Automatically created under the Erfa-Kreise overview page, gets tag \"erfa-detail\", and uses the chapter detail template." | 39 | label: "Erfa", |
| 40 | hint: "Automatically created under the Erfa-Kreise overview page, gets tag \"erfa-detail\", and uses the chapter detail template." | ||
| 37 | }, | 41 | }, |
| 38 | "chaostreff" => { | 42 | "chaostreff" => { |
| 39 | parent: -> { Node.find_by_unique_name!(CHAOSTREFF_PARENT_NAME) }, | 43 | parent: -> { Node.find_by_unique_name!(CHAOSTREFF_PARENT_NAME) }, |
| 40 | tags: ["chaostreff-detail"], | 44 | parent_match: ->(path) { path == ["club", "chaostreffs"] }, |
| 41 | template: "chapter_detail", | 45 | tags: ["chaostreff-detail"], |
| 42 | path_prefix: CHAOSTREFF_PARENT_NAME, | 46 | template: "chapter_detail", |
| 43 | label: "Chaostreff", | 47 | path_prefix: CHAOSTREFF_PARENT_NAME, |
| 44 | hint: "Automatically created under the Chaostreffs overview page, gets tag \"chaostreff-detail\", and uses the chapter detail template." | 48 | label: "Chaostreff", |
| 49 | hint: "Automatically created under the Chaostreffs overview page, gets tag \"chaostreff-detail\", and uses the chapter detail template." | ||
| 45 | } | 50 | } |
| 46 | }.freeze | 51 | }.freeze |
| 47 | end | 52 | end |
diff --git a/public/javascripts/admin_search.js b/public/javascripts/admin_search.js index 2565929..6ef9087 100644 --- a/public/javascripts/admin_search.js +++ b/public/javascripts/admin_search.js | |||
| @@ -208,14 +208,20 @@ parent_search = { | |||
| 208 | }, | 208 | }, |
| 209 | 209 | ||
| 210 | initialize_radio_buttons : function() { | 210 | initialize_radio_buttons : function() { |
| 211 | $("input[name='kind']").bind("change", function(){ | 211 | parent_search.sync_parent_field(); |
| 212 | if ($(this).val() === "generic") { | 212 | $("input[name='kind']").bind("change", function() { |
| 213 | $("#parent_search_field").show(); | 213 | parent_search.sync_parent_field(); |
| 214 | } else { | ||
| 215 | $("#parent_search_field").hide(); | ||
| 216 | } | ||
| 217 | parent_search.update_resulting_path(); | 214 | parent_search.update_resulting_path(); |
| 218 | }); | 215 | }); |
| 216 | }, | ||
| 217 | |||
| 218 | sync_parent_field : function() { | ||
| 219 | var kind = $("input[name='kind']:checked").val(); | ||
| 220 | if (kind === "generic") { | ||
| 221 | $("#parent_search_field").show(); | ||
| 222 | } else { | ||
| 223 | $("#parent_search_field").hide(); | ||
| 224 | } | ||
| 219 | } | 225 | } |
| 220 | } | 226 | } |
| 221 | 227 | ||
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index 1196d83..3033798 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css | |||
| @@ -338,6 +338,14 @@ input[type=radio] { | |||
| 338 | border: 1px solid #989898; | 338 | border: 1px solid #989898; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | .add_child_links { | ||
| 342 | margin-top: 0.5rem; | ||
| 343 | } | ||
| 344 | |||
| 345 | .add_child_links a { | ||
| 346 | white-space: nowrap; | ||
| 347 | } | ||
| 348 | |||
| 341 | div#login_form input[type=text], div#login_form input[type=password] { | 349 | div#login_form input[type=text], div#login_form input[type=password] { |
| 342 | width: 150px; | 350 | width: 150px; |
| 343 | } | 351 | } |
