diff --git a/app/controllers/discourse_assign/assign_controller.rb b/app/controllers/discourse_assign/assign_controller.rb index c0d4a9f..faf9fa8 100644 --- a/app/controllers/discourse_assign/assign_controller.rb +++ b/app/controllers/discourse_assign/assign_controller.rb @@ -144,6 +144,10 @@ module DiscourseAssign .order('COUNT(users.id) DESC') .group('users.id') .select('users.*, COUNT(users.id) as "assignments_count"') + + members = members.where("users.name ILIKE :pattern OR users.username_lower ILIKE :pattern", pattern: "%#{params[:filter]}%") if params[:filter] + + members = members .limit(limit) .offset(offset) diff --git a/assets/javascripts/discourse-assign/controllers/group-assigned.js.es6 b/assets/javascripts/discourse-assign/controllers/group-assigned.js.es6 index a8d8b16..693f016 100644 --- a/assets/javascripts/discourse-assign/controllers/group-assigned.js.es6 +++ b/assets/javascripts/discourse-assign/controllers/group-assigned.js.es6 @@ -1,13 +1,42 @@ import { inject as service } from "@ember/service"; import Controller, { inject as controller } from "@ember/controller"; import { ajax } from "discourse/lib/ajax"; -import { observes } from "discourse-common/utils/decorators"; +import discourseComputed, { observes } from "discourse-common/utils/decorators"; +import discourseDebounce from "discourse/lib/debounce"; export default Controller.extend({ router: service(), application: controller(), loading: false, offset: 0, + filterName: "", + filter: "", + + @discourseComputed("site.mobileView") + isDesktop(mobileView) { + return !mobileView; + }, + + @observes("filterName") + _setFilter: discourseDebounce(function() { + this.set("filter", this.filterName); + }, 500), + + @observes("filter") + _filterModel() { + this.set("loading", true); + this.set("offset", 0); + ajax(`/assign/members/${this.group.name}`, { + type: "GET", + data: { filter: this.filter, offset: this.offset } + }).then(result => { + if (this.router.currentRoute.params.filter !== "everyone") { + this.transitionToRoute("group.assigned.show", "everyone"); + } + this.set("members", result.members); + this.set("loading", false); + }); + }, @observes("model.assignment_count") assignmentCountChanged() { @@ -27,12 +56,13 @@ export default Controller.extend({ if (this.model.members.length >= this.offset + 50) { this.set("loading", true); this.set("offset", this.offset + 50); - ajax(`/assign/members/${this.group.name}?offset=${this.offset}`).then( - result => { - this.members.pushObjects(result.members); - this.set("loading", false); - } - ); + ajax(`/assign/members/${this.group.name}`, { + type: "GET", + data: { filter: this.filter, offset: this.offset } + }).then(result => { + this.members.pushObjects(result.members); + this.set("loading", false); + }); } }, diff --git a/assets/javascripts/discourse/templates/group/assigned.hbs b/assets/javascripts/discourse/templates/group/assigned.hbs index 46f3a3e..db6b467 100644 --- a/assets/javascripts/discourse/templates/group/assigned.hbs +++ b/assets/javascripts/discourse/templates/group/assigned.hbs @@ -1,5 +1,10 @@
{{#mobile-nav class="activity-nav" desktopClass="action-list activity-list nav-stacked" currentPath=router._router.currentPath}} + {{#if isDesktop}} +
+ {{input type="text" placeholder=(i18n "discourse_assign.sidebar_name_filter_placeholder") value=filterName class="search"}} +
+ {{/if}} {{#load-more selector=".activity-nav li" action=(action "loadMore")}} {{group-assigned-filter show-avatar=false filter="everyone" routeType=route_type assignment_count=group.assignment_count}} {{#each members as |member|}} diff --git a/assets/stylesheets/assigns.scss b/assets/stylesheets/assigns.scss index 9f49424..05d15ad 100644 --- a/assets/stylesheets/assigns.scss +++ b/assets/stylesheets/assigns.scss @@ -117,4 +117,11 @@ grid-area: count; } } + .search { + height: 1em; + width: 100%; + } + .search-div { + padding: 13px; + } } diff --git a/assets/stylesheets/mobile/assigns.scss b/assets/stylesheets/mobile/assigns.scss index 58b153a..fb67ccc 100644 --- a/assets/stylesheets/mobile/assigns.scss +++ b/assets/stylesheets/mobile/assigns.scss @@ -39,7 +39,7 @@ margin: 0; padding: 0; } - img { + a { width: 1em; height: 1em; } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 753cd7b..261eec9 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -11,6 +11,7 @@ en: add_unassigned_filter: "Add 'unassigned' filter to category" cant_act: "You cannot act on flags that have been assigned to other users" cant_act_unclaimed: "You must claim this topic before acting on flags." + sidebar_name_filter_placeholder: "Name/Username" assigned: "Assigned" group_everyone: "Everyone" assigned_to: "Assigned to" diff --git a/spec/requests/assign_controller_spec.rb b/spec/requests/assign_controller_spec.rb index d8cca28..b040bc6 100644 --- a/spec/requests/assign_controller_spec.rb +++ b/spec/requests/assign_controller_spec.rb @@ -8,9 +8,9 @@ RSpec.describe DiscourseAssign::AssignController do before { SiteSetting.assign_enabled = true } let(:default_allowed_group) { Group.find_by(name: 'staff') } - let(:user) { Fabricate(:admin, groups: [default_allowed_group]) } + let(:user) { Fabricate(:admin, groups: [default_allowed_group], name: 'Robin Ward', username: 'eviltrout') } let(:post) { Fabricate(:post) } - let(:user2) { Fabricate(:active_user) } + let(:user2) { Fabricate(:active_user, name: 'David Tylor', username: 'david') } let(:nonadmin) { Fabricate(:user, groups: [default_allowed_group]) } let(:normal_user) { Fabricate(:user) } let(:normal_admin) { Fabricate(:admin) } @@ -231,6 +231,22 @@ RSpec.describe DiscourseAssign::AssignController do expect(JSON.parse(response.body)['members'].map { |m| m['id'] }).to match_array([user.id, user2.id]) end + it "returns members as according to filter" do + sign_in(user) + + get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: 'a' } + expect(response.status).to eq(200) + expect(JSON.parse(response.body)['members'].map { |m| m['id'] }).to match_array([user.id, user2.id]) + + get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: 'david' } + expect(response.status).to eq(200) + expect(JSON.parse(response.body)['members'].map { |m| m['id'] }).to match_array([user2.id]) + + get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: 'Tylor' } + expect(response.status).to eq(200) + expect(JSON.parse(response.body)['members'].map { |m| m['id'] }).to match_array([user2.id]) + end + it "404 error to non-group-members" do sign_in(normal_user)