feat: Group by filter in reports (#3973)
This commit is contained in:
parent
a703ef2de6
commit
e6f8895c1b
14 changed files with 343 additions and 35 deletions
|
@ -49,3 +49,4 @@ exclude_patterns:
|
|||
- 'app/javascript/dashboard/routes/dashboard/contacts/contactFilterItems/index.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/automation/constants.js'
|
||||
- 'app/javascript/dashboard/components/widgets/FilterInput/FilterOperatorTypes.js'
|
||||
- 'app/javascript/dashboard/routes/dashboard/settings/reports/constants.js'
|
||||
|
|
|
@ -2,6 +2,8 @@ class V2::ReportBuilder
|
|||
include DateRangeHelper
|
||||
attr_reader :account, :params
|
||||
|
||||
DEFAULT_GROUP_BY = 'day'.freeze
|
||||
|
||||
def initialize(account, params)
|
||||
@account = account
|
||||
@params = params
|
||||
|
@ -64,26 +66,30 @@ class V2::ReportBuilder
|
|||
|
||||
def conversations_count
|
||||
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
|
||||
end
|
||||
|
||||
def incoming_messages_count
|
||||
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
|
||||
end
|
||||
|
||||
def outgoing_messages_count
|
||||
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
|
||||
end
|
||||
|
||||
def resolutions_count
|
||||
scope.conversations
|
||||
.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
|
||||
end
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
|||
type: params[:type].to_sym,
|
||||
since: params[:since],
|
||||
until: params[:until],
|
||||
id: params[:id]
|
||||
id: params[:id],
|
||||
group_by: params[:group_by]
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -56,7 +57,8 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
|||
type: params[:type].to_sym,
|
||||
since: params[:since],
|
||||
until: params[:until],
|
||||
id: params[:id]
|
||||
id: params[:id],
|
||||
group_by: params[:group_by]
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@ class ReportsAPI extends ApiClient {
|
|||
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}`, {
|
||||
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`, {
|
||||
params: { since, until, type, id },
|
||||
params: { since, until, type, id, group_by },
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,24 @@
|
|||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"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": {
|
||||
"HEADER": "Agents Overview",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="column content-box">
|
||||
<report-date-range-selector @date-range-change="onDateRangeChange" />
|
||||
<report-filter-selector @date-range-change="onDateRangeChange" />
|
||||
<csat-metrics />
|
||||
<csat-table :page-index="pageIndex" @page-change="onPageNumberChange" />
|
||||
</div>
|
||||
|
@ -8,14 +8,14 @@
|
|||
<script>
|
||||
import CsatMetrics from './components/CsatMetrics';
|
||||
import CsatTable from './components/CsatTable';
|
||||
import ReportDateRangeSelector from './components/DateRangeSelector';
|
||||
import ReportFilterSelector from './components/FilterSelector';
|
||||
|
||||
export default {
|
||||
name: 'CsatResponses',
|
||||
components: {
|
||||
CsatMetrics,
|
||||
CsatTable,
|
||||
ReportDateRangeSelector,
|
||||
ReportFilterSelector,
|
||||
},
|
||||
data() {
|
||||
return { pageIndex: 1, from: 0, to: 0 };
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
{{ $t('REPORT.DOWNLOAD_AGENT_REPORTS') }}
|
||||
</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">
|
||||
<woot-report-stats-card
|
||||
v-for="(metric, index) in metrics"
|
||||
|
@ -41,7 +46,8 @@
|
|||
import { mapGetters } from 'vuex';
|
||||
import fromUnixTime from 'date-fns/fromUnixTime';
|
||||
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 = {
|
||||
CONVERSATIONS: 'conversations_count',
|
||||
|
@ -54,10 +60,17 @@ const REPORTS_KEYS = {
|
|||
|
||||
export default {
|
||||
components: {
|
||||
ReportDateRangeSelector,
|
||||
ReportFilterSelector,
|
||||
},
|
||||
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: {
|
||||
...mapGetters({
|
||||
|
@ -69,9 +82,28 @@ export default {
|
|||
return {};
|
||||
}
|
||||
if (!this.accountReport.data.length) return {};
|
||||
const labels = this.accountReport.data.map(element =>
|
||||
format(fromUnixTime(element.timestamp), 'dd/MMM')
|
||||
);
|
||||
const labels = this.accountReport.data.map(element => {
|
||||
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);
|
||||
return {
|
||||
labels,
|
||||
|
@ -102,16 +134,21 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
fetchAllData() {
|
||||
const { from, to } = this;
|
||||
this.$store.dispatch('fetchAccountSummary', { from, to });
|
||||
const { from, to, groupBy } = this;
|
||||
this.$store.dispatch('fetchAccountSummary', {
|
||||
from,
|
||||
to,
|
||||
groupBy: groupBy.period,
|
||||
});
|
||||
this.fetchChartData();
|
||||
},
|
||||
fetchChartData() {
|
||||
const { from, to } = this;
|
||||
const { from, to, groupBy } = this;
|
||||
this.$store.dispatch('fetchAccountReport', {
|
||||
metric: this.metrics[this.currentSelection].KEY,
|
||||
from,
|
||||
to,
|
||||
groupBy: groupBy.period,
|
||||
});
|
||||
},
|
||||
downloadAgentReports() {
|
||||
|
@ -126,11 +163,37 @@ export default {
|
|||
this.currentSelection = index;
|
||||
this.fetchChartData();
|
||||
},
|
||||
onDateRangeChange({ from, to }) {
|
||||
onDateRangeChange({ from, to, groupBy }) {
|
||||
this.from = from;
|
||||
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();
|
||||
},
|
||||
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>
|
||||
|
|
|
@ -23,6 +23,24 @@
|
|||
:placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')"
|
||||
@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>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -31,16 +49,28 @@ const CUSTOM_DATE_RANGE_ID = 5;
|
|||
import subDays from 'date-fns/subDays';
|
||||
import startOfDay from 'date-fns/startOfDay';
|
||||
import getUnixTime from 'date-fns/getUnixTime';
|
||||
import { GROUP_BY_FILTER } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WootDateRangePicker,
|
||||
},
|
||||
props: {
|
||||
filterItemsList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
selectedGroupByFilter: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0],
|
||||
dateRange: this.$t('REPORT.DATE_RANGE'),
|
||||
customDateRange: [new Date(), new Date()],
|
||||
currentSelectedFilter: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -68,13 +98,38 @@ export default {
|
|||
const fromDate = subDays(new Date(), diff);
|
||||
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() {
|
||||
this.onDateRangeChange();
|
||||
},
|
||||
methods: {
|
||||
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) {
|
||||
return getUnixTime(startOfDay(date));
|
||||
|
@ -87,6 +142,9 @@ export default {
|
|||
this.customDateRange = value;
|
||||
this.onDateRangeChange();
|
||||
},
|
||||
changeFilterSelection() {
|
||||
this.$emit('filter-change', this.currentSelectedFilter);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -127,6 +127,24 @@
|
|||
:placeholder="$t('REPORT.CUSTOM_DATE_RANGE.PLACEHOLDER')"
|
||||
@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>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -136,6 +154,7 @@ import subDays from 'date-fns/subDays';
|
|||
import startOfDay from 'date-fns/startOfDay';
|
||||
import getUnixTime from 'date-fns/getUnixTime';
|
||||
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
|
||||
import { GROUP_BY_FILTER } from '../constants';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -147,10 +166,18 @@ export default {
|
|||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
groupByFilterItemsList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'agent',
|
||||
},
|
||||
selectedGroupByFilter: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -158,6 +185,7 @@ export default {
|
|||
currentDateRangeSelection: this.$t('REPORT.DATE_RANGE')[0],
|
||||
dateRange: this.$t('REPORT.DATE_RANGE'),
|
||||
customDateRange: [new Date(), new Date()],
|
||||
currentSelectedGroupByFilter: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -194,19 +222,42 @@ export default {
|
|||
};
|
||||
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: {
|
||||
filterItemsList(val) {
|
||||
this.currentSelectedFilter = val[0];
|
||||
this.changeFilterSelection();
|
||||
},
|
||||
groupByFilterItemsList() {
|
||||
this.currentSelectedGroupByFilter = this.selectedGroupByFilter;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.onDateRangeChange();
|
||||
},
|
||||
methods: {
|
||||
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) {
|
||||
return getUnixTime(startOfDay(date));
|
||||
|
@ -222,6 +273,9 @@ export default {
|
|||
this.customDateRange = value;
|
||||
this.onDateRangeChange();
|
||||
},
|
||||
changeGroupByFilterSelection() {
|
||||
this.$emit('group-by-filter-change', this.currentSelectedGroupByFilter);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
v-if="filterItemsList"
|
||||
:type="type"
|
||||
:filter-items-list="filterItemsList"
|
||||
:group-by-filter-items-list="groupByfilterItemsList"
|
||||
:selected-group-by-filter="selectedGroupByFilter"
|
||||
@date-range-change="onDateRangeChange"
|
||||
@filter-change="onFilterChange"
|
||||
@group-by-filter-change="onGroupByFilterChange"
|
||||
/>
|
||||
<div>
|
||||
<div v-if="filterItemsList.length" class="row">
|
||||
|
@ -51,6 +54,7 @@
|
|||
import ReportFilters from './ReportFilters';
|
||||
import fromUnixTime from 'date-fns/fromUnixTime';
|
||||
import format from 'date-fns/format';
|
||||
import { GROUP_BY_FILTER } from '../constants';
|
||||
|
||||
const REPORTS_KEYS = {
|
||||
CONVERSATIONS: 'conversations_count',
|
||||
|
@ -88,6 +92,9 @@ export default {
|
|||
to: 0,
|
||||
currentSelection: 0,
|
||||
selectedFilter: null,
|
||||
groupBy: GROUP_BY_FILTER[1],
|
||||
groupByfilterItemsList: this.$t('REPORT.GROUP_BY_DAY_OPTIONS'),
|
||||
selectedGroupByFilter: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -105,9 +112,28 @@ export default {
|
|||
return {};
|
||||
}
|
||||
if (!this.accountReport.data.length) return {};
|
||||
const labels = this.accountReport.data.map(element =>
|
||||
format(fromUnixTime(element.timestamp), 'dd/MMM')
|
||||
);
|
||||
const labels = this.accountReport.data.map(element => {
|
||||
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);
|
||||
return {
|
||||
labels,
|
||||
|
@ -148,24 +174,26 @@ export default {
|
|||
methods: {
|
||||
fetchAllData() {
|
||||
if (this.selectedFilter) {
|
||||
const { from, to } = this;
|
||||
const { from, to, groupBy } = this;
|
||||
this.$store.dispatch('fetchAccountSummary', {
|
||||
from,
|
||||
to,
|
||||
type: this.type,
|
||||
id: this.selectedFilter.id,
|
||||
groupBy: groupBy.period,
|
||||
});
|
||||
this.fetchChartData();
|
||||
}
|
||||
},
|
||||
fetchChartData() {
|
||||
const { from, to } = this;
|
||||
const { from, to, groupBy } = this;
|
||||
this.$store.dispatch('fetchAccountReport', {
|
||||
metric: this.metrics[this.currentSelection].KEY,
|
||||
from,
|
||||
to,
|
||||
type: this.type,
|
||||
id: this.selectedFilter.id,
|
||||
groupBy: groupBy.period,
|
||||
});
|
||||
},
|
||||
downloadReports() {
|
||||
|
@ -195,9 +223,19 @@ export default {
|
|||
this.currentSelection = index;
|
||||
this.fetchChartData();
|
||||
},
|
||||
onDateRangeChange({ from, to }) {
|
||||
onDateRangeChange({ from, to, groupBy }) {
|
||||
this.from = from;
|
||||
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();
|
||||
},
|
||||
onFilterChange(payload) {
|
||||
|
@ -206,6 +244,22 @@ export default {
|
|||
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>
|
||||
|
|
|
@ -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' },
|
||||
};
|
|
@ -43,7 +43,8 @@ export const actions = {
|
|||
reportObj.from,
|
||||
reportObj.to,
|
||||
reportObj.type,
|
||||
reportObj.id
|
||||
reportObj.id,
|
||||
reportObj.groupBy
|
||||
).then(accountReport => {
|
||||
let { data } = accountReport;
|
||||
data = data.filter(
|
||||
|
@ -68,7 +69,8 @@ export const actions = {
|
|||
reportObj.from,
|
||||
reportObj.to,
|
||||
reportObj.type,
|
||||
reportObj.id
|
||||
reportObj.id,
|
||||
reportObj.groupBy
|
||||
)
|
||||
.then(accountSummary => {
|
||||
commit(types.default.SET_ACCOUNT_SUMMARY, accountSummary.data);
|
||||
|
|
|
@ -57,6 +57,7 @@ en:
|
|||
conversations_count: Conversations count
|
||||
avg_first_response_time: Avg first response time (Minutes)
|
||||
avg_resolution_time: Avg resolution time (Minutes)
|
||||
default_group_by: day
|
||||
|
||||
notifications:
|
||||
notification_title:
|
||||
|
|
|
@ -147,6 +147,18 @@ describe ::V2::ReportBuilder do
|
|||
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: :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
|
||||
|
||||
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[:resolutions_count]).to be 0
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue