diff --git a/client/views/omnichannel/analytics/AgentOverview.js b/client/views/omnichannel/analytics/AgentOverview.js index 30d88d1d77e17..210d0b0f7f51a 100644 --- a/client/views/omnichannel/analytics/AgentOverview.js +++ b/client/views/omnichannel/analytics/AgentOverview.js @@ -1,8 +1,8 @@ -import React, { useMemo } from 'react'; +import React, { useMemo, useEffect, useState } from 'react'; import { Table } from '@rocket.chat/fuselage'; import { useTranslation } from '../../../contexts/TranslationContext'; -import { useMethodData } from '../../../hooks/useMethodData'; +import { useMethod } from '../../../contexts/ServerContext'; const style = { width: '100%' }; @@ -10,22 +10,35 @@ const AgentOverview = ({ type, dateRange, departmentId }) => { const t = useTranslation(); const { start, end } = dateRange; - const params = useMemo(() => [{ + const params = useMemo(() => ({ chartOptions: { name: type }, daterange: { from: start, to: end }, ...departmentId && { departmentId }, - }], [departmentId, end, start, type]); + }), [departmentId, end, start, type]); - const { value: displayData } = useMethodData('livechat:getAgentOverviewData', params); + const [displayData, setDisplayData] = useState({ head: [], data: [] }); + + const loadData = useMethod('livechat:getAgentOverviewData'); + + useEffect(() => { + async function fetchData() { + if (!start || !end) { + return; + } + const value = await loadData(params); + setDisplayData(value); + } + fetchData(); + }, [start, end, loadData, params]); return - {displayData?.head?.map(({ name }, i) => { t(name) })} + {displayData.head?.map(({ name }, i) => { t(name) })} - {displayData?.data?.map(({ name, value }, i) => + {displayData.data?.map(({ name, value }, i) => {name} {value} )} diff --git a/client/views/omnichannel/analytics/AnalyticsPage.js b/client/views/omnichannel/analytics/AnalyticsPage.js index b68ade11709e0..c5669bcb522b4 100644 --- a/client/views/omnichannel/analytics/AnalyticsPage.js +++ b/client/views/omnichannel/analytics/AnalyticsPage.js @@ -1,5 +1,5 @@ import React, { useMemo, useState, useEffect } from 'react'; -import { Box, Select, Margins, Field } from '@rocket.chat/fuselage'; +import { Box, Select, Margins, Field, Label } from '@rocket.chat/fuselage'; import DepartmentAutoComplete from '../DepartmentAutoComplete'; import DateRangePicker from './DateRangePicker'; @@ -50,26 +50,16 @@ const AnalyticsPage = () => { - - - - - {t('Type')} - - - + + + + + diff --git a/client/views/omnichannel/analytics/DateRangePicker.js b/client/views/omnichannel/analytics/DateRangePicker.js index 33cdf4f118e13..512eb050adda4 100644 --- a/client/views/omnichannel/analytics/DateRangePicker.js +++ b/client/views/omnichannel/analytics/DateRangePicker.js @@ -1,42 +1,23 @@ import React, { useState, useMemo, useEffect } from 'react'; -import { Box, InputBox, Menu, Margins, Field } from '@rocket.chat/fuselage'; +import { Box, InputBox, Menu, Field } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; +import moment from 'moment'; import { useTranslation } from '../../../contexts/TranslationContext'; -const date = new Date(); +const formatToDateInput = (date) => date.format('YYYY-MM-DD'); -const formatToDateInput = (date) => date.toISOString().slice(0, 10); +const todayDate = formatToDateInput(moment()); -const todayDate = formatToDateInput(date); +const getMonthRange = (monthsToSubtractFromToday) => ({ + start: formatToDateInput(moment().subtract(monthsToSubtractFromToday, 'month').date(1)), + end: formatToDateInput(monthsToSubtractFromToday === 0 ? moment() : moment().subtract(monthsToSubtractFromToday).date(0)), +}); -const getMonthRange = (monthsToSubtractFromToday) => { - const date = new Date(); - return { - start: formatToDateInput(new Date( - date.getFullYear(), - date.getMonth() - monthsToSubtractFromToday, - 1)), - end: formatToDateInput(new Date( - date.getFullYear(), - date.getMonth() - monthsToSubtractFromToday + 1, - 0)), - }; -}; - -const getWeekRange = (daysToSubtractFromStart, daysToSubtractFromEnd) => { - const date = new Date(); - return { - start: formatToDateInput(new Date( - date.getFullYear(), - date.getMonth(), - date.getDate() - daysToSubtractFromStart)), - end: formatToDateInput(new Date( - date.getFullYear(), - date.getMonth(), - date.getDate() - daysToSubtractFromEnd)), - }; -}; +const getWeekRange = (daysToSubtractFromStart, daysToSubtractFromEnd) => ({ + start: formatToDateInput(moment().subtract(daysToSubtractFromStart, 'day')), + end: formatToDateInput(moment().subtract(daysToSubtractFromEnd, 'day')), +}); const DateRangePicker = ({ onChange = () => {}, ...props }) => { const t = useTranslation(); @@ -110,22 +91,20 @@ const DateRangePicker = ({ onChange = () => {}, ...props }) => { }, }), [handleRange, t]); - return - - - {t('Start')} - - - - - - {t('End')} - - - - - - + return + + {t('Start')} + + + + + + {t('End')} + + + + + ; }; diff --git a/client/views/omnichannel/analytics/InterchangeableChart.js b/client/views/omnichannel/analytics/InterchangeableChart.js index d29c323ccbffc..1b5bfad12e475 100644 --- a/client/views/omnichannel/analytics/InterchangeableChart.js +++ b/client/views/omnichannel/analytics/InterchangeableChart.js @@ -24,9 +24,12 @@ const InterchangeableChart = ({ departmentId, dateRange, chartName, ...props }) const draw = useMutableCallback(async (params) => { try { + if (!params?.daterange?.from || !params?.daterange?.to) { + return; + } const result = await loadData(params); - if (!(result && result.chartLabel && result.dataLabels && result.dataPoints)) { - return console.log('livechat:getAnalyticsChartData => Missing Data'); + if (!result?.chartLabel || !result?.dataLabels || !result?.dataPoints) { + throw new Error('Error! fetching chart data. Details: livechat:getAnalyticsChartData => Missing Data'); } context.current = await drawLineChart(canvas.current, context.current, [result.chartLabel], result.dataLabels, [result.dataPoints]); } catch (error) { @@ -43,7 +46,7 @@ const InterchangeableChart = ({ departmentId, dateRange, chartName, ...props }) chartOptions: { name: chartName }, ...departmentId && { departmentId }, }); - }, [chartName, departmentId, draw, end, start, t]); + }, [chartName, departmentId, draw, end, start, t, loadData]); return ; }; diff --git a/client/views/omnichannel/analytics/Overview.js b/client/views/omnichannel/analytics/Overview.js index 2e151192089df..2195c855368bc 100644 --- a/client/views/omnichannel/analytics/Overview.js +++ b/client/views/omnichannel/analytics/Overview.js @@ -4,8 +4,7 @@ import { Box, Skeleton } from '@rocket.chat/fuselage'; import CounterItem from '../realTimeMonitoring/counter/CounterItem'; import CounterRow from '../realTimeMonitoring/counter/CounterRow'; import { useTranslation } from '../../../contexts/TranslationContext'; -import { useMethodData } from '../../../hooks/useMethodData'; -import { AsyncStatePhase } from '../../../hooks/useAsyncState'; +import { useMethod } from '../../../contexts/ServerContext'; const initialData = Array.from({ length: 3 }).map(() => ({ title: '', value: '' })); @@ -17,13 +16,13 @@ const Overview = ({ type, dateRange, departmentId }) => { const { start, end } = dateRange; - const params = useMemo(() => [{ + const params = useMemo(() => ({ analyticsOptions: { name: type }, daterange: { from: start, to: end }, ...departmentId && { departmentId }, - }], [departmentId, end, start, type]); + }), [departmentId, end, start, type]); - const { phase, value } = useMethodData('livechat:getAnalyticsOverviewData', params); + const loadData = useMethod('livechat:getAnalyticsOverviewData'); const [displayData, setDisplayData] = useState(conversationsInitialData); @@ -32,14 +31,24 @@ const Overview = ({ type, dateRange, departmentId }) => { }, [type]); useEffect(() => { - if (phase === AsyncStatePhase.RESOLVED) { - if (value?.length > 3) { - setDisplayData([value.slice(0, 3), value.slice(3)]); - } else if (value) { - setDisplayData([value]); + async function fetchData() { + if (!start || !end) { + return; } + + const value = await loadData(params); + if (!value) { + return; + } + + if (value.length > 3) { + return setDisplayData([value.slice(0, 3), value.slice(3)]); + } + + setDisplayData([value]); } - }, [value, phase]); + fetchData(); + }, [start, end, loadData, params]); return