FEATURE: Add groups page.
This commit is contained in:
parent
0c9499874d
commit
4b940dc8bd
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,8 +1,9 @@
|
||||||
import { ajax } from 'discourse/lib/ajax';
|
import { ajax } from 'discourse/lib/ajax';
|
||||||
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
||||||
import GroupHistory from 'discourse/models/group-history';
|
import GroupHistory from 'discourse/models/group-history';
|
||||||
|
import RestModel from 'discourse/models/rest';
|
||||||
|
|
||||||
const Group = Discourse.Model.extend({
|
const Group = RestModel.extend({
|
||||||
limit: 50,
|
limit: 50,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
user_count: 0,
|
user_count: 0,
|
||||||
|
|
|
@ -50,6 +50,8 @@ export default function() {
|
||||||
this.route(defaultHomepage(), { path: '/' });
|
this.route(defaultHomepage(), { path: '/' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.route('groups', { resetNamespace: true });
|
||||||
|
|
||||||
this.route('group', { path: '/groups/:name', resetNamespace: true }, function() {
|
this.route('group', { path: '/groups/:name', resetNamespace: true }, function() {
|
||||||
this.route('members');
|
this.route('members');
|
||||||
this.route('posts');
|
this.route('posts');
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
|
@ -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}}
|
|
@ -103,6 +103,8 @@ export default createWidget('hamburger-menu', {
|
||||||
links.push({ route: 'users', className: 'user-directory-link', label: 'directory.title' });
|
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) {
|
if (this.siteSettings.tagging_enabled) {
|
||||||
links.push({ route: 'tags', label: 'tagging.tags' });
|
links.push({ route: 'tags', label: 'tagging.tags' });
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,9 +111,7 @@ table.group-members {
|
||||||
|
|
||||||
.group-details {
|
.group-details {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
|
||||||
|
|
||||||
.group-details {
|
|
||||||
span {
|
span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,22 @@ class GroupsController < ApplicationController
|
||||||
|
|
||||||
skip_before_filter :preload_json, :check_xhr, only: [:posts_feed, :mentions_feed]
|
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
|
def show
|
||||||
render_serialized(find_group(:id), GroupShowSerializer, root: 'basic_group')
|
render_serialized(find_group(:id), GroupShowSerializer, root: 'basic_group')
|
||||||
end
|
end
|
||||||
|
|
|
@ -417,6 +417,7 @@ en:
|
||||||
request: "Request to Join Group"
|
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)"
|
allow_membership_requests: "Allow users to send membership requests to group owners (Requires everyone to be able to mention the group)"
|
||||||
name: "Name"
|
name: "Name"
|
||||||
|
user_count: "Number of Members"
|
||||||
bio: "About Group"
|
bio: "About Group"
|
||||||
selector_placeholder: "Add members"
|
selector_placeholder: "Add members"
|
||||||
owner: "owner"
|
owner: "owner"
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Fabricator(:group) do
|
Fabricator(:group) do
|
||||||
name 'my_group'
|
name { sequence(:name) { |n| "my_group_#{n}" } }
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,24 @@ describe "Groups" do
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
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
|
describe "checking if a group can be mentioned" do
|
||||||
it "should return the right response" do
|
it "should return the right response" do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
|
|
|
@ -3,6 +3,20 @@ import { acceptance, logIn } from "helpers/qunit-helpers";
|
||||||
acceptance("Groups");
|
acceptance("Groups");
|
||||||
|
|
||||||
test("Browsing 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");
|
visit("/groups/discourse");
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
|
@ -34,7 +48,7 @@ test("Browsing Groups", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Admin Browsing Groups", () => {
|
test("Admin Viewing Group", () => {
|
||||||
logIn();
|
logIn();
|
||||||
Discourse.reset();
|
Discourse.reset();
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -242,6 +242,10 @@ export default function() {
|
||||||
slug: request.params.slug } });
|
slug: request.params.slug } });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.get("groups", () => {
|
||||||
|
return response(200, fixturesByUrl['/groups.json']);
|
||||||
|
});
|
||||||
|
|
||||||
this.get("/groups/discourse/topics.json", () => {
|
this.get("/groups/discourse/topics.json", () => {
|
||||||
return response(200, fixturesByUrl['/groups/discourse/posts.json']);
|
return response(200, fixturesByUrl['/groups/discourse/posts.json']);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue