Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remaining realtime charts to TS #33111

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
10 changes: 5 additions & 5 deletions apps/meteor/app/livechat/client/lib/chartHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type LineChartConfigOptions = Partial<{
anim: boolean;
displayColors: boolean;
tooltipCallbacks: any;
smallTicks: boolean;
}>;

const lineChartConfiguration = ({
Expand Down Expand Up @@ -108,7 +109,7 @@ const doughnutChartConfiguration = (

type ChartDataSet = {
label: string;
data: number;
data: number[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this type change expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was wrong before, but since the files that consumed this type were all in js, no error was raised

backgroundColor: string;
borderColor: string;
borderWidth: number;
Expand All @@ -128,12 +129,11 @@ export const drawLineChart = async (
chartContext: { destroy: () => void } | undefined,
chartLabels: string[],
dataLabels: string[],
dataSets: number[],
dataSets: number[][],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it was wrong before, but since the files that consumed this type were all in js, no error was raised

options: LineChartConfigOptions = {},
): Promise<ChartType<'line', number, string> | void> => {
): Promise<ChartType> => {
if (!chart) {
console.error('No chart element');
return;
throw new Error('No chart element');
}
if (chartContext) {
chartContext.destroy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const InterchangeableChart = ({
const dispatchToastMessage = useToastMessageDispatch();

const canvas = useRef<HTMLCanvasElement | null>(null);
const context = useRef<ChartType<'line', number, string> | void>();
const context = useRef<ChartType>();

const { start, end } = dateRange;

Expand All @@ -73,7 +73,7 @@ const InterchangeableChart = ({
context.current,
[result.chartLabel],
result.dataLabels,
[result.dataPoints as unknown as number], // TODO fix this
[result.dataPoints],
{
tooltipCallbacks,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { SelectOption } from '@rocket.chat/fuselage';
import { Box, Select, Margins, Option } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { MutableRefObject } from 'react';
import React, { useRef, useState, useMemo, useEffect, Fragment } from 'react';

import AutoCompleteDepartment from '../../../components/AutoCompleteDepartment';
Expand All @@ -18,7 +20,7 @@ import ChatsOverview from './overviews/ChatsOverview';
import ConversationOverview from './overviews/ConversationOverview';
import ProductivityOverview from './overviews/ProductivityOverview';

const randomizeKeys = (keys) => {
const randomizeKeys = (keys: MutableRefObject<string[]>) => {
keys.current = keys.current.map((_key, i) => {
return `${i}_${new Date().getTime()}`;
});
Expand All @@ -29,12 +31,12 @@ const dateRange = getDateRange();
const RealTimeMonitoringPage = () => {
const t = useTranslation();

const keys = useRef([...Array(10).keys()]);
const keys = useRef<string[]>([...Array(10).map((_, i) => `${i}_${new Date().getTime()}`)]);

const [reloadFrequency, setReloadFrequency] = useState(5);
const [reloadFrequency, setReloadFrequency] = useState<string>('5');
const [departmentId, setDepartment] = useState('');

const reloadRef = useRef({});
const reloadRef = useRef<{ [x: string]: () => void }>({});

const departmentParams = useMemo(
() => ({
Expand Down Expand Up @@ -62,20 +64,22 @@ const RealTimeMonitoringPage = () => {
});

useEffect(() => {
const interval = setInterval(reloadCharts, reloadFrequency * 1000);
const interval = setInterval(reloadCharts, Number(reloadFrequency) * 1000);
return () => {
clearInterval(interval);
randomizeKeys(keys);
};
}, [reloadCharts, reloadFrequency]);

// TODO Check if Select Options does indeed accepts Elements as labels
const reloadOptions = useMemo(
() => [
[5, <Fragment key='5 seconds'>5 {t('seconds')}</Fragment>],
[10, <Fragment key='10 seconds'>10 {t('seconds')}</Fragment>],
[30, <Fragment key='30 seconds'>30 {t('seconds')}</Fragment>],
[60, <Fragment key='1 minute'>1 {t('minute')}</Fragment>],
],
() =>
[
['5', <Fragment key='5 seconds'>5 {t('seconds')}</Fragment>],
['10', <Fragment key='10 seconds'>10 {t('seconds')}</Fragment>],
['30', <Fragment key='30 seconds'>30 {t('seconds')}</Fragment>],
['60', <Fragment key='1 minute'>1 {t('minute')}</Fragment>],
] as unknown as SelectOption[],
[t],
);

Expand All @@ -99,11 +103,15 @@ const RealTimeMonitoringPage = () => {
</Box>
<Box maxWidth='50%' display='flex' mi={4} flexGrow={1} flexDirection='column'>
<Label mb={4}>{t('Update_every')}</Label>
<Select options={reloadOptions} onChange={useMutableCallback((val) => setReloadFrequency(val))} value={reloadFrequency} />
<Select
options={reloadOptions}
onChange={useMutableCallback((val) => setReloadFrequency(val as string))}
value={reloadFrequency}
/>
</Box>
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<ConversationOverview key={keys?.current[0]} flexGrow={1} flexShrink={1} width='50%' reloadRef={reloadRef} params={allParams} />
<ConversationOverview key={keys?.current[0]} reloadRef={reloadRef} params={allParams} />
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<ChatsChart key={keys?.current[1]} flexGrow={1} flexShrink={1} width='50%' mie={2} reloadRef={reloadRef} params={allParams} />
Expand All @@ -118,7 +126,7 @@ const RealTimeMonitoringPage = () => {
/>
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<ChatsOverview key={keys?.current[3]} flexGrow={1} flexShrink={1} width='50%' reloadRef={reloadRef} params={allParams} />
<ChatsOverview key={keys?.current[3]} reloadRef={reloadRef} params={allParams} />
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<AgentStatusChart
Expand All @@ -141,16 +149,16 @@ const RealTimeMonitoringPage = () => {
/>
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<AgentsOverview key={keys?.current[6]} flexGrow={1} flexShrink={1} reloadRef={reloadRef} params={allParams} />
<AgentsOverview key={keys?.current[6]} reloadRef={reloadRef} params={allParams} />
</Box>
<Box display='flex' w='full' flexShrink={1}>
<ChatDurationChart key={keys?.current[7]} flexGrow={1} flexShrink={1} w='100%' reloadRef={reloadRef} params={allParams} />
<ChatDurationChart key={keys?.current[7]} reloadRef={reloadRef} params={allParams} />
</Box>
<Box display='flex' flexDirection='row' w='full' alignItems='stretch' flexShrink={1}>
<ProductivityOverview key={keys?.current[8]} flexGrow={1} flexShrink={1} reloadRef={reloadRef} params={allParams} />
<ProductivityOverview key={keys?.current[8]} reloadRef={reloadRef} params={allParams} />
</Box>
<Box display='flex' w='full' flexShrink={1}>
<ResponseTimesChart key={keys?.current[9]} flexGrow={1} flexShrink={1} w='100%' reloadRef={reloadRef} params={allParams} />
<ResponseTimesChart key={keys?.current[9]} reloadRef={reloadRef} params={allParams} />
</Box>
</Margins>
</PageScrollableContentWithShadow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Box } from '@rocket.chat/fuselage';
import type { OperationParams } from '@rocket.chat/rest-typings';
import type { TranslationContextValue, TranslationKey } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { Chart as ChartType } from 'chart.js';
import type { MutableRefObject } from 'react';
import type { ComponentProps, MutableRefObject } from 'react';
import React, { useRef, useEffect } from 'react';

import { drawDoughnutChart } from '../../../../../app/livechat/client/lib/chartHandler';
Expand Down Expand Up @@ -32,7 +33,7 @@ const init = (canvas: HTMLCanvasElement, context: ChartType | undefined, t: Tran
type AgentStatusChartsProps = {
params: OperationParams<'GET', '/v1/livechat/analytics/dashboards/charts/agents-status'>;
reloadRef: MutableRefObject<{ [x: string]: () => void }>;
};
} & ComponentProps<typeof Box>;

const AgentStatusChart = ({ params, reloadRef, ...props }: AgentStatusChartsProps) => {
const t = useTranslation();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Box } from '@rocket.chat/fuselage';
import type { MutableRefObject } from 'react';
import type { ComponentProps, MutableRefObject } from 'react';
import React from 'react';

type ChartProps = { canvasRef: MutableRefObject<HTMLCanvasElement | null> };

type ChartProps = { canvasRef: MutableRefObject<HTMLCanvasElement | null> } & ComponentProps<typeof Box>;
const style = {
minHeight: '250px',
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import type { Box } from '@rocket.chat/fuselage';
import type { OperationParams } from '@rocket.chat/rest-typings';
import type { TranslationContextValue } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { Chart as ChartType } from 'chart.js';
import type { ComponentProps, MutableRefObject } from 'react';
import React, { useRef, useEffect } from 'react';

import { drawLineChart } from '../../../../../app/livechat/client/lib/chartHandler';
Expand All @@ -13,17 +18,17 @@ import { useUpdateChartData } from './useUpdateChartData';
const [labels, initialData] = getMomentChartLabelsAndData();
const tooltipCallbacks = {
callbacks: {
title([ctx]) {
title([ctx]: { dataset: { label: string } }[]) {
const { dataset } = ctx;
return dataset.label;
},
label(ctx) {
label(ctx: { dataset: { label: string; data: string[] }; dataIndex: number }) {
const { dataset, dataIndex } = ctx;
return `${dataset.label}: ${secondsToHHMMSS(dataset.data[dataIndex])}`;
},
},
};
const init = (canvas, context, t) =>
const init = (canvas: HTMLCanvasElement, context: ChartType | undefined, t: TranslationContextValue['translate']) =>
drawLineChart(canvas, context, [t('Avg_chat_duration'), t('Longest_chat_duration')], labels, [initialData, initialData.slice()], {
legends: true,
anim: true,
Expand All @@ -32,11 +37,16 @@ const init = (canvas, context, t) =>
tooltipCallbacks,
});

const ChatDurationChart = ({ params, reloadRef, ...props }) => {
type ChatDurationChartProps = {
params: OperationParams<'GET', '/v1/livechat/analytics/dashboards/charts/timings'>;
reloadRef: MutableRefObject<{ [x: string]: () => void }>;
} & ComponentProps<typeof Box>;

const ChatDurationChart = ({ params, reloadRef, ...props }: ChatDurationChartProps) => {
const t = useTranslation();

const canvas = useRef();
const context = useRef();
const canvas: MutableRefObject<HTMLCanvasElement | null> = useRef(null);
const context: MutableRefObject<ChartType | undefined> = useRef();

const updateChartData = useUpdateChartData({
context,
Expand All @@ -60,7 +70,9 @@ const ChatDurationChart = ({ params, reloadRef, ...props }) => {

useEffect(() => {
const initChart = async () => {
context.current = await init(canvas.current, context.current, t);
if (canvas?.current) {
context.current = await init(canvas.current, context.current, t);
}
};
initChart();
}, [t]);
Expand All @@ -72,7 +84,7 @@ const ChatDurationChart = ({ params, reloadRef, ...props }) => {
}
}, [avg, longest, state, t, updateChartData]);

return <Chart canvasRef={canvas} {...props} />;
return <Chart canvasRef={canvas} flexGrow={1} flexShrink={1} w='100%' {...props} />;
};

export default ChatDurationChart;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { Box } from '@rocket.chat/fuselage';
import type { OperationParams } from '@rocket.chat/rest-typings';
import type { TranslationContextValue, TranslationKey } from '@rocket.chat/ui-contexts';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { Chart as ChartType } from 'chart.js';
import type { MutableRefObject } from 'react';
import type { ComponentProps, MutableRefObject } from 'react';
import React, { useRef, useEffect } from 'react';

import { drawDoughnutChart } from '../../../../../app/livechat/client/lib/chartHandler';
Expand Down Expand Up @@ -32,7 +33,7 @@ const init = (canvas: HTMLCanvasElement, context: ChartType | undefined, t: Tran
type ChatsChartProps = {
params: OperationParams<'GET', '/v1/livechat/analytics/dashboards/charts/chats'>;
reloadRef: MutableRefObject<{ [x: string]: () => void }>;
};
} & ComponentProps<typeof Box>;

const ChatsChart = ({ params, reloadRef, ...props }: ChatsChartProps) => {
const t = useTranslation();
Expand Down

This file was deleted.

Loading
Loading