UX: Display group topics in a topic list.
This commit is contained in:
parent
d3f5b4e4b0
commit
a35227918f
|
@ -0,0 +1,7 @@
|
|||
export default Ember.Controller.extend({
|
||||
actions: {
|
||||
loadMore() {
|
||||
this.get('model').loadMore();
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,3 +1,11 @@
|
|||
import { buildGroupPage } from 'discourse/routes/group-activity-posts';
|
||||
export default Discourse.Route.extend({
|
||||
titleToken() {
|
||||
return I18n.t(`groups.topics`);
|
||||
},
|
||||
|
||||
export default buildGroupPage('topics');
|
||||
model() {
|
||||
return this.store.findFiltered("topicList", {
|
||||
filter: `topics/groups/${this.modelFor('group').get('name')}`
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{{#load-more class="paginated-topics-list" selector=".paginated-topics-list .topic-list tr" action="loadMore"}}
|
||||
{{basic-topic-list topicList=model
|
||||
showPosters=true}}
|
||||
{{conditional-loading-spinner condition=model.loadingMore}}
|
||||
{{/load-more}}
|
|
@ -101,15 +101,6 @@ class GroupsController < ApplicationController
|
|||
render 'posts/latest', formats: [:rss]
|
||||
end
|
||||
|
||||
def topics
|
||||
group = find_group(:group_id)
|
||||
posts = group.posts_for(
|
||||
guardian,
|
||||
params.permit(:before_post_id, :category_id)
|
||||
).where(post_number: 1).limit(20)
|
||||
render_serialized posts.to_a, GroupPostSerializer
|
||||
end
|
||||
|
||||
def mentions
|
||||
raise Discourse::NotFound unless SiteSetting.enable_mentions?
|
||||
group = find_group(:group_id)
|
||||
|
|
|
@ -50,6 +50,7 @@ class ListController < ApplicationController
|
|||
TopTopic.periods.map { |p| :"category_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"category_none_top_#{p}" },
|
||||
TopTopic.periods.map { |p| :"parent_category_category_top_#{p}" },
|
||||
:group_topics
|
||||
].flatten
|
||||
|
||||
# Create our filters
|
||||
|
@ -131,6 +132,18 @@ class ListController < ApplicationController
|
|||
respond_with_list(list)
|
||||
end
|
||||
|
||||
def group_topics
|
||||
group = Group.find_by(name: params[:group_name])
|
||||
raise Discourse::NotFound unless group
|
||||
guardian.ensure_can_see_group!(group)
|
||||
|
||||
list_opts = build_topic_list_options
|
||||
list = generate_list_for("group_topics", group, list_opts)
|
||||
list.more_topics_url = url_for(construct_url_with(:next, list_opts))
|
||||
list.prev_topics_url = url_for(construct_url_with(:prev, list_opts))
|
||||
respond_with_list(list)
|
||||
end
|
||||
|
||||
def self.generate_message_route(action)
|
||||
define_method("#{action}") do
|
||||
list_opts = build_topic_list_options
|
||||
|
|
|
@ -455,7 +455,6 @@ Discourse::Application.routes.draw do
|
|||
|
||||
get 'members'
|
||||
get 'posts'
|
||||
get 'topics'
|
||||
get 'mentions'
|
||||
get 'messages'
|
||||
get 'counts'
|
||||
|
@ -608,6 +607,7 @@ Discourse::Application.routes.draw do
|
|||
get "private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive"
|
||||
get "private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread"
|
||||
get "private-messages-tags/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", constraints: StaffConstraint.new
|
||||
get "groups/:group_name.json" => "list#group_topics", as: "group_topics"
|
||||
|
||||
scope "/private-messages-group/:username", group_name: RouteFormat.username do
|
||||
get ":group_name.json" => "list#private_messages_group", as: "topics_private_messages_group"
|
||||
|
|
|
@ -220,6 +220,16 @@ class TopicQuery
|
|||
.where('um.user_id IS NULL')
|
||||
end
|
||||
|
||||
def list_group_topics(group)
|
||||
list = default_results.where("
|
||||
topics.user_id IN (
|
||||
SELECT user_id FROM group_users gu WHERE gu.group_id = #{group.id.to_i}
|
||||
)
|
||||
")
|
||||
|
||||
create_list(:group_topics, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages(user)
|
||||
list = private_messages_for(user, :user)
|
||||
|
||||
|
|
|
@ -885,10 +885,49 @@ describe TopicQuery do
|
|||
expect(suggested_topics[1, 3]).to include(closed_topic.id)
|
||||
expect(suggested_topics[1, 3]).to include(archived_topic.id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#list_group_topics' do
|
||||
let(:group) { Fabricate(:group) }
|
||||
|
||||
let(:user) do
|
||||
user = Fabricate(:user)
|
||||
group.add(user)
|
||||
user
|
||||
end
|
||||
|
||||
let(:user2) do
|
||||
user = Fabricate(:user)
|
||||
group.add(user)
|
||||
user
|
||||
end
|
||||
|
||||
let(:private_category) do
|
||||
Fabricate(:private_category, group: group)
|
||||
end
|
||||
|
||||
let!(:private_message_topic) { Fabricate(:private_message_post, user: user).topic }
|
||||
let!(:topic1) { Fabricate(:topic, user: user) }
|
||||
let!(:topic2) { Fabricate(:topic, user: user, category: Fabricate(:category)) }
|
||||
let!(:topic3) { Fabricate(:topic, user: user, category: private_category) }
|
||||
let!(:topic4) { Fabricate(:topic) }
|
||||
let!(:topic5) { Fabricate(:topic, user: user, visible: false) }
|
||||
let!(:topic6) { Fabricate(:topic, user: user2) }
|
||||
|
||||
it 'should return the right list' do
|
||||
topics = TopicQuery.new.list_group_topics(group).topics
|
||||
|
||||
expect(topics).to contain_exactly(topic1, topic2, topic6)
|
||||
|
||||
topics = TopicQuery.new(user).list_group_topics(group).topics
|
||||
|
||||
expect(topics).to contain_exactly(topic1, topic2, topic3, topic6)
|
||||
|
||||
topics = TopicQuery.new(user2).list_group_topics(group).topics
|
||||
|
||||
expect(topics).to contain_exactly(topic1, topic2, topic3, topic6)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,7 +104,84 @@ RSpec.describe ListController do
|
|||
[moderator, admin].each do |user|
|
||||
sign_in(user)
|
||||
get "/topics/private-messages-tags/#{user.username}/#{tag.name}.json"
|
||||
expect(response).to be_success
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#group_topics' do
|
||||
let(:group) { Fabricate(:group) }
|
||||
|
||||
%i{user user2}.each do |user|
|
||||
let(user) do
|
||||
user = Fabricate(:user)
|
||||
group.add(user)
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
let!(:topic) { Fabricate(:topic, user: user) }
|
||||
let!(:topic2) { Fabricate(:topic, user: user2) }
|
||||
let!(:another_topic) { Fabricate(:topic) }
|
||||
|
||||
describe 'when an invalid group name is given' do
|
||||
it 'should return the right response' do
|
||||
get "/topics/groups/something.json"
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'for an anon user' do
|
||||
describe 'public visible group' do
|
||||
it 'should return the right response' do
|
||||
get "/topics/groups/#{group.name}.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(JSON.parse(response.body)["topic_list"]).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
describe 'restricted group' do
|
||||
before { group.update!(visibility_level: Group.visibility_levels[:staff]) }
|
||||
|
||||
it 'should return the right response' do
|
||||
get "/topics/groups/#{group.name}.json"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'for a normal user' do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
|
||||
describe 'restricted group' do
|
||||
before { group.update!(visibility_level: Group.visibility_levels[:staff]) }
|
||||
|
||||
it 'should return the right response' do
|
||||
get "/topics/groups/#{group.name}.json"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'for a group user' do
|
||||
before do
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'should be able to view the topics started by group users' do
|
||||
get "/topics/groups/#{group.name}.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
topics = JSON.parse(response.body)["topic_list"]["topics"]
|
||||
|
||||
expect(topics.map { |topic| topic["id"] }).to contain_exactly(
|
||||
topic.id, topic2.id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,7 +60,8 @@ QUnit.test("Anonymous Viewing Group", assert => {
|
|||
click(".group-activity-nav li a[href='/groups/discourse/activity/topics']");
|
||||
|
||||
andThen(() => {
|
||||
assert.ok(count('.group-post') > 0, "it lists stream items");
|
||||
assert.ok(find('.topic-list'), "it shows the topic list");
|
||||
assert.equal(count('.topic-list-item'), 2, "it lists stream items");
|
||||
});
|
||||
|
||||
click(".group-activity-nav li a[href='/groups/discourse/activity/mentions']");
|
||||
|
|
|
@ -16,6 +16,106 @@ export default {
|
|||
"messageable":true
|
||||
}
|
||||
},
|
||||
"/topics/groups/discourse.json":{
|
||||
"users":[
|
||||
{
|
||||
"id":2,
|
||||
"username":"bruce1",
|
||||
"avatar_template":"/letter_avatar_proxy/v2/letter/b/9de053/{size}.png"
|
||||
},
|
||||
{
|
||||
"id":1,
|
||||
"username":"bruce0",
|
||||
"avatar_template":"/letter_avatar_proxy/v2/letter/b/90ced4/{size}.png"
|
||||
}
|
||||
],
|
||||
"primary_groups":[],
|
||||
"topic_list":{
|
||||
"can_create_topic":true,
|
||||
"draft":null,
|
||||
"draft_key":"new_topic",
|
||||
"draft_sequence":1,
|
||||
"per_page":30,
|
||||
"topics":[
|
||||
{
|
||||
"id":12074,
|
||||
"title":"This is a test topic 1",
|
||||
"fancy_title":"This is a test topic 1",
|
||||
"slug":"this-is-a-test-topic-1",
|
||||
"posts_count":0,
|
||||
"reply_count":0,
|
||||
"highest_post_number":0,
|
||||
"image_url":null,
|
||||
"created_at":"2018-03-15T03:12:48.955Z",
|
||||
"last_posted_at":null,
|
||||
"bumped":true,
|
||||
"bumped_at":"2018-03-15T03:12:48.955Z",
|
||||
"unseen":true,
|
||||
"pinned":false,
|
||||
"unpinned":null,
|
||||
"visible":true,
|
||||
"closed":false,
|
||||
"archived":false,
|
||||
"bookmarked":null,
|
||||
"liked":null,
|
||||
"views":0,
|
||||
"like_count":0,
|
||||
"has_summary":false,
|
||||
"archetype":"regular",
|
||||
"last_poster_username":"bruce1",
|
||||
"category_id":1,
|
||||
"pinned_globally":false,
|
||||
"featured_link":null,
|
||||
"posters":[
|
||||
{
|
||||
"extras":"latest single",
|
||||
"description":"Original Poster, Most Recent Poster",
|
||||
"user_id":2,
|
||||
"primary_group_id":null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id":12073,
|
||||
"title":"This is a test topic 0",
|
||||
"fancy_title":"This is a test topic 0",
|
||||
"slug":"this-is-a-test-topic-0",
|
||||
"posts_count":0,
|
||||
"reply_count":0,
|
||||
"highest_post_number":0,
|
||||
"image_url":null,
|
||||
"created_at":"2018-03-15T03:12:48.899Z",
|
||||
"last_posted_at":null,
|
||||
"bumped":true,
|
||||
"bumped_at":"2018-03-15T03:12:48.900Z",
|
||||
"unseen":true,
|
||||
"pinned":false,
|
||||
"unpinned":null,
|
||||
"visible":true,
|
||||
"closed":false,
|
||||
"archived":false,
|
||||
"bookmarked":null,
|
||||
"liked":null,
|
||||
"views":0,
|
||||
"like_count":0,
|
||||
"has_summary":false,
|
||||
"archetype":"regular",
|
||||
"last_poster_username":"bruce0",
|
||||
"category_id":1,
|
||||
"pinned_globally":false,
|
||||
"featured_link":null,
|
||||
"posters":[
|
||||
{
|
||||
"extras":"latest single",
|
||||
"description":"Original Poster, Most Recent Poster",
|
||||
"user_id":1,
|
||||
"primary_group_id":null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/groups/discourse/counts.json":{
|
||||
"counts":{
|
||||
"posts":17829,
|
||||
|
|
|
@ -295,8 +295,8 @@ export default function() {
|
|||
return response(200, []);
|
||||
});
|
||||
|
||||
this.get("/groups/discourse/topics.json", () => {
|
||||
return response(200, fixturesByUrl['/groups/discourse/posts.json']);
|
||||
this.get("/topics/groups/discourse.json", () => {
|
||||
return response(200, fixturesByUrl['/topics/groups/discourse.json']);
|
||||
});
|
||||
|
||||
this.get("/groups/discourse/mentions.json", () => {
|
||||
|
|
Loading…
Reference in New Issue