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
5 changes: 5 additions & 0 deletions .changeset/cool-yaks-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Adds deprecation warning for `livechat:saveUnit`
30 changes: 24 additions & 6 deletions apps/meteor/client/omnichannel/units/UnitEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type { ILivechatDepartment, ILivechatUnitMonitor, Serialized, IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';
import type {
ILivechatDepartment,
ILivechatUnitMonitor,
Serialized,
IOmnichannelBusinessUnit,
OmnichannelBusinessUnitPayload,
} from '@rocket.chat/core-typings';
import type { SelectOption } from '@rocket.chat/fuselage';
import { FieldError, Field, TextInput, Button, Select, ButtonGroup, FieldGroup, Box, FieldLabel, FieldRow } from '@rocket.chat/fuselage';
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts';
import { useToastMessageDispatch, useTranslation, useEndpoint } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import { useId, useMemo } from 'react';
import { useForm, Controller } from 'react-hook-form';
Expand Down Expand Up @@ -34,13 +40,14 @@ type UnitEditProps = {
unitData?: Serialized<IOmnichannelBusinessUnit>;
unitMonitors?: Serialized<ILivechatUnitMonitor>[];
unitDepartments?: Serialized<ILivechatDepartment>[];
onClose: () => void;
onUpdate?: (params: OmnichannelBusinessUnitPayload) => void;
onDelete?: () => void;
onClose: () => void;
};

const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onClose, onDelete }: UnitEditProps) => {
const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onUpdate, onDelete, onClose }: UnitEditProps) => {
const t = useTranslation();
const saveUnit = useMethod('livechat:saveUnit');
const saveUnit = useEndpoint('POST', '/v1/livechat/units');
const dispatchToastMessage = useToastMessageDispatch();
const queryClient = useQueryClient();

Expand Down Expand Up @@ -94,8 +101,19 @@ const UnitEdit = ({ unitData, unitMonitors, unitDepartments, onClose, onDelete }
username: monitor.label,
}));

const payload = {
unitData: { name, visibility },
unitMonitors: monitorsData,
unitDepartments: departmentsData,
};

