Skip to content

Commit c5ee569

Browse files
chore: Adds deprecation warning and serves new chart data endpoint (RocketChat#36845)
Co-authored-by: Guilherme Gazzo <5263975+ggazzo@users.noreply.github.com>
1 parent 7787147 commit c5ee569

6 files changed

Lines changed: 164 additions & 7 deletions

File tree

.changeset/fresh-deers-march.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@rocket.chat/meteor": patch
3+
"@rocket.chat/rest-typings": patch
4+
---
5+
6+
Adds deprecation warning to `livechat:getAnalyticsChartData`, as well as it adds a new endpoint to replace it; `livechat/analytics/dashboards/charts-data`

apps/meteor/app/livechat/imports/server/rest/dashboards.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1+
import { OmnichannelAnalytics } from '@rocket.chat/core-services';
12
import { Users } from '@rocket.chat/models';
2-
import { isGETDashboardTotalizerParams, isGETDashboardsAgentStatusParams } from '@rocket.chat/rest-typings';
3+
import {
4+
isGETDashboardTotalizerParams,
5+
isGETDashboardsAgentStatusParams,
6+
isGETLivechatAnalyticsDashboardsChartDataParams,
7+
validateUnauthorizedErrorResponse,
8+
validateForbiddenErrorResponse,
9+
GETLivechatAnalyticsDashboardsChartDataSuccessSchema,
10+
} from '@rocket.chat/rest-typings';
311

412
import { API } from '../../../../api/server';
13+
import type { ExtractRoutesFromAPI } from '../../../../api/server/ApiClass';
514
import {
615
getProductivityMetricsAsyncCached,
716
getConversationsMetricsAsyncCached,
@@ -238,3 +247,50 @@ API.v1.addRoute(
238247
},
239248
},
240249
);
250+
251+
const livechatAnalyticsEndpoints = API.v1.get(
252+
'livechat/analytics/dashboards/charts-data',
253+
{
254+
response: {
255+
200: GETLivechatAnalyticsDashboardsChartDataSuccessSchema,
256+
401: validateUnauthorizedErrorResponse,
257+
403: validateForbiddenErrorResponse,
258+
},
259+
authRequired: true,
260+
permissionsRequired: ['view-livechat-manager'],
261+
query: isGETLivechatAnalyticsDashboardsChartDataParams,
262+
},
263+
async function action() {
264+
const { chartName, start, end, departmentId } = this.queryParams;
265+
266+
const chartData = await OmnichannelAnalytics.getAnalyticsChartData({
267+
daterange: {
268+
from: start,
269+
to: end,
270+
},
271+
chartOptions: {
272+
name: chartName,
273+
},
274+
utcOffset: this.user.utcOffset,
275+
executedBy: this.user._id,
276+
departmentId,
277+
});
278+
279+
if (!chartData) {
280+
return API.v1.success({
281+
chartLabel: chartName,
282+
dataLabels: [],
283+
dataPoints: [],
284+
});
285+
}
286+
287+
return API.v1.success(chartData);
288+
},
289+
);
290+
291+
type LivechatAnalyticsEndpoints = ExtractRoutesFromAPI<typeof livechatAnalyticsEndpoints>;
292+
293+
declare module '@rocket.chat/rest-typings' {
294+
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
295+
interface Endpoints extends LivechatAnalyticsEndpoints {}
296+
}

apps/meteor/app/livechat/server/methods/getAnalyticsChartData.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Users } from '@rocket.chat/models';
55
import { Meteor } from 'meteor/meteor';
66

77
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
8+
import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
89

