Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions app/livechat/client/views/app/livechatAgents.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand All @@ -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) {
Expand Down Expand Up @@ -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();

Expand All @@ -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);
Expand Down Expand Up @@ -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)));
};
});
21 changes: 9 additions & 12 deletions app/livechat/client/views/app/livechatDepartments.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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');
Expand Down Expand Up @@ -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));
};
});
2 changes: 2 additions & 0 deletions app/livechat/imports/server/rest/departments.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions app/livechat/imports/server/rest/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
10 changes: 8 additions & 2 deletions app/livechat/server/api/lib/departments.js
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
28 changes: 21 additions & 7 deletions app/livechat/server/api/lib/users.js
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions app/models/server/raw/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions tests/end-to-end/api/livechat/agents.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down