diff --git a/.changeset/fluffy-cats-crash.md b/.changeset/fluffy-cats-crash.md new file mode 100644 index 00000000000..fa678d04d33 --- /dev/null +++ b/.changeset/fluffy-cats-crash.md @@ -0,0 +1,7 @@ +--- +"@rocket.chat/meteor": minor +"@rocket.chat/model-typings": minor +"@rocket.chat/models": minor +--- + +Adds user object in department/:deparmentId/agents with username and name. diff --git a/apps/meteor/app/livechat/server/api/lib/departments.ts b/apps/meteor/app/livechat/server/api/lib/departments.ts index 049dbebaf7a..32be8d1a7f3 100644 --- a/apps/meteor/app/livechat/server/api/lib/departments.ts +++ b/apps/meteor/app/livechat/server/api/lib/departments.ts @@ -168,18 +168,24 @@ export async function findDepartmentsToAutocomplete({ export async function findDepartmentAgents({ departmentId, pagination: { offset, count, sort }, -}: FindDepartmentAgentsParams): Promise> { - const { cursor, totalCount } = LivechatDepartmentAgents.findAgentsByDepartmentId(departmentId, { +}: FindDepartmentAgentsParams): Promise< + PaginatedResult<{ agents: (ILivechatDepartmentAgents & { user: { _id: string; username: string; name: string } })[] }> +> { + const cursor = LivechatDepartmentAgents.findAgentsByDepartmentId(departmentId, { sort: sort || { username: 1 }, skip: offset, limit: count, }); - - const [agents, total] = await Promise.all([cursor.toArray(), totalCount]); + const [ + { + result, + totalCount: [{ total } = { total: 0 }], + }, + ] = await cursor.toArray(); return { - agents, - count: agents.length, + agents: result, + count: result.length, offset, total, }; diff --git a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts index f219a7a4f00..e8af9470439 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/10-departments.ts @@ -841,6 +841,10 @@ import { IS_EE } from '../../../e2e/config/constants'; expect(res.body.agents[0]).to.have.property('_id'); expect(res.body.agents[0]).to.have.property('departmentId', dep._id); expect(res.body.agents[0]).to.have.property('departmentEnabled', true); + expect(res.body.agents[0]).to.have.property('user'); + expect(res.body.agents[0].user).to.have.property('_id'); + expect(res.body.agents[0].user).to.have.property('username'); + expect(res.body.agents[0].user).to.have.property('name'); expect(res.body.count).to.be.equal(1); await deleteDepartment(dep._id); }); diff --git a/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts b/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts index 651a14847b3..e76fc337f42 100644 --- a/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts +++ b/packages/model-typings/src/models/ILivechatDepartmentAgentsModel.ts @@ -1,7 +1,7 @@ import type { AvailableAgentsAggregation, ILivechatDepartmentAgents } from '@rocket.chat/core-typings'; import type { DeleteResult, FindCursor, FindOptions, Document, UpdateResult, Filter, AggregationCursor } from 'mongodb'; -import type { FindPaginated, IBaseModel } from './IBaseModel'; +import type { IBaseModel } from './IBaseModel'; export interface ILivechatDepartmentAgentsModel extends IBaseModel { findUsersInQueue(usersList: string[]): FindCursor; @@ -22,22 +22,13 @@ export interface ILivechatDepartmentAgentsModel extends IBaseModel | FindCursor

; findByAgentId(agentId: string, options?: FindOptions): FindCursor; - findAgentsByDepartmentId(departmentId: string): FindPaginated>; - - findAgentsByDepartmentId( - departmentId: string, - options: FindOptions, - ): FindPaginated>; - - findAgentsByDepartmentId

( - departmentId: string, - options: FindOptions

, - ): FindPaginated>; - findAgentsByDepartmentId( departmentId: string, - options?: undefined | FindOptions, - ): FindPaginated>; + options?: FindOptions, + ): AggregationCursor<{ + result: (ILivechatDepartmentAgents & { user: { _id: string; username: string; name: string } })[]; + totalCount: { _id: null; total: number }[]; + }>; findByDepartmentIds(departmentIds: string[], options?: Record): FindCursor; findAgentsByAgentIdAndBusinessHourId(_agentId: string, _businessHourId: string): Promise; diff --git a/packages/models/src/models/LivechatDepartmentAgents.ts b/packages/models/src/models/LivechatDepartmentAgents.ts index 70913a5d359..f643cf879a1 100644 --- a/packages/models/src/models/LivechatDepartmentAgents.ts +++ b/packages/models/src/models/LivechatDepartmentAgents.ts @@ -1,5 +1,5 @@ import type { AvailableAgentsAggregation, ILivechatDepartmentAgents, RocketChatRecordDeleted } from '@rocket.chat/core-typings'; -import type { FindPaginated, ILivechatDepartmentAgentsModel } from '@rocket.chat/model-typings'; +import type { ILivechatDepartmentAgentsModel } from '@rocket.chat/model-typings'; import type { Collection, FindCursor, @@ -15,6 +15,7 @@ import type { } from 'mongodb'; import { Users } from '../index'; +import { readSecondaryPreferred } from '../readSecondaryPreferred'; import { BaseRaw } from './BaseRaw'; export class LivechatDepartmentAgentsRaw extends BaseRaw implements ILivechatDepartmentAgentsModel { @@ -87,29 +88,72 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw>; - findAgentsByDepartmentId( departmentId: string, - options: FindOptions, - ): FindPaginated>; + options?: FindOptions, + ): AggregationCursor<{ + result: (ILivechatDepartmentAgents & { user: { _id: string; username: string; name: string } })[]; + totalCount: { _id: null; total: number }[]; + }> { + const lookup = { + $lookup: { + from: 'users', + let: { + agentId: '$agentId', + }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$agentId'], + }, + }, + }, + { + $project: { + _id: 1, + username: 1, + name: 1, + }, + }, + ], + as: 'user', + }, + }; + const unwind = { $unwind: { path: '$user' } }; - findAgentsByDepartmentId

( - departmentId: string, - options: FindOptions

, - ): FindPaginated>; + const sort: Document = { $sort: options?.sort || { username: 1 } }; + const pagination = [sort]; - findAgentsByDepartmentId( - departmentId: string, - options?: undefined | FindOptions, - ): FindPaginated> { - const query = { departmentId }; + if (options?.skip) { + pagination.push({ $skip: options.skip }); + } - if (options === undefined) { - return this.findPaginated(query); + if (options?.limit) { + pagination.push({ $limit: options.limit }); } - return this.findPaginated(query, options); + const facet = { + $facet: { + result: pagination, + totalCount: [{ $group: { _id: null, total: { $sum: 1 } } }], + }, + }; + + return this.col.aggregate<{ + result: (ILivechatDepartmentAgents & { user: { _id: string; username: string; name: string } })[]; + totalCount: { _id: null; total: number }[]; + }>( + [ + { + $match: { departmentId }, + }, + lookup, + unwind, + facet, + ], + { readPreference: readSecondaryPreferred(), allowDiskUse: true }, + ); } findByDepartmentIds(departmentIds: string[], options = {}): FindCursor {