Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
6 changes: 6 additions & 0 deletions .changeset/shaggy-clocks-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": patch
"@rocket.chat/rest-typings": patch
---

Adds deprecation warning on `livechat:removeTag` with new endpoint replacing it; `livechat/tags.remove`
7 changes: 4 additions & 3 deletions apps/meteor/client/omnichannel/tags/useRemoveTag.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
import { GenericModal } from '@rocket.chat/ui-client';
import { useSetModal, useToastMessageDispatch, useRouter, useMethod } from '@rocket.chat/ui-contexts';
import { useSetModal, useToastMessageDispatch, useRouter, useEndpoint } from '@rocket.chat/ui-contexts';
import { useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';

export const useRemoveTag = () => {
const { t } = useTranslation();
const setModal = useSetModal();
const dispatchToastMessage = useToastMessageDispatch();
const removeTag = useMethod('livechat:removeTag');
// const removeTag = useMethod('livechat:removeTag');
Comment thread
lucas-a-pelegrino marked this conversation as resolved.
Outdated
const removeTag = useEndpoint('POST', '/v1/livechat/tags.remove');
const queryClient = useQueryClient();
const router = useRouter();

const handleDeleteTag = useEffectEvent((tagId: string) => {
const handleDelete = async () => {
try {
await removeTag(tagId);
await removeTag({ id: tagId });
dispatchToastMessage({ type: 'success', message: t('Tag_removed') });
router.navigate('/omnichannel/tags');
queryClient.invalidateQueries({
Expand Down
48 changes: 48 additions & 0 deletions apps/meteor/ee/app/livechat-enterprise/server/api/tags.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { findTags, findTagById } from './lib/tags';
import { API } from '../../../../../app/api/server';
import type { ExtractRoutesFromAPI } from '../../../../../app/api/server/ApiClass';
import { getPaginationItems } from '../../../../../app/api/server/helpers/getPaginationItems';

import {

Check failure on line 6 in apps/meteor/ee/app/livechat-enterprise/server/api/tags.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

`@rocket.chat/rest-typings` import should occur before import of `./lib/tags`
isPOSTLivechatTagsRemoveParams,
POSTLivechatTagsRemoveSuccessResponse,
validateBadRequestErrorResponse,
validateForbiddenErrorResponse,
validateUnauthorizedErrorResponse,
} from '@rocket.chat/rest-typings';

import { LivechatEnterprise } from '../lib/LivechatEnterprise';

API.v1.addRoute(
'livechat/tags',
{
Expand Down Expand Up @@ -56,3 +67,40 @@
},
},
);

const livechatTagsEndpoints = API.v1.post(
'livechat/tags.remove',
{
response: {
200: POSTLivechatTagsRemoveSuccessResponse,
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
403: validateForbiddenErrorResponse,
},
authRequired: true,
permissions: ['manage-livechat-tags'],
license: ['livechat-enterprise'],
body: isPOSTLivechatTagsRemoveParams,
},
async function action() {
const { id } = this.bodyParams;
try {
await LivechatEnterprise.removeTag(id);

return API.v1.success();
} catch (error: unknown) {
if (error instanceof Meteor.Error) {
return API.v1.failure(error.reason);
}

return API.v1.failure('error-removing-tag');
Comment thread
lucas-a-pelegrino marked this conversation as resolved.
}
Comment thread
lucas-a-pelegrino marked this conversation as resolved.
},
);
Comment thread
lucas-a-pelegrino marked this conversation as resolved.

type LivechatTagsEndpoints = ExtractRoutesFromAPI<typeof livechatTagsEndpoints>;

declare module '@rocket.chat/rest-typings' {
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
interface Endpoints extends LivechatTagsEndpoints {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { check } from 'meteor/check';
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:removeTag'(id) {
methodDeprecationLogger.method('livechat:removeTag', '8.0.0', '/v1/livechat/tags.remove');
const uid = Meteor.userId();
if (!uid || !(await hasPermissionAsync(uid, 'manage-livechat-tags'))) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'livechat:removeTag' });
Expand Down
5 changes: 1 addition & 4 deletions apps/meteor/tests/e2e/utils/omnichannel/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ type CreateTagParams = {
departments?: { departmentId: string }[];
};

const removeTag = async (api: BaseTest['api'], id: string) =>
api.post('/method.call/omnichannel:removeTag', {
message: JSON.stringify({ msg: 'method', id: '33', method: 'livechat:removeTag', params: [id] }),
});
const removeTag = async (api: BaseTest['api'], id: string) => api.post('/livechat/tags.remove', { id });

export const createTag = async (api: BaseTest['api'], { id = null, name, description = '', departments = [] }: CreateTagParams = {}) => {
const response = await api.post('/method.call/livechat:saveTag', {
Expand Down
30 changes: 30 additions & 0 deletions packages/rest-typings/src/v1/omnichannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,36 @@ const LivechatMonitorsListSchema = {

export const isLivechatMonitorsListProps = ajv.compile<LivechatMonitorsListProps>(LivechatMonitorsListSchema);

type POSTLivechatTagsRemoveParams = {
id: string;
};

const POSTLivechatTagsRemoveSchema = {
type: 'object',
properties: {
id: {
type: 'string',
},
},
required: ['id'],
additionalProperties: false,
};

export const isPOSTLivechatTagsRemoveParams = ajv.compile<POSTLivechatTagsRemoveParams>(POSTLivechatTagsRemoveSchema);

const POSTLivechatTagsRemoveSuccessResponseSchema = {
type: 'object',
properties: {
success: {
type: 'boolean',
enum: [true],
},
},
additionalProperties: false,
};

export const POSTLivechatTagsRemoveSuccessResponse = ajv.compile<void>(POSTLivechatTagsRemoveSuccessResponseSchema);

type LivechatTagsListProps = PaginatedRequest<{ text: string; viewAll?: 'true' | 'false'; department?: string }, 'name'>;

const LivechatTagsListSchema = {
Expand Down
Loading