From 7d6575e2f11aa0fdcb901e3e782654aee73ec497 Mon Sep 17 00:00:00 2001
From: Taico Aerts <t.v.aerts@tudelft.nl>
Date: Mon, 12 Sep 2022 23:19:45 +0200
Subject: [PATCH] Add ability to create tags for mods

Closes #180
---
 app/controllers/tags_controller.rb | 21 ++++++++++--
 app/views/tags/_form.html.erb      | 54 ++++++++++++++++++++++++++++++
 app/views/tags/category.html.erb   |  4 +++
 app/views/tags/edit.html.erb       | 45 +------------------------
 app/views/tags/new.html.erb        |  7 ++++
 config/routes.rb                   |  2 ++
 6 files changed, 86 insertions(+), 47 deletions(-)
 create mode 100644 app/views/tags/_form.html.erb
 create mode 100644 app/views/tags/new.html.erb

diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index aba4ed97d..d8c4a206e 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -1,8 +1,8 @@
 class TagsController < ApplicationController
-  before_action :authenticate_user!, only: [:edit, :update, :rename, :merge, :select_merge]
+  before_action :authenticate_user!, only: [:new, :create, :edit, :update, :rename, :merge, :select_merge]
   before_action :set_category, except: [:index]
   before_action :set_tag, only: [:show, :edit, :update, :children, :rename, :merge, :select_merge, :nuke, :nuke_warning]
-  before_action :verify_moderator, only: [:rename, :merge, :select_merge]
+  before_action :verify_moderator, only: [:new, :create, :rename, :merge, :select_merge]
   before_action :verify_admin, only: [:nuke, :nuke_warning]
 
   def index
@@ -59,6 +59,21 @@ class TagsController < ApplicationController
     end
   end
 
+  def new
+    @tag = Tag.new
+  end
+
+  def create
+    @tag = Tag.new(tag_params.merge(tag_set_id: @category.tag_set.id))
+    if @tag.save
+      flash[:danger] = nil
+      redirect_to tag_path(id: @category.id, tag_id: @tag.id)
+    else
+      flash[:danger] = @tag.errors.full_messages.join(', ')
+      render :new, status: :bad_request
+    end
+  end
+
   def edit
     check_your_privilege('edit_tags', nil, true)
   end
@@ -177,7 +192,7 @@ class TagsController < ApplicationController
   end
 
   def tag_params
-    params.require(:tag).permit(:excerpt, :wiki_markdown, :parent_id)
+    params.require(:tag).permit(:excerpt, :wiki_markdown, :parent_id, :name)
   end
 
   def exec(sql_array)
diff --git a/app/views/tags/_form.html.erb b/app/views/tags/_form.html.erb
new file mode 100644
index 000000000..f88e1d6d4
--- /dev/null
+++ b/app/views/tags/_form.html.erb
@@ -0,0 +1,54 @@
+<%= render 'posts/markdown_script' %>
+
+<% if @tag.errors.any? %>
+  <div class="notice is-danger">
+    There were some errors while saving this tag:
+
+    <ul>
+      <% @tag.errors.full_messages.each do |msg| %>
+        <li><%= msg %></li>
+      <% end %>
+    </ul>
+  </div>
+<% end %>
+
+<%= form_for @tag, url: submit_path do |f| %>
+  <% if submit_path == create_tag_path %>
+    <div class="form-group">
+      <%= f.label :name, 'Name', class: 'form-element' %>
+      <span class="form-caption">
+        Name of the tag
+      </span>
+      <%= f.text_field :name, class: 'form-element' %>
+    </div>
+  <% end %>
+
+  <div class="form-group">
+    <%= f.label :parent_id, 'Parent tag', class: 'form-element' %>
+    <span class="form-caption">
+      Optional. Select a parent tag to make this part of a tag hierarchy.
+    </span>
+    <%= f.select :parent_id, options_for_select(@tag.parent.present? ? [[@tag.parent.name, @tag.parent_id]] : [],
+                                                selected: @tag.parent.present? ? @tag.parent_id : nil),
+                 { include_blank: true }, class: "form-element js-tag-select",
+                 data: { tag_set: @category.tag_set_id, use_ids: true, placeholder: "None" } %>
+  </div>
+
+  <div class="form-group">
+    <%= f.label :excerpt, 'Usage guidance', class: 'form-element' %>
+    <span class="form-caption">
+      Short usage guidance for this tag. Will be cut off at 120 characters in the tags list, but displayed in full on
+      the tag page.
+    </span>
+    <%= f.text_area :excerpt, class: 'form-element js-tag-excerpt', rows: 3 %>
+    <span class="has-float-right has-font-size-caption js-character-count"
+          data-target=".js-tag-excerpt" data-max="600">0 / 600</span>
+  </div>
+
+  <%= render 'shared/body_field', f: f, field_name: :wiki_markdown, field_label: 'Wiki', post: @tag do %>
+    Full usage guidance and any other information you want people to know about this tag.
+  <% end %>
+  <div class="post-preview"></div>
+
+  <%= f.submit 'Save', class: 'button is-filled' %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/tags/category.html.erb b/app/views/tags/category.html.erb
index d783816d7..a3119f65f 100644
--- a/app/views/tags/category.html.erb
+++ b/app/views/tags/category.html.erb
@@ -2,6 +2,10 @@
 
 <h1>Tags used in <%= @category.name %></h1>
 