try {
await saveUnit(_id as unknown as string, { name, visibility }, monitorsData, departmentsData);
if (_id && onUpdate) {
await onUpdate(payload);
} else {
await saveUnit(payload);
}

dispatchToastMessage({ type: 'success', message: t('Saved') });
queryClient.invalidateQueries({
queryKey: ['livechat-units'],
Expand Down
4 changes: 3 additions & 1 deletion apps/meteor/client/omnichannel/units/UnitEditWithData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const UnitEditWithData = ({ unitId, onClose }: { unitId: IOmnichannelBusinessUni
const getUnitById = useEndpoint('GET', '/v1/livechat/units/:id', { id: unitId });
const getMonitorsByUnitId = useEndpoint('GET', '/v1/livechat/units/:unitId/monitors', { unitId });
const getDepartmentsByUnitId = useEndpoint('GET', '/v1/livechat/units/:unitId/departments', { unitId });
const editUnit = useEndpoint('POST', '/v1/livechat/units/:id', { id: unitId });
const removeUnit = useRemoveUnit(unitId);

const {
Expand Down Expand Up @@ -61,8 +62,9 @@ const UnitEditWithData = ({ unitId, onClose }: { unitId: IOmnichannelBusinessUni
unitData={unitData}
unitMonitors={unitMonitors?.monitors}
unitDepartments={unitDepartments?.departments}
onClose={onClose}
onUpdate={editUnit}
onDelete={removeUnit}
onClose={onClose}
/>
);
};
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/ee/app/livechat-enterprise/server/api/units.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ILivechatUnitMonitor, IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';
import type { ILivechatUnitMonitor, IOmnichannelBusinessUnit, OmnichannelBusinessUnitPayload } from '@rocket.chat/core-typings';
import type { PaginatedResult, PaginatedRequest } from '@rocket.chat/rest-typings';

import { API } from '../../../../../app/api/server';
Expand All @@ -16,11 +16,11 @@ declare module '@rocket.chat/rest-typings' {
};
'/v1/livechat/units': {
GET: (params: PaginatedRequest<{ text?: string }>) => PaginatedResult & { units: IOmnichannelBusinessUnit[] };
POST: (params: { unitData: string; unitMonitors: string; unitDepartments: string }) => Omit<IOmnichannelBusinessUnit, '_updatedAt'>;
POST: (params: OmnichannelBusinessUnitPayload) => Omit<IOmnichannelBusinessUnit, '_updatedAt'>;
};
'/v1/livechat/units/:id': {
GET: () => IOmnichannelBusinessUnit;
POST: (params: { unitData: string; unitMonitors: string; unitDepartments: string }) => Omit<IOmnichannelBusinessUnit, '_updatedAt'>;
POST: (params: OmnichannelBusinessUnitPayload) => Omit<IOmnichannelBusinessUnit, '_updatedAt'>;
DELETE: () => number;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ServerMethods } from '@rocket.chat/ddp-client';
import { Meteor } from 'meteor/meteor';

import { hasPermissionAsync } from '../../../../../app/authorization/server/functions/hasPermission';
import { methodDeprecationLogger } from '../../../../../app/lib/server/lib/deprecationWarningLogger';
import { LivechatEnterprise } from '../lib/LivechatEnterprise';

declare module '@rocket.chat/ddp-client' {
Expand All @@ -14,6 +15,7 @@ declare module '@rocket.chat/ddp-client' {

Meteor.methods<ServerMethods>({
async 'livechat:saveUnit'(_id, unitData, unitMonitors, unitDepartments) {
methodDeprecationLogger.method('livechat:saveUnit', '8.0.0', '/v1/livechat/units');
const uid = Meteor.userId();
if (!uid || !(await hasPermissionAsync(uid, 'manage-livechat-units'))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'livechat:saveUnit' });
Expand Down
26 changes: 9 additions & 17 deletions apps/meteor/tests/data/livechat/units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,21 @@ export const createUnit = async (
): Promise<IOmnichannelBusinessUnit> => {
return new Promise((resolve, reject) => {
void request
.post(methodCall(`livechat:saveUnit`))
.post(api('livechat/units'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'livechat:saveUnit',
params: [
null,
{
name: name || `${faker.person.firstName()} ${faker.string.uuid()}`,
visibility: faker.helpers.arrayElement(['public', 'private']),
},
[{ monitorId, username }, ...extraMonitor],
departmentIds.map((departmentId) => ({ departmentId })),
],
id: '101',
msg: 'method',
}),
unitData: {
name: name || `${faker.person.firstName()} ${faker.string.uuid()}`,
visibility: faker.helpers.arrayElement(['public', 'private']),
},
unitMonitors: [{ monitorId, username }, ...extraMonitor],
unitDepartments: departmentIds.map((departmentId) => ({ departmentId })),
})
.end((err: Error, res: DummyResponse<string, 'wrapped'>) => {
.end((err: Error, res: DummyResponse<IOmnichannelBusinessUnit, 'not-wrapped'>) => {
if (err) {
return reject(err);
}
resolve(JSON.parse(res.body.message).result);
resolve(res.body);
});
});
};
Expand Down
30 changes: 17 additions & 13 deletions apps/meteor/tests/e2e/utils/omnichannel/units.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { faker } from '@faker-js/faker';
import type { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';

import { parseMeteorResponse } from '../parseMeteorResponse';
import type { BaseTest } from '../test';

type CreateUnitParams = {
Expand All @@ -21,21 +19,27 @@ export const createOrUpdateUnit = async (
api: BaseTest['api'],
{ id = null, name, visibility, monitors, departments }: CreateUnitParams = {},
) => {
const response = await api.post('/method.call/livechat:saveUnit', {
message: JSON.stringify({
msg: 'method',
id: '34',
method: 'livechat:saveUnit',
params: [id, { name: name || faker.string.uuid(), visibility: visibility || 'public' }, monitors, departments],
}),
});
const unitPayload = {
unitData: {
name: name ?? faker.string.uuid(),
visibility: visibility ?? 'public',
},
unitMonitors: monitors,
unitDepartments: departments,
};

const response = id ? await api.post(`/livechat/units/${id}`, unitPayload) : await api.post('/livechat/units', unitPayload);

if (response.status() !== 200) {
throw new Error(`Failed to create or update unit [http status: ${response.status()}]`);
}

const unit = await parseMeteorResponse<IOmnichannelBusinessUnit>(response);
const data = await response.json();

return {
response,
data: unit,
delete: async () => removeUnit(api, unit?._id),
data,
delete: async () => removeUnit(api, data?._id),
};
};

Expand Down
13 changes: 13 additions & 0 deletions packages/core-typings/src/IOmnichannelBusinessUnit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,16 @@ export interface IOmnichannelBusinessUnit extends IRocketChatRecord {
// Units don't have ancestors per se, but we need TS to know it can access the property from the collection
ancestors?: string[];
}

export type OmnichannelBusinessUnitPayload = {
unitData: {
name: string;
visibility: string;
enabled?: boolean;
description?: string;
email?: string;
showOnOfflineForm?: boolean;
};
unitMonitors: { monitorId: string; username: string }[];
unitDepartments: { departmentId: string }[];
};
Loading