diff --git a/app/livechat/client/views/app/livechatAgents.js b/app/livechat/client/views/app/livechatAgents.js index f1f515addfde4..46e7270484a80 100644 --- a/app/livechat/client/views/app/livechatAgents.js +++ b/app/livechat/client/views/app/livechatAgents.js @@ -2,15 +2,20 @@ import { Meteor } from 'meteor/meteor'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { ReactiveDict } from 'meteor/reactive-dict'; -import s from 'underscore.string'; import _ from 'underscore'; import { modal, call } from '../../../../ui-utils'; import { t, handleError, APIClient } from '../../../../utils/client'; import './livechatAgents.html'; -const loadAgents = async (instance, limit = 50) => { - const { users } = await APIClient.v1.get(`livechat/users/agent?count=${ limit }`); +const loadAgents = async (instance, limit = 50, text) => { + let baseUrl = `livechat/users/agent?count=${ limit }`; + + if (text) { + baseUrl += `&text=${ encodeURIComponent(text) }`; + } + + const { users } = await APIClient.v1.get(baseUrl); instance.agents.set(users); instance.ready.set(true); }; @@ -34,7 +39,7 @@ Template.livechatAgents.helpers({ return Template.instance().state.get('loading'); }, agents() { - return Template.instance().getAgentsWithCriteria(); + return Template.instance().agents.get(); }, emailAddress() { if (this.emails && this.emails.length > 0) { @@ -119,7 +124,7 @@ Template.livechatAgents.events({ async 'submit #form-agent'(e, instance) { e.preventDefault(); - const { selectedAgents, state } = instance; + const { selectedAgents, state, limit, filter } = instance; const users = selectedAgents.get(); @@ -132,7 +137,8 @@ Template.livechatAgents.events({ await Promise.all( users.map(({ username }) => call('livechat:addAgent', username)) ); - await loadAgents(instance); + + await loadAgents(instance, limit.get(), filter.get()); selectedAgents.set([]); } finally { state.set('loading', false); @@ -186,18 +192,7 @@ Template.livechatAgents.onCreated(function() { this.autorun(function() { const limit = instance.limit.get(); - loadAgents(instance, limit); + const filter = instance.filter.get(); + loadAgents(instance, limit, filter); }); - this.getAgentsWithCriteria = function() { - let filter; - - if (instance.filter && instance.filter.get()) { - filter = s.trim(instance.filter.get()); - } - const regex = new RegExp(s.escapeRegExp(filter), 'i'); - return instance.agents.get() - .filter((agent) => agent.name.match(regex) - || agent.username.match(regex) - || agent.emails.some((email) => email.address.match(regex))); - }; }); diff --git a/app/livechat/client/views/app/livechatDepartments.js b/app/livechat/client/views/app/livechatDepartments.js index d8a9f422f641f..97b50f7516033 100644 --- a/app/livechat/client/views/app/livechatDepartments.js +++ b/app/livechat/client/views/app/livechatDepartments.js @@ -3,7 +3,6 @@ import { FlowRouter } from 'meteor/kadira:flow-router'; import { Template } from 'meteor/templating'; import { ReactiveVar } from 'meteor/reactive-var'; import { ReactiveDict } from 'meteor/reactive-dict'; -import s from 'underscore.string'; import _ from 'underscore'; import { modal } from '../../../../ui-utils'; @@ -13,7 +12,7 @@ import { APIClient } from '../../../../utils/client'; Template.livechatDepartments.helpers({ departments() { - return Template.instance().getDepartmentsWithCriteria(); + return Template.instance().departments.get(); }, isLoading() { return Template.instance().state.get('loading'); @@ -98,17 +97,15 @@ Template.livechatDepartments.onCreated(function() { this.autorun(async function() { const limit = instance.limit.get(); - const { departments } = await APIClient.v1.get(`livechat/department?count=${ limit }`); + const filter = instance.filter.get(); + let baseUrl = `livechat/department?count=${ limit }`; + + if (filter) { + baseUrl += `&text=${ encodeURIComponent(filter) }`; + } + + const { departments } = await APIClient.v1.get(baseUrl); instance.departments.set(departments); instance.ready.set(true); }); - this.getDepartmentsWithCriteria = function() { - let filter; - - if (instance.filter && instance.filter.get()) { - filter = s.trim(instance.filter.get()); - } - const regex = new RegExp(s.escapeRegExp(filter), 'i'); - return instance.departments.get().filter((department) => department.name.match(regex)); - }; }); diff --git a/app/livechat/imports/server/rest/departments.js b/app/livechat/imports/server/rest/departments.js index b0c560f34cc9f..18fa8bf891219 100644 --- a/app/livechat/imports/server/rest/departments.js +++ b/app/livechat/imports/server/rest/departments.js @@ -10,9 +10,11 @@ API.v1.addRoute('livechat/department', { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); + const { text } = this.queryParams; const departments = Promise.await(findDepartments({ userId: this.userId, + text, pagination: { offset, count, diff --git a/app/livechat/imports/server/rest/users.js b/app/livechat/imports/server/rest/users.js index 179cb61379255..6bf082858c4bd 100644 --- a/app/livechat/imports/server/rest/users.js +++ b/app/livechat/imports/server/rest/users.js @@ -14,10 +14,12 @@ API.v1.addRoute('livechat/users/:type', { authRequired: true }, { }); const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); + const { text } = this.queryParams; if (this.urlParams.type === 'agent') { return API.v1.success(Promise.await(findAgents({ userId: this.userId, + text, pagination: { offset, count, @@ -28,6 +30,7 @@ API.v1.addRoute('livechat/users/:type', { authRequired: true }, { if (this.urlParams.type === 'manager') { return API.v1.success(Promise.await(findManagers({ userId: this.userId, + text, pagination: { offset, count, diff --git a/app/livechat/server/api/lib/departments.js b/app/livechat/server/api/lib/departments.js index c12a422e2b1cc..b404a2e200b03 100644 --- a/app/livechat/server/api/lib/departments.js +++ b/app/livechat/server/api/lib/departments.js @@ -1,12 +1,18 @@ +import s from 'underscore.string'; + import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission'; import { LivechatDepartment, LivechatDepartmentAgents } from '../../../../models/server/raw'; -export async function findDepartments({ userId, pagination: { offset, count, sort } }) { +export async function findDepartments({ userId, text, pagination: { offset, count, sort } }) { if (!await hasPermissionAsync(userId, 'view-livechat-departments') && !await hasPermissionAsync(userId, 'view-l-room')) { throw new Error('error-not-authorized'); } - const cursor = LivechatDepartment.find({}, { + const query = { + ...text && { name: new RegExp(s.escapeRegExp(text), 'i') }, + }; + + const cursor = LivechatDepartment.find(query, { sort: sort || { name: 1 }, skip: offset, limit: count, diff --git a/app/livechat/server/api/lib/users.js b/app/livechat/server/api/lib/users.js index 0fb8f1d307bc7..e630088badb09 100644 --- a/app/livechat/server/api/lib/users.js +++ b/app/livechat/server/api/lib/users.js @@ -1,12 +1,16 @@ -import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission'; +import s from 'underscore.string'; + +import { hasAllPermissionAsync } from '../../../../authorization/server/functions/hasPermission'; import { Users } from '../../../../models/server/raw'; -async function findUsers({ userId, role, pagination: { offset, count, sort } }) { - if (!await hasPermissionAsync(userId, 'view-livechat-manager') || !await hasPermissionAsync(userId, 'manage-livechat-agents')) { - throw new Error('error-not-authorized'); +async function findUsers({ role, text, pagination: { offset, count, sort } }) { + const query = {}; + if (text) { + const filterReg = new RegExp(s.escapeRegExp(text), 'i'); + Object.assign(query, { $or: [{ username: filterReg }, { name: filterReg }, { 'emails.address': filterReg }] }); } - const cursor = await Users.findUsersInRoles(role, undefined, { + const cursor = await Users.findUsersInRolesWithQuery(role, query, { sort: sort || { name: 1 }, skip: offset, limit: count, @@ -30,10 +34,15 @@ async function findUsers({ userId, role, pagination: { offset, count, sort } }) total, }; } -export async function findAgents({ userId, pagination: { offset, count, sort } }) { +export async function findAgents({ userId, text, pagination: { offset, count, sort } }) { + if (!await hasAllPermissionAsync(userId, ['view-l-room', 'transfer-livechat-guest'])) { + throw new Error('error-not-authorized'); + } + return findUsers({ role: 'livechat-agent', userId, + text, pagination: { offset, count, @@ -42,10 +51,15 @@ export async function findAgents({ userId, pagination: { offset, count, sort } } }); } -export async function findManagers({ userId, pagination: { offset, count, sort } }) { +export async function findManagers({ userId, text, pagination: { offset, count, sort } }) { + if (!await hasAllPermissionAsync(userId, ['view-livechat-manager', 'manage-livechat-agents'])) { + throw new Error('error-not-authorized'); + } + return findUsers({ role: 'livechat-manager', userId, + text, pagination: { offset, count, diff --git a/app/models/server/raw/Users.js b/app/models/server/raw/Users.js index a9bffcdaff839..e7b0668bef044 100644 --- a/app/models/server/raw/Users.js +++ b/app/models/server/raw/Users.js @@ -13,6 +13,14 @@ export class UsersRaw extends BaseRaw { return this.find(query, options); } + findUsersInRolesWithQuery(roles, query, options) { + roles = [].concat(roles); + + Object.assign(query, { roles: { $in: roles } }); + + return this.find(query, options); + } + isUserInRole(userId, roleName) { const query = { _id: userId, diff --git a/tests/end-to-end/api/livechat/agents.js b/tests/end-to-end/api/livechat/agents.js index 5e265a2133ba6..01a5e091f21b8 100644 --- a/tests/end-to-end/api/livechat/agents.js +++ b/tests/end-to-end/api/livechat/agents.js @@ -24,8 +24,8 @@ describe('LIVECHAT - Agents', function() { describe('livechat/users/:type', () => { it('should return an "unauthorized error" when the user does not have the necessary permission', (done) => { - updatePermission('view-livechat-manager', []) - .then(() => updatePermission('manage-livechat-agents', [])) + updatePermission('view-l-room', []) + .then(() => updatePermission('transfer-livechat-guest', [])) .then(() => { request.get(api('livechat/users/agent')) .set(credentials) @@ -54,8 +54,8 @@ describe('LIVECHAT - Agents', function() { }); }); it('should return an array of agents', (done) => { - updatePermission('view-livechat-manager', ['admin']) - .then(() => updatePermission('manage-livechat-agents', ['admin'])) + updatePermission('view-l-room', ['admin']) + .then(() => updatePermission('transfer-livechat-guest', ['admin'])) .then(() => { request.get(api('livechat/users/agent')) .set(credentials)