FEATURE: First stab at groups page with member list
This commit is contained in:
parent
e511e8a80b
commit
3b617b04b0
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -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({
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
GROUP INDEX
|
||||
{{name}}
|
||||
|
||||
<div class='user-stream'>
|
||||
{{#groupedEach model}}
|
||||
<div class='item'>
|
||||
<div class='clearfix info'>
|
||||
{{#link-to 'user' user class="avatar-link"}}<div class='avatar-wrapper'>{{avatar user imageSize="large" extraClasses="actor" ignoreTitle="true"}}</div>{{/link-to}}
|
||||
<span class='time'>{{unboundDate path="created_at" leaveAgo="true"}}</span>
|
||||
<span class="title">
|
||||
<a href="{{unbound url}}">{{unbound title}}</a>
|
||||
</span>
|
||||
</div>
|
||||
<p class='excerpt'>
|
||||
{{{unbound cooked}}}
|
||||
</p>
|
||||
</div>
|
||||
{{/groupedEach}}
|
||||
</div>
|
||||
|
|
|
@ -44,11 +44,12 @@
|
|||
<div class='bio'>{{{bio_cooked}}}</div>
|
||||
|
||||
{{#if custom_groups}}
|
||||
<div class='groups'>
|
||||
{{#each custom_groups}}
|
||||
{{#link-to 'group' this}}{{name}}{{/link-to}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class='groups'>
|
||||
{{i18n groups.title count=custom_groups.length}}:
|
||||
{{#each custom_groups}}
|
||||
{{#link-to 'group' this}}{{name}}{{/link-to}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if isSuspended}}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Discourse.GroupIndexView = Discourse.View.extend(Discourse.LoadMore, {
|
||||
eyelineSelector: '.user-stream .item'
|
||||
});
|
||||
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -174,6 +174,9 @@ en:
|
|||
sent_by_you: "Sent by <a href='{{userUrl}}'>you</a>"
|
||||
|
||||
groups:
|
||||
title:
|
||||
one: "group"
|
||||
other: "groups"
|
||||
members: "Members"
|
||||
posts: "Posts"
|
||||
alias_levels:
|
||||
|
|
|
@ -165,6 +165,7 @@ Discourse::Application.routes.draw do
|
|||
|
||||
resources :groups do
|
||||
get 'members'
|
||||
get 'posts'
|
||||
end
|
||||
|
||||
resources :posts do
|
||||
|
|
Loading…
Reference in New Issue