Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
234ddb0
[FIX] Omnichannel Analytics Page
murtaza98 Dec 18, 2020
415e87e
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
murtaza98 Dec 18, 2020
d2b906f
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
murtaza98 Dec 19, 2020
8c3be85
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Dec 21, 2020
f12e9de
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
murtaza98 Dec 22, 2020
63f4b13
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Jan 11, 2021
71cadd3
Fix error logs appearing on server
murtaza98 Jan 12, 2021
2ab8d9f
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Jan 12, 2021
3c25031
Change layout for filter inputs
murtaza98 Jan 13, 2021
77e0bb7
Merge branch 'omnichannel/fix-analytics-page-layout-1' of https://git…
murtaza98 Jan 13, 2021
bc7c962
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Jan 13, 2021
88d9442
Apply suggestions from code review
murtaza98 Jan 13, 2021
7f394e5
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Jan 13, 2021
d6a25f3
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
renatobecker Jan 14, 2021
48bb99b
Merge branch 'develop' into omnichannel/fix-analytics-page-layout-1
murtaza98 Jan 14, 2021
ede0834
Apply suggestion from code review
murtaza98 Jan 14, 2021
6c23115
Apply suggestions from code review
murtaza98 Jan 14, 2021
9d6056a
Minor fix - renaming issue
murtaza98 Jan 14, 2021
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
27 changes: 20 additions & 7 deletions client/views/omnichannel/analytics/AgentOverview.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
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%' };

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 <Table style={style} fixed>
<Table.Head>
<Table.Row>
{displayData?.head?.map(({ name }, i) => <Table.Cell key={i}>{ t(name) }</Table.Cell>)}
{displayData.head?.map(({ name }, i) => <Table.Cell key={i}>{ t(name) }</Table.Cell>)}
</Table.Row>
</Table.Head>
<Table.Body>
{displayData?.data?.map(({ name, value }, i) => <Table.Row key={i}>
{displayData.data?.map(({ name, value }, i) => <Table.Row key={i}>
<Table.Cell>{name}</Table.Cell>
<Table.Cell>{value}</Table.Cell>
</Table.Row>)}
Expand Down
30 changes: 10 additions & 20 deletions client/views/omnichannel/analytics/AnalyticsPage.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -50,26 +50,16 @@ const AnalyticsPage = () => {
<Page.Header title={t('Analytics')}/>
<Page.ScrollableContentWithShadow display='flex' flexDirection='column'>
<Margins block='x4'>
<Box display='flex' flexDirection='row' justifyContent='space-between' flexWrap='wrap' mi='neg-x4' mb='neg-x4'>
<Box display='flex' flexWrap='nowrap' flexGrow={1} flexShrink={1} justifyContent='stretch' mb='x4'>
<Margins inline='x2'>
<Field>
<Field.Label>{t('Type')}</Field.Label>
<Field.Row>
<Select options={typeOptions} value={type} onChange={setType} />
</Field.Row>
</Field>
</Margins>
<Margins inline='x2'>
<Field>
<Field.Label>{t('Departments')}</Field.Label>
<Field.Row>
<DepartmentAutoComplete placeholder={t('All')} value={departmentId} onChange={setDepartmentId}/>
</Field.Row>
</Field>
</Margins>
<Box display='flex' flexDirection='row' flexWrap='wrap' >
<Box display='flex' mie='x8' flexGrow={1} flexDirection='column'>
<Label mb='x4' >{t('Type')}</Label>
<Select flexShrink={0} options={typeOptions} value={type} onChange={setType} />
</Box>
<DateRangePicker mi='none' mb='x4' flexWrap='nowrap' display='flex' flexGrow={1} flexShrink={1} justifyContent='stretch' onChange={setDateRange}/>
<Box display='flex' mie='x8' flexGrow={1} flexDirection='column'>
<Label mb='x4'>{t('Departments')}</Label>
<DepartmentAutoComplete flexShrink={0} placeholder={t('All')} value={departmentId} onChange={setDepartmentId}/>
</Box>
<DateRangePicker onChange={setDateRange}/>
</Box>
<Box>
<Overview type={type} dateRange={dateRange} departmentId={departmentId}/>
Expand Down
73 changes: 26 additions & 47 deletions client/views/omnichannel/analytics/DateRangePicker.js
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -110,22 +91,20 @@ const DateRangePicker = ({ onChange = () => {}, ...props }) => {
},
}), [handleRange, t]);

return <Box mi='neg-x4' {...props}>
<Margins inline='x4'>
<Field>
<Field.Label>{t('Start')}</Field.Label>
<Field.Row>
<InputBox type='date' onChange={handleStart} max={todayDate} value={start}/>
</Field.Row>
</Field>
<Field>
<Field.Label>{t('End')}</Field.Label>
<Field.Row>
<InputBox type='date' onChange={handleEnd} min={start} max={todayDate} value={end}/>
<Menu options={options}/>
</Field.Row>
</Field>
</Margins>
return <Box display='flex' mie='x8' flexGrow={1} flexDirection='row' {...props}>
<Field mie='x4' flexShrink={1} flexGrow={1}>
<Field.Label>{t('Start')}</Field.Label>
<Field.Row>
<InputBox type='date' onChange={handleStart} max={todayDate} value={start}/>
</Field.Row>
</Field>
<Field mie='x4' flexShrink={1} flexGrow={1}>
<Field.Label>{t('End')}</Field.Label>
<Field.Row>
<InputBox type='date' onChange={handleEnd} min={start} max={todayDate} value={end}/>
<Menu options={options}/>
</Field.Row>
</Field>
</Box>;
};

Expand Down
9 changes: 6 additions & 3 deletions client/views/omnichannel/analytics/InterchangeableChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 <Chart border='none' pi='none' ref={canvas} {...props}/>;
};
Expand Down
31 changes: 20 additions & 11 deletions client/views/omnichannel/analytics/Overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: '' }));

Expand All @@ -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);

Expand All @@ -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 <Box
pb='x28'
Expand Down