From 3b617b04b00070bbacf78776880194b31e6849b4 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 7 Feb 2014 10:44:03 -0500 Subject: [PATCH] FEATURE: First stab at groups page with member list --- .../discourse/controllers/group_controller.js | 8 +++++ .../controllers/group_index_controller.js | 32 +++++++++++++++++++ .../javascripts/discourse/models/group.js | 15 ++++++++- .../discourse/routes/group_index_route.js | 10 +++++- .../discourse/routes/group_members_route.js | 8 +++++ .../discourse/routes/group_route.js | 8 +++++ .../templates/group/index.js.handlebars | 19 +++++++++-- .../templates/user/user.js.handlebars | 11 ++++--- .../discourse/views/group_index_view.js | 4 +++ app/controllers/groups_controller.rb | 7 ++++ app/models/group.rb | 19 ++++++++++- app/serializers/group_post_serializer.rb | 15 +++++++++ config/locales/client.en.yml | 3 ++ config/routes.rb | 1 + 14 files changed, 149 insertions(+), 11 deletions(-) create mode 100644 app/assets/javascripts/discourse/controllers/group_index_controller.js create mode 100644 app/assets/javascripts/discourse/views/group_index_view.js create mode 100644 app/serializers/group_post_serializer.rb diff --git a/app/assets/javascripts/discourse/controllers/group_controller.js b/app/assets/javascripts/discourse/controllers/group_controller.js index c6efff8fe43..3fa523e0d8c 100644 --- a/app/assets/javascripts/discourse/controllers/group_controller.js +++ b/app/assets/javascripts/discourse/controllers/group_controller.js @@ -1,3 +1,11 @@ +/** + The basic controller for a group + + @class GroupController + @extends Discourse.ObjectController + @namespace Discourse + @module Discourse +**/ Discourse.GroupController = Discourse.ObjectController.extend({ // It would be nice if bootstrap marked action lists as selected when their links diff --git a/app/assets/javascripts/discourse/controllers/group_index_controller.js b/app/assets/javascripts/discourse/controllers/group_index_controller.js new file mode 100644 index 00000000000..ec2d196cb75 --- /dev/null +++ b/app/assets/javascripts/discourse/controllers/group_index_controller.js @@ -0,0 +1,32 @@ +/** + Handles displaying posts within a group + + @class GroupIndexController + @extends Ember.ArrayController + @namespace Discourse + @module Discourse +**/ +Discourse.GroupIndexController = Ember.ArrayController.extend({ + needs: ['group'], + loading: false, + + actions: { + loadMore: function() { + + if (this.get('loading')) { return; } + this.set('loading', true); + var posts = this.get('model'), + self = this; + if (posts && posts.length) { + var lastPostId = posts[posts.length-1].get('id'), + group = this.get('controllers.group.model'); + + group.findPosts({beforePostId: lastPostId}).then(function(newPosts) { + posts.addObjects(newPosts); + self.set('loading', false); + }); + } + } + } +}); + diff --git a/app/assets/javascripts/discourse/models/group.js b/app/assets/javascripts/discourse/models/group.js index a76dae825cf..5d307de07cf 100644 --- a/app/assets/javascripts/discourse/models/group.js +++ b/app/assets/javascripts/discourse/models/group.js @@ -126,8 +126,21 @@ Discourse.Group = Discourse.Model.extend({ var message = $.parseJSON(e.responseText).errors; bootbox.alert(message); }); - } + }, + findPosts: function(opts) { + opts = opts || {}; + + var data = {}; + if (opts.beforePostId) { data.before_post_id = opts.beforePostId; } + + return Discourse.ajax("/groups/" + this.get('name') + "/posts.json", { data: data }).then(function (posts) { + return posts.map(function (p) { + p.user = Discourse.User.create(p.user); + return Em.Object.create(p); + }); + }); + } }); Discourse.Group.reopenClass({ diff --git a/app/assets/javascripts/discourse/routes/group_index_route.js b/app/assets/javascripts/discourse/routes/group_index_route.js index 675b35b432b..3976e0e9ddb 100644 --- a/app/assets/javascripts/discourse/routes/group_index_route.js +++ b/app/assets/javascripts/discourse/routes/group_index_route.js @@ -1,6 +1,14 @@ +/** + The route for the index of a Group + + @class GroupIndexRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ Discourse.GroupIndexRoute = Discourse.Route.extend({ model: function() { - return this.modelFor('group'); + return this.modelFor('group').findPosts(); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/discourse/routes/group_members_route.js b/app/assets/javascripts/discourse/routes/group_members_route.js index 3ac3a06a31f..4cea70c09ce 100644 --- a/app/assets/javascripts/discourse/routes/group_members_route.js +++ b/app/assets/javascripts/discourse/routes/group_members_route.js @@ -1,3 +1,11 @@ +/** + Set things up to display the members of a group + + @class GroupMembersRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ Discourse.GroupMembersRoute = Discourse.Route.extend({ model: function() { return this.modelFor('group'); diff --git a/app/assets/javascripts/discourse/routes/group_route.js b/app/assets/javascripts/discourse/routes/group_route.js index 668528f7b2c..acbbbe823e2 100644 --- a/app/assets/javascripts/discourse/routes/group_route.js +++ b/app/assets/javascripts/discourse/routes/group_route.js @@ -1,3 +1,11 @@ +/** + The base route for a group + + @class GroupRoute + @extends Discourse.Route + @namespace Discourse + @module Discourse +**/ Discourse.GroupRoute = Discourse.Route.extend({ model: function(params) { diff --git a/app/assets/javascripts/discourse/templates/group/index.js.handlebars b/app/assets/javascripts/discourse/templates/group/index.js.handlebars index 932962af79b..8e73e8e3ebb 100644 --- a/app/assets/javascripts/discourse/templates/group/index.js.handlebars +++ b/app/assets/javascripts/discourse/templates/group/index.js.handlebars @@ -1,3 +1,16 @@ -GROUP INDEX -{{name}} - +
+ {{#groupedEach model}} +
+
+ {{#link-to 'user' user class="avatar-link"}}
{{avatar user imageSize="large" extraClasses="actor" ignoreTitle="true"}}
{{/link-to}} + {{unboundDate path="created_at" leaveAgo="true"}} + + {{unbound title}} + +
+

+ {{{unbound cooked}}} +

+
+ {{/groupedEach}} +
diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars index 05feafb5098..73e4c35677e 100644 --- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars @@ -44,11 +44,12 @@
{{{bio_cooked}}}
{{#if custom_groups}} -
- {{#each custom_groups}} - {{#link-to 'group' this}}{{name}}{{/link-to}} - {{/each}} -
+
+ {{i18n groups.title count=custom_groups.length}}: + {{#each custom_groups}} + {{#link-to 'group' this}}{{name}}{{/link-to}} + {{/each}} +
{{/if}} {{#if isSuspended}} diff --git a/app/assets/javascripts/discourse/views/group_index_view.js b/app/assets/javascripts/discourse/views/group_index_view.js new file mode 100644 index 00000000000..c73a56d4391 --- /dev/null +++ b/app/assets/javascripts/discourse/views/group_index_view.js @@ -0,0 +1,4 @@ +Discourse.GroupIndexView = Discourse.View.extend(Discourse.LoadMore, { + eyelineSelector: '.user-stream .item' +}); + diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 75fff2aa31f..c9fc37c5062 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -6,6 +6,13 @@ class GroupsController < ApplicationController render_serialized(group, BasicGroupSerializer) end + def posts + group = Group.where(name: params.require(:group_id)).first + guardian.ensure_can_see!(group) + posts = group.posts_for(guardian, params[:before_post_id]) + render_serialized posts.to_a, GroupPostSerializer + end + def members group = Group.where(name: params.require(:group_id)).first guardian.ensure_can_see!(group) diff --git a/app/models/group.rb b/app/models/group.rb index b83144b6f17..ef2c3060c0f 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -31,6 +31,24 @@ class Group < ActiveRecord::Base validate :alias_level, inclusion: { in: ALIAS_LEVELS.values} + def posts_for(guardian, before_post_id) + user_ids = group_users.map {|gu| gu.user_id} + result = Post.where(user_id: user_ids).includes(:user, :topic).references(:posts, :topics) + result = result.where('topics.archetype <> ?', Archetype.private_message) + + unless guardian.is_staff? + allowed_ids = guardian.allowed_category_ids + if allowed_ids.length > 0 + result = result.where('topics.category_id IS NULL or topics.category_id IN (?)', allowed_ids) + else + result = result.where('topics.category_id IS NULL') + end + end + + result = result.where('posts.id < ?', before_post_id) if before_post_id + result.order('posts.created_at desc').limit(20) + end + def self.trust_group_ids (10..19).to_a end @@ -156,7 +174,6 @@ class Group < ActiveRecord::Base end end - def self.builtin Enum.new(:moderators, :admins, :trust_level_1, :trust_level_2) end diff --git a/app/serializers/group_post_serializer.rb b/app/serializers/group_post_serializer.rb new file mode 100644 index 00000000000..db451432a94 --- /dev/null +++ b/app/serializers/group_post_serializer.rb @@ -0,0 +1,15 @@ +class GroupPostSerializer < ApplicationSerializer + attributes :id, + :cooked, + :created_at, + :title, + :url + + has_one :user, serializer: BasicUserSerializer, embed: :objects + + def title + object.topic.title + end + +end + diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 820ca9d7494..80e724f8c30 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -174,6 +174,9 @@ en: sent_by_you: "Sent by you" groups: + title: + one: "group" + other: "groups" members: "Members" posts: "Posts" alias_levels: diff --git a/config/routes.rb b/config/routes.rb index 3092ffecfe5..e19f563f4c2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -165,6 +165,7 @@ Discourse::Application.routes.draw do resources :groups do get 'members' + get 'posts' end resources :posts do