diff --git a/app/assets/javascripts/categories.js b/app/assets/javascripts/categories.js new file mode 100644 index 0000000000000000000000000000000000000000..8b766b11ba22e3014b8edfb5729ce1858a42935b --- /dev/null +++ b/app/assets/javascripts/categories.js @@ -0,0 +1,27 @@ +$(() => { + $('.js-category-tag-set-select').on('change', ev => { + const $tgt = $(ev.target); + const tagSetId = $tgt.val(); + const formGroups = $('.js-category-tags-group'); + if (tagSetId) { + formGroups.each((i, el) => { + const $el = $(el); + const $caption = $el.find('.js-tags-group-caption'); + $caption.find('[data-state="absent"]').hide(); + $caption.find('[data-state="present"]').show(); + + $el.find('.js-tag-select').attr('data-tag-set', tagSetId); + }); + } + else { + formGroups.each((i, el) => { + const $el = $(el); + const $caption = $el.find('.js-tags-group-caption'); + $caption.find('[data-state="absent"]').show(); + $caption.find('[data-state="present"]').hide(); + + $el.find('.js-tag-select').attr('data-tag-set', null); + }); + } + }); +}); \ No newline at end of file diff --git a/app/assets/javascripts/tags.js b/app/assets/javascripts/tags.js index 1439c371fbb44404ba78077aad700a62e59ba74e..3b07c93a3c9a5984ed97a33af79d3c6115e74d90 100644 --- a/app/assets/javascripts/tags.js +++ b/app/assets/javascripts/tags.js @@ -1,14 +1,17 @@ $(() => { - $('.js-tag-select').select2({ - tags: true, - ajax: { - url: '/tags', - data: function (params) { - return Object.assign(params, { tag_set: $(this).data('tag-set') }); - }, - headers: { 'Accept': 'application/json' }, - delay: 100, - processResults: data => ({results: data.map(t => ({id: t.name, text: t.name}))}), - } + $('.js-tag-select').each((i, el) => { + const $tgt = $(el); + $tgt.select2({ + tags: $tgt.attr('data-create') !== 'false', + ajax: { + url: '/tags', + data: function (params) { + return Object.assign(params, { tag_set: $(this).data('tag-set') }); + }, + headers: { 'Accept': 'application/json' }, + delay: 100, + processResults: data => ({results: data.map(t => ({id: t.name, text: t.name}))}), + } + }); }); }); \ No newline at end of file diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index e1bd54c0ffea160de3bbed723f6d166219bfc664..62b0a6329f515529a6d3bcfeae4523c016b96516 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -75,7 +75,7 @@ class CategoriesController < ApplicationController def category_params params.require(:category).permit(:name, :short_wiki, :tag_set_id, :is_homepage, :min_trust_level, :button_text, :color_code, :min_view_trust_level, :license_id, :sequence, display_post_types: [], - post_type_ids: []) + post_type_ids: [], required_tag_ids: [], topic_tag_ids: []) end def verify_view_access diff --git a/app/models/category.rb b/app/models/category.rb index 486fcb87cdb1eff8302af486e14df3391e433031..cba36d5c375277c0d5167594751f06bb4cb98096 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -2,6 +2,8 @@ class Category < ApplicationRecord include CommunityRelated has_and_belongs_to_many :post_types + has_and_belongs_to_many :required_tags, class_name: 'Tag', join_table: 'categories_required_tags' + has_and_belongs_to_many :topic_tags, class_name: 'Tag', join_table: 'categories_topic_tags' has_many :posts belongs_to :tag_set belongs_to :license diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb index 9613e9d0cbf9cc64c572d419ba5182430c52640f..95a830f61756bd1b16766c982e6fbc12baaa3226 100644 --- a/app/views/categories/_form.html.erb +++ b/app/views/categories/_form.html.erb @@ -31,7 +31,7 @@ <%= f.label :tag_set_id, 'Tag set', class: 'form-element' %> <span class="form-caption">Which tag set may posts in this category draw from?</span> <%= f.select :tag_set_id, options_for_select(TagSet.all.map { |ts| [ts.name, ts.id] }, selected: @category.tag_set_id), - { include_blank: true }, class: 'form-element' %> + { include_blank: true }, class: 'form-element js-category-tag-set-select' %> </div> <div class="form-group"> @@ -90,5 +90,37 @@ <%= f.number_field :sequence, class: 'form-element' %> </div> + <div class="form-group js-category-tags-group"> + <%= f.label :required_tag_ids, 'Required tags', class: 'form-element' %> + <span class="form-caption js-tags-group-caption"> + <span data-state="present" style="<%= @category.tag_set.nil? ? 'display: none' : '' %>"> + Required tags for this category - every post will be required to have one of these tags. + </span> + <span data-state="absent" style="<%= @category.tag_set.nil? ? '' : 'display: none' %>"> + Select a tag set first. + </span> + </span> + <%= f.select :required_tag_ids, options_for_select(@category.required_tags.map { |t| [t.name, t.id] }, + selected: @category.required_tags.pluck(:name)), + { include_blank: true }, multiple: true, class: 'form-element js-tag-select', + data: { tag_set: @category.tag_set&.id, create: 'false' } %> + </div> + + <div class="form-group js-category-tags-group"> + <%= f.label :required_tag_ids, 'Topic tags', class: 'form-element' %> + <span class="form-caption js-tags-group-caption"> + <span data-state="present" style="<%= @category.tag_set.nil? ? 'display: none' : '' %>"> + Tags that will be highlighted as the most important tag on a question. + </span> + <span data-state="absent" style="<%= @category.tag_set.nil? ? '' : 'display: none' %>"> + Select a tag set first. + </span> + </span> + <%= f.select :topic_tag_ids, options_for_select(@category.topic_tags.map { |t| [t.name, t.id] }, + selected: @category.topic_tags.pluck(:name)), + { include_blank: true }, multiple: true, class: 'form-element js-tag-select', + data: { tag_set: @category.tag_set&.id, create: 'false' } %> + </div> + <%= f.submit 'Save', class: 'button is-filled' %> <% end %> diff --git a/db/migrate/20200508115752_add_category_tag_join_tables.rb b/db/migrate/20200508115752_add_category_tag_join_tables.rb new file mode 100644 index 0000000000000000000000000000000000000000..f79752d7c334bd55acda2dd6c834f5305deab2e7 --- /dev/null +++ b/db/migrate/20200508115752_add_category_tag_join_tables.rb @@ -0,0 +1,13 @@ +class AddCategoryTagJoinTables < ActiveRecord::Migration[5.2] + def change + create_table :categories_required_tags, id: false, primary_key: [:category_id, :tag_id] do |t| + t.bigint :category_id + t.bigint :tag_id + end + + create_table :categories_topic_tags, id: false, primary_key: [:category_id, :tag_id] do |t| + t.bigint :category_id + t.bigint :tag_id + end + end +end