mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 12:12:46 +08:00
FEATURE: filter personal messages by tags
This commit is contained in:
parent
4132c37add
commit
c29660c8f1
|
@ -12,6 +12,8 @@ export default Ember.Controller.extend({
|
||||||
currentPath: Em.computed.alias('application.currentPath'),
|
currentPath: Em.computed.alias('application.currentPath'),
|
||||||
selected: Em.computed.alias('userTopicsList.selected'),
|
selected: Em.computed.alias('userTopicsList.selected'),
|
||||||
bulkSelectEnabled: Em.computed.alias('userTopicsList.bulkSelectEnabled'),
|
bulkSelectEnabled: Em.computed.alias('userTopicsList.bulkSelectEnabled'),
|
||||||
|
pmTags: Em.computed.alias('userTopicsList.model.topic_list.pm_tags'),
|
||||||
|
pmTaggingEnabled: Ember.computed.alias('site.can_tag_pms'),
|
||||||
|
|
||||||
showNewPM: function(){
|
showNewPM: function(){
|
||||||
return this.get('user.viewingSelf') &&
|
return this.get('user.viewingSelf') &&
|
||||||
|
|
|
@ -65,7 +65,6 @@
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
{{#if bulkSelectEnabled}}
|
{{#if bulkSelectEnabled}}
|
||||||
<button {{action "selectAll"}} class="btn btn-select-all">
|
<button {{action "selectAll"}} class="btn btn-select-all">
|
||||||
{{i18n "user.messages.select_all"}}
|
{{i18n "user.messages.select_all"}}
|
||||||
|
@ -75,6 +74,10 @@
|
||||||
{{#if isGroup}}
|
{{#if isGroup}}
|
||||||
{{group-notifications-button value=group.group_user.notification_level group=group user=model}}
|
{{group-notifications-button value=group.group_user.notification_level group=group user=model}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if pmTaggingEnabled}}
|
||||||
|
{{pm-tag-drop pmTags=pmTags}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{outlet}}
|
{{outlet}}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import TagDropComponent from "select-kit/components/tag-drop";
|
||||||
|
import DiscourseURL from "discourse/lib/url";
|
||||||
|
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
|
export default TagDropComponent.extend({
|
||||||
|
@computed
|
||||||
|
allTagsUrl() {
|
||||||
|
return `/u/${this.currentUser.username}/messages/`;
|
||||||
|
},
|
||||||
|
|
||||||
|
content: Ember.computed.alias("pmTags"),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onSelect(tagId) {
|
||||||
|
const url = `/u/${this.currentUser.username}/messages/tag/${tagId}`;
|
||||||
|
DiscourseURL.routeTo(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -134,6 +134,7 @@ class ListController < ApplicationController
|
||||||
def self.generate_message_route(action)
|
def self.generate_message_route(action)
|
||||||
define_method("#{action}") do
|
define_method("#{action}") do
|
||||||
list_opts = build_topic_list_options
|
list_opts = build_topic_list_options
|
||||||
|
list_opts[:show_pm_tags] = true if guardian.can_tag_pms?
|
||||||
target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
|
target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
|
||||||
guardian.ensure_can_see_private_messages!(target_user.id)
|
guardian.ensure_can_see_private_messages!(target_user.id)
|
||||||
list = generate_list_for(action.to_s, target_user, list_opts)
|
list = generate_list_for(action.to_s, target_user, list_opts)
|
||||||
|
|
|
@ -59,6 +59,24 @@ class Tag < ActiveRecord::Base
|
||||||
tag_names_with_counts.map { |row| row['tag_name'] }
|
tag_names_with_counts.map { |row| row['tag_name'] }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.pm_tags(limit_arg: nil, guardian: nil)
|
||||||
|
return [] unless (guardian || Guardian.new).can_tag_pms?
|
||||||
|
limit = limit_arg || SiteSetting.max_tags_in_filter_list
|
||||||
|
|
||||||
|
tag_names = Tag.exec_sql <<~SQL
|
||||||
|
SELECT tags.name AS tag_name
|
||||||
|
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'
|
||||||
|
GROUP BY tags.name
|
||||||
|
LIMIT #{limit}
|
||||||
|
SQL
|
||||||
|
|
||||||
|
tag_names.values.flatten
|
||||||
|
end
|
||||||
|
|
||||||
def self.include_tags?
|
def self.include_tags?
|
||||||
SiteSetting.tagging_enabled && SiteSetting.show_filter_by_tag
|
SiteSetting.tagging_enabled && SiteSetting.show_filter_by_tag
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,6 +35,7 @@ class TopicList
|
||||||
:for_period,
|
:for_period,
|
||||||
:per_page,
|
:per_page,
|
||||||
:top_tags,
|
:top_tags,
|
||||||
|
:pm_tags,
|
||||||
:current_user,
|
:current_user,
|
||||||
:tags
|
:tags
|
||||||
|
|
||||||
|
@ -59,6 +60,15 @@ class TopicList
|
||||||
Tag.top_tags(opts)
|
Tag.top_tags(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def pm_tags
|
||||||
|
guardian = Guardian.new(@current_user)
|
||||||
|
if @opts[:show_pm_tags] && guardian.can_tag_pms?
|
||||||
|
Tag.pm_tags(guardian: guardian)
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def preload_key
|
def preload_key
|
||||||
if @category
|
if @category
|
||||||
"topic_list_#{@category.url.sub(/^\//, '')}/l/#{@filter}"
|
"topic_list_#{@category.url.sub(/^\//, '')}/l/#{@filter}"
|
||||||
|
|
|
@ -8,6 +8,7 @@ class TopicListSerializer < ApplicationSerializer
|
||||||
:for_period,
|
:for_period,
|
||||||
:per_page,
|
:per_page,
|
||||||
:top_tags,
|
:top_tags,
|
||||||
|
:pm_tags,
|
||||||
:tags
|
:tags
|
||||||
|
|
||||||
has_many :topics, serializer: TopicListItemSerializer, embed: :objects
|
has_many :topics, serializer: TopicListItemSerializer, embed: :objects
|
||||||
|
@ -29,6 +30,10 @@ class TopicListSerializer < ApplicationSerializer
|
||||||
Tag.include_tags?
|
Tag.include_tags?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def include_pm_tags?
|
||||||
|
scope.can_tag_pms?
|
||||||
|
end
|
||||||
|
|
||||||
def include_tags?
|
def include_tags?
|
||||||
SiteSetting.tagging_enabled && object.tags.present?
|
SiteSetting.tagging_enabled && object.tags.present?
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,8 @@ class TopicQuery
|
||||||
match_all_tags
|
match_all_tags
|
||||||
no_subcategories
|
no_subcategories
|
||||||
slow_platform
|
slow_platform
|
||||||
no_tags)
|
no_tags
|
||||||
|
show_pm_tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.valid_options
|
def self.valid_options
|
||||||
|
|
|
@ -96,6 +96,28 @@ describe Tag do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#pm_tags' do
|
||||||
|
before do
|
||||||
|
@private_tags = []
|
||||||
|
personal_message = Fabricate(:private_message_topic)
|
||||||
|
2.times { |i| @private_tags << Fabricate(:tag, topics: [personal_message]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nothing if user is not a staff" do
|
||||||
|
expect(described_class.pm_tags.sort).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nothing if allow_staff_to_tag_pms setting is disabled" do
|
||||||
|
SiteSetting.allow_staff_to_tag_pms = false
|
||||||
|
expect(described_class.pm_tags(guardian: Guardian.new(Fabricate(:admin))).sort).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns all pm tags if user is a staff and pm tagging is enabled" do
|
||||||
|
SiteSetting.allow_staff_to_tag_pms = true
|
||||||
|
expect(described_class.pm_tags(guardian: Guardian.new(Fabricate(:admin)))).to match_array(@private_tags.map(&:name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "topic counts" do
|
context "topic counts" do
|
||||||
it "should exclude private message topics" do
|
it "should exclude private message topics" do
|
||||||
topic
|
topic
|
||||||
|
|
|
@ -78,4 +78,28 @@ describe TopicList do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#pm_tags' do
|
||||||
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
let(:personal_message) { Fabricate(:private_message_topic) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.tagging_enabled = true
|
||||||
|
SiteSetting.allow_staff_to_tag_pms = true
|
||||||
|
@private_tags = []
|
||||||
|
2.times { |i| @private_tags << Fabricate(:tag, topics: [personal_message]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when viewed as normal user' do
|
||||||
|
it 'returns no tags' do
|
||||||
|
expect(TopicList.new('liked', personal_message.user, [personal_message], show_pm_tags: true).pm_tags).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when viewed as admin' do
|
||||||
|
it 'returns pm tags' do
|
||||||
|
expect(TopicList.new('liked', admin, [personal_message], show_pm_tags: true).pm_tags).to match_array(@private_tags.map(&:name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -105,6 +105,8 @@ RSpec.describe ListController do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
get "/topics/private-messages-tag/#{user.username}/#{tag.name}.json"
|
get "/topics/private-messages-tag/#{user.username}/#{tag.name}.json"
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
|
data = JSON.parse(response.body)
|
||||||
|
expect(data["topic_list"]["pm_tags"].length).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user