diff --git a/app/assets/javascripts/discourse/components/tag-list.js.es6 b/app/assets/javascripts/discourse/components/tag-list.js.es6 index efa958d71a2..decb1cea5df 100644 --- a/app/assets/javascripts/discourse/components/tag-list.js.es6 +++ b/app/assets/javascripts/discourse/components/tag-list.js.es6 @@ -1,22 +1,23 @@ +import computed from "ember-addons/ember-computed-decorators"; + export default Ember.Component.extend({ classNameBindings: [':tag-list', 'categoryClass'], isPrivateMessage: false, sortedTags: Ember.computed.sort('tags', 'sortProperties'), - title: function() { - if (this.get('titleKey')) { return I18n.t(this.get('titleKey')); } - }.property('titleKey'), + @computed("titleKey") + title(titleKey) { + return titleKey && I18n.t(titleKey); + }, - category: function() { - if (this.get('categoryId')) { - return Discourse.Category.findById(this.get('categoryId')); - } - }.property('categoryId'), + @computed("categoryId") + category(categoryId) { + return categoryId && Discourse.Category.findById(categoryId); + }, - categoryClass: function() { - if (this.get('category')) { - return "tag-list-" + this.get('category.fullSlug'); - } - }.property('category') + @computed("category.fullSlug") + categoryClass(slug) { + return slug && `tag-list-${slug}`; + } }); diff --git a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 b/app/assets/javascripts/discourse/controllers/tags-index.js.es6 index cce4fa05b10..acf1c58d466 100644 --- a/app/assets/javascripts/discourse/controllers/tags-index.js.es6 +++ b/app/assets/javascripts/discourse/controllers/tags-index.js.es6 @@ -1,7 +1,7 @@ import computed from 'ember-addons/ember-computed-decorators'; export default Ember.Controller.extend({ - sortProperties: ['count:desc', 'id'], + sortProperties: ['totalCount:desc', 'id'], sortedByCount: true, sortedByName: false, @@ -21,7 +21,7 @@ export default Ember.Controller.extend({ actions: { sortByCount() { this.setProperties({ - sortProperties: ['count:desc', 'id'], + sortProperties: ['totalCount:desc', 'id'], sortedByCount: true, sortedByName: false }); diff --git a/app/assets/javascripts/discourse/models/category-list.js.es6 b/app/assets/javascripts/discourse/models/category-list.js.es6 index 987e5020530..9511c49c589 100644 --- a/app/assets/javascripts/discourse/models/category-list.js.es6 +++ b/app/assets/javascripts/discourse/models/category-list.js.es6 @@ -37,7 +37,6 @@ CategoryList.reopenClass({ c.topics = c.topics.map(t => Discourse.Topic.create(t)); } - switch(statPeriod) { case "week": case "month": diff --git a/app/assets/javascripts/discourse/models/tag.js.es6 b/app/assets/javascripts/discourse/models/tag.js.es6 new file mode 100644 index 00000000000..572463e5bde --- /dev/null +++ b/app/assets/javascripts/discourse/models/tag.js.es6 @@ -0,0 +1,9 @@ +import RestModel from "discourse/models/rest"; +import computed from "ember-addons/ember-computed-decorators"; + +export default RestModel.extend({ + @computed("count", "pm_count") + totalCount(count, pmCount) { + return count + pmCount; + } +}); diff --git a/app/assets/javascripts/discourse/routes/tags-index.js.es6 b/app/assets/javascripts/discourse/routes/tags-index.js.es6 index dcbe6f19290..7b7bffedb9a 100644 --- a/app/assets/javascripts/discourse/routes/tags-index.js.es6 +++ b/app/assets/javascripts/discourse/routes/tags-index.js.es6 @@ -1,6 +1,22 @@ +import Tag from "discourse/models/tag"; + export default Discourse.Route.extend({ model() { - return this.store.findAll('tag'); + return this.store.findAll("tag").then(result => { + if (result.extras) { + if (result.extras.categories) { + result.extras.categories.forEach(category => { + category.tags = category.tags.map(t => Tag.create(t)); + }); + } + if (result.extras.tag_groups) { + result.extras.tag_groups.forEach(tagGroup => { + tagGroup.tags = tagGroup.tags.map(t => Tag.create(t)); + }); + } + } + return result; + }); }, titleToken() { @@ -10,7 +26,7 @@ export default Discourse.Route.extend({ setupController(controller, model) { this.controllerFor('tags.index').setProperties({ model, - sortProperties: this.siteSettings.tags_sort_alphabetically ? ['id'] : ['count:desc', 'id'] + sortProperties: this.siteSettings.tags_sort_alphabetically ? ['id'] : ['totalCount:desc', 'id'] }); }, diff --git a/app/assets/javascripts/discourse/templates/components/tag-list.hbs b/app/assets/javascripts/discourse/templates/components/tag-list.hbs index cd09db7bc35..7be97e2439f 100644 --- a/app/assets/javascripts/discourse/templates/components/tag-list.hbs +++ b/app/assets/javascripts/discourse/templates/components/tag-list.hbs @@ -9,11 +9,7 @@ {{/if}} {{#each sortedTags as |tag|}}
- {{#if tag.count}} - {{discourse-tag tag.id isPrivateMessage=isPrivateMessage tagsForUser=tagsForUser}} x {{tag.count}} - {{else}} - {{discourse-tag tag.id}} - {{/if}} + {{discourse-tag tag.id isPrivateMessage=isPrivateMessage tagsForUser=tagsForUser}} {{#if tag.pm_count}}{{d-icon "envelope"}}{{/if}}{{#if tag.totalCount}} x {{tag.totalCount}}{{/if}}
{{/each}}
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index f566dc453ce..0d67cb80770 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -33,7 +33,11 @@ class TagsController < ::ApplicationController format.json do ungrouped_tags = Tag.where("tags.id NOT IN (select tag_id from tag_group_memberships)") - ungrouped_tags = ungrouped_tags.where("tags.topic_count > 0") unless guardian.can_admin_tags? + + # show all the tags to admins + unless guardian.can_admin_tags? && guardian.is_admin? + ungrouped_tags = ungrouped_tags.where("tags.topic_count > 0") + end if SiteSetting.tags_listed_by_group grouped_tag_counts = TagGroup.allowed(guardian).order('name ASC').includes(:tags).map do |tag_group| @@ -210,7 +214,7 @@ class TagsController < ::ApplicationController end def self.tag_counts_json(tags) - tags.map { |t| { id: t.name, text: t.name, count: t.topic_count } } + tags.map { |t| { id: t.name, text: t.name, count: t.topic_count, pm_count: t.pm_topic_count } } end def set_category_from_params diff --git a/app/models/tag.rb b/app/models/tag.rb index 8fcba761387..62aee017d37 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -20,22 +20,40 @@ class Tag < ActiveRecord::Base after_commit :trigger_tag_destroyed_event, on: :destroy def self.ensure_consistency! - update_topic_counts # topic_count counter cache can miscount + update_topic_counts end def self.update_topic_counts - Category.exec_sql <<~SQL + Tag.exec_sql <<~SQL UPDATE tags t - SET topic_count = x.topic_count - FROM ( - SELECT COUNT(topics.id) AS topic_count, tags.id AS tag_id - FROM tags - LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id - LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL AND topics.archetype != 'private_message' - GROUP BY tags.id - ) x - WHERE x.tag_id = t.id - AND x.topic_count <> t.topic_count + SET topic_count = x.topic_count + FROM ( + SELECT COUNT(topics.id) AS topic_count, tags.id AS tag_id + FROM tags + LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id + LEFT JOIN topics ON topics.id = topic_tags.topic_id + AND topics.deleted_at IS NULL + AND topics.archetype != 'private_message' + GROUP BY tags.id + ) x + WHERE x.tag_id = t.id + AND x.topic_count <> t.topic_count + SQL + + Tag.exec_sql <<~SQL + UPDATE tags t + SET pm_topic_count = x.pm_topic_count + FROM ( + SELECT COUNT(topics.id) AS pm_topic_count, tags.id AS tag_id + FROM tags + LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id + LEFT JOIN topics ON topics.id = topic_tags.topic_id + AND topics.deleted_at IS NULL + AND topics.archetype = 'private_message' + GROUP BY tags.id + ) x + WHERE x.tag_id = t.id + AND x.pm_topic_count <> t.pm_topic_count SQL end @@ -54,7 +72,7 @@ class Tag < ActiveRecord::Base tag_names_with_counts = Tag.exec_sql <<~SQL SELECT tags.name as tag_name, SUM(stats.topic_count) AS sum_topic_count FROM category_tag_stats stats - INNER JOIN tags ON stats.tag_id = tags.id AND stats.topic_count > 0 + JOIN tags ON stats.tag_id = tags.id AND stats.topic_count > 0 WHERE stats.category_id in (#{scope_category_ids.join(',')}) #{filter_sql} GROUP BY tags.name @@ -71,23 +89,24 @@ class Tag < ActiveRecord::Base user_id = allowed_user.id tag_names_with_counts = Tag.exec_sql <<~SQL - SELECT tags.name, - COUNT(topics.id) AS topic_count - FROM tags - INNER JOIN topic_tags ON tags.id = topic_tags.tag_id - INNER JOIN topics ON topics.id = topic_tags.topic_id - AND topics.deleted_at IS NULL - AND topics.archetype = 'private_message' - WHERE topic_tags.topic_id IN - (SELECT topic_id - FROM topic_allowed_users - WHERE user_id = #{user_id} - UNION ALL SELECT tg.topic_id - FROM topic_allowed_groups tg - JOIN group_users gu ON gu.user_id = #{user_id} - AND gu.group_id = tg.group_id) - GROUP BY tags.name - LIMIT #{limit} + SELECT tags.name, COUNT(topics.id) AS topic_count + FROM tags + JOIN topic_tags ON tags.id = topic_tags.tag_id + JOIN topics ON topics.id = topic_tags.topic_id + AND topics.deleted_at IS NULL + AND topics.archetype = 'private_message' + WHERE topic_tags.topic_id IN ( + SELECT topic_id + FROM topic_allowed_users + WHERE user_id = #{user_id} + UNION + SELECT tg.topic_id + FROM topic_allowed_groups tg + JOIN group_users gu ON gu.user_id = #{user_id} + AND gu.group_id = tg.group_id + ) + GROUP BY tags.name + LIMIT #{limit} SQL tag_names_with_counts.map { |t| { id: t['name'], text: t['name'], count: t['topic_count'] } } @@ -120,11 +139,12 @@ end # # Table name: tags # -# id :integer not null, primary key -# name :string not null -# topic_count :integer default(0), not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# name :string not null +# topic_count :integer default(0), not null +# created_at :datetime not null +# updated_at :datetime not null +# pm_topic_count :integer default(0), not null # # Indexes # diff --git a/db/migrate/20180514133440_add_pm_topic_count_to_tags.rb b/db/migrate/20180514133440_add_pm_topic_count_to_tags.rb new file mode 100644 index 00000000000..9bcf5724eb4 --- /dev/null +++ b/db/migrate/20180514133440_add_pm_topic_count_to_tags.rb @@ -0,0 +1,5 @@ +class AddPmTopicCountToTags < ActiveRecord::Migration[5.1] + def change + add_column :tags, :pm_topic_count, :integer, null: false, default: 0 + end +end