+<% if current_user&.is_moderator %>
+  <%= link_to 'New', new_tag_path(id: @category.id), class: 'button is-muted is-outlined' %>
+<% end %>
+
 <%= form_tag category_tags_path(@category), method: :get, class: 'form-inline' do %>
   <div class="form-group-horizontal">
     <div class="form-group">
diff --git a/app/views/tags/edit.html.erb b/app/views/tags/edit.html.erb
index 93b6ec10e..ee785c700 100644
--- a/app/views/tags/edit.html.erb
+++ b/app/views/tags/edit.html.erb
@@ -1,50 +1,7 @@
 <% content_for :title, 'Edit tag' %>
 
-<%= render 'posts/markdown_script' %>
-
 <h1>
   Edit <span class="<%= @classes %> is-large"><%= @tag.name %></span>
 </h1>
 
-<% if @tag.errors.any? %>
-  <div class="notice is-danger">
-    There were some errors while saving this tag:
-
-    <ul>
-      <% @tag.errors.full_messages.each do |msg| %>
-        <li><%= msg %></li>
-      <% end %>
-    </ul>
-  </div>
-<% end %>
-
-<%= form_for @tag, url: update_tag_path(id: @category.id, tag_id: @tag.id) do |f| %>
-  <div class="form-group">
-    <%= f.label :parent_id, 'Parent tag', class: 'form-element' %>
-    <span class="form-caption">
-      Optional. Select a parent tag to make this part of a tag hierarchy.
-    </span>
-    <%= f.select :parent_id, options_for_select(@tag.parent.present? ? [[@tag.parent.name, @tag.parent_id]] : [],
-                                                selected: @tag.parent.present? ? @tag.parent_id : nil),
-                 { include_blank: true }, class: "form-element js-tag-select",
-                 data: { tag_set: @category.tag_set_id, use_ids: true, placeholder: "None" } %>
-  </div>
-
-  <div class="form-group">
-    <%= f.label :excerpt, 'Usage guidance', class: 'form-element' %>
-    <span class="form-caption">
-      Short usage guidance for this tag. Will be cut off at 120 characters in the tags list, but displayed in full on
-      the tag page.
-    </span>
-    <%= f.text_area :excerpt, class: 'form-element js-tag-excerpt', rows: 3 %>
-    <span class="has-float-right has-font-size-caption js-character-count"
-          data-target=".js-tag-excerpt" data-max="600">0 / 600</span>
-  </div>
-
-  <%= render 'shared/body_field', f: f, field_name: :wiki_markdown, field_label: 'Wiki', post: @tag do %>
-    Full usage guidance and any other information you want people to know about this tag.
-  <% end %>
-  <div class="post-preview"></div>
-
-  <%= f.submit 'Save', class: 'button is-filled' %>
-<% end %>
\ No newline at end of file
+<%= render 'form', submit_path: update_tag_path(id: @category.id, tag_id: @tag.id) %>
\ No newline at end of file
diff --git a/app/views/tags/new.html.erb b/app/views/tags/new.html.erb
new file mode 100644
index 000000000..1dfb8c674
--- /dev/null
+++ b/app/views/tags/new.html.erb
@@ -0,0 +1,7 @@
+<% content_for :title, 'Create tag' %>
+
+<h1>
+  Create <span class="<%= @classes %> is-large">Tag</span>
+</h1>
+
+<%= render 'form', submit_path: create_tag_path %>
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index a23af0142..694164c6d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -246,6 +246,8 @@ Rails.application.routes.draw do
     get    ':id/types',                    to: 'categories#post_types', as: :category_post_types
     get    ':id/feed',                     to: 'categories#rss_feed', as: :category_feed
     get    ':id/tags',                     to: 'tags#category', as: :category_tags
+    get    ':id/tags/new',                 to: 'tags#new', as: :new_tag
+    post   ':id/tags/new',                 to: 'tags#create', as: :create_tag
     get    ':id/tags/:tag_id',             to: 'tags#show', as: :tag
     get    ':id/tags/:tag_id/children',    to: 'tags#children', as: :tag_children
     get    ':id/tags/:tag_id/edit',        to: 'tags#edit', as: :edit_tag
-- 
GitLab