feat: Group by filter in reports (#3973)

This commit is contained in:
Aswin Dev P.S
2022-02-15 03:40:49 -08:00
committed by GitHub
parent a703ef2de6
commit e6f8895c1b
14 changed files with 343 additions and 35 deletions

View File

@@ -49,3 +49,4 @@ exclude_patterns:
- 'app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js' - 'app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js'
- 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js' - 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js'
- 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js' - 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'
- 'app/javascript/dashboard/routes/dashboard/settings/reports/constants.js'

View File

@@ -2,6 +2,8 @@ class V2::ReportBuilder
include DateRangeHelper include DateRangeHelper
attr_reader :account, :params attr_reader :account, :params
DEFAULT_GROUP_BY = 'day'.freeze
def initialize(account, params) def initialize(account, params)
@account = account @account = account
@params = params @params = params
@@ -64,26 +66,30 @@ class V2::ReportBuilder
def conversations_count def conversations_count
scope.conversations scope.conversations
.group_by_day(:created_at, range: range, default_value: 0) .group_by_period(params[:group_by] || DEFAULT_GROUP_BY,
:created_at, range: range, default_value: 0, permit: %w[day week month year])
.count .count
end end
def incoming_messages_count def incoming_messages_count
scope.messages.incoming.unscope(:order) scope.messages.incoming.unscope(:order)
.group_by_day(:created_at, range: range, default_value: 0) .group_by_period(params[:group_by] || DEFAULT_GROUP_BY,
:created_at, range: range, default_value: 0, permit: %w[day week month year])
.count .count
end end
def outgoing_messages_count def outgoing_messages_count
scope.messages.outgoing.unscope(:order) scope.messages.outgoing.unscope(:order)
.group_by_day(:created_at, range: range, default_value: 0) .group_by_period(params[:group_by] || DEFAULT_GROUP_BY,
:created_at, range: range, default_value: 0, permit: %w[day week month year])
.count .count
end end
def resolutions_count def resolutions_count
scope.conversations scope.conversations
.resolved .resolved
.group_by_day(:created_at, range: range, default_value: 0) .group_by_period(params[:group_by] || DEFAULT_GROUP_BY,
:created_at, range: range, default_value: 0, permit: %w[day week month year])
.count .count
end end

View File

@@ -46,7 +46,8 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
type: params[:type].to_sym, type: params[:type].to_sym,
since: params[:since], since: params[:since],
until: params[:until], until: params[:until],
id: params[:id] id: params[:id],
group_by: params[:group_by]
} }
end end
@@ -56,7 +57,8 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
type: params[:type].to_sym, type: params[:type].to_sym,
since: params[:since], since: params[:since],
until: params[:until], until: params[:until],
id: params[:id] id: params[:id],
group_by: params[:group_by]
} }
end end

View File

@@ -6,15 +6,15 @@ class ReportsAPI extends ApiClient {
super('reports', { accountScoped: true, apiVersion: 'v2' }); super('reports', { accountScoped: true, apiVersion: 'v2' });
} }
getReports(metric, since, until, type = 'account', id) { getReports(metric, since, until, type = 'account', id, group_by) {
return axios.get(`${this.url}`, { return axios.get(`${this.url}`, {
params: { metric, since, until, type, id }, params: { metric, since, until, type, id, group_by },
}); });
} }
getSummary(since, until, type = 'account', id) { getSummary(since, until, type = 'account', id, group_by) {
return axios.get(`${this.url}/summary`, { return axios.get(`${this.url}/summary`, {
params: { since, until, type, id }, params: { since, until, type, id, group_by },
}); });
} }

View File

