-<% end %>
\ No newline at end of file
+<% end %>
diff --git a/app/assets/javascripts/app/views/popover/organization.jst.eco b/app/assets/javascripts/app/views/popover/organization.jst.eco
index 7bfcd1d5e..a8f40ba47 100644
--- a/app/assets/javascripts/app/views/popover/organization.jst.eco
+++ b/app/assets/javascripts/app/views/popover/organization.jst.eco
@@ -1,11 +1,9 @@
<%- @V('popover/single_object_generic', object: @object, attributes: @attributes) %>
-<% if @object.members: %>
+<% if @object.member_ids: %>
- <% for user in @object.members: %>
-
<%= user.displayName() %>
- <% end %>
+
<% end %>
diff --git a/app/assets/javascripts/app/views/widget/organization.jst.eco b/app/assets/javascripts/app/views/widget/organization.jst.eco
index 37a6d4629..d6f45f442 100644
--- a/app/assets/javascripts/app/views/widget/organization.jst.eco
+++ b/app/assets/javascripts/app/views/widget/organization.jst.eco
@@ -25,14 +25,13 @@
<% end %>
<% end %>
-<% if @organization.members: %>
+<% if @organization.member_ids: %>
-
-<% for user in @organization.members: %>
-
-<% end %>
-
<% end %>
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index ce28c6d91..daaa4ce90 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -217,11 +217,12 @@ class UsersController < ApplicationController
# The requester has to be in the role 'Admin' or 'Agent' to
# be able to search for User records.
#
- # @parameter query [String] The search query.
- # @parameter limit [Integer] The limit of search results.
- # @parameter role_ids(multi) [Array] A list of Role identifiers to which the Users have to be allocated to.
- # @parameter group_ids(multi) [HashString,Array>] A list of Group identifiers to which the Users have to be allocated to.
- # @parameter full [Boolean] Defines if the result should be
+ # @parameter query [String] The search query.
+ # @parameter limit [Integer] The limit of search results.
+ # @parameter ids(multi) [Array] A list of User IDs which should be returned
+ # @parameter role_ids(multi) [Array] A list of Role identifiers to which the Users have to be allocated to.
+ # @parameter group_ids(multi) [HashString,Array>] A list of Group identifiers to which the Users have to be allocated to.
+ # @parameter full [Boolean] Defines if the result should be
# true: { user_ids => [1,2,...], assets => {...} }
# or false: [{:id => user.id, :label => "firstname lastname ", :value => "firstname lastname "},...].
#
@@ -255,7 +256,7 @@ class UsersController < ApplicationController
order_by: params[:order_by],
current_user: current_user,
}
- %i[role_ids group_ids permissions].each do |key|
+ %i[ids role_ids group_ids permissions].each do |key|
next if params[key].blank?
query_params[key] = params[key]
diff --git a/app/models/organization/assets.rb b/app/models/organization/assets.rb
index 0b3371ba7..10fcb9572 100644
--- a/app/models/organization/assets.rb
+++ b/app/models/organization/assets.rb
@@ -40,11 +40,10 @@ returns
app_model_user = User.to_app_model
if local_attributes['member_ids'].present?
- # feature used for different purpose; do limit references
- if local_attributes['member_ids'].count > 100
- local_attributes['member_ids'] = local_attributes['member_ids'].sort[0, 100]
- end
- local_attributes['member_ids'].each do |local_user_id|
+ # only provide assets for the first 10 organization users
+ # rest will be loaded optionally by the frontend
+ local_attributes['member_ids'] = local_attributes['member_ids'].sort
+ local_attributes['member_ids'][0, 10].each do |local_user_id|
next if data[ app_model_user ] && data[ app_model_user ][ local_user_id ]
user = User.lookup(id: local_user_id)
diff --git a/app/models/user/search.rb b/app/models/user/search.rb
index b9280b1fd..dd4f61081 100644
--- a/app/models/user/search.rb
+++ b/app/models/user/search.rb
@@ -114,16 +114,20 @@ returns
}
query_extension['bool']['must'].push access_condition
end
+
+ user_ids = []
if params[:group_ids].present?
- query_extension['bool'] ||= {}
- query_extension['bool']['must'] ||= []
- user_ids = []
params[:group_ids].each do |group_id, access|
user_ids |= User.group_access(group_id.to_i, access).pluck(:id)
end
-
return [] if user_ids.blank?
-
+ end
+ if params[:ids].present?
+ user_ids |= params[:ids].map(&:to_i)
+ end
+ if user_ids.present?
+ query_extension['bool'] ||= {}
+ query_extension['bool']['must'] ||= []
query_extension['bool']['must'].push({ 'terms' => { '_id' => user_ids } })
end
@@ -149,6 +153,10 @@ returns
query.delete! '*'
statement = User
+ if params[:ids].present?
+ statement = statement.where(id: params[:ids])
+ end
+
if params[:role_ids]
statement = statement.joins(:roles).where('roles.id' => params[:role_ids])
end
diff --git a/spec/requests/user_spec.rb b/spec/requests/user_spec.rb
index 1bc0147da..c074a19f5 100644
--- a/spec/requests/user_spec.rb
+++ b/spec/requests/user_spec.rb
@@ -1507,6 +1507,50 @@ RSpec.describe 'User', type: :request do
end
end
+ describe 'GET /api/v1/users/search, checks usage of the ids parameter', authenticated_as: :agent do
+ let(:agent) { create(:agent) }
+
+ let(:search_agents) { create_list(:agent, 3, firstname: 'Nick') }
+
+ shared_examples 'ids requests' do
+
+ before do
+ post '/api/v1/users/search', params: { query: 'Nick', ids: search_ids, sort_by: ['created_at'], order_by: ['ASC'] }, as: :json
+ end
+
+ shared_examples 'result check' do
+
+ it 'returns only agents matching search parameter ids' do
+ expect(json_response.map { |row| row['id'] }).to eq(search_ids)
+ end
+ end
+
+ context 'when searching for first two agents' do
+ let(:search_ids) { search_agents.first(2).map(&:id) }
+
+ include_examples 'result check'
+ end
+
+ context 'when searching for last two agents' do
+ let(:search_ids) { search_agents.last(2).map(&:id) }
+
+ include_examples 'result check'
+ end
+ end
+
+ context 'with elasticsearch', searchindex: true do
+ include_examples 'ids requests' do
+ before do
+ configure_elasticsearch(required: true, rebuild: true)
+ end
+ end
+ end
+
+ context 'without elasticsearch' do
+ include_examples 'ids requests'
+ end
+ end
+
describe 'PUT /api/v1/users/unlock/{id}' do
let(:admin) { create(:admin) }
let(:agent) { create(:agent) }
diff --git a/spec/system/organization_profile_spec.rb b/spec/system/organization_profile_spec.rb
new file mode 100644
index 000000000..820a29529
--- /dev/null
+++ b/spec/system/organization_profile_spec.rb
@@ -0,0 +1,24 @@
+# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
+
+require 'rails_helper'
+
+RSpec.describe 'Organization Profile', type: :system do
+
+ context 'members section' do
+ let(:organization) { create(:organization) }
+ let(:members) { organization.members.order(id: :asc) }
+
+ before do
+ create_list(:customer, 50, organization: organization)
+ visit "#organization/profile/#{organization.id}"
+ end
+
+ it 'shows first 10 members and loads more on demand' do
+ expect(page).to have_text(members[9].fullname)
+ expect(page).to have_no_text(members[10].fullname)
+
+ click '.js-showMoreMembers'
+ expect(page).to have_text(members[10].fullname)
+ end
+ end
+end
diff --git a/spec/system/search_spec.rb b/spec/system/search_spec.rb
index df85a5759..ef19e25b0 100644
--- a/spec/system/search_spec.rb
+++ b/spec/system/search_spec.rb
@@ -17,6 +17,28 @@ RSpec.describe 'Search', type: :system, searchindex: true do
end
end
+ context 'Organization members', authenticated_as: :authenticate do
+ let(:organization) { create(:organization) }
+ let(:members) { organization.members.order(id: :asc) }
+
+ def authenticate
+ create_list(:customer, 50, organization: organization)
+ true
+ end
+
+ before do
+ sleep 3 # wait for popover killer to pass
+ fill_in id: 'global-search', with: organization.name.to_s
+ end
+
+ it 'shows only first 10 members' do
+ expect(page).to have_text(organization.name)
+ popover_on_hover(first('a.nav-tab.organization'))
+ expect(page).to have_text(members[9].fullname, wait: 30)
+ expect(page).to have_no_text(members[10].fullname)
+ end
+ end
+
context 'inactive user and organizations' do
before do
create(:organization, name: 'Example Inc.', active: true)
diff --git a/spec/system/ticket/zoom_spec.rb b/spec/system/ticket/zoom_spec.rb
index 14a8b2ed4..78e89034f 100644
--- a/spec/system/ticket/zoom_spec.rb
+++ b/spec/system/ticket/zoom_spec.rb
@@ -1682,4 +1682,28 @@ RSpec.describe 'Ticket zoom', type: :system do
expect(page).to have_text(ticket_closed.title, wait: 20)
end
end
+
+ context 'Sidebar - Organization' do
+ let(:organization) { create(:organization) }
+
+ context 'members section' do
+
+ let(:customers) { create_list(:customer, 50, organization: organization) }
+ let(:ticket) { create(:ticket, group: Group.find_by(name: 'Users'), customer: customers.first) }
+ let(:members) { organization.members.order(id: :asc) }
+
+ before do
+ visit "#ticket/zoom/#{ticket.id}"
+ click '.tabsSidebar-tab[data-tab=organization]'
+ end
+
+ it 'shows first 10 members and loads more on demand' do
+ expect(page).to have_text(members[9].fullname)
+ expect(page).to have_no_text(members[10].fullname)
+
+ click '.js-showMoreMembers'
+ expect(page).to have_text(members[10].fullname)
+ end
+ end
+ end
end