UX: Allow groups page to be searchable.

This commit is contained in:
Guo Xiang Tan 2018-03-19 17:16:51 +08:00
parent 0522aabaab
commit 05ea034490
7 changed files with 93 additions and 57 deletions

View File

@ -1,10 +1,18 @@
import { observes } from 'ember-addons/ember-computed-decorators';
import debounce from 'discourse/lib/debounce';
export default Ember.Controller.extend({
application: Ember.inject.controller(),
queryParams: ["order", "asc"],
queryParams: ["order", "asc", "filter"],
order: null,
asc: null,
filter: "",
filterInput: "",
@observes("filterInput")
_setFilter: debounce(function() {
this.set("filter", this.get("filterInput"));
}, 500),
@observes("model.canLoadMore")
_showFooter() {

View File

@ -2,6 +2,7 @@ export default Discourse.Route.extend({
queryParams: {
order: { refreshModel: true, replace: true },
asc: { refreshModel: true, replace: true },
filter: { refreshModel: true }
},
refreshQueryWithoutTransition: true,

View File

@ -1,68 +1,74 @@
{{#d-section pageClass="groups"}}
<h1>{{i18n "groups.index.title"}}</h1>
{{text-field value=filterInput
placeholderKey="groups.filter_name"
class="group-filter-name no-blur"}}
{{#if model}}
{{#load-more selector=".groups-table .groups-table-row" action="loadMore"}}
<div class='container'>
<table class="groups-table">
<thead>
<th></th>
{{directory-toggle field="user_count" labelKey="groups.user_count" order=order asc=asc}}
<th>{{i18n "groups.membership"}}</th>
</thead>
{{#conditional-loading-spinner condition=model.loading}}
{{#load-more selector=".groups-table .groups-table-row" action="loadMore"}}
<div class='container'>
<table class="groups-table">
<thead>
<th></th>
{{directory-toggle field="user_count" labelKey="groups.user_count" order=order asc=asc}}
<th>{{i18n "groups.membership"}}</th>
</thead>
<tbody>
{{#each model as |group|}}
<tr class="groups-table-row">
<td class="groups-info">
{{#link-to "group.members" group.name}}
{{#if group.flair_url}}
<span class='group-avatar-flair'>
{{avatar-flair
flairURL=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
groupName=group.name}}
<tbody>
{{#each model as |group|}}
<tr class="groups-table-row">
<td class="groups-info">
{{#link-to "group.members" group.name}}
{{#if group.flair_url}}
<span class='group-avatar-flair'>
{{avatar-flair
flairURL=group.flair_url
flairBgColor=group.flair_bg_color
flairColor=group.flair_color
groupName=group.name}}
</span>
{{/if}}
<span>
<span class='groups-info-name'>{{group.displayName}}</span>
{{#if group.full_name}}
<span class='groups-info-full-name'>{{group.full_name}}</span>
{{/if}}
{{#if group.title}}
<div>
<span class='groups-info-title'>{{group.title}}</span>
</div>
{{/if}}
</span>
{{/if}}
{{/link-to}}
</td>
<span>
<span class='groups-info-name'>{{group.displayName}}</span>
<td class="groups-user-count">{{group.user_count}}</td>
{{#if group.full_name}}
<span class='groups-info-full-name'>{{group.full_name}}</span>
{{/if}}
<td>
{{#group-membership-button model=group
showMembershipStatus=true
groupUserIds=groups.extras.group_user_ids
showLogin='showLogin'}}
{{#if group.title}}
<div>
<span class='groups-info-title'>{{group.title}}</span>
</div>
{{/if}}
</span>
{{/link-to}}
</td>
{{d-button icon="ban"
label=(if group.automatic 'groups.automatic_group' 'groups.closed_group')
disabled=true}}
{{/group-membership-button}}
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{/load-more}}
<td class="groups-user-count">{{group.user_count}}</td>
<td>
{{#group-membership-button model=group
showMembershipStatus=true
groupUserIds=groups.extras.group_user_ids
showLogin='showLogin'}}
{{d-button icon="ban"
label=(if group.automatic 'groups.automatic_group' 'groups.closed_group')
disabled=true}}
{{/group-membership-button}}
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{/load-more}}
{{conditional-loading-spinner condition=model.loadingMore}}
{{conditional-loading-spinner condition=model.loadingMore}}
{{/conditional-loading-spinner}}
{{else}}
<p>{{i18n "groups.index.empty"}}</p>
{{/if}}

View File

@ -1,9 +1,15 @@
.groups-page {
h1 {
margin: 20px 0;
margin-bottom: 20px;
display: inline-block;
}
}
.group-filter-name {
display: inline-block;
float: right;
}
.groups-table {
width: 100%;

View File

@ -24,6 +24,10 @@ class GroupsController < ApplicationController
dir = params[:asc] ? 'ASC' : 'DESC'
groups = Group.visible_groups(current_user, order ? "#{order} #{dir}" : nil)
if (filter = params[:filter]).present?
groups = Group.search_groups(filter, groups: groups)
end
unless guardian.is_staff?
# hide automatic groups from all non stuff to de-clutter page
groups = groups.where(automatic: false)

View File

@ -432,6 +432,7 @@ en:
join: "Join Group"
leave: "Leave Group"
request: "Request to Join Group"
filter_name: "filter by group name"
message: "Message"
automatic_group: Automatic Group
closed_group: Closed Group

View File

@ -18,6 +18,16 @@ describe GroupsController do
end
end
context 'searchable' do
it 'should return the right response' do
other_group = Fabricate(:group, name: 'testing')
get "/groups.json", params: { filter: 'test' }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["groups"].first["id"]).to eq(other_group.id)
end
end
context 'sortable' do
let!(:other_group) { Fabricate(:group, name: "zzzzzz", users: [user]) }