Re-write live-conversations API

This commit is contained in:
Pranav
2024-02-10 18:41:11 -08:00
parent eb379e1849
commit 375d216d12
8 changed files with 107 additions and 86 deletions
-33
View File
@@ -54,14 +54,6 @@ class V2::ReportBuilder
}
end
def conversation_metrics
if params[:type].equal?(:account)
live_conversations
else
agent_metrics.sort_by { |hash| hash[:metric][:open] }.reverse
end
end
private
def metric_valid?
@@ -100,29 +92,4 @@ class V2::ReportBuilder
time_zone: @timezone
)
end
def agent_metrics
account_users = @account.account_users.page(params[:page]).per(AGENT_RESULTS_PER_PAGE)
account_users.each_with_object([]) do |account_user, arr|
@user = account_user.user
arr << {
id: @user.id,
name: @user.name,
email: @user.email,
thumbnail: @user.avatar_url,
availability: account_user.availability_status,
metric: live_conversations
}
end
end
def live_conversations
@open_conversations = scope.conversations.where(account_id: @account.id).open
metric = {
open: @open_conversations.count,
unattended: @open_conversations.unattended.count
}
metric[:unassigned] = @open_conversations.unassigned.count if params[:type].equal?(:account)
metric
end
end
@@ -0,0 +1,57 @@
class Api::V2::Accounts::LiveReportsController < Api::V1::Accounts::BaseController
before_action :load_conversations, only: [:conversation_metrics, :grouped_conversation_metrics]
before_action :set_group_scope, only: [:grouped_conversation_metrics]
def conversation_metrics
render json: {
open: @conversations.open.count,
unattended: @conversations.open.unattended.count,
unassigned: @conversations.open.unassigned.count
}
end
def grouped_conversation_metrics
count_by_group = @conversations.open.group(@group_scope).count
unattended_by_group = @conversations.open.unattended.group(@group_scope).count
unassigned_by_group = @conversations.open.unassigned.group(@group_scope).count
group_metrics = count_by_group.map do |group_id, count|
metric = {
open: count,
unattended: unattended_by_group[group_id] || 0,
unassigned: unassigned_by_group[group_id] || 0
}
metric[@group_scope] = group_id
metric
end
render json: group_metrics
end
private
def set_group_scope
render json: { error: 'invalid group_by' }, status: :unprocessable_entity and return unless %w[
team_id
assignee_id
].include?(permitted_params[:group_by])
@group_scope = permitted_params[:group_by]
end
def team
return unless permitted_params[:team_id]
@team ||= Current.account.teams.find_by(permitted_params[:team_id])
end
def load_conversations
scope = Current.account.conversations
scope = scope.where(team_id: team.id) if team.present?
@conversations = scope
end
def permitted_params
params.permit(:team_id, :group_by)
end
end
@@ -42,12 +42,6 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
generate_csv('conversation_traffic_reports', 'api/v2/accounts/reports/conversation_traffic')
end
def conversations
return head :unprocessable_entity if params[:type].blank?
render json: conversation_metrics
end
private
def generate_csv(filename, template)
@@ -120,8 +114,4 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
summary[:previous] = V2::ReportBuilder.new(Current.account, previous_summary_params).summary
summary
end
def conversation_metrics
V2::ReportBuilder.new(Current.account, conversation_params).conversation_metrics
end
end
@@ -0,0 +1,20 @@
/* global axios */
import ApiClient from './ApiClient';
class LiveReportsAPI extends ApiClient {
constructor() {
super('live_reports', { accountScoped: true, apiVersion: 'v2' });
}
getConversationMetric() {
return axios.get(`${this.url}/conversation_metrics`);
}
getGroupedConversations({ groupBy } = { groupBy: 'assignee_id' }) {
return axios.get(`${this.url}/grouped_conversation_metrics`, {
params: { group_by: groupBy },
});
}
}
export default new LiveReportsAPI();
@@ -62,7 +62,6 @@
:agent-metrics="agentConversationMetric"
:page-index="pageIndex"
:is-loading="uiFlags.isFetchingAgentConversationMetric"
@page-change="onPageNumberChange"
/>
</metric-card>
</div>
@@ -132,8 +131,8 @@ export default {
},
methods: {
fetchAllData() {
this.fetchAccountConversationMetric();
this.fetchAgentConversationMetric();
this.$store.dispatch('fetchLiveConversationMetric');
this.$store.dispatch('fetchAgentConversationMetric');
this.fetchHeatmapData();
},
downloadHeatmapData() {
@@ -170,21 +169,6 @@ export default {
businessHours: false,
});
},
fetchAccountConversationMetric() {
this.$store.dispatch('fetchAccountConversationMetric', {
type: 'account',
});
},
fetchAgentConversationMetric() {
this.$store.dispatch('fetchAgentConversationMetric', {
type: 'agent',
page: this.pageIndex,
});
},
onPageNumberChange(pageIndex) {
this.pageIndex = pageIndex;
this.fetchAgentConversationMetric();
},
},
};
</script>
@@ -12,17 +12,12 @@
$t('OVERVIEW_REPORTS.AGENT_CONVERSATIONS.LOADING_MESSAGE')
}}</span>
</div>
<empty-state
v-else-if="!isLoading && !agentMetrics.length"
:title="$t('OVERVIEW_REPORTS.AGENT_CONVERSATIONS.NO_AGENTS')"
/>
<div v-if="agentMetrics.length > 0" class="table-pagination">
<div v-if="agents.length > 0" class="table-pagination">
<ve-pagination
:total="agents.length"
:page-index="pageIndex"
:page-size="25"
:page-size-option="[25]"
@on-page-number-change="onPageNumberChange"
/>
</div>
</div>
@@ -31,14 +26,12 @@
<script>
import { VeTable, VePagination } from 'vue-easytable';
import Spinner from 'shared/components/Spinner.vue';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
import rtlMixin from 'shared/mixins/rtlMixin';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
export default {
name: 'AgentTable',
components: {
EmptyState,
Spinner,
VeTable,
VePagination,
@@ -64,15 +57,15 @@ export default {
},
computed: {
tableData() {
return this.agentMetrics.map(agent => {
const agentInformation = this.getAgentInformation(agent.id);
return this.agents.map(agent => {
const agentMetrics = this.getAgentMetrics(agent.id);
return {
agent: agentInformation.name,
email: agentInformation.email,
thumbnail: agentInformation.thumbnail,
open: agent.metric.open || 0,
unattended: agent.metric.unattended || 0,
status: agentInformation.availability_status,
agent: agent.name,
email: agent.email,
thumbnail: agent.thumbnail,
open: agentMetrics.open || 0,
unattended: agentMetrics.unattended || 0,
status: agent.availability_status,
};
});
},
@@ -126,11 +119,11 @@ export default {
},
},
methods: {
onPageNumberChange(pageIndex) {
this.$emit('page-change', pageIndex);
},
getAgentInformation(id) {
return this.agents.find(agent => agent.id === Number(id));
getAgentMetrics(id) {
return (
this.agentMetrics.find(metrics => metrics.assignee_id === Number(id)) ||
{}
);
},
},
};
@@ -170,6 +163,7 @@ export default {
.title {
@apply text-sm m-0 leading-[1.2] text-slate-800 dark:text-slate-100;
}
.sub-title {
@apply text-xs text-slate-600 dark:text-slate-200;
}
@@ -8,6 +8,7 @@ import {
reconcileHeatmapData,
clampDataBetweenTimeline,
} from 'shared/helpers/ReportsDataHelper';
import liveReports from '../../api/liveReports';
const state = {
fetchingStatus: false,
@@ -125,9 +126,10 @@ export const actions = {
commit(types.default.TOGGLE_ACCOUNT_REPORT_LOADING, false);
});
},
fetchAccountConversationMetric({ commit }, reportObj) {
fetchLiveConversationMetric({ commit }) {
commit(types.default.TOGGLE_ACCOUNT_CONVERSATION_METRIC_LOADING, true);
Report.getConversationMetric(reportObj.type)
liveReports
.getConversationMetric()
.then(accountConversationMetric => {
commit(
types.default.SET_ACCOUNT_CONVERSATION_METRIC,
@@ -139,9 +141,10 @@ export const actions = {
commit(types.default.TOGGLE_ACCOUNT_CONVERSATION_METRIC_LOADING, false);
});
},
fetchAgentConversationMetric({ commit }, reportObj) {
fetchAgentConversationMetric({ commit }) {
commit(types.default.TOGGLE_AGENT_CONVERSATION_METRIC_LOADING, true);
Report.getConversationMetric(reportObj.type, reportObj.page)
liveReports
.getGroupedConversations()
.then(agentConversationMetric => {
commit(
types.default.SET_AGENT_CONVERSATION_METRIC,
+6
View File
@@ -294,6 +294,12 @@ Rails.application.routes.draw do
namespace :v2 do
resources :accounts, only: [:create] do
scope module: :accounts do
resources :live_reports, only: [] do
collection do
get :conversation_metrics
get :grouped_conversation_metrics
end
end
resources :reports, only: [:index] do
collection do
get :summary