diff --git a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 b/app/assets/javascripts/discourse/controllers/tags-index.js.es6 index 07a9da7cfed..545bf7b21ec 100644 --- a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 +++ b/app/assets/javascripts/discourse/controllers/tags-index.js.es6 @@ -1,7 +1,20 @@ +import computed from 'ember-addons/ember-computed-decorators'; + export default Ember.Controller.extend({ sortProperties: ['count:desc', 'id'], canAdminTags: Ember.computed.alias("currentUser.staff"), + groupedByCategory: Ember.computed.notEmpty('model.extras.categories'), + groupedByTagGroup: Ember.computed.notEmpty('model.extras.tag_groups'), + + @computed('groupedByCategory', 'groupedByTagGroup') + otherTagsTitleKey(groupedByCategory, groupedByTagGroup) { + if (!groupedByCategory && !groupedByTagGroup) { + return 'tagging.all_tags'; + } else { + return 'tagging.other_tags'; + } + }, actions: { sortByCount() { diff --git a/app/assets/javascripts/discourse/templates/components/tag-list.hbs b/app/assets/javascripts/discourse/templates/components/tag-list.hbs index a3e912d26ca..9c791cf25d7 100644 --- a/app/assets/javascripts/discourse/templates/components/tag-list.hbs +++ b/app/assets/javascripts/discourse/templates/components/tag-list.hbs @@ -4,6 +4,9 @@ {{#if category}} {{category-title-link category=category}} {{/if}} +{{#if tagGroupName}} +

{{tagGroupName}}

+{{/if}} {{#each sortedTags as |tag|}}
{{#if tag.count}} diff --git a/app/assets/javascripts/discourse/templates/tags/index.hbs b/app/assets/javascripts/discourse/templates/tags/index.hbs index 1cf1beb970b..1036b77bc77 100644 --- a/app/assets/javascripts/discourse/templates/tags/index.hbs +++ b/app/assets/javascripts/discourse/templates/tags/index.hbs @@ -23,4 +23,8 @@ {{tag-list tags=category.tags sortProperties=sortProperties categoryId=category.id}} {{/each}} -{{tag-list tags=model sortProperties=sortProperties titleKey="tagging.all_tags"}} +{{#each model.extras.tag_groups as |tagGroup|}} + {{tag-list tags=tagGroup.tags sortProperties=sortProperties tagGroupName=tagGroup.name}} +{{/each}} + +{{tag-list tags=model sortProperties=sortProperties titleKey=otherTagsTitleKey}} diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 54115945e06..b65d54ae0c9 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -19,30 +19,60 @@ class TagsController < ::ApplicationController before_action :set_category_from_params, except: [:index, :update, :destroy, :tag_feed, :search, :notifications, :update_notifications] def index - categories = Category.where("id in (select category_id from category_tags)") - .where("id in (?)", guardian.allowed_category_ids) - .preload(:tags) - category_tag_counts = categories.map do |c| - h = Tag.category_tags_by_count_query(c, limit: 300).count(Tag::COUNT_ARG) - h.merge!(c.tags.where.not(name: h.keys).inject({}) { |sum, t| sum[t.name] = 0; sum }) # unused tags - { id: c.id, tags: self.class.tag_counts_json(h) } - end - - tag_counts = self.class.tags_by_count(guardian, limit: 300).count(Tag::COUNT_ARG) - @tags = self.class.tag_counts_json(tag_counts) - @description_meta = I18n.t("tags.title") @title = @description_meta respond_to do |format| + format.html do + tag_counts = self.class.tags_by_count(guardian, limit: 300).count(Tag::COUNT_ARG) + @tags = self.class.tag_counts_json(tag_counts) render :index end + format.json do - render json: { - tags: @tags, - extras: { categories: category_tag_counts } - } + if SiteSetting.tags_listed_by_group + # TODO: performance is bad + grouped_tag_counts = TagGroup.order('name ASC').preload(:tags).map do |tag_group| + h = Tag.tags_by_count_query(limit: 300) + .joins("LEFT JOIN tag_group_memberships ON tags.id = tag_group_memberships.tag_id") + .where('tag_group_memberships.tag_group_id = ?', tag_group.id) + .count(Tag::COUNT_ARG) + { id: tag_group.id, name: tag_group.name, tags: self.class.tag_counts_json(h) } + end + + ungrouped_tag_counts = guardian.filter_allowed_categories( + Tag.tags_by_count_query(limit: 300) + .where("tags.id NOT IN (select tag_id from tag_group_memberships)") + .count(Tag::COUNT_ARG) + ) + + render json: { + tags: self.class.tag_counts_json(ungrouped_tag_counts), # tags that don't belong to a group + extras: { tag_groups: grouped_tag_counts } + } + else + unrestricted_tag_counts = guardian.filter_allowed_categories( + Tag.tags_by_count_query(limit: 300) + .where("tags.id NOT IN (select tag_id from category_tags)") + .count(Tag::COUNT_ARG) + ) + + categories = Category.where("id in (select category_id from category_tags)") + .where("id in (?)", guardian.allowed_category_ids) + .preload(:tags) + + category_tag_counts = categories.map do |c| + h = Tag.category_tags_by_count_query(c, limit: 300).count(Tag::COUNT_ARG) + h.merge!(c.tags.where.not(name: h.keys).inject({}) { |sum, t| sum[t.name] = 0; sum }) # unused tags + { id: c.id, tags: self.class.tag_counts_json(h) } + end + + render json: { + tags: self.class.tag_counts_json(unrestricted_tag_counts), + extras: { categories: category_tag_counts } + } + end end end end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 4af1df836d7..ede17d1af9b 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2507,6 +2507,7 @@ en: tagging: all_tags: "All Tags" + other_tags: "Other Tags" selector_all_tags: "all tags" selector_no_tags: "no tags" changed: "tags changed:" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index b55a7364b0e..04a9b1bb849 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1584,6 +1584,7 @@ en: show_filter_by_tag: "Show a dropdown to filter a topic list by tag." max_tags_in_filter_list: "Maximum number of tags to show in the filter dropdown. The most used tags will be shown." tags_sort_alphabetically: "Show tags in alphabetical order. Default is to show in order of popularity." + tags_listed_by_group: "List tags by tag group on the Tags page (/tags)." tag_style: "Visual style for tag badges." staff_tags: "A list of tags that can only be applied by staff members" min_trust_level_to_tag_topics: "Minimum trust level required to tag topics" diff --git a/config/site_settings.yml b/config/site_settings.yml index 9ea097e0acf..00d579e71c0 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -1521,6 +1521,9 @@ tags: client: true default: false refresh: true + tags_listed_by_group: + client: true + default: false staff_tags: type: list client: true