Merge pull request #4603 from tgxworld/group_index_page

FEATURE: Add groups page.
This commit is contained in:
Guo Xiang Tan 2016-12-14 23:26:05 +08:00 committed by GitHub
commit 13c344245d
15 changed files with 177 additions and 5 deletions

View File

@ -0,0 +1,16 @@
import { observes } from 'ember-addons/ember-computed-decorators';
export default Ember.Controller.extend({
application: Ember.inject.controller(),
@observes("groups.canLoadMore")
_showFooter() {
this.set("application.showFooter", !this.get("groups.canLoadMore"));
},
actions: {
loadMore() {
this.get('groups').loadMore();
}
}
});

View File

@ -1,8 +1,9 @@
import { ajax } from 'discourse/lib/ajax';
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import GroupHistory from 'discourse/models/group-history';
import RestModel from 'discourse/models/rest';
const Group = Discourse.Model.extend({
const Group = RestModel.extend({
limit: 50,
offset: 0,
user_count: 0,

View File

@ -50,6 +50,8 @@ export default function() {
this.route(defaultHomepage(), { path: '/' });
});
this.route('groups', { resetNamespace: true });
this.route('group', { path: '/groups/:name', resetNamespace: true }, function() {
this.route('members');
this.route('posts');

View File

@ -0,0 +1,13 @@
export default Discourse.Route.extend({
titleToken() {
return I18n.t('groups.index');
},
model(params) {
return this.store.findAll('group', params);
},
setupController(controller, model) {
controller.set('groups', model);
}
});

View File

@ -0,0 +1,39 @@
{{#d-section pageClass="groups"}}
{{#load-more selector=".groups-table .groups-table-row" action="loadMore"}}
<h1>{{i18n "groups.index"}}</h1>
<div class='container'>
<table class="groups-table">
<thead>
<th>{{i18n "groups.name"}}</th>
<th>{{i18n "groups.user_count"}}</th>
</thead>
<tbody>
{{#each groups as |group|}}
<tr class="groups-table-row">
<td class="groups-name">
{{#link-to "group.members" group.name}}
{{#if group.flair_url}}
<span>
{{avatar-flair
flairURL=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
groupName=group.name}}
</span>
{{/if}}
<span><h4>@{{group.name}}</h4></span>
{{/link-to}}
</td>
<td>{{group.user_count}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{/load-more}}
{{conditional-loading-spinner condition=groups.loadingMore}}
{{/d-section}}

View File

@ -103,6 +103,8 @@ export default createWidget('hamburger-menu', {
links.push({ route: 'users', className: 'user-directory-link', label: 'directory.title' });
}
links.push({ route: 'groups', className: 'groups-link', label: 'groups.index' });
if (this.siteSettings.tagging_enabled) {
links.push({ route: 'tags', label: 'tagging.tags' });
}

View File

@ -111,9 +111,7 @@ table.group-members {
.group-details {
width: 100%;
}
.group-details {
span {
display: inline-block;
vertical-align: middle;

View File

@ -0,0 +1,45 @@
.groups-page {
h1 {
margin: 20px 0px;
}
}
.groups-table {
width: 100%;
.groups-name {
span {
display: inline-block;
vertical-align: middle;
}
.avatar-flair {
$size: 30px;
background-size: $size;
height: $size;
width: $size;
i {
font-size: $size !important;
}
}
}
th {
border-bottom: 3px solid dark-light-diff($primary, $secondary, 90%, -60%);
padding: 5px 0px 5px 5px;
color: dark-light-choose(scale-color($primary, $lightness: 50%), scale-color($secondary, $lightness: 50%));
font-weight: normal;
}
tr {
border-bottom: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
td {
text-align: center;
color: dark-light-diff($primary, $secondary, 50%, -50%);
padding: 0.8em 0;
}
}
}

View File

@ -10,6 +10,22 @@ class GroupsController < ApplicationController
skip_before_filter :preload_json, :check_xhr, only: [:posts_feed, :mentions_feed]
def index
page_size = 30
page = params[:page]&.to_i || 0
groups = Group.order(user_count: :desc, name: :asc)
.where(visible: true)
.offset(page * page_size)
.limit(page_size)
render json: {
groups: serialize_data(groups, BasicGroupSerializer),
total_rows_groups: Group.count,
load_more_groups: groups_path(page: page + 1)
}
end
def show
render_serialized(find_group(:id), GroupShowSerializer, root: 'basic_group')
end

View File

@ -417,6 +417,7 @@ en:
request: "Request to Join Group"
allow_membership_requests: "Allow users to send membership requests to group owners (Requires everyone to be able to mention the group)"
name: "Name"
user_count: "Number of Members"
bio: "About Group"
selector_placeholder: "Add members"
owner: "owner"

View File

@ -1,3 +1,3 @@
Fabricator(:group) do
name 'my_group'
name { sequence(:name) { |n| "my_group_#{n}" } }
end

View File

@ -12,6 +12,24 @@ describe "Groups" do
expect(response).to be_success
end
describe 'viewing groups' do
it 'should return the right response' do
group.update_attributes!(visible: true)
other_group = Fabricate(:group, name: '0000', visible: true)
get "/groups.json"
expect(response).to be_success
response_body = JSON.parse(response.body)
group_ids = response_body["groups"].map { |g| g["id"] }
expect(group_ids).to include(group.id, other_group.id)
expect(response_body["load_more_groups"]).to eq("/groups?page=1")
end
end
describe "checking if a group can be mentioned" do
it "should return the right response" do
sign_in(user)

View File

@ -3,6 +3,20 @@ import { acceptance, logIn } from "helpers/qunit-helpers";
acceptance("Groups");
test("Browsing Groups", () => {
visit("/groups");
andThen(() => {
equal(count('.groups-table-row'), 18, 'it displays visible groups');
});
click("a[href='/groups/discourse/members']");
andThen(() => {
equal(find('.group-header').text().trim(), 'Awesome Team', "it displays the group page");
});
});
test("Viewing Group", () => {
visit("/groups/discourse");
andThen(() => {
@ -34,7 +48,7 @@ test("Browsing Groups", () => {
});
});
test("Admin Browsing Groups", () => {
test("Admin Viewing Group", () => {
logIn();
Discourse.reset();

File diff suppressed because one or more lines are too long

View File

@ -242,6 +242,10 @@ export default function() {
slug: request.params.slug } });
});
this.get("groups", () => {
return response(200, fixturesByUrl['/groups.json']);
});
this.get("/groups/discourse/topics.json", () => {
return response(200, fixturesByUrl['/groups/discourse/posts.json']);
});