Skip to content

Commit

Permalink
refactor: Remove canned responses model (#28686)
Browse files Browse the repository at this point in the history
  • Loading branch information
KevLehman authored Mar 30, 2023
1 parent a0f4358 commit fcb2551
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 150 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { CannedResponse } from '@rocket.chat/models';

import { callbacks } from '../../../../../lib/callbacks';
import CannedResponse from '../../../models/server/models/CannedResponse';
import notifications from '../../../../../app/notifications/server/lib/Notifications';

callbacks.add(
'livechat.removeAgentDepartment',
async (options: Record<string, any>): Promise<any> => {
const { departmentId, agentsId } = options;
CannedResponse.findByDepartmentId(departmentId, { fields: { _id: 1 } }).forEach((response: any) => {
await CannedResponse.findByDepartmentId(departmentId, { projection: { _id: 1 } }).forEach((response: any) => {
const { _id } = response;
notifications.streamCannedResponses.emit('canned-responses', { type: 'removed', _id }, { agentsId });
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { CannedResponse } from '@rocket.chat/models';

import { callbacks } from '../../../../../lib/callbacks';
import CannedResponse from '../../../models/server/models/CannedResponse';
import notifications from '../../../../../app/notifications/server/lib/Notifications';

callbacks.add(
'livechat.saveAgentDepartment',
async (options: Record<string, any>): Promise<any> => {
const { departmentId, agentsId } = options;
CannedResponse.findByDepartmentId(departmentId, {}).forEach((response: any) => {
await CannedResponse.findByDepartmentId(departmentId, {}).forEach((response: any) => {
notifications.streamCannedResponses.emit('canned-responses', { type: 'changed', ...response }, { agentsId });
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { CannedResponse } from '@rocket.chat/models';

import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission';
import CannedResponse from '../../../models/server/models/CannedResponse';
import notifications from '../../../../../app/notifications/server/lib/Notifications';

declare module '@rocket.chat/ui-contexts' {
// eslint-disable-next-line @typescript-eslint/naming-convention
interface ServerMethods {
removeCannedResponse(_id: string): void;
removeCannedResponse(_id: string): Promise<void>;
}
}

Expand All @@ -25,7 +25,7 @@ Meteor.methods<ServerMethods>({

check(_id, String);

const cannedResponse = CannedResponse.findOneById(_id);
const cannedResponse = await CannedResponse.findOneById(_id);
if (!cannedResponse) {
throw new Meteor.Error('error-canned-response-not-found', 'Canned Response not found', {
method: 'removeCannedResponse',
Expand All @@ -34,6 +34,6 @@ Meteor.methods<ServerMethods>({

notifications.streamCannedResponses.emit('canned-responses', { type: 'removed', _id });

return CannedResponse.removeById(_id);
await CannedResponse.removeById(_id);
},
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Meteor } from 'meteor/meteor';
import { Match, check } from 'meteor/check';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { LivechatDepartment } from '@rocket.chat/models';
import { LivechatDepartment, CannedResponse } from '@rocket.chat/models';
import type { IOmnichannelCannedResponse } from '@rocket.chat/core-typings';

import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission';
import CannedResponse from '../../../models/server/models/CannedResponse';
import { Users } from '../../../../../app/models/server';
import notifications from '../../../../../app/notifications/server/lib/Notifications';

Expand All @@ -20,7 +20,7 @@ declare module '@rocket.chat/ui-contexts' {
tags?: string[];
departmentId?: string;
},
): void;
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'> & { _createdAt?: Date }>;
}
}

Expand Down Expand Up @@ -62,8 +62,8 @@ Meteor.methods<ServerMethods>({
// TODO: check if the department i'm trying to save is a department i can interact with

// check if the response already exists and we're not updating one
const duplicateShortcut = CannedResponse.findOneByShortcut(responseData.shortcut, {
fields: { _id: 1 },
const duplicateShortcut = await CannedResponse.findOneByShortcut(responseData.shortcut, {
projection: { _id: 1 },
});
if ((!_id && duplicateShortcut) || (_id && duplicateShortcut && duplicateShortcut._id !== _id)) {
throw new Meteor.Error('error-invalid-shortcut', 'Shortcut provided already exists', {
Expand All @@ -83,44 +83,35 @@ Meteor.methods<ServerMethods>({
});
}

const data: {
shortcut: string;
text: string;
scope: string;
tags: string[];
departmentId?: string;
createdBy?: {
_id: string;
username: string;
};
_createdAt?: Date;
userId?: string;
} = { ...responseData, departmentId: responseData.departmentId ?? undefined };
let result: Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'> & { _createdAt?: Date };

if (_id) {
const cannedResponse = CannedResponse.findOneById(_id);
const cannedResponse = await CannedResponse.findOneById(_id);
if (!cannedResponse) {
throw new Meteor.Error('error-canned-response-not-found', 'Canned Response not found', {
method: 'saveCannedResponse',
});
}

data.createdBy = cannedResponse.createdBy;
result = await CannedResponse.updateCannedResponse(_id, { ...responseData, createdBy: cannedResponse.createdBy });
} else {
const user = Users.findOneById(Meteor.userId());

if (data.scope === 'user') {
data.userId = user._id;
}
data.createdBy = { _id: user._id, username: user.username };
data._createdAt = new Date();
const data = {
...responseData,
...(responseData.scope === 'user' && { userId: user._id }),
createdBy: { _id: user._id, username: user.username },
_createdAt: new Date(),
};

result = await CannedResponse.createCannedResponse(data);
}
const createdCannedResponse = CannedResponse.createOrUpdateCannedResponse(_id, data);

notifications.streamCannedResponses.emit('canned-responses', {
type: 'changed',
...createdCannedResponse,
...result,
});

return createdCannedResponse;
return result;
},
});
2 changes: 1 addition & 1 deletion apps/meteor/ee/app/license/server/getStatistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async function getEEStatistics(): Promise<EEOnlyStats | undefined> {

// Number of canned responses
statsPms.push(
CannedResponse.col.count().then((count) => {
CannedResponse.col.estimatedDocumentCount().then((count) => {
statistics.cannedResponses = count;
return true;
}),
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/ee/app/models/server/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import LivechatTag from './models/LivechatTag';
import LivechatUnit from './models/LivechatUnit';
import LivechatUnitMonitors from './models/LivechatUnitMonitors';
import './models/CannedResponse';
import './models/LivechatDepartment';
import './models/LivechatPriority';
import './models/Messages';
Expand Down
97 changes: 0 additions & 97 deletions apps/meteor/ee/app/models/server/models/CannedResponse.js

This file was deleted.

38 changes: 29 additions & 9 deletions apps/meteor/ee/server/models/raw/CannedResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export class CannedResponseRaw extends BaseRaw<IOmnichannelCannedResponse> imple
];
}

async createOrUpdateCannedResponse(
async updateCannedResponse(
_id: string,
{ shortcut, text, tags, scope, userId, departmentId, createdBy, _createdAt }: IOmnichannelCannedResponse,
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt'>> {
{ shortcut, text, tags, scope, userId, departmentId, createdBy }: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt' | '_createdAt'>,
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'>> {
const record = {
shortcut,
text,
Expand All @@ -33,15 +33,35 @@ export class CannedResponseRaw extends BaseRaw<IOmnichannelCannedResponse> imple
userId,
departmentId,
createdBy,
_createdAt,
};

if (_id) {
await this.updateOne({ _id }, { $set: record });
} else {
_id = (await this.insertOne(record)).insertedId;
}
await this.updateOne({ _id }, { $set: record });

return Object.assign(record, { _id });
}

async createCannedResponse({
shortcut,
text,
tags,
scope,
userId,
departmentId,
createdBy,
_createdAt,
}: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt'>): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt'>> {
const record = {
shortcut,
text,
scope,
tags,
userId,
departmentId,
createdBy,
_createdAt,
};

const _id = (await this.insertOne(record)).insertedId;
return Object.assign(record, { _id });
}

Expand Down
3 changes: 2 additions & 1 deletion packages/core-typings/src/IOmnichannelCannedResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export interface IOmnichannelCannedResponse extends IRocketChatRecord {
text: string;
scope: string;
tags: any;
userId: IUser['_id'];
// userId is optional, its only required when scope === 'user'
userId?: IUser['_id'];
departmentId?: ILivechatDepartment['_id'];
createdBy: {
_id: IUser['_id'];
Expand Down
19 changes: 14 additions & 5 deletions packages/model-typings/src/models/ICannedResponseModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@ import type { FindOptions, FindCursor, DeleteResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';

export interface ICannedResponseModel extends IBaseModel<IOmnichannelCannedResponse> {
createOrUpdateCannedResponse(
_id: string,
{ shortcut, text, tags, scope, userId, departmentId, createdBy, _createdAt }: IOmnichannelCannedResponse,
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt'>>;

findOneById(_id: string, options?: FindOptions<IOmnichannelCannedResponse>): Promise<IOmnichannelCannedResponse | null>;
findOneByShortcut(shortcut: string, options?: FindOptions<IOmnichannelCannedResponse>): Promise<IOmnichannelCannedResponse | null>;
findByCannedResponseId(_id: string, options?: FindOptions<IOmnichannelCannedResponse>): FindCursor<IOmnichannelCannedResponse>;
findByDepartmentId(departmentId: string, options?: FindOptions<IOmnichannelCannedResponse>): FindCursor<IOmnichannelCannedResponse>;
findByShortcut(shortcut: string, options?: FindOptions<IOmnichannelCannedResponse>): FindCursor<IOmnichannelCannedResponse>;
removeById(_id: string): Promise<DeleteResult>;
createCannedResponse({
shortcut,
text,
tags,
scope,
userId,
departmentId,
createdBy,
_createdAt,
}: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt'>): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt'>>;
updateCannedResponse(
_id: string,
{ shortcut, text, tags, scope, userId, departmentId, createdBy }: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt' | '_createdAt'>,
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'>>;
}

0 comments on commit fcb2551

Please sign in to comment.