@@ -59,7 +59,24 @@
"CUSTOM_DATE_RANGE": { "CUSTOM_DATE_RANGE": {
"CONFIRM": "Apply", "CONFIRM": "Apply",
"PLACEHOLDER": "Select date range" "PLACEHOLDER": "Select date range"
} },
"GROUP_BY_FILTER_DROPDOWN_LABEL": "Group By",
"GROUP_BY_DAY_OPTIONS": [{ "id": 1, "groupBy": "Day" }],
"GROUP_BY_WEEK_OPTIONS": [
{ "id": 1, "groupBy": "Day" },
{ "id": 2, "groupBy": "Week" }
],
"GROUP_BY_MONTH_OPTIONS": [
{ "id": 1, "groupBy": "Day" },
{ "id": 2, "groupBy": "Week" },
{ "id": 3, "groupBy": "Month" }
],
"GROUP_BY_YEAR_OPTIONS": [
{ "id": 1, "groupBy": "Day" },
{ "id": 2, "groupBy": "Week" },
{ "id": 3, "groupBy": "Month" },
{ "id": 4, "groupBy": "Year" }
]
}, },
"AGENT_REPORTS": { "AGENT_REPORTS": {
"HEADER": "Agents Overview", "HEADER": "Agents Overview",

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="column content-box"> <div class="column content-box">
<report-date-range-selector @date-range-change="onDateRangeChange" /> <report-filter-selector @date-range-change="onDateRangeChange" />
<csat-metrics /> <csat-metrics />
<csat-table :page-index="pageIndex" @page-change="onPageNumberChange" /> <csat-table :page-index="pageIndex" @page-change="onPageNumberChange" />
</div> </div>
@@ -8,14 +8,14 @@
<script> <script>
import CsatMetrics from './components/CsatMetrics'; import CsatMetrics from './components/CsatMetrics';
import CsatTable from './components/CsatTable'; import CsatTable from './components/CsatTable';
import ReportDateRangeSelector from './components/DateRangeSelector'; import ReportFilterSelector from './components/FilterSelector';
export default { export default {
name: 'CsatResponses', name: 'CsatResponses',
components: { components: {
CsatMetrics, CsatMetrics,
CsatTable, CsatTable,
ReportDateRangeSelector, ReportFilterSelector,
}, },
data() { data() {
return { pageIndex: 1, from: 0, to: 0 }; return { pageIndex: 1, from: 0, to: 0 };

View File

@@ -9,7 +9,12 @@
{{ $t('REPORT.DOWNLOAD_AGENT_REPORTS') }} {{ $t('REPORT.DOWNLOAD_AGENT_REPORTS') }}
</woot-button> </woot-button>
<report-date-range-selector @date-range-change="onDateRangeChange" /> <report-filter-selector
:selected-group-by-filter="selectedGroupByFilter"
:filter-items-list="filterItemsList"
@date-range-change="onDateRangeChange"
@filter-change="onFilterChange"
/>
<div class="row"> <div class="row">
<woot-report-stats-card <woot-report-stats-card
v-for="(metric, index) in metrics" v-for="(metric, index) in metrics"
@@ -41,7 +46,8 @@
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import fromUnixTime from 'date-fns/fromUnixTime'; import fromUnixTime from 'date-fns/fromUnixTime';
import format from 'date-fns/format'; import format from 'date-fns/format';
import ReportDateRangeSelector from './components/DateRangeSelector'; import ReportFilterSelector from './components/FilterSelector';
import { GROUP_BY_FILTER } from './constants';
const REPORTS_KEYS = { const REPORTS_KEYS = {
CONVERSATIONS: 'conversations_count', CONVERSATIONS: 'conversations_count',
@@ -54,10 +60,17 @@ const REPORTS_KEYS = {
export default { export default {
components: { components: {
ReportDateRangeSelector, ReportFilterSelector,
}, },
data() { data() {
return { from: 0, to: 0, currentSelection: 0 }; return {
from: 0,
to: 0,
currentSelection: 0,
groupBy: GROUP_BY_FILTER[1],
filterItemsList: this.$t('REPORT.GROUP_BY_DAY_OPTIONS'),
selectedGroupByFilter: {},
};
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
@@ -69,9 +82,28 @@ export default {
return {}; return {};
} }
if (!this.accountReport.data.length) return {}; if (!this.accountReport.data.length) return {};
const labels = this.accountReport.data.map(element => const labels = this.accountReport.data.map(element => {
format(fromUnixTime(element.timestamp), 'dd/MMM') if (this.groupBy.period === GROUP_BY_FILTER[2].period) {
); let week_date = new Date(fromUnixTime(element.timestamp));
const first_day = week_date.getDate() - week_date.getDay();
const last_day = first_day + 6;
const week_first_date = new Date(week_date.setDate(first_day));
const week_last_date = new Date(week_date.setDate(last_day));
return `${format(week_first_date, 'dd/MM/yy')} - ${format(
week_last_date,
'dd/MM/yy'
)}`;
}
if (this.groupBy.period === GROUP_BY_FILTER[3].period) {
return format(fromUnixTime(element.timestamp), 'MMM-yyyy');
}
if (this.groupBy.period === GROUP_BY_FILTER[4].period) {
return format(fromUnixTime(element.timestamp), 'yyyy');
}
return format(fromUnixTime(element.timestamp), 'dd-MMM-yyyy');
});
const data = this.accountReport.data.map(element => element.value); const data = this.accountReport.data.map(element => element.value);
return { return {
labels, labels,
@@ -102,16 +134,21 @@ export default {
}, },
methods: { methods: {
fetchAllData() { fetchAllData() {
const { from, to } = this; const { from, to, groupBy } = this;
this.$store.dispatch('fetchAccountSummary', { from, to }); this.$store.dispatch('fetchAccountSummary', {
from,
to,
groupBy: groupBy.period,
});
this.fetchChartData(); this.fetchChartData();
}, },
fetchChartData() { fetchChartData() {
const { from, to } = this; const { from, to, groupBy } = this;
this.$store.dispatch('fetchAccountReport', { this.$store.dispatch('fetchAccountReport', {
metric: this.metrics[this.currentSelection].KEY, metric: this.metrics[this.currentSelection].KEY,
from, from,
to, to,
groupBy: groupBy.period,
}); });
}, },
downloadAgentReports() { downloadAgentReports() {
@@ -126,11 +163,37 @@ export default {
this.currentSelection = index; this.currentSelection = index;
this.fetchChartData(); this.fetchChartData();
}, },
onDateRangeChange({ from, to }) { onDateRangeChange({ from, to, groupBy }) {
this.from = from; this.from = from;
this.to = to; this.to = to;
this.filterItemsList = this.fetchFilterItems(groupBy);
const filterItems = this.filterItemsList.filter(
item => item.id === this.groupBy.id
);
if (filterItems.length > 0) {
this.selectedGroupByFilter = filterItems[0];
} else {
this.selectedGroupByFilter = this.filterItemsList[0];
this.groupBy = GROUP_BY_FILTER[this.selectedGroupByFilter.id];
}
this.fetchAllData(); this.fetchAllData();
}, },
onFilterChange(payload) {
this.groupBy = GROUP_BY_FILTER[payload.id];
this.fetchAllData();
},
fetchFilterItems(group_by) {
switch (group_by) {
case GROUP_BY_FILTER[2].period:
return this.$t('REPORT.GROUP_BY_WEEK_OPTIONS');
case GROUP_BY_FILTER[3].period:
return this.$t('REPORT.GROUP_BY_MONTH_OPTIONS');
case GROUP_BY_FILTER[4].period:
return this.$t('REPORT.GROUP_BY_YEAR_OPTIONS');
default:
return this.$t('REPORT.GROUP_BY_DAY_OPTIONS');
}
},
}, },
}; };
</script> </script>

View File

@@ -23,6 +23,24 @@
:placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')" :placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')"
@change="onChange" @change="onChange"
/> />
<div
v-if="notLast7Days"
class="small-12 medium-3 pull-right margin-left-small"
>
<p aria-hidden="true" class="hide">
{{ $t('REPORT.GROUP_BY_FILTER_DROPDOWN_LABEL') }}
</p>
<multiselect
v-model="currentSelectedFilter"
track-by="id"
label="groupBy"
:placeholder="$t('REPORT.GROUP_BY_FILTER_DROPDOWN_LABEL')"
:options="filterItemsList"
:allow-empty="false"
:show-labels="false"
@input="changeFilterSelection"
/>
</div>
</div> </div>
</template> </template>
<script> <script>
@@ -31,16 +49,28 @@ const CUSTOM_DATE_RANGE_ID = 5;
import subDays from 'date-fns/subDays'; import subDays from 'date-fns/subDays';
import startOfDay from 'date-fns/startOfDay'; import startOfDay from 'date-fns/startOfDay';
import getUnixTime from 'date-fns/getUnixTime'; import getUnixTime from 'date-fns/getUnixTime';
import { GROUP_BY_FILTER } from '../constants';
export default { export default {
components: { components: {
WootDateRangePicker, WootDateRangePicker,
}, },
props: {
filterItemsList: {
type: Array,
default: () => [],
},
selectedGroupByFilter: {
type: Object,
default: () => {},
},
},
data() { data() {
return { return {
currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0], currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0],
dateRange: this.$t('REPORT.DATE_RANGE'), dateRange: this.$t('REPORT.DATE_RANGE'),
customDateRange: [new Date(), new Date()], customDateRange: [new Date(), new Date()],
currentSelectedFilter: null,
}; };
}, },
computed: { computed: {
@@ -68,13 +98,38 @@ export default {
const fromDate = subDays(new Date(), diff); const fromDate = subDays(new Date(), diff);
return this.fromCustomDate(fromDate); return this.fromCustomDate(fromDate);
}, },
groupBy() {
if (this.isDateRangeSelected) {
return GROUP_BY_FILTER[4].period;
}
const groupRange = {
0: GROUP_BY_FILTER[1].period,
1: GROUP_BY_FILTER[2].period,
2: GROUP_BY_FILTER[3].period,
3: GROUP_BY_FILTER[3].period,
4: GROUP_BY_FILTER[3].period,
};
return groupRange[this.currentDateRangeSelection.id];
},
notLast7Days() {
return this.groupBy !== GROUP_BY_FILTER[1].period;
},
},
watch: {
filterItemsList() {
this.currentSelectedFilter = this.selectedGroupByFilter;
},
}, },
mounted() { mounted() {
this.onDateRangeChange(); this.onDateRangeChange();
}, },
methods: { methods: {
onDateRangeChange() { onDateRangeChange() {
this.$emit('date-range-change', { from: this.from, to: this.to }); this.$emit('date-range-change', {
from: this.from,
to: this.to,
groupBy: this.groupBy,
});
}, },
fromCustomDate(date) { fromCustomDate(date) {
return getUnixTime(startOfDay(date)); return getUnixTime(startOfDay(date));
@@ -87,6 +142,9 @@ export default {
this.customDateRange = value; this.customDateRange = value;
this.onDateRangeChange(); this.onDateRangeChange();
}, },
changeFilterSelection() {
this.$emit('filter-change', this.currentSelectedFilter);
},
}, },
}; };
</script> </script>

View File

@@ -127,6 +127,24 @@
:placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')" :placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')"
@change="onChange" @change="onChange"
/> />
<div
v-if="notLast7Days"
class="small-12 medium-3 pull-right margin-left-small"
>
<p aria-hidden="true" class="hide">
{{ $t('REPORT.GROUP_BY_FILTER_DROPDOWN_LABEL') }}
</p>
<multiselect
v-model="currentSelectedGroupByFilter"
track-by="id"
label="groupBy"
:placeholder="$t('REPORT.GROUP_BY_FILTER_DROPDOWN_LABEL')"
:options="groupByFilterItemsList"
:allow-empty="false"
:show-labels="false"
@input="changeGroupByFilterSelection"
/>
</div>
</div> </div>
</template> </template>
<script> <script>
@@ -136,6 +154,7 @@ import subDays from 'date-fns/subDays';
import startOfDay from 'date-fns/startOfDay'; import startOfDay from 'date-fns/startOfDay';
import getUnixTime from 'date-fns/getUnixTime'; import getUnixTime from 'date-fns/getUnixTime';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue'; import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import { GROUP_BY_FILTER } from '../constants';
export default { export default {
components: { components: {
@@ -147,10 +166,18 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
groupByFilterItemsList: {
type: Array,
default: () => [],
},
type: { type: {
type: String, type: String,
default: 'agent', default: 'agent',
}, },
selectedGroupByFilter: {
type: Object,
default: () => {},
},
}, },
data() { data() {
return { return {
@@ -158,6 +185,7 @@ export default {
currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0], currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0],
dateRange: this.$t('REPORT.DATE_RANGE'), dateRange: this.$t('REPORT.DATE_RANGE'),
customDateRange: [new Date(), new Date()], customDateRange: [new Date(), new Date()],
currentSelectedGroupByFilter: null,
}; };
}, },
computed: { computed: {
@@ -194,19 +222,42 @@ export default {
}; };
return typeLabels[this.type] || this.$t('FORMS.MULTISELECT.SELECT_ONE'); return typeLabels[this.type] || this.$t('FORMS.MULTISELECT.SELECT_ONE');
}, },
groupBy() {
if (this.isDateRangeSelected) {
return GROUP_BY_FILTER[4].period;
}
const groupRange = {
0: GROUP_BY_FILTER[1].period,
1: GROUP_BY_FILTER[2].period,
2: GROUP_BY_FILTER[3].period,
3: GROUP_BY_FILTER[3].period,
4: GROUP_BY_FILTER[3].period,
};
return groupRange[this.currentDateRangeSelection.id];
},
notLast7Days() {
return this.groupBy !== GROUP_BY_FILTER[1].period;
},
}, },
watch: { watch: {
filterItemsList(val) { filterItemsList(val) {
this.currentSelectedFilter = val[0]; this.currentSelectedFilter = val[0];
this.changeFilterSelection(); this.changeFilterSelection();
}, },
groupByFilterItemsList() {
this.currentSelectedGroupByFilter = this.selectedGroupByFilter;
},
}, },
mounted() { mounted() {
this.onDateRangeChange(); this.onDateRangeChange();
}, },
methods: { methods: {
onDateRangeChange() { onDateRangeChange() {
this.$emit('date-range-change', { from: this.from, to: this.to }); this.$emit('date-range-change', {
from: this.from,
to: this.to,
groupBy: this.groupBy,
});
}, },
fromCustomDate(date) { fromCustomDate(date) {
return getUnixTime(startOfDay(date)); return getUnixTime(startOfDay(date));
@@ -222,6 +273,9 @@ export default {
this.customDateRange = value; this.customDateRange = value;
this.onDateRangeChange(); this.onDateRangeChange();
}, },
changeGroupByFilterSelection() {
this.$emit('group-by-filter-change', this.currentSelectedGroupByFilter);
},
}, },
}; };
</script> </script>

View File

@@ -12,8 +12,11 @@
v-if="filterItemsList" v-if="filterItemsList"
:type="type" :type="type"
:filter-items-list="filterItemsList" :filter-items-list="filterItemsList"
:group-by-filter-items-list="groupByfilterItemsList"
:selected-group-by-filter="selectedGroupByFilter"
@date-range-change="onDateRangeChange" @date-range-change="onDateRangeChange"
@filter-change="onFilterChange" @filter-change="onFilterChange"
@group-by-filter-change="onGroupByFilterChange"
/> />
<div> <div>
<div v-if="filterItemsList.length" class="row"> <div v-if="filterItemsList.length" class="row">
@@ -51,6 +54,7 @@
import ReportFilters from './ReportFilters'; import ReportFilters from './ReportFilters';
import fromUnixTime from 'date-fns/fromUnixTime'; import fromUnixTime from 'date-fns/fromUnixTime';
import format from 'date-fns/format'; import format from 'date-fns/format';
import { GROUP_BY_FILTER } from '../constants';
const REPORTS_KEYS = { const REPORTS_KEYS = {
CONVERSATIONS: 'conversations_count', CONVERSATIONS: 'conversations_count',
@@ -88,6 +92,9 @@ export default {
to: 0, to: 0,
currentSelection: 0, currentSelection: 0,
selectedFilter: null, selectedFilter: null,
groupBy: GROUP_BY_FILTER[1],
groupByfilterItemsList: this.$t('REPORT.GROUP_BY_DAY_OPTIONS'),
selectedGroupByFilter: null,
}; };
}, },
computed: { computed: {
@@ -105,9 +112,28 @@ export default {
return {}; return {};
} }
if (!this.accountReport.data.length) return {}; if (!this.accountReport.data.length) return {};
const labels = this.accountReport.data.map(element => const labels = this.accountReport.data.map(element => {
format(fromUnixTime(element.timestamp), 'dd/MMM') if (this.groupBy.period === GROUP_BY_FILTER[2].period) {
); let week_date = new Date(fromUnixTime(element.timestamp));
const first_day = week_date.getDate() - week_date.getDay();
const last_day = first_day + 6;
const week_first_date = new Date(week_date.setDate(first_day));
const week_last_date = new Date(week_date.setDate(last_day));
return `${format(week_first_date, 'dd/MM/yy')} - ${format(
week_last_date,
'dd/MM/yy'
)}`;
}
if (this.groupBy.period === GROUP_BY_FILTER[3].period) {
return format(fromUnixTime(element.timestamp), 'MMM-yyyy');
}
if (this.groupBy.period === GROUP_BY_FILTER[4].period) {
return format(fromUnixTime(element.timestamp), 'yyyy');
}
return format(fromUnixTime(element.timestamp), 'dd-MMM-yyyy');
});
const data = this.accountReport.data.map(element => element.value); const data = this.accountReport.data.map(element => element.value);
return { return {
labels, labels,
@@ -148,24 +174,26 @@ export default {
methods: { methods: {
fetchAllData() { fetchAllData() {
if (this.selectedFilter) { if (this.selectedFilter) {
const { from, to } = this; const { from, to, groupBy } = this;
this.$store.dispatch('fetchAccountSummary', { this.$store.dispatch('fetchAccountSummary', {
from, from,
to, to,
type: this.type, type: this.type,
id: this.selectedFilter.id, id: this.selectedFilter.id,
groupBy: groupBy.period,
}); });
this.fetchChartData(); this.fetchChartData();
} }
}, },
fetchChartData() { fetchChartData() {
const { from, to } = this; const { from, to, groupBy } = this;
this.$store.dispatch('fetchAccountReport', { this.$store.dispatch('fetchAccountReport', {
metric: this.metrics[this.currentSelection].KEY, metric: this.metrics[this.currentSelection].KEY,
from, from,
to, to,
type: this.type, type: this.type,
id: this.selectedFilter.id, id: this.selectedFilter.id,
groupBy: groupBy.period,
}); });
}, },
downloadReports() { downloadReports() {
@@ -195,9 +223,19 @@ export default {
this.currentSelection = index; this.currentSelection = index;
this.fetchChartData(); this.fetchChartData();
}, },
onDateRangeChange({ from, to }) { onDateRangeChange({ from, to, groupBy }) {
this.from = from; this.from = from;
this.to = to; this.to = to;
this.groupByfilterItemsList = this.fetchFilterItems(groupBy);
const filterItems = this.groupByfilterItemsList.filter(
item => item.id === this.groupBy.id
);
if (filterItems.length > 0) {
this.selectedGroupByFilter = filterItems[0];
} else {
this.selectedGroupByFilter = this.groupByfilterItemsList[0];
this.groupBy = GROUP_BY_FILTER[this.selectedGroupByFilter.id];
}
this.fetchAllData(); this.fetchAllData();
}, },
onFilterChange(payload) { onFilterChange(payload) {
@@ -206,6 +244,22 @@ export default {
this.fetchAllData(); this.fetchAllData();
} }
}, },
onGroupByFilterChange(payload) {
this.groupBy = GROUP_BY_FILTER[payload.id];
this.fetchAllData();
},
fetchFilterItems(group_by) {
switch (group_by) {
case GROUP_BY_FILTER[2].period:
return this.$t('REPORT.GROUP_BY_WEEK_OPTIONS');
case GROUP_BY_FILTER[3].period:
return this.$t('REPORT.GROUP_BY_MONTH_OPTIONS');
case GROUP_BY_FILTER[4].period:
return this.$t('REPORT.GROUP_BY_YEAR_OPTIONS');
default:
return this.$t('REPORT.GROUP_BY_DAY_OPTIONS');
}
},
}, },
}; };
</script> </script>

View File

@@ -0,0 +1,6 @@
export const GROUP_BY_FILTER = {
1: { id: 1, period: 'day' },
2: { id: 2, period: 'week' },
3: { id: 3, period: 'month' },
4: { id: 4, period: 'year' },
};

View File

@@ -43,7 +43,8 @@ export const actions = {
reportObj.from, reportObj.from,
reportObj.to, reportObj.to,
reportObj.type, reportObj.type,
reportObj.id reportObj.id,
reportObj.groupBy
).then(accountReport => { ).then(accountReport => {
let { data } = accountReport; let { data } = accountReport;
data = data.filter( data = data.filter(
@@ -68,7 +69,8 @@ export const actions = {
reportObj.from, reportObj.from,
reportObj.to, reportObj.to,
reportObj.type, reportObj.type,
reportObj.id reportObj.id,
reportObj.groupBy
) )
.then(accountSummary => { .then(accountSummary => {
commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data); commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data);

View File

@@ -57,6 +57,7 @@ en:
conversations_count: Conversations count conversations_count: Conversations count
avg_first_response_time: Avg first response time (Minutes) avg_first_response_time: Avg first response time (Minutes)
avg_resolution_time: Avg resolution time (Minutes) avg_resolution_time: Avg resolution time (Minutes)
default_group_by: day
notifications: notifications:
notification_title: notification_title:

View File

@@ -147,6 +147,18 @@ describe ::V2::ReportBuilder do
expect(metrics[:avg_resolution_time]).to be 0 expect(metrics[:avg_resolution_time]).to be 0
expect(metrics[:resolutions_count]).to be 0 expect(metrics[:resolutions_count]).to be 0
end end
it 'returns argument error for incorrect group by' do
params = {
type: :account,
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
until: Time.zone.today.to_time.to_i.to_s,
group_by: 'test'.to_s
}
builder = V2::ReportBuilder.new(account, params)
expect { builder.summary }.to raise_error(ArgumentError)
end
end end
context 'when report type is label' do context 'when report type is label' do
@@ -247,6 +259,38 @@ describe ::V2::ReportBuilder do
expect(metrics[:avg_resolution_time]).to be 0 expect(metrics[:avg_resolution_time]).to be 0
expect(metrics[:resolutions_count]).to be 0 expect(metrics[:resolutions_count]).to be 0
end end
it 'returns summary for correct group by' do
params = {
type: :label,
id: label_2.id,
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
until: Time.zone.today.to_time.to_i.to_s,
group_by: 'week'.to_s
}
builder = V2::ReportBuilder.new(account, params)
metrics = builder.summary
expect(metrics[:conversations_count]).to be 5
expect(metrics[:incoming_messages_count]).to be 5
expect(metrics[:outgoing_messages_count]).to be 15
expect(metrics[:avg_resolution_time]).to be 0
expect(metrics[:resolutions_count]).to be 0
end
it 'returns argument error for incorrect group by' do
params = {
type: :label,
id: label_2.id,
since: (Time.zone.today - 3.days).to_time.to_i.to_s,
until: Time.zone.today.to_time.to_i.to_s,
group_by: 'test'.to_s
}
builder = V2::ReportBuilder.new(account, params)
expect { builder.summary }.to raise_error(ArgumentError)
end
end end
end end
end end