From 051a2a3d143ddb0e601dc02879758aa7904f7f38 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 19 Mar 2015 18:07:31 -0400 Subject: [PATCH] FEATURE: Can search the user directory by name --- .../discourse/controllers/users.js.es6 | 7 ++++++- .../javascripts/discourse/lib/debounce.js | 5 ----- .../javascripts/discourse/routes/users.js.es6 | 19 ++++++++++++++++--- .../javascripts/discourse/templates/users.hbs | 7 +++++-- .../stylesheets/common/base/directory.scss | 9 +++++---- app/controllers/directory_items_controller.rb | 15 ++++++++++++++- config/locales/client.en.yml | 3 ++- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/users.js.es6 b/app/assets/javascripts/discourse/controllers/users.js.es6 index 631be71d7..8ff6e6e49 100644 --- a/app/assets/javascripts/discourse/controllers/users.js.es6 +++ b/app/assets/javascripts/discourse/controllers/users.js.es6 @@ -1,11 +1,16 @@ export default Ember.Controller.extend({ - queryParams: ['period', 'order', 'asc'], + queryParams: ['period', 'order', 'asc', 'name'], period: 'weekly', order: 'likes_received', asc: null, + name: '', showTimeRead: Ember.computed.equal('period', 'all'), + _setName: Discourse.debounce(function() { + this.set('name', this.get('nameInput')); + }, 500).observes('nameInput'), + actions: { loadMore() { this.get('model').loadMore(); diff --git a/app/assets/javascripts/discourse/lib/debounce.js b/app/assets/javascripts/discourse/lib/debounce.js index 571e146ae..583e8bb9b 100644 --- a/app/assets/javascripts/discourse/lib/debounce.js +++ b/app/assets/javascripts/discourse/lib/debounce.js @@ -2,11 +2,6 @@ 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). 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) { var self, args; diff --git a/app/assets/javascripts/discourse/routes/users.js.es6 b/app/assets/javascripts/discourse/routes/users.js.es6 index d30e57097..e033ae08e 100644 --- a/app/assets/javascripts/discourse/routes/users.js.es6 +++ b/app/assets/javascripts/discourse/routes/users.js.es6 @@ -2,18 +2,31 @@ export default Discourse.Route.extend({ queryParams: { period: { refreshModel: true }, order: { refreshModel: true }, - asc: { refreshModel: true } + asc: { refreshModel: true }, + name: { refreshModel: true, replace: true } }, refreshQueryWithoutTransition: true, + resetController(controller, isExiting, transition) { + if (isExiting) { + controller.setProperties({ + period: 'weekly', + order: 'likes_received', + asc: null, + name: '' + }); + } + }, + model(params) { // If we refresh via `refreshModel` set the old model to loading - this._period = params.period; + this._params = params; return this.store.find('directoryItem', params); }, setupController(controller, model) { - controller.setProperties({ model, period: this._period }); + const params = this._params; + controller.setProperties({ model, period: params.period, nameInput: params.name }); } }); diff --git a/app/assets/javascripts/discourse/templates/users.hbs b/app/assets/javascripts/discourse/templates/users.hbs index c486a9995..83d9e8993 100644 --- a/app/assets/javascripts/discourse/templates/users.hbs +++ b/app/assets/javascripts/discourse/templates/users.hbs @@ -1,11 +1,14 @@
- {{period-chooser period=period}} +
+ {{period-chooser period=period}} + {{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name"}} +
{{#loading-spinner condition=model.loading}} {{#if model.length}} - {{i18n "directory.total_rows" count=model.totalRows}} +
{{i18n "directory.total_rows" count=model.totalRows}}
diff --git a/app/assets/stylesheets/common/base/directory.scss b/app/assets/stylesheets/common/base/directory.scss index a904883ba..c9562135f 100644 --- a/app/assets/stylesheets/common/base/directory.scss +++ b/app/assets/stylesheets/common/base/directory.scss @@ -4,18 +4,19 @@ .period-chooser { float: left; } - .total-rows { - margin-top: 0.5em; - color: darken(scale-color-diff(), 20%); + .filter-name { float: right; } + .total-rows { + color: darken(scale-color-diff(), 20%); + text-align: right; + } .spinner { clear: both; } table { width: 100%; - margin-top: 1em; margin-bottom: 1em; td, th { diff --git a/app/controllers/directory_items_controller.rb b/app/controllers/directory_items_controller.rb index 9de15381e..1c44e7d54 100644 --- a/app/controllers/directory_items_controller.rb +++ b/app/controllers/directory_items_controller.rb @@ -23,10 +23,23 @@ class DirectoryItemsController < ApplicationController end 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_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[:page] = page + 1 diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index ce53ed965..af0f69377 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -238,6 +238,7 @@ en: sent_by_you: "Sent by you" directory: + filter_name: "filter by username" title: "User Directory" likes_given: "Given" likes_received: "Received" @@ -245,7 +246,7 @@ en: time_read: "Time Read" topic_count: "Topics" post_count: "Replies" - no_results: "No results were found for this time period." + no_results: "No results were found." total_rows: one: "1 user" other: "%{count} users"