From f6f6bd8f60cd7528f943a1315c3e9ef2bdfbc6b1 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 09:27:12 -0600 Subject: [PATCH 01/15] remove unused endpoints --- .../imports/server/rest/officeHour.js | 21 ---- .../app/livechat/server/api/lib/officeHour.js | 12 -- apps/meteor/app/livechat/server/index.js | 2 - .../livechat/server/methods/getInitialData.js | 112 ------------------ .../server/methods/startFileUploadRoom.js | 29 ----- .../livechat-enterprise/server/api/units.ts | 46 ------- .../omnichannel/units/UnitEditWithData.tsx | 2 +- .../ee/client/omnichannel/units/UnitsRoute.js | 2 +- 8 files changed, 2 insertions(+), 224 deletions(-) delete mode 100644 apps/meteor/app/livechat/imports/server/rest/officeHour.js delete mode 100644 apps/meteor/app/livechat/server/api/lib/officeHour.js delete mode 100644 apps/meteor/app/livechat/server/methods/getInitialData.js delete mode 100644 apps/meteor/app/livechat/server/methods/startFileUploadRoom.js diff --git a/apps/meteor/app/livechat/imports/server/rest/officeHour.js b/apps/meteor/app/livechat/imports/server/rest/officeHour.js deleted file mode 100644 index 1dcb2827f63b..000000000000 --- a/apps/meteor/app/livechat/imports/server/rest/officeHour.js +++ /dev/null @@ -1,21 +0,0 @@ -import { API } from '../../../../api/server'; -import { findLivechatOfficeHours } from '../../../server/api/lib/officeHour'; - -API.v1.addRoute( - 'livechat/office-hours', - { authRequired: true }, - { - get() { - const { officeHours } = Promise.await(findLivechatOfficeHours({ userId: this.userId })); - return API.v1.success( - this.deprecationWarning({ - endpoint: 'livechat/office-hours', - versionWillBeRemoved: '4.0.0', - response: { - officeHours, - }, - }), - ); - }, - }, -); diff --git a/apps/meteor/app/livechat/server/api/lib/officeHour.js b/apps/meteor/app/livechat/server/api/lib/officeHour.js deleted file mode 100644 index dbdadd48fe22..000000000000 --- a/apps/meteor/app/livechat/server/api/lib/officeHour.js +++ /dev/null @@ -1,12 +0,0 @@ -import { hasPermissionAsync } from '../../../../authorization/server/functions/hasPermission'; -import { LivechatBusinessHours } from '../../../../models/server/raw'; - -export async function findLivechatOfficeHours({ userId }) { - if (!(await hasPermissionAsync(userId, 'view-livechat-business-hours'))) { - throw new Error('error-not-authorized'); - } - - return { - officeHours: (await LivechatBusinessHours.findOneDefaultBusinessHour()).workHours, - }; -} diff --git a/apps/meteor/app/livechat/server/index.js b/apps/meteor/app/livechat/server/index.js index 217db0c7a35b..e681d8010ae4 100644 --- a/apps/meteor/app/livechat/server/index.js +++ b/apps/meteor/app/livechat/server/index.js @@ -31,7 +31,6 @@ import './methods/getAgentData'; import './methods/getAgentOverviewData'; import './methods/getAnalyticsChartData'; import './methods/getAnalyticsOverviewData'; -import './methods/getInitialData'; import './methods/getNextAgent'; import './methods/getRoutingConfig'; import './methods/loadHistory'; @@ -61,7 +60,6 @@ import './methods/sendOfflineMessage'; import './methods/setCustomField'; import './methods/setDepartmentForVisitor'; import './methods/startVideoCall'; -import './methods/startFileUploadRoom'; import './methods/transfer'; import './methods/webhookTest'; import './methods/setUpConnection'; diff --git a/apps/meteor/app/livechat/server/methods/getInitialData.js b/apps/meteor/app/livechat/server/methods/getInitialData.js deleted file mode 100644 index e46c66e042f7..000000000000 --- a/apps/meteor/app/livechat/server/methods/getInitialData.js +++ /dev/null @@ -1,112 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import _ from 'underscore'; - -import { LivechatRooms, Users, LivechatDepartment, LivechatVisitors } from '../../../models/server'; -import { LivechatTrigger } from '../../../models/server/raw'; -import { Livechat } from '../lib/Livechat'; -import { deprecationWarning } from '../../../api/server/helpers/deprecationWarning'; - -Meteor.methods({ - async 'livechat:getInitialData'(visitorToken, departmentId) { - const info = { - enabled: null, - title: null, - color: null, - registrationForm: null, - room: null, - visitor: null, - triggers: [], - departments: [], - allowSwitchingDepartments: null, - online: true, - offlineColor: null, - offlineMessage: null, - offlineSuccessMessage: null, - offlineUnavailableMessage: null, - displayOfflineForm: null, - videoCall: null, - fileUpload: null, - conversationFinishedMessage: null, - conversationFinishedText: null, - nameFieldRegistrationForm: null, - emailFieldRegistrationForm: null, - registrationFormMessage: null, - showConnecting: false, - }; - - const options = { - fields: { - name: 1, - t: 1, - cl: 1, - u: 1, - usernames: 1, - v: 1, - servedBy: 1, - departmentId: 1, - }, - }; - const room = departmentId - ? LivechatRooms.findOpenByVisitorTokenAndDepartmentId(visitorToken, departmentId, options).fetch() - : LivechatRooms.findOpenByVisitorToken(visitorToken, options).fetch(); - if (room && room.length > 0) { - info.room = room[0]; - } - - const visitor = LivechatVisitors.getVisitorByToken(visitorToken, { - fields: { - name: 1, - username: 1, - visitorEmails: 1, - department: 1, - }, - }); - - if (room) { - info.visitor = visitor; - } - - const initSettings = Livechat.getInitSettings(); - - info.title = initSettings.Livechat_title; - info.color = initSettings.Livechat_title_color; - info.enabled = initSettings.Livechat_enabled; - info.registrationForm = initSettings.Livechat_registration_form; - info.offlineTitle = initSettings.Livechat_offline_title; - info.offlineColor = initSettings.Livechat_offline_title_color; - info.offlineMessage = initSettings.Livechat_offline_message; - info.offlineSuccessMessage = initSettings.Livechat_offline_success_message; - info.offlineUnavailableMessage = initSettings.Livechat_offline_form_unavailable; - info.displayOfflineForm = initSettings.Livechat_display_offline_form; - info.language = initSettings.Language; - info.videoCall = initSettings.Omnichannel_call_provider === 'Jitsi' && initSettings.Jitsi_Enabled === true; - info.fileUpload = initSettings.Livechat_fileupload_enabled && initSettings.FileUpload_Enabled; - info.transcript = initSettings.Livechat_enable_transcript; - info.transcriptMessage = initSettings.Livechat_transcript_message; - info.conversationFinishedMessage = initSettings.Livechat_conversation_finished_message; - info.conversationFinishedText = initSettings.Livechat_conversation_finished_text; - info.nameFieldRegistrationForm = initSettings.Livechat_name_field_registration_form; - info.emailFieldRegistrationForm = initSettings.Livechat_email_field_registration_form; - info.registrationFormMessage = initSettings.Livechat_registration_form_message; - info.showConnecting = initSettings.Livechat_Show_Connecting; - - info.agentData = room && room[0] && room[0].servedBy && Users.getAgentInfo(room[0].servedBy._id); - - await LivechatTrigger.findEnabled().forEach((trigger) => { - info.triggers.push(_.pick(trigger, '_id', 'actions', 'conditions', 'runOnce')); - }); - - LivechatDepartment.findEnabledWithAgents().forEach((department) => { - info.departments.push(department); - }); - info.allowSwitchingDepartments = initSettings.Livechat_allow_switching_departments; - - info.online = Users.findOnlineAgents().count() > 0; - - return deprecationWarning({ - endpoint: 'livechat:getInitialData', - versionWillBeRemoved: '5.0', - response: info, - }); - }, -}); diff --git a/apps/meteor/app/livechat/server/methods/startFileUploadRoom.js b/apps/meteor/app/livechat/server/methods/startFileUploadRoom.js deleted file mode 100644 index f6a3691faeb1..000000000000 --- a/apps/meteor/app/livechat/server/methods/startFileUploadRoom.js +++ /dev/null @@ -1,29 +0,0 @@ -import { Meteor } from 'meteor/meteor'; -import { Random } from 'meteor/random'; -import { OmnichannelSourceType } from '@rocket.chat/core-typings'; - -import { LivechatVisitors } from '../../../models'; -import { Livechat } from '../lib/Livechat'; -import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger'; - -Meteor.methods({ - 'livechat:startFileUploadRoom'(roomId, token) { - methodDeprecationLogger.warn('livechat:startFileUploadRoom will be deprecated in future versions of Rocket.Chat'); - const guest = LivechatVisitors.getVisitorByToken(token); - - const message = { - _id: Random.id(), - rid: roomId || Random.id(), - msg: '', - ts: new Date(), - token: guest.token, - }; - - const roomInfo = { - source: OmnichannelSourceType.API, - alias: 'file-upload', - }; - - return Livechat.getRoom(guest, message, roomInfo); - }, -}); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts index 0e7d0f8fc423..f09ba78e8340 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts @@ -1,53 +1,7 @@ import { API } from '../../../../../app/api/server'; -import { deprecationWarning } from '../../../../../app/api/server/helpers/deprecationWarning'; import { findUnits, findUnitById, findUnitMonitors } from './lib/units'; import { LivechatEnterprise } from '../lib/LivechatEnterprise'; -API.v1.addRoute( - 'livechat/units.list', - { authRequired: true }, - { - async get() { - const { offset, count } = this.getPaginationItems(); - const { sort } = this.parseJsonQuery(); - const { text } = this.queryParams; - - const response = await findUnits({ - userId: this.userId, - text, - pagination: { - offset, - count, - sort, - }, - }); - - return API.v1.success(deprecationWarning({ response, endpoint: 'livechat/units.list' })); - }, - }, -); - -API.v1.addRoute( - 'livechat/units.getOne', - { authRequired: true }, - { - async get() { - const { unitId } = this.queryParams; - - if (!unitId) { - return API.v1.failure('Missing "unitId" query parameter'); - } - - const unit = await findUnitById({ - userId: this.userId, - unitId, - }); - - return API.v1.success(deprecationWarning({ response: unit, endpoint: 'livechat/units.getOne' })); - }, - }, -); - API.v1.addRoute( 'livechat/unitMonitors.list', { authRequired: true }, diff --git a/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx b/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx index af33ccc139d1..e4ea521a2d20 100644 --- a/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx +++ b/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx @@ -14,7 +14,7 @@ const UnitEditWithData: FC<{ }> = function UnitEditWithData({ unitId, reload, title }) { const query = useMemo(() => ({ unitId }), [unitId]); - const { value: data, phase: state, error } = useEndpointData('/v1/livechat/units.getOne', query); + const { value: data, phase: state, error } = useEndpointData(`/v1/livechat/units/${unitId}`); const { value: unitMonitors, diff --git a/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js b/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js index 5362af00f8f0..2001cf686a79 100644 --- a/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js +++ b/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js @@ -59,7 +59,7 @@ function UnitsRoute() { }), ); - const { value: data = {}, reload } = useEndpointData('/v1/livechat/units.list', query); + const { value: data = {}, reload } = useEndpointData('/v1/livechat/units', query); const header = useMemo( () => From c753a837bda9161b08d5a92acaefdc2a1adc6c07 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 10:23:33 -0600 Subject: [PATCH 02/15] Update departments endpoints to more rest format --- .../views/hooks/useDepartmentsByUnitsList.ts | 2 +- .../server/api/departments.js | 50 ------------------- .../livechat-enterprise/server/api/units.ts | 46 ++++++++++++++++- .../omnichannel/units/UnitEditWithData.tsx | 8 ++- .../rest/v1/omnichannel/businessUnits.ts | 2 +- packages/rest-typings/src/v1/omnichannel.ts | 13 +++-- 6 files changed, 59 insertions(+), 62 deletions(-) diff --git a/apps/meteor/client/views/hooks/useDepartmentsByUnitsList.ts b/apps/meteor/client/views/hooks/useDepartmentsByUnitsList.ts index 8a5d99b9f83e..282897f298fb 100644 --- a/apps/meteor/client/views/hooks/useDepartmentsByUnitsList.ts +++ b/apps/meteor/client/views/hooks/useDepartmentsByUnitsList.ts @@ -22,7 +22,7 @@ export const useDepartmentsByUnitsList = ( const [itemsList, setItemsList] = useState(() => new RecordList()); const reload = useCallback(() => setItemsList(new RecordList()), []); - const getDepartments = useEndpoint('GET', `/v1/livechat/departments.available-by-unit/${options.unitId || 'none'}`); + const getDepartments = useEndpoint('GET', `/v1/livechat/units/${options.unitId || 'none'}/departments/available`); useComponentDidUpdate(() => { options && reload(); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/departments.js b/apps/meteor/ee/app/livechat-enterprise/server/api/departments.js index 25f596288c05..09228006e48c 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/departments.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/departments.js @@ -12,7 +12,6 @@ import { findPercentageOfAbandonedRooms, findAllAverageOfChatDurationTime, } from '../../../../../app/livechat/server/lib/analytics/departments'; -import { findAllDepartmentsAvailable, findAllDepartmentsByUnit } from '../lib/Department'; API.v1.addRoute( 'livechat/analytics/departments/amount-of-chats', @@ -351,52 +350,3 @@ API.v1.addRoute( }, }, ); - -API.v1.addRoute( - 'livechat/departments.available-by-unit/:unitId', - { authRequired: true }, - { - get() { - check(this.urlParams, { - unitId: Match.Maybe(String), - }); - const { offset, count } = this.getPaginationItems(); - const { unitId } = this.urlParams; - const { text, onlyMyDepartments } = this.queryParams; - - const { departments, total } = Promise.await( - findAllDepartmentsAvailable(this.userId, unitId, offset, count, text, onlyMyDepartments === 'true'), - ); - - return API.v1.success({ - departments, - count: departments.length, - offset, - total, - }); - }, - }, -); - -API.v1.addRoute( - 'livechat/departments.by-unit/:id', - { authRequired: true }, - { - async get() { - check(this.urlParams, { - id: String, - }); - const { offset, count } = this.getPaginationItems(); - const { id } = this.urlParams; - - const { departments, total } = await findAllDepartmentsByUnit(id, offset, count); - - return API.v1.success({ - departments, - count: departments.length, - offset, - total, - }); - }, - }, -); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts index f09ba78e8340..a16882486749 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts @@ -1,9 +1,10 @@ import { API } from '../../../../../app/api/server'; import { findUnits, findUnitById, findUnitMonitors } from './lib/units'; import { LivechatEnterprise } from '../lib/LivechatEnterprise'; +import { findAllDepartmentsAvailable, findAllDepartmentsByUnit } from '../lib/Department'; API.v1.addRoute( - 'livechat/unitMonitors.list', + 'livechat/units/:unitId/monitors', { authRequired: true }, { async get() { @@ -76,3 +77,46 @@ API.v1.addRoute( }, }, ); + +API.v1.addRoute( + 'livechat/units/:unitId/departments', + { authRequired: true }, + { + async get() { + const { offset, count } = this.getPaginationItems(); + const { unitId } = this.urlParams; + + const { departments, total } = await findAllDepartmentsByUnit(unitId, offset, count); + + return API.v1.success({ + departments, + count: departments.length, + offset, + total, + }); + }, + }, +); + +API.v1.addRoute( + 'livechat/units/:unitId/departments/available', + { authRequired: true }, + { + get() { + const { offset, count } = this.getPaginationItems(); + const { unitId } = this.urlParams; + const { text, onlyMyDepartments } = this.queryParams; + + const { departments, total } = Promise.await( + findAllDepartmentsAvailable(this.userId, unitId, offset, count, text, onlyMyDepartments === 'true'), + ); + + return API.v1.success({ + departments, + count: departments.length, + offset, + total, + }); + }, + }, +); diff --git a/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx b/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx index e4ea521a2d20..c1e9b58ec8c8 100644 --- a/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx +++ b/apps/meteor/ee/client/omnichannel/units/UnitEditWithData.tsx @@ -1,6 +1,6 @@ import { Callout } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo, FC } from 'react'; +import React, { FC } from 'react'; import { FormSkeleton } from '../../../../client/components/Skeleton'; import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState'; @@ -12,21 +12,19 @@ const UnitEditWithData: FC<{ title: string; reload: () => void; }> = function UnitEditWithData({ unitId, reload, title }) { - const query = useMemo(() => ({ unitId }), [unitId]); - const { value: data, phase: state, error } = useEndpointData(`/v1/livechat/units/${unitId}`); const { value: unitMonitors, phase: unitMonitorsState, error: unitMonitorsError, - } = useEndpointData('/v1/livechat/unitMonitors.list', query); + } = useEndpointData(`/v1/livechat/units/${unitId}/monitors`); const { value: unitDepartments, phase: unitDepartmentsState, error: unitDepartmentsError, - } = useEndpointData(`/v1/livechat/departments.by-unit/${unitId}`); + } = useEndpointData(`/v1/livechat/units/${unitId}/departments`); const t = useTranslation(); diff --git a/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts b/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts index 5f01ca96b3e0..4b871ce476f1 100644 --- a/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts +++ b/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts @@ -12,7 +12,7 @@ declare module '@rocket.chat/rest-typings' { '/v1/livechat/units.getOne': { GET: (params: { unitId: string }) => IOmnichannelBusinessUnit; }; - '/v1/livechat/unitMonitors.list': { + '/v1/livechat/units/:unitId/monitors': { GET: (params: { unitId: string }) => { monitors: ILivechatMonitor[] }; }; '/v1/livechat/units': { diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index ff1a26f8e9b7..b932f0b27d51 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -382,7 +382,7 @@ const LivechatDepartmentSchema = { export const isLivechatDepartmentProps = ajv.compile(LivechatDepartmentSchema); -type LivechatDepartmentsAvailableByUnitIdProps = PaginatedRequest<{ text: string }>; +type LivechatDepartmentsAvailableByUnitIdProps = PaginatedRequest<{ text: string; onlyMyDepartments?: 'true' | 'false' }>; const LivechatDepartmentsAvailableByUnitIdSchema = { type: 'object', @@ -390,6 +390,11 @@ const LivechatDepartmentsAvailableByUnitIdSchema = { text: { type: 'string', }, + onlyMyDepartments: { + type: 'string', + enum: ['true', 'false'], + nullable: true, + }, count: { type: 'number', nullable: true, @@ -446,7 +451,7 @@ const LivechatDepartmentsByUnitSchema = { export const isLivechatDepartmentsByUnitProps = ajv.compile(LivechatDepartmentsByUnitSchema); -type LivechatDepartmentsByUnitIdProps = PaginatedRequest<{ text: string }>; +type LivechatDepartmentsByUnitIdProps = PaginatedRequest<{}>; const LivechatDepartmentsByUnitIdSchema = { type: 'object', @@ -842,7 +847,7 @@ export type OmnichannelEndpoints = { GET: (params: LivechatDepartmentDepartmentIdAgentsGET) => PaginatedResult<{ agents: ILivechatDepartmentAgents[] }>; POST: (params: LivechatDepartmentDepartmentIdAgentsPOST) => void; }; - '/v1/livechat/departments.available-by-unit/:id': { + '/v1/livechat/units/:unitId/departments/available': { GET: (params: LivechatDepartmentsAvailableByUnitIdProps) => PaginatedResult<{ departments: ILivechatDepartment[]; }>; @@ -853,7 +858,7 @@ export type OmnichannelEndpoints = { }>; }; - '/v1/livechat/departments.by-unit/:id': { + '/v1/livechat/units/:unitId/departments': { GET: (params: LivechatDepartmentsByUnitIdProps) => PaginatedResult<{ departments: ILivechatDepartment[]; }>; From 54f63e204d8b10eaaeaa5b2b8fb9e24f5506ce83 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 10:25:18 -0600 Subject: [PATCH 03/15] Update business hour endpoints --- .../ee/app/livechat-enterprise/server/api/business-hours.ts | 2 +- .../meteor/ee/client/omnichannel/BusinessHoursTableContainer.js | 2 +- apps/meteor/ee/definition/rest/v1/omnichannel/businessHours.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/business-hours.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/business-hours.ts index 8f024abe8041..507952e5162a 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/business-hours.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/business-hours.ts @@ -2,7 +2,7 @@ import { API } from '../../../../../app/api/server'; import { findBusinessHours } from '../business-hour/lib/business-hour'; API.v1.addRoute( - 'livechat/business-hours.list', + 'livechat/business-hours', { authRequired: true }, { async get() { diff --git a/apps/meteor/ee/client/omnichannel/BusinessHoursTableContainer.js b/apps/meteor/ee/client/omnichannel/BusinessHoursTableContainer.js index 601ebdd0ecd2..b0603a932c85 100644 --- a/apps/meteor/ee/client/omnichannel/BusinessHoursTableContainer.js +++ b/apps/meteor/ee/client/omnichannel/BusinessHoursTableContainer.js @@ -15,7 +15,7 @@ const BusinessHoursTableContainer = () => { phase: state, reload, } = useEndpointData( - '/v1/livechat/business-hours.list', + '/v1/livechat/business-hours', useMemo( () => ({ count: params.itemsPerPage, diff --git a/apps/meteor/ee/definition/rest/v1/omnichannel/businessHours.ts b/apps/meteor/ee/definition/rest/v1/omnichannel/businessHours.ts index 3eff58121555..4e3e09befe40 100644 --- a/apps/meteor/ee/definition/rest/v1/omnichannel/businessHours.ts +++ b/apps/meteor/ee/definition/rest/v1/omnichannel/businessHours.ts @@ -3,7 +3,7 @@ import type { ILivechatBusinessHour } from '@rocket.chat/core-typings'; declare module '@rocket.chat/rest-typings' { // eslint-disable-next-line @typescript-eslint/interface-name-prefix interface Endpoints { - '/v1/livechat/business-hours.list': { + '/v1/livechat/business-hours': { GET: (params: { name?: string; offset: number; count: number; sort: Record }) => { businessHours: ILivechatBusinessHour[]; count: number; From 45642fc4498e1e2739bdd1e40e083f643b1151a2 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 10:32:27 -0600 Subject: [PATCH 04/15] MRestify monitors --- .../client/views/hooks/useMonitorsList.ts | 2 +- .../server/api/{index.js => index.ts} | 0 .../server/api/{inquiries.js => inquiries.ts} | 14 +++---- .../server/api/{monitors.js => monitors.ts} | 40 +++++++++---------- .../omnichannel/monitors/MonitorsPage.js | 2 +- .../ee/client/omnichannel/units/UnitNew.js | 2 +- packages/rest-typings/src/v1/omnichannel.ts | 5 ++- 7 files changed, 31 insertions(+), 34 deletions(-) rename apps/meteor/ee/app/livechat-enterprise/server/api/{index.js => index.ts} (100%) rename apps/meteor/ee/app/livechat-enterprise/server/api/{inquiries.js => inquiries.ts} (74%) rename apps/meteor/ee/app/livechat-enterprise/server/api/{monitors.js => monitors.ts} (53%) diff --git a/apps/meteor/client/views/hooks/useMonitorsList.ts b/apps/meteor/client/views/hooks/useMonitorsList.ts index decfa3ee3c70..3bac71b62df2 100644 --- a/apps/meteor/client/views/hooks/useMonitorsList.ts +++ b/apps/meteor/client/views/hooks/useMonitorsList.ts @@ -21,7 +21,7 @@ export const useMonitorsList = ( const [itemsList, setItemsList] = useState(() => new RecordList()); const reload = useCallback(() => setItemsList(new RecordList()), []); - const getMonitors = useEndpoint('GET', '/v1/livechat/monitors.list'); + const getMonitors = useEndpoint('GET', '/v1/livechat/monitors'); useComponentDidUpdate(() => { options && reload(); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/index.js b/apps/meteor/ee/app/livechat-enterprise/server/api/index.ts similarity index 100% rename from apps/meteor/ee/app/livechat-enterprise/server/api/index.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/index.ts diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.js b/apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.ts similarity index 74% rename from apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.ts index e5d689a80e67..15adb00b8e2a 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/inquiries.ts @@ -5,18 +5,16 @@ API.v1.addRoute( 'livechat/inquiry.prioritize', { authRequired: true }, { - put() { + async put() { const { roomId, priority } = this.bodyParams; if (!roomId) { return API.v1.failure("The 'roomId' param is required"); } - Promise.await( - setPriorityToInquiry({ - userId: this.userId, - roomId, - priority, - }), - ); + await setPriorityToInquiry({ + userId: this.userId, + roomId, + priority, + }); return API.v1.success(); }, }, diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/monitors.js b/apps/meteor/ee/app/livechat-enterprise/server/api/monitors.ts similarity index 53% rename from apps/meteor/ee/app/livechat-enterprise/server/api/monitors.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/monitors.ts index 340d6ba925a7..3c28d32a7cf8 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/monitors.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/monitors.ts @@ -2,45 +2,41 @@ import { API } from '../../../../../app/api/server'; import { findMonitors, findMonitorByUsername } from './lib/monitors'; API.v1.addRoute( - 'livechat/monitors.list', + 'livechat/monitors', { authRequired: true }, { - get() { + async get() { const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); const { text } = this.queryParams; return API.v1.success( - Promise.await( - findMonitors({ - userId: this.userId, - text, - pagination: { - offset, - count, - sort, - }, - }), - ), + await findMonitors({ + userId: this.userId, + text, + pagination: { + offset, + count, + sort, + }, + }), ); }, }, ); API.v1.addRoute( - 'livechat/monitors.getOne', + 'livechat/monitors/:username', { authRequired: true }, { - get() { - const { username } = this.queryParams; + async get() { + const { username } = this.urlParams; return API.v1.success( - Promise.await( - findMonitorByUsername({ - userId: this.userId, - username, - }), - ), + await findMonitorByUsername({ + userId: this.userId, + username, + }), ); }, }, diff --git a/apps/meteor/ee/client/omnichannel/monitors/MonitorsPage.js b/apps/meteor/ee/client/omnichannel/monitors/MonitorsPage.js index d0bf1593fc1c..1be85c984ec9 100644 --- a/apps/meteor/ee/client/omnichannel/monitors/MonitorsPage.js +++ b/apps/meteor/ee/client/omnichannel/monitors/MonitorsPage.js @@ -30,7 +30,7 @@ const MonitorsPage = () => { const [sort, setSort] = useState(['name', 'asc']); const [username, setUsername] = useState(''); - const { value: data, phase: state, reload } = useEndpointData('/v1/livechat/monitors.list', useQuery(params, sort)); + const { value: data, phase: state, reload } = useEndpointData('/v1/livechat/monitors', useQuery(params, sort)); const addMonitor = useMethod('livechat:addMonitor'); diff --git a/apps/meteor/ee/client/omnichannel/units/UnitNew.js b/apps/meteor/ee/client/omnichannel/units/UnitNew.js index 1f93c587bb68..3bc99fa38ad6 100644 --- a/apps/meteor/ee/client/omnichannel/units/UnitNew.js +++ b/apps/meteor/ee/client/omnichannel/units/UnitNew.js @@ -19,7 +19,7 @@ function UnitNew({ reload, allUnits }) { value: availableMonitors, phase: availableMonitorsState, error: availableMonitorsError, - } = useEndpointData('/v1/livechat/monitors.list'); + } = useEndpointData('/v1/livechat/monitors'); if ([availableDepartmentsState, availableMonitorsState].includes(AsyncStatePhase.LOADING)) { return ; diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index b932f0b27d51..6b8332a732e9 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -808,11 +808,14 @@ export type OmnichannelEndpoints = { '/v1/livechat/room.join': { GET: (params: LiveChatRoomJoin) => { success: boolean }; }; - '/v1/livechat/monitors.list': { + '/v1/livechat/monitors': { GET: (params: LivechatMonitorsListProps) => PaginatedResult<{ monitors: ILivechatMonitor[]; }>; }; + '/v1/livechat/monitors/:username': { + GET: () => ILivechatMonitor; + }; '/v1/livechat/tags.list': { GET: (params: LivechatTagsListProps) => PaginatedResult<{ tags: ILivechatTag[]; From 0d991df81168f4af676bf31eb73a8d4297ccfda9 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 10:49:06 -0600 Subject: [PATCH 05/15] Restify priorities --- .../chats/contextualBar/PriorityField.js | 11 +---- .../directory/chats/contextualBar/RoomEdit.js | 2 +- .../visitorEditCustomFieldsForm.js | 2 +- .../customTemplates/visitorInfoCustomForm.js | 2 +- .../api/{priorities.js => priorities.ts} | 40 +++++++++---------- .../omnichannel/priorities/PrioritiesRoute.js | 2 +- .../core-typings/src/ILivechatPriority.ts | 7 ++++ packages/core-typings/src/index.ts | 1 + packages/rest-typings/src/v1/omnichannel.ts | 39 ++++++++++++++++++ 9 files changed, 71 insertions(+), 35 deletions(-) rename apps/meteor/ee/app/livechat-enterprise/server/api/{priorities.js => priorities.ts} (52%) create mode 100644 packages/core-typings/src/ILivechatPriority.ts diff --git a/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/PriorityField.js b/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/PriorityField.js index 66626c80715b..3e6506348a35 100644 --- a/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/PriorityField.js +++ b/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/PriorityField.js @@ -1,6 +1,6 @@ import { Box } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo } from 'react'; +import React from 'react'; import { useEndpointData } from '../../../../../hooks/useEndpointData'; import { AsyncStatePhase } from '../../../../../lib/asyncState'; @@ -11,14 +11,7 @@ import { FormSkeleton } from '../../Skeleton'; const PriorityField = ({ id }) => { const t = useTranslation(); - const { - value: data, - phase: state, - error, - } = useEndpointData( - '/v1/livechat/priorities.getOne', - useMemo(() => ({ priorityId: id }), [id]), - ); + const { value: data, phase: state, error } = useEndpointData(`/v1/livechat/priorities/${id}`); if (state === AsyncStatePhase.LOADING) { return ; } diff --git a/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/RoomEdit.js b/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/RoomEdit.js index 0f4a5578c4b3..75b566f3d4fa 100644 --- a/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/RoomEdit.js +++ b/apps/meteor/client/views/omnichannel/directory/chats/contextualBar/RoomEdit.js @@ -65,7 +65,7 @@ function RoomEdit({ room, visitor, reload, reloadInfo, close }) { const [customFieldsError, setCustomFieldsError] = useState([]); const { value: allCustomFields, phase: stateCustomFields } = useEndpointData('/v1/livechat/custom-fields'); - const { value: prioritiesResult = {}, phase: statePriorities } = useEndpointData('/v1/livechat/priorities.list'); + const { value: prioritiesResult = {}, phase: statePriorities } = useEndpointData('/v1/livechat/priorities'); const jsonConverterToValidFormat = (customFields) => { const jsonObj = {}; diff --git a/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorEditCustomFieldsForm.js b/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorEditCustomFieldsForm.js index 65b844dea979..2f1048b619a1 100644 --- a/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorEditCustomFieldsForm.js +++ b/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorEditCustomFieldsForm.js @@ -24,6 +24,6 @@ Template.visitorEditCustomFieldsForm.onCreated(async function () { if (priorityId) { this.roomPriority.set(priorityId); } - const { priorities } = await APIClient.get('/v1/livechat/priorities.list'); + const { priorities } = await APIClient.get('/v1/livechat/priorities'); this.priorities.set(priorities); }); diff --git a/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorInfoCustomForm.js b/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorInfoCustomForm.js index 20e02feaebbc..67f15789064f 100644 --- a/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorInfoCustomForm.js +++ b/apps/meteor/ee/app/livechat-enterprise/client/views/app/customTemplates/visitorInfoCustomForm.js @@ -20,7 +20,7 @@ Template.visitorInfoCustomForm.onCreated(function () { let priority; if (priorityId) { - priority = await APIClient.get('/v1/livechat/priorities.getOne', { priorityId }); + priority = await APIClient.get(`/v1/livechat/priorities/${priorityId}`); } this.priority.set(priority); diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.js b/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts similarity index 52% rename from apps/meteor/ee/app/livechat-enterprise/server/api/priorities.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts index 9c6792d15175..c4f4a35c9345 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts @@ -2,45 +2,41 @@ import { API } from '../../../../../app/api/server'; import { findPriorities, findPriorityById } from './lib/priorities'; API.v1.addRoute( - 'livechat/priorities.list', + 'livechat/priorities', { authRequired: true }, { - get() { + async get() { const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); const { text } = this.queryParams; return API.v1.success( - Promise.await( - findPriorities({ - userId: this.userId, - text, - pagination: { - offset, - count, - sort, - }, - }), - ), + await findPriorities({ + userId: this.userId, + text, + pagination: { + offset, + count, + sort, + }, + }), ); }, }, ); API.v1.addRoute( - 'livechat/priorities.getOne', + 'livechat/priorities/:priorityId', { authRequired: true }, { - get() { - const { priorityId } = this.queryParams; + async get() { + const { priorityId } = this.urlParams; return API.v1.success( - Promise.await( - findPriorityById({ - userId: this.userId, - priorityId, - }), - ), + await findPriorityById({ + userId: this.userId, + priorityId, + }), ); }, }, diff --git a/apps/meteor/ee/client/omnichannel/priorities/PrioritiesRoute.js b/apps/meteor/ee/client/omnichannel/priorities/PrioritiesRoute.js index 2d143cdfd3e6..7d1d4e4536ae 100644 --- a/apps/meteor/ee/client/omnichannel/priorities/PrioritiesRoute.js +++ b/apps/meteor/ee/client/omnichannel/priorities/PrioritiesRoute.js @@ -61,7 +61,7 @@ function PrioritiesRoute() { }), ); - const { value: data = {}, reload } = useEndpointData('/v1/livechat/priorities.list', query); + const { value: data = {}, reload } = useEndpointData('/v1/livechat/priorities', query); const header = useMemo( () => diff --git a/packages/core-typings/src/ILivechatPriority.ts b/packages/core-typings/src/ILivechatPriority.ts new file mode 100644 index 000000000000..3ef6bde7dee3 --- /dev/null +++ b/packages/core-typings/src/ILivechatPriority.ts @@ -0,0 +1,7 @@ +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface ILivechatPriority extends IRocketChatRecord { + name: string; + description: string; + dueTimeInMinutes: number; +} diff --git a/packages/core-typings/src/index.ts b/packages/core-typings/src/index.ts index 44045c4613d4..3412df8ffd70 100644 --- a/packages/core-typings/src/index.ts +++ b/packages/core-typings/src/index.ts @@ -105,5 +105,6 @@ export * from './IVoipServerConfig'; export * from './IVoipServerConnectivityStatus'; export * from './IOmnichannelVoipServiceResult'; export * from './IInquiry'; +export * from './ILivechatPriority'; export * from './IAutoTranslate'; diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index 6b8332a732e9..6ddd20957014 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -12,6 +12,7 @@ import type { IOmnichannelRoom, IRoom, ISetting, + ILivechatPriority, } from '@rocket.chat/core-typings'; import Ajv from 'ajv'; @@ -782,6 +783,38 @@ const LivechatUsersAgentSchema = { export const isLivechatUsersAgentProps = ajv.compile(LivechatUsersAgentSchema); +type LivechatPrioritiesProps = PaginatedRequest<{ text?: string }>; + +const LivechatPrioritiesPropsSchema = { + type: 'object', + properties: { + text: { + type: 'string', + nullable: true, + }, + count: { + type: 'number', + nullable: true, + }, + offset: { + type: 'number', + nullable: true, + }, + sort: { + type: 'string', + nullable: true, + }, + query: { + type: 'string', + nullable: true, + }, + }, + required: [], + additionalProperties: false, +}; + +export const isLivechatPrioritiesProps = ajv.compile(LivechatPrioritiesPropsSchema); + export type OmnichannelEndpoints = { '/v1/livechat/appearance': { GET: () => { @@ -986,4 +1019,10 @@ export type OmnichannelEndpoints = { '/v1/livechat/webrtc.call/:callId': { PUT: (params: { rid: string; status: 'ended' }) => void; }; + '/v1/livechat/priorities': { + GET: (params: LivechatPrioritiesProps) => PaginatedResult<{ priorities: ILivechatPriority[] }>; + }; + '/v1/livechat/priorities/:priorityId': { + GET: () => ILivechatPriority; + }; }; From 4f332896fb51c26151c85f7430535b5e512c9001 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 10:58:00 -0600 Subject: [PATCH 06/15] Restify tags endpoints --- .../client/components/Omnichannel/Tags.tsx | 2 +- .../server/api/{tags.js => tags.ts} | 40 +++++++++---------- apps/meteor/ee/client/hooks/useTagsList.ts | 2 +- .../omnichannel/tags/TagEditWithData.js | 5 +-- .../ee/client/omnichannel/tags/TagsRoute.js | 2 +- packages/rest-typings/src/v1/omnichannel.ts | 5 ++- 6 files changed, 27 insertions(+), 29 deletions(-) rename apps/meteor/ee/app/livechat-enterprise/server/api/{tags.js => tags.ts} (53%) diff --git a/apps/meteor/client/components/Omnichannel/Tags.tsx b/apps/meteor/client/components/Omnichannel/Tags.tsx index ad2d515f4373..fdbaee73396b 100644 --- a/apps/meteor/client/components/Omnichannel/Tags.tsx +++ b/apps/meteor/client/components/Omnichannel/Tags.tsx @@ -23,7 +23,7 @@ const Tags = ({ const t = useTranslation(); const forms = useSubscription(formsSubscription); - const { value: tagsResult, phase: stateTags } = useEndpointData('/v1/livechat/tags.list'); + const { value: tagsResult, phase: stateTags } = useEndpointData('/v1/livechat/tags'); // TODO: Refactor the formsSubscription to use components instead of hooks (since the only thing the hook does is return a component) const { useCurrentChatTags } = forms; diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/tags.js b/apps/meteor/ee/app/livechat-enterprise/server/api/tags.ts similarity index 53% rename from apps/meteor/ee/app/livechat-enterprise/server/api/tags.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/tags.ts index 9d385bb1acdf..472db95c9b5d 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/tags.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/tags.ts @@ -2,45 +2,41 @@ import { API } from '../../../../../app/api/server'; import { findTags, findTagById } from './lib/tags'; API.v1.addRoute( - 'livechat/tags.list', + 'livechat/tags', { authRequired: true }, { - get() { + async get() { const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); const { text } = this.queryParams; return API.v1.success( - Promise.await( - findTags({ - userId: this.userId, - text, - pagination: { - offset, - count, - sort, - }, - }), - ), + await findTags({ + userId: this.userId, + text, + pagination: { + offset, + count, + sort, + }, + }), ); }, }, ); API.v1.addRoute( - 'livechat/tags.getOne', + 'livechat/tags/:tagId', { authRequired: true }, { - get() { - const { tagId } = this.queryParams; + async get() { + const { tagId } = this.urlParams; return API.v1.success( - Promise.await( - findTagById({ - userId: this.userId, - tagId, - }), - ), + await findTagById({ + userId: this.userId, + tagId, + }), ); }, }, diff --git a/apps/meteor/ee/client/hooks/useTagsList.ts b/apps/meteor/ee/client/hooks/useTagsList.ts index 2e3452cb46da..5c887d28d713 100644 --- a/apps/meteor/ee/client/hooks/useTagsList.ts +++ b/apps/meteor/ee/client/hooks/useTagsList.ts @@ -21,7 +21,7 @@ export const useTagsList = ( const [itemsList, setItemsList] = useState(() => new RecordList()); const reload = useCallback(() => setItemsList(new RecordList()), []); - const getTags = useEndpoint('GET', '/v1/livechat/tags.list'); + const getTags = useEndpoint('GET', '/v1/livechat/tags'); useComponentDidUpdate(() => { options && reload(); diff --git a/apps/meteor/ee/client/omnichannel/tags/TagEditWithData.js b/apps/meteor/ee/client/omnichannel/tags/TagEditWithData.js index 5b53f7f20ed8..9e575230aa7c 100644 --- a/apps/meteor/ee/client/omnichannel/tags/TagEditWithData.js +++ b/apps/meteor/ee/client/omnichannel/tags/TagEditWithData.js @@ -1,6 +1,6 @@ import { Callout } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo } from 'react'; +import React from 'react'; import { FormSkeleton } from '../../../../client/components/Skeleton'; import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState'; @@ -9,8 +9,7 @@ import TagEdit from './TagEdit'; import TagEditWithDepartmentData from './TagEditWithDepartmentData'; function TagEditWithData({ tagId, reload, title }) { - const query = useMemo(() => ({ tagId }), [tagId]); - const { value: data, phase: state, error } = useEndpointData('/v1/livechat/tags.getOne', query); + const { value: data, phase: state, error } = useEndpointData(`/v1/livechat/tags/${tagId}`); const t = useTranslation(); diff --git a/apps/meteor/ee/client/omnichannel/tags/TagsRoute.js b/apps/meteor/ee/client/omnichannel/tags/TagsRoute.js index 80b8e8e06204..84edbcc511dc 100644 --- a/apps/meteor/ee/client/omnichannel/tags/TagsRoute.js +++ b/apps/meteor/ee/client/omnichannel/tags/TagsRoute.js @@ -59,7 +59,7 @@ function TagsRoute() { }), ); - const { value: data = {}, reload } = useEndpointData('/v1/livechat/tags.list', query); + const { value: data = {}, reload } = useEndpointData('/v1/livechat/tags', query); const header = useMemo( () => diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index 6ddd20957014..a7ed98a22f21 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -849,11 +849,14 @@ export type OmnichannelEndpoints = { '/v1/livechat/monitors/:username': { GET: () => ILivechatMonitor; }; - '/v1/livechat/tags.list': { + '/v1/livechat/tags': { GET: (params: LivechatTagsListProps) => PaginatedResult<{ tags: ILivechatTag[]; }>; }; + '/v1/livechat/tags/:tagId': { + GET: () => ILivechatTag; + }; '/v1/livechat/department': { GET: (params: LivechatDepartmentProps) => PaginatedResult<{ departments: ILivechatDepartment[]; From 899b95f3141d47487995607088cde9b8422296ce Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 15 Jun 2022 11:01:04 -0600 Subject: [PATCH 07/15] woops --- apps/meteor/app/livechat/server/api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/meteor/app/livechat/server/api.js b/apps/meteor/app/livechat/server/api.js index 9e2902ad30b3..55f2768a0941 100644 --- a/apps/meteor/app/livechat/server/api.js +++ b/apps/meteor/app/livechat/server/api.js @@ -13,5 +13,4 @@ import '../imports/server/rest/visitors.js'; import '../imports/server/rest/visitors.ts'; import '../imports/server/rest/dashboards.js'; import '../imports/server/rest/queue.js'; -import '../imports/server/rest/officeHour.js'; import '../imports/server/rest/businessHours.js'; From 86847d7e5536086eb82f771a56f13b001c9ef748 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 22 Jun 2022 08:06:54 -0600 Subject: [PATCH 08/15] Remove unused tests --- apps/meteor/.mocharc.api.js | 1 + .../livechat-enterprise/server/api/units.ts | 11 +++-- .../rest/v1/omnichannel/businessUnits.ts | 3 -- .../end-to-end/api/livechat/office-hour.js | 46 ------------------- 4 files changed, 9 insertions(+), 52 deletions(-) delete mode 100644 apps/meteor/tests/end-to-end/api/livechat/office-hour.js diff --git a/apps/meteor/.mocharc.api.js b/apps/meteor/.mocharc.api.js index c7994105d68a..1eb2aa7f348d 100644 --- a/apps/meteor/.mocharc.api.js +++ b/apps/meteor/.mocharc.api.js @@ -14,5 +14,6 @@ module.exports = { 'tests/end-to-end/api/*.js', 'tests/end-to-end/api/*.ts', 'tests/end-to-end/apps/*.js', + 'tests/end-to-end/api/livechat/*.js', ], }; diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts index a16882486749..524672620549 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts @@ -102,13 +102,18 @@ API.v1.addRoute( 'livechat/units/:unitId/departments/available', { authRequired: true }, { - get() { + async get() { const { offset, count } = this.getPaginationItems(); const { unitId } = this.urlParams; const { text, onlyMyDepartments } = this.queryParams; - const { departments, total } = Promise.await( - findAllDepartmentsAvailable(this.userId, unitId, offset, count, text, onlyMyDepartments === 'true'), + const { departments, total } = await findAllDepartmentsAvailable( + this.userId, + unitId, + offset, + count, + text, + onlyMyDepartments === 'true', ); return API.v1.success({ diff --git a/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts b/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts index 4b871ce476f1..88f38bc3e39e 100644 --- a/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts +++ b/apps/meteor/ee/definition/rest/v1/omnichannel/businessUnits.ts @@ -9,9 +9,6 @@ declare module '@rocket.chat/rest-typings' { units: IOmnichannelBusinessUnit[]; }; }; - '/v1/livechat/units.getOne': { - GET: (params: { unitId: string }) => IOmnichannelBusinessUnit; - }; '/v1/livechat/units/:unitId/monitors': { GET: (params: { unitId: string }) => { monitors: ILivechatMonitor[] }; }; diff --git a/apps/meteor/tests/end-to-end/api/livechat/office-hour.js b/apps/meteor/tests/end-to-end/api/livechat/office-hour.js deleted file mode 100644 index 22448b88d525..000000000000 --- a/apps/meteor/tests/end-to-end/api/livechat/office-hour.js +++ /dev/null @@ -1,46 +0,0 @@ -import { expect } from 'chai'; - -import { getCredentials, api, request, credentials } from '../../../data/api-data.js'; -import { updatePermission, updateSetting } from '../../../data/permissions.helper'; - -describe('LIVECHAT - office hours', function () { - this.retries(0); - - before((done) => getCredentials(done)); - - before((done) => { - updateSetting('Livechat_enabled', true).then(done); - }); - - describe('livechat/office-hours', () => { - it('should return an "unauthorized error" when the user does not have the necessary permission', (done) => { - updatePermission('view-livechat-business-hours', []).then(() => { - request - .get(api('livechat/office-hours')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(400) - .expect((res) => { - expect(res.body).to.have.property('success', false); - expect(res.body.error).to.be.equal('error-not-authorized'); - }) - .end(done); - }); - }); - it('should return an array of office hours', (done) => { - updatePermission('view-livechat-business-hours', ['admin']).then(() => { - request - .get(api('livechat/office-hours')) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('officeHours'); - expect(res.body.officeHours).to.be.an('array'); - }) - .end(done); - }); - }); - }); -}); From 403954fbe050acf94801eb0decd881cba425014a Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 22 Jun 2022 09:51:28 -0600 Subject: [PATCH 09/15] Fix permissions for livechat-department endpoint --- apps/meteor/app/livechat/imports/server/rest/departments.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/livechat/imports/server/rest/departments.ts b/apps/meteor/app/livechat/imports/server/rest/departments.ts index e501782744d4..472a00192635 100644 --- a/apps/meteor/app/livechat/imports/server/rest/departments.ts +++ b/apps/meteor/app/livechat/imports/server/rest/departments.ts @@ -2,7 +2,7 @@ import { isLivechatDepartmentProps } from '@rocket.chat/rest-typings'; import { Match, check } from 'meteor/check'; import { API } from '../../../../api/server'; -import { hasPermission } from '../../../../authorization/server'; +import { hasPermission, hasAtLeastOnePermission } from '../../../../authorization/server'; import { LivechatDepartment, LivechatDepartmentAgents } from '../../../../models/server'; import { Livechat } from '../../../server/lib/Livechat'; import { @@ -18,6 +18,10 @@ API.v1.addRoute( { authRequired: true, validateParams: isLivechatDepartmentProps }, { async get() { + if (!hasAtLeastOnePermission(this.userId, ['view-livechat-departments', 'view-l-room'])) { + return API.v1.unauthorized(); + } + const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); From d0c4fa0686f71572328a5795247b180859ebee75 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 22 Jun 2022 10:37:18 -0600 Subject: [PATCH 10/15] cant belive --- apps/meteor/tests/end-to-end/api/livechat/01-department.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/tests/end-to-end/api/livechat/01-department.js b/apps/meteor/tests/end-to-end/api/livechat/01-department.js index 84822885ec63..8ae6a4daf11e 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/01-department.js +++ b/apps/meteor/tests/end-to-end/api/livechat/01-department.js @@ -29,7 +29,7 @@ describe('LIVECHAT - departments', function () { .get(api('livechat/department')) .set(credentials) .expect('Content-Type', 'application/json') - .expect(400) + .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body.error).to.be.equal('error-not-authorized'); From a996183fdecb112f0a782bf68f3de3635f783ec4 Mon Sep 17 00:00:00 2001 From: Kevin Aleman Date: Wed, 22 Jun 2022 14:29:04 -0600 Subject: [PATCH 11/15] yet another test --- apps/meteor/app/livechat/imports/server/rest/departments.ts | 4 ++++ apps/meteor/tests/end-to-end/api/livechat/01-department.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/meteor/app/livechat/imports/server/rest/departments.ts b/apps/meteor/app/livechat/imports/server/rest/departments.ts index 472a00192635..ce0d9e83143e 100644 --- a/apps/meteor/app/livechat/imports/server/rest/departments.ts +++ b/apps/meteor/app/livechat/imports/server/rest/departments.ts @@ -80,6 +80,10 @@ API.v1.addRoute( { authRequired: true }, { async get() { + if (!hasAtLeastOnePermission(this.userId, ['view-livechat-departments', 'view-l-room'])) { + return API.v1.unauthorized(); + } + check(this.urlParams, { _id: String, }); diff --git a/apps/meteor/tests/end-to-end/api/livechat/01-department.js b/apps/meteor/tests/end-to-end/api/livechat/01-department.js index 8ae6a4daf11e..224a5016b937 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/01-department.js +++ b/apps/meteor/tests/end-to-end/api/livechat/01-department.js @@ -32,7 +32,7 @@ describe('LIVECHAT - departments', function () { .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); - expect(res.body.error).to.be.equal('error-not-authorized'); + expect(res.body.error).to.be.equal('unauthorized'); }) .end(done); }); @@ -90,7 +90,7 @@ describe('LIVECHAT - departments', function () { .get(api(`livechat/department/${department._id}`)) .set(credentials) .expect('Content-Type', 'application/json') - .expect(400) + .expect(403) .expect((res) => { expect(res.body).to.have.property('success', false); expect(res.body.error).to.be.equal('error-not-authorized'); From 0fe4a62854d8a2d8523aeeb1647b12124a23b6c8 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Fri, 24 Jun 2022 18:06:13 +0530 Subject: [PATCH 12/15] Update PriorityEditWithData to use new endpoint to retrieve priority data --- .../ee/client/omnichannel/priorities/PriorityEditWithData.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/meteor/ee/client/omnichannel/priorities/PriorityEditWithData.js b/apps/meteor/ee/client/omnichannel/priorities/PriorityEditWithData.js index c1303c4d5caa..9362d516e5bb 100644 --- a/apps/meteor/ee/client/omnichannel/priorities/PriorityEditWithData.js +++ b/apps/meteor/ee/client/omnichannel/priorities/PriorityEditWithData.js @@ -1,6 +1,6 @@ import { Callout } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo } from 'react'; +import React from 'react'; import { FormSkeleton } from '../../../../client/components/Skeleton'; import { AsyncStatePhase } from '../../../../client/hooks/useAsyncState'; @@ -8,8 +8,7 @@ import { useEndpointData } from '../../../../client/hooks/useEndpointData'; import PriorityEdit from './PriorityEdit'; function PriorityEditWithData({ priorityId, reload }) { - const query = useMemo(() => ({ priorityId }), [priorityId]); - const { value: data, phase: state, error } = useEndpointData('/v1/livechat/priorities.getOne', query); + const { value: data, phase: state, error } = useEndpointData(`/v1/livechat/priorities/${priorityId}`); const t = useTranslation(); From d9d1a164ee32aa33f58d718c26ac56d0bd833be3 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Fri, 24 Jun 2022 18:26:20 +0530 Subject: [PATCH 13/15] go back to ignoring livechat test cases :( We'll fix that seperately --- apps/meteor/.mocharc.api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/meteor/.mocharc.api.js b/apps/meteor/.mocharc.api.js index 1eb2aa7f348d..c7994105d68a 100644 --- a/apps/meteor/.mocharc.api.js +++ b/apps/meteor/.mocharc.api.js @@ -14,6 +14,5 @@ module.exports = { 'tests/end-to-end/api/*.js', 'tests/end-to-end/api/*.ts', 'tests/end-to-end/apps/*.js', - 'tests/end-to-end/api/livechat/*.js', ], }; From 8987ee7c8cd1f5840455ac46de6bdc9ec1b3e36b Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Tue, 28 Jun 2022 17:49:32 +0530 Subject: [PATCH 14/15] Fix issues raised by QA More info: https://app.clickup.com/t/2jzcz2u?comment=1039489919 --- .../ee/app/api-enterprise/server/lib/canned-responses.js | 3 ++- .../app/livechat-enterprise/server/api/lib/priorities.js | 2 +- .../ee/app/livechat-enterprise/server/api/units.ts | 2 +- apps/meteor/ee/client/omnichannel/units/UnitsRoute.js | 9 +++++++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/meteor/ee/app/api-enterprise/server/lib/canned-responses.js b/apps/meteor/ee/app/api-enterprise/server/lib/canned-responses.js index 622e0896bc07..758ca394b47a 100644 --- a/apps/meteor/ee/app/api-enterprise/server/lib/canned-responses.js +++ b/apps/meteor/ee/app/api-enterprise/server/lib/canned-responses.js @@ -1,7 +1,8 @@ import { escapeRegExp } from '@rocket.chat/string-helpers'; -import { LivechatDepartmentAgents, CannedResponse, LivechatUnit } from '@rocket.chat/models'; +import { LivechatDepartmentAgents, CannedResponse } from '@rocket.chat/models'; import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission'; +import LivechatUnit from '../../../models/server/models/LivechatUnit'; export async function findAllCannedResponses({ userId }) { if (!(await hasPermissionAsync(userId, 'view-canned-responses'))) { diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js index 5d14e24c356e..c263269e3159 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js @@ -1,5 +1,5 @@ import { escapeRegExp } from '@rocket.chat/string-helpers'; -import LivechatPriority from '@rocket.chat/models'; +import { LivechatPriority } from '@rocket.chat/models'; import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission'; diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts index 524672620549..930b6f554ad1 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/units.ts @@ -8,7 +8,7 @@ API.v1.addRoute( { authRequired: true }, { async get() { - const { unitId } = this.queryParams; + const { unitId } = this.urlParams; if (!unitId) { return API.v1.failure('The "unitId" parameter is required'); diff --git a/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js b/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js index 2001cf686a79..7fcfb57b4ee4 100644 --- a/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js +++ b/apps/meteor/ee/client/omnichannel/units/UnitsRoute.js @@ -7,6 +7,7 @@ import GenericTable from '../../../../client/components/GenericTable'; import { useEndpointData } from '../../../../client/hooks/useEndpointData'; import NotAuthorizedPage from '../../../../client/views/notAuthorized/NotAuthorizedPage'; import RemoveUnitButton from './RemoveUnitButton'; +import UnitEdit from './UnitEdit'; import UnitEditWithData from './UnitEditWithData'; import UnitsPage from './UnitsPage'; @@ -94,8 +95,12 @@ function UnitsRoute() { [reload, onRowClick], ); - if (context === 'edit' || context === 'new') { - return ; + if (context === 'edit') { + return ; + } + + if (context === 'new') { + return ; } if (!canViewUnits) { From 43489a0c68559f6dec44b32881554ac0a02bde76 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Tue, 28 Jun 2022 18:21:54 +0530 Subject: [PATCH 15/15] Fix build and convert priorities helper file to typescript --- .../api/lib/{priorities.js => priorities.ts} | 39 ++++++++++++++++--- .../server/api/priorities.ts | 16 +++++--- .../ee/server/models/raw/LivechatPriority.ts | 4 +- .../src/models/ILivechatPriorityModel.ts | 4 +- 4 files changed, 48 insertions(+), 15 deletions(-) rename apps/meteor/ee/app/livechat-enterprise/server/api/lib/{priorities.js => priorities.ts} (50%) diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.ts similarity index 50% rename from apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js rename to apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.ts index c263269e3159..c376a3f0ff6a 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.js +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/lib/priorities.ts @@ -1,16 +1,45 @@ import { escapeRegExp } from '@rocket.chat/string-helpers'; import { LivechatPriority } from '@rocket.chat/models'; +import { ILivechatPriority } from '@rocket.chat/core-typings'; import { hasPermissionAsync } from '../../../../../../app/authorization/server/functions/hasPermission'; -export async function findPriorities({ userId, text, pagination: { offset, count, sort } }) { +type FindPrioritiesParams = { + userId: string; + text?: string; + pagination: { + offset: number; + count: number; + sort: object; + }; +}; + +type FindPrioritiesResult = { + priorities: ILivechatPriority[]; + count: number; + offset: number; + total: number; +}; + +type FindPrioritiesByIdParams = { + userId: string; + priorityId: string; +}; + +type FindPrioritiesByIdResult = ILivechatPriority | null; + +export async function findPriorities({ + userId, + text, + pagination: { offset, count, sort }, +}: FindPrioritiesParams): Promise { if (!(await hasPermissionAsync(userId, 'manage-livechat-priorities')) && !(await hasPermissionAsync(userId, 'view-l-room'))) { throw new Error('error-not-authorized'); } - const filterReg = new RegExp(escapeRegExp(text), 'i'); - - const query = { ...(text && { $or: [{ name: filterReg }, { description: filterReg }] }) }; + const query = { + ...(text && { $or: [{ name: new RegExp(escapeRegExp(text), 'i') }, { description: new RegExp(escapeRegExp(text), 'i') }] }), + }; const cursor = LivechatPriority.find(query, { sort: sort || { name: 1 }, @@ -30,7 +59,7 @@ export async function findPriorities({ userId, text, pagination: { offset, count }; } -export async function findPriorityById({ userId, priorityId }) { +export async function findPriorityById({ userId, priorityId }: FindPrioritiesByIdParams): Promise { if (!(await hasPermissionAsync(userId, 'manage-livechat-priorities')) && !(await hasPermissionAsync(userId, 'view-l-room'))) { throw new Error('error-not-authorized'); } diff --git a/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts b/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts index c4f4a35c9345..dce9f005856f 100644 --- a/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts +++ b/apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts @@ -32,12 +32,16 @@ API.v1.addRoute( async get() { const { priorityId } = this.urlParams; - return API.v1.success( - await findPriorityById({ - userId: this.userId, - priorityId, - }), - ); + const priority = await findPriorityById({ + userId: this.userId, + priorityId, + }); + + if (!priority) { + return API.v1.notFound(`Priority with id ${priorityId} not found`); + } + + return API.v1.success(priority); }, }, ); diff --git a/apps/meteor/ee/server/models/raw/LivechatPriority.ts b/apps/meteor/ee/server/models/raw/LivechatPriority.ts index 2a85d7fa3873..60bcc3aaee85 100644 --- a/apps/meteor/ee/server/models/raw/LivechatPriority.ts +++ b/apps/meteor/ee/server/models/raw/LivechatPriority.ts @@ -1,4 +1,4 @@ -import type { IRocketChatRecord } from '@rocket.chat/core-typings'; +import type { ILivechatPriority } from '@rocket.chat/core-typings'; import type { ILivechatPriorityModel } from '@rocket.chat/model-typings'; import type { Db } from 'mongodb'; import { getCollectionName } from '@rocket.chat/models'; @@ -6,7 +6,7 @@ import { getCollectionName } from '@rocket.chat/models'; import { BaseRaw } from '../../../../server/models/raw/BaseRaw'; // TODO need to define type for LivechatPriority object -export class LivechatPriorityRaw extends BaseRaw implements ILivechatPriorityModel { +export class LivechatPriorityRaw extends BaseRaw implements ILivechatPriorityModel { constructor(db: Db) { super(db, getCollectionName('livechat_priority')); } diff --git a/packages/model-typings/src/models/ILivechatPriorityModel.ts b/packages/model-typings/src/models/ILivechatPriorityModel.ts index 1ece4ef9b247..2439a92a2bbd 100644 --- a/packages/model-typings/src/models/ILivechatPriorityModel.ts +++ b/packages/model-typings/src/models/ILivechatPriorityModel.ts @@ -1,7 +1,7 @@ -import type { IRocketChatRecord } from '@rocket.chat/core-typings'; +import type { ILivechatPriority } from '@rocket.chat/core-typings'; import type { IBaseModel } from './IBaseModel'; -export interface ILivechatPriorityModel extends IBaseModel { +export interface ILivechatPriorityModel extends IBaseModel { findOneByIdOrName(_idOrName: string, options?: any): any; }