910
declare module '@rocket.chat/ddp-client' {
1011
// eslint-disable-next-line @typescript-eslint/naming-convention
@@ -15,6 +16,7 @@ declare module '@rocket.chat/ddp-client' {
1516

1617
Meteor.methods<ServerMethods>({
1718
async 'livechat:getAnalyticsChartData'(options) {
19+
methodDeprecationLogger.method('livechat:getAnalyticsChartData', '8.0.0', '/v1/livechat/analytics/dashboards/charts-data');
1820
const userId = Meteor.userId();
1921
if (!userId || !(await hasPermissionAsync(userId, 'view-livechat-manager'))) {
2022
throw new Meteor.Error('error-not-allowed', 'Not allowed', {

apps/meteor/client/views/omnichannel/analytics/InterchangeableChart.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffectEvent } from '@rocket.chat/fuselage-hooks';
2-
import { useToastMessageDispatch, useMethod } from '@rocket.chat/ui-contexts';
2+
import { useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts';
33
import type * as chartjs from 'chart.js';
4-
import { useRef, useEffect } from 'react';
4+
import { useEffect, useRef } from 'react';
55
import { useTranslation } from 'react-i18next';
66

77
import { drawLineChart } from '../../../../app/livechat/client/lib/chartHandler';
@@ -55,7 +55,7 @@ const InterchangeableChart = ({
5555

5656
const { start, end } = dateRange;
5757

58-
const loadData = useMethod('livechat:getAnalyticsChartData');
58+
const loadData = useEndpoint('GET', '/v1/livechat/analytics/dashboards/charts-data');
5959

6060
const draw = useEffectEvent(
6161
async (params: {
@@ -66,15 +66,23 @@ const InterchangeableChart = ({
6666
chartOptions: {
6767
name: string;
6868
};
69+
departmentId?: string;
6970
}) => {
7071
try {
7172
const tooltipCallbacks = getChartTooltips(chartName);
7273
if (!params?.daterange?.from || !params?.daterange?.to) {
7374
return;
7475
}
75-
const result = await loadData(params);
76-
if (!result?.chartLabel || !result?.dataLabels || !result?.dataPoints) {
77-
throw new Error('Error! fetching chart data. Details: livechat:getAnalyticsChartData => Missing Data');
76+
77+
const result = await loadData({
78+
chartName,
79+
start,
80+
end,
81+
...(departmentId && { departmentId }),
82+
});
83+
84+
if (!result?.dataLabels || !result?.dataPoints) {
85+
throw new Error('Error! fetching chart data.');
7886
}
7987
(context.current || typeof context.current === 'undefined') &&
8088
canvas.current &&

apps/meteor/tests/end-to-end/api/livechat/04-dashboards.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,28 @@ describe('LIVECHAT - dashboards', function () {
714714
});
715715
});
716716

717+
describe('livechat/analytics/dashboards/charts-data', () => {
718+
it('should return the correct data structure for the charts', async () => {
719+
const yesterday = moment().subtract(1, 'days').format('YYYY-MM-DD');
720+
const today = moment().startOf('day').format('YYYY-MM-DD');
721+
722+
const result = await request
723+
.get(api('livechat/analytics/dashboards/charts-data'))
724+
.query({ chartName: 'Total_conversations', start: yesterday, end: today })
725+
.set(credentials)
726+
.expect('Content-Type', 'application/json')
727+
.expect(200);
728+
729+
expect(result.body).to.have.property('success', true);
730+
731+
expect(result.body).to.have.property('chartLabel', 'Total_conversations');
732+
expect(result.body).to.have.property('dataLabels').to.be.an('array');
733+
expect(result.body).to.have.property('dataPoints').to.be.an('array');
734+
});
735+
736+
// it('should return the correct data structure but empty for unavailable data');
737+
});
738+
717739
describe('livechat/analytics/agent-overview', () => {
718740
it('should return an "unauthorized error" when the user does not have the necessary permission', async () => {
719741
await removePermissionFromAllRoles('view-livechat-manager');

packages/rest-typings/src/v1/omnichannel.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3438,6 +3438,69 @@ export const isGETDashboardsAgentStatusParams = ajv.compile<GETDashboardsAgentSt
34383438
GETLivechatAnalyticsDashboardsAgentStatusParamsSchema,
34393439
);
34403440

3441+
type GETLivechatAnalyticsDashboardsChartDataParams = {
3442+
chartName: string;
3443+
start: string;
3444+
end: string;
3445+
departmentId?: string;
3446+
};
3447+
3448+
const GETLivechatAnalyticsDashboardsChartDataParamsSchema = {
3449+
type: 'object',
3450+
properties: {
3451+
chartName: {
3452+
type: 'string',
3453+
},
3454+
start: {
3455+
type: 'string',
3456+
},
3457+
end: {
3458+
type: 'string',
3459+
},
3460+
departmentId: {
3461+
type: 'string',
3462+
},
3463+
},
3464+
additionalProperties: false,
3465+
required: ['chartName', 'start', 'end'],
3466+
};
3467+
3468+
export const isGETLivechatAnalyticsDashboardsChartDataParams = ajv.compile<GETLivechatAnalyticsDashboardsChartDataParams>(
3469+
GETLivechatAnalyticsDashboardsChartDataParamsSchema,
3470+
);
3471+
3472+
const GETLivechatAnalyticsDashboardsChartDataSuccess = {
3473+
type: 'object',
3474+
properties: {
3475+
chartLabel: {
3476+
type: 'string',
3477+
},
3478+
dataLabels: {
3479+
type: 'array',
3480+
items: {
3481+
type: 'string',
3482+
},
3483+
},
3484+
dataPoints: {
3485+
type: 'array',
3486+
items: {
3487+
type: 'number',
3488+
},
3489+
},
3490+
success: {
3491+
type: 'boolean',
3492+
enum: [true],
3493+
},
3494+
},
3495+
additionalProperties: false,
3496+
};
3497+
3498+
export const GETLivechatAnalyticsDashboardsChartDataSuccessSchema = ajv.compile<{
3499+
chartLabel: string;
3500+
dataLabels: string[];
3501+
dataPoints: number[];
3502+
}>(GETLivechatAnalyticsDashboardsChartDataSuccess);
3503+
34413504
type PUTLivechatPriority = { name: string } | { reset: boolean };
34423505
const PUTLivechatPrioritySchema = {
34433506
oneOf: [

0 commit comments

Comments
 (0)