UX: show an enveloppe icon when a badge is used in messages

- the badge count now includes messages
- only show the message badges to admins
This commit is contained in:
Régis Hanol 2018-05-14 19:02:00 +02:00
parent 1e132b4599
commit e9abdaebbe
9 changed files with 110 additions and 60 deletions

View File

@ -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}`;
}
});

View File

@ -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
});

View File

@ -37,7 +37,6 @@ CategoryList.reopenClass({
c.topics = c.topics.map(t => Discourse.Topic.create(t));
}
switch(statPeriod) {
case "week":
case "month":

View File

@ -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;
}
});

View File

@ -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']
});
},

View File

@ -9,11 +9,7 @@
{{/if}}
{{#each sortedTags as |tag|}}
<div class='tag-box'>
{{#if tag.count}}
{{discourse-tag tag.id isPrivateMessage=isPrivateMessage tagsForUser=tagsForUser}} <span class='tag-count'>x {{tag.count}}</span>
{{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}} <span class='tag-count'>x {{tag.totalCount}}</span>{{/if}}
</div>
{{/each}}
<div class="clearfix" />

View File

@ -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

View File

@ -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
#

View File

@ -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