update team reports

This commit is contained in:
Pranav
2024-02-13 18:16:52 -08:00
parent 8aa0a347d6
commit cc80e4122a
5 changed files with 208 additions and 20 deletions
@@ -1,7 +1,16 @@
<template>
<div class="overflow-auto">
<div class="column overflow-auto">
<metric-card :is-live="false" header="All teams overview">
<team-list-table />
<woot-summary-reports
key="team-reports"
class="!p-0"
type="team"
getter-key="teams/getTeams"
attribute-key="team_id"
action-key="summaryReports/fetchTeamSummaryReports"
summary-key="summaryReports/getTeamSummaryReports"
:download-button-label="$t('TEAM_REPORTS.DOWNLOAD_TEAM_REPORTS')"
/>
</metric-card>
<metric-card
:is-live="false"
@@ -10,26 +19,26 @@
>
<woot-reports
key="team-reports"
:show-download-button="false"
class="!p-0"
type="team"
getter-key="teams/getTeams"
action-key="teams/get"
:download-button-label="$t('TEAM_REPORTS.DOWNLOAD_TEAM_REPORTS')"
/>
</metric-card>
</div>
</template>
<script>
import TeamListTable from './components/AggregateTables/TeamListTable.vue';
import WootReports from './components/WootReports.vue';
import WootSummaryReports from './components/WootSummaryReports.vue';
import MetricCard from './components/overview/MetricCard.vue';
import WootReports from './components/WootReports.vue';
export default {
components: {
WootReports,
MetricCard,
TeamListTable,
WootSummaryReports,
},
};
</script>
@@ -25,18 +25,7 @@ export default {
teams: 'teams/getTeams',
teamMetrics: 'summaryReports/getTeamSummaryReports',
}),
tableData() {
return this.teams.map(team => {
const teamMetrics = this.getTeamMetrics(team.id);
return {
name: team.name,
conversationsCount: teamMetrics.open || 0,
avgFirstResponseTime: teamMetrics.open || 0,
avgResolutionTime: teamMetrics.open || 0,
resolutionsCount: teamMetrics.open || 0,
};
});
},
columns() {
return [
{
@@ -1,6 +1,7 @@
<template>
<div class="flex-1 overflow-auto p-4">
<woot-button
v-if="showDownloadButton"
color-scheme="success"
class-names="button--fixed-top"
icon="arrow-download"
@@ -64,6 +65,10 @@ export default {
type: String,
default: 'Download Reports',
},
showDownloadButton: {
type: Boolean,
default: true,
},
},
data() {
return {
@@ -0,0 +1,184 @@
<template>
<div class="flex-1 overflow-auto p-4">
<woot-button
color-scheme="success"
class-names="button--fixed-top"
icon="arrow-download"
@click="downloadReports"
>
{{ downloadButtonLabel }}
</woot-button>
<report-filter-selector
:show-agents-filter="false"
:show-group-by-filter="false"
@filter-change="onFilterChange"
/>
<ve-table
max-height="calc(100vh - 21.875rem)"
:fixed-header="true"
:columns="columns"
:table-data="tableData"
/>
</div>
</template>
<script>
import ReportFilterSelector from './FilterSelector.vue';
import { formatTime } from '@chatwoot/utils';
import reportMixin from '../../../../../mixins/reportMixin';
import { generateFileName } from '../../../../../helper/downloadHelper';
import { VeTable } from 'vue-easytable';
export default {
components: {
VeTable,
ReportFilterSelector,
},
mixins: [reportMixin],
props: {
type: {
type: String,
default: 'account',
},
getterKey: {
type: String,
default: '',
},
actionKey: {
type: String,
default: '',
},
summaryKey: {
type: String,
default: '',
},
attributeKey: {
type: String,
default: '',
},
downloadButtonLabel: {
type: String,
default: 'Download Reports',
},
},
data() {
return {
from: 0,
to: 0,
selectedFilter: null,
businessHours: false,
};
},
computed: {
columns() {
return [
{
field: 'agent',
key: 'agent',
title: this.type,
fixed: 'left',
align: this.isRTLView ? 'right' : 'left',
width: 25,
renderBodyCell: ({ row }) => (
<div class="row-user-block">
<div class="user-block">
<h6 class="title overflow-hidden whitespace-nowrap text-ellipsis text-sm">
{row.name}
</h6>
</div>
</div>
),
},
{
field: 'conversationsCount',
key: 'conversationsCount',
title: 'All conversations',
align: this.isRTLView ? 'right' : 'left',
width: 20,
},
{
field: 'resolutionsCount',
key: 'resolutionsCount',
title: 'Resolved conversations',
align: this.isRTLView ? 'right' : 'left',
width: 20,
},
{
field: 'avgFirstResponseTime',
key: 'avgFirstResponseTime',
title: 'Avg. first response time',
align: this.isRTLView ? 'right' : 'left',
width: 20,
},
{
field: 'avgResolutionTime',
key: 'avgResolutionTime',
title: 'Avg. resolution time',
align: this.isRTLView ? 'right' : 'left',
width: 20,
},
];
},
tableData() {
return this.filterItemsList.map(team => {
const typeMetrics = this.getMetrics(team.id);
return {
name: team.name,
conversationsCount: typeMetrics.conversations_count || '--',
avgFirstResponseTime:
this.renderContent(typeMetrics.avg_first_response_time) || '--',
avgResolutionTime:
this.renderContent(typeMetrics.avg_resolution_time) || '--',
resolutionsCount: typeMetrics.resolved_conversations_count || '--',
};
});
},
filterItemsList() {
return this.$store.getters[this.getterKey] || [];
},
typeMetrics() {
return this.$store.getters[this.summaryKey] || [];
},
},
mounted() {
this.fetchAllData();
},
methods: {
renderContent(value) {
return value ? formatTime(value) : '--';
},
getMetrics(id) {
return this.typeMetrics.find(metrics => metrics.id === Number(id)) || {};
},
fetchAllData() {
const { from, to, businessHours } = this;
this.$store.dispatch(this.actionKey, {
since: from,
until: to,
businessHours,
});
},
downloadReports() {
const { from, to, type, businessHours } = this;
const dispatchMethods = {
agent: 'downloadAgentReports',
label: 'downloadLabelReports',
inbox: 'downloadInboxReports',
team: 'downloadTeamReports',
};
if (dispatchMethods[type]) {
const fileName = generateFileName({ type, to, businessHours });
const params = { from, to, fileName, businessHours };
this.$store.dispatch(dispatchMethods[type], params);
}
},
onFilterChange({ from, to, businessHours }) {
this.from = from;
this.to = to;
this.businessHours = businessHours;
this.fetchAllData();
},
},
};
</script>
@@ -1,4 +1,5 @@
import SummaryReportsAPI from '../../api/summaryReports';
import Vue from 'vue';
export const state = {
teamSummaryReports: [],
@@ -36,10 +37,10 @@ export const actions = {
export const mutations = {
setTeamSummaryReport(_state, data) {
_state.teamSummaryReports = data;
Vue.set(_state, 'teamSummaryReports', data);
},
setAgentSummaryReport(_state, data) {
_state.agentSummaryReports = data;
Vue.set(_state, 'agentSummaryReports', data);
},
};