FEATURE: Can search the user directory by name

This commit is contained in:
Robin Ward 2015-03-19 18:07:31 -04:00
parent 9e13067be0
commit 051a2a3d14
7 changed files with 48 additions and 17 deletions

View file

@ -1,11 +1,16 @@
export default Ember.Controller.extend({ export default Ember.Controller.extend({
queryParams: ['period', 'order', 'asc'], queryParams: ['period', 'order', 'asc', 'name'],
period: 'weekly', period: 'weekly',
order: 'likes_received', order: 'likes_received',
asc: null, asc: null,
name: '',
showTimeRead: Ember.computed.equal('period', 'all'), showTimeRead: Ember.computed.equal('period', 'all'),
_setName: Discourse.debounce(function() {
this.set('name', this.get('nameInput'));
}, 500).observes('nameInput'),
actions: { actions: {
loadMore() { loadMore() {
this.get('model').loadMore(); this.get('model').loadMore();

View file

@ -2,11 +2,6 @@
Debounce a Javascript function. This means if it's called many times in a time limit it Debounce a Javascript function. This means if it's called many times in a time limit it
should only be executed once (at the end of the limit counted from the last call made). should only be executed once (at the end of the limit counted from the last call made).
Original function will be called with the context and arguments from the last call made. Original function will be called with the context and arguments from the last call made.
@method debounce
@module Discourse
@param {function} func The function to debounce
@param {Number} wait how long to wait
**/ **/
Discourse.debounce = function(func, wait) { Discourse.debounce = function(func, wait) {
var self, args; var self, args;

View file

@ -2,18 +2,31 @@ export default Discourse.Route.extend({
queryParams: { queryParams: {
period: { refreshModel: true }, period: { refreshModel: true },
order: { refreshModel: true }, order: { refreshModel: true },
asc: { refreshModel: true } asc: { refreshModel: true },
name: { refreshModel: true, replace: true }
}, },
refreshQueryWithoutTransition: true, refreshQueryWithoutTransition: true,
resetController(controller, isExiting, transition) {
if (isExiting) {
controller.setProperties({
period: 'weekly',
order: 'likes_received',
asc: null,
name: ''
});
}
},
model(params) { model(params) {
// If we refresh via `refreshModel` set the old model to loading // If we refresh via `refreshModel` set the old model to loading
this._period = params.period; this._params = params;
return this.store.find('directoryItem', params); return this.store.find('directoryItem', params);
}, },
setupController(controller, model) { setupController(controller, model) {
controller.setProperties({ model, period: this._period }); const params = this._params;
controller.setProperties({ model, period: params.period, nameInput: params.name });
} }
}); });

View file

@ -1,11 +1,14 @@
<div class="container"> <div class="container">
<div class='directory'> <div class='directory'>
{{period-chooser period=period}} <div class='clearfix'>
{{period-chooser period=period}}
{{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name"}}
</div>
{{#loading-spinner condition=model.loading}} {{#loading-spinner condition=model.loading}}
{{#if model.length}} {{#if model.length}}
<span class='total-rows'>{{i18n "directory.total_rows" count=model.totalRows}}</span> <div class='total-rows'>{{i18n "directory.total_rows" count=model.totalRows}}</div>
<table> <table>
<thead> <thead>

View file

@ -4,18 +4,19 @@
.period-chooser { .period-chooser {
float: left; float: left;
} }
.total-rows { .filter-name {
margin-top: 0.5em;
color: darken(scale-color-diff(), 20%);
float: right; float: right;
} }
.total-rows {
color: darken(scale-color-diff(), 20%);
text-align: right;
}
.spinner { .spinner {
clear: both; clear: both;
} }
table { table {
width: 100%; width: 100%;
margin-top: 1em;
margin-bottom: 1em; margin-bottom: 1em;
td, th { td, th {

View file

@ -23,10 +23,23 @@ class DirectoryItemsController < ApplicationController
end end
page = params[:page].to_i page = params[:page].to_i
user_ids = nil
if params[:name].present?
user_ids = UserSearch.new(params[:name]).search.pluck(:id)
if user_ids.present?
# Add the current user if we have at least one other match
if current_user && result.dup.where(user_id: user_ids).count > 0
user_ids << current_user.id
end
result = result.where(user_id: user_ids)
else
result = result.where('false')
end
end
result = result.order('users.username') result = result.order('users.username')
result_count = result.dup.count result_count = result.dup.count
result = result.limit(PAGE_SIZE).offset(PAGE_SIZE * page) result = result.limit(PAGE_SIZE).offset(PAGE_SIZE * page).to_a
more_params = params.slice(:period, :order, :asc) more_params = params.slice(:period, :order, :asc)
more_params[:page] = page + 1 more_params[:page] = page + 1

View file

@ -238,6 +238,7 @@ en:
sent_by_you: "Sent by <a href='{{userUrl}}'>you</a>" sent_by_you: "Sent by <a href='{{userUrl}}'>you</a>"
directory: directory:
filter_name: "filter by username"
title: "User Directory" title: "User Directory"
likes_given: "Given" likes_given: "Given"
likes_received: "Received" likes_received: "Received"
@ -245,7 +246,7 @@ en:
time_read: "Time Read" time_read: "Time Read"
topic_count: "Topics" topic_count: "Topics"
post_count: "Replies" post_count: "Replies"
no_results: "No results were found for this time period." no_results: "No results were found."
total_rows: total_rows:
one: "1 user" one: "1 user"
other: "%{count} users" other: "%{count} users"