Skip to content

Commit

Permalink
Merge pull request #29 from DigitalTolk/custom-report-filter
Browse files Browse the repository at this point in the history
feat: custom report filter
  • Loading branch information
jderecho authored Apr 15, 2024
2 parents b0f5a87 + 13b3871 commit 7f45dff
Show file tree
Hide file tree
Showing 16 changed files with 416 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def set_csat_survey_responses
.filter_by_inbox_id(params[:inbox_id])
.filter_by_team_id(params[:team_id])
.filter_by_rating(params[:rating])
.filter_by_label(params[:label])
end

def set_current_page_surveys
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/api/v2/accounts/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ def common_params
type: params[:type].to_sym,
id: params[:id],
group_by: params[:group_by],
business_hours: ActiveModel::Type::Boolean.new.cast(params[:business_hours])
business_hours: ActiveModel::Type::Boolean.new.cast(params[:business_hours]),
custom_filter: params[:custom_filter]
}
end

Expand Down
122 changes: 110 additions & 12 deletions app/helpers/report_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,104 @@ def scope
end
end

def custom_filter(collection)
return collection if collection.blank?

case collection.model_name.name
when 'Conversation'
filter_conversations(collection)
when 'Message'
filter_messages(collection)
when 'ReportingEvent'
filter_reporting_events(collection)
else
collection
end
end

def get_filter(key, field)
filter = params.dig(:custom_filter, key)
return [] unless filter.present?

filter.to_unsafe_h.values
end

def selected_label
get_filter(:selected_label, :title)
end

def selected_team
get_filter(:selected_team, :id)
end

def selected_inbox
get_filter(:selected_inbox, :id)
end

def selected_rating
get_filter(:selected_rating, :value)
end

def filter_conversations(collection)
if selected_label.present?
collection = collection.where(cached_label_list: selected_label)
end

if selected_team.present?
collection = collection.where(team_id: selected_team)
end

if selected_inbox.present?
collection = collection.where(inbox_id: selected_inbox)
end

if selected_rating.present?
collection = collection.joins(:csat_survey_responses).where(csat_survey_responses: {rating: selected_rating}).distinct
end

collection
end

def filter_messages(collection)
if selected_label.present?
collection = collection.joins(:conversation).where(conversations: {cached_label_list: selected_label})
end

if selected_team.present?
collection = collection.joins(:conversation).where(conversations: {team_id: selected_team})
end

if selected_inbox.present?
collection = collection.where(inbox_id: selected_inbox)
end

if selected_rating.present?
collection = collection.joins(conversation: :csat_survey_responses).where(csat_survey_responses: {rating: selected_rating}).distinct
end

collection
end

def filter_reporting_events(collection)
if selected_label.present?
collection = collection.joins(:conversation).where(conversations: {cached_label_list: selected_label})
end

if selected_team.present?
collection = collection.joins(:conversation).where(conversations: {team_id: selected_team})
end

if selected_inbox.present?
collection = collection.where(inbox_id: selected_inbox)
end

if selected_rating.present?
collection = collection.joins(conversation: :csat_survey_responses).where(csat_survey_responses: {rating: selected_rating}).distinct
end

collection
end

def conversations_count
(get_grouped_values conversations).count
end
Expand All @@ -41,55 +139,55 @@ def bot_handoffs_count
end

def conversations
scope.conversations.where(account_id: account.id, created_at: range)
custom_filter(scope.conversations).where(account_id: account.id, created_at: range)
end

def incoming_messages
scope.messages.where(account_id: account.id, created_at: range).incoming.unscope(:order)
custom_filter(scope.messages).where(account_id: account.id, created_at: range).incoming.unscope(:order)
end

def outgoing_messages
scope.messages.where(account_id: account.id, created_at: range).outgoing.unscope(:order)
custom_filter(scope.messages).where(account_id: account.id, created_at: range).outgoing.unscope(:order)
end

def resolutions
scope.reporting_events.joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_resolved,
custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_resolved,
conversations: { status: :resolved }, created_at: range).distinct
end

def bot_resolutions
scope.reporting_events.joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_bot_resolved,
custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_bot_resolved,
conversations: { status: :resolved }, created_at: range).distinct
end

def bot_handoffs
scope.reporting_events.joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_bot_handoff,
custom_filter(scope.reporting_events).joins(:conversation).select(:conversation_id).where(account_id: account.id, name: :conversation_bot_handoff,
created_at: range).distinct
end

def avg_first_response_time
grouped_reporting_events = (get_grouped_values scope.reporting_events.where(name: 'first_response', account_id: account.id))
grouped_reporting_events = (get_grouped_values custom_filter(scope.reporting_events).where(name: 'first_response', account_id: account.id))
return grouped_reporting_events.average(:value_in_business_hours) if params[:business_hours]

grouped_reporting_events.average(:value)
end

def reply_time
grouped_reporting_events = (get_grouped_values scope.reporting_events.where(name: 'reply_time', account_id: account.id))
grouped_reporting_events = (get_grouped_values custom_filter(scope.reporting_events).where(name: 'reply_time', account_id: account.id))
return grouped_reporting_events.average(:value_in_business_hours) if params[:business_hours]

grouped_reporting_events.average(:value)
end

def avg_resolution_time
grouped_reporting_events = (get_grouped_values scope.reporting_events.where(name: 'conversation_resolved', account_id: account.id))
grouped_reporting_events = (get_grouped_values custom_filter(scope.reporting_events).where(name: 'conversation_resolved', account_id: account.id))
return grouped_reporting_events.average(:value_in_business_hours) if params[:business_hours]

grouped_reporting_events.average(:value)
end

def avg_resolution_time_summary
reporting_events = scope.reporting_events
reporting_events = custom_filter(scope.reporting_events)
.where(name: 'conversation_resolved', account_id: account.id, created_at: range)
avg_rt = if params[:business_hours].present?
reporting_events.average(:value_in_business_hours)
Expand All @@ -103,7 +201,7 @@ def avg_resolution_time_summary
end

def reply_time_summary
reporting_events = scope.reporting_events
reporting_events = custom_filter(scope.reporting_events)
.where(name: 'reply_time', account_id: account.id, created_at: range)
reply_time = params[:business_hours] ? reporting_events.average(:value_in_business_hours) : reporting_events.average(:value)

Expand All @@ -113,7 +211,7 @@ def reply_time_summary
end

def avg_first_response_time_summary
reporting_events = scope.reporting_events
reporting_events = custom_filter(scope.reporting_events)
.where(name: 'first_response', account_id: account.id, created_at: range)
avg_frt = if params[:business_hours].present?
reporting_events.average(:value_in_business_hours)
Expand Down
12 changes: 8 additions & 4 deletions app/javascript/dashboard/api/csatReports.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class CSATReportsAPI extends ApiClient {
team_id,
rating,
question_id,
label,
} = {}) {
return axios.get(this.url, {
params: {
Expand All @@ -27,11 +28,12 @@ class CSATReportsAPI extends ApiClient {
team_id,
rating,
question_id,
label,
},
});
}

getQuestions({ from, to, user_ids, inbox_id, team_id, rating } = {}) {
getQuestions({ from, to, user_ids, inbox_id, team_id, rating, label } = {}) {
return axios.get(`${this.url}/questions`, {
params: {
since: from,
Expand All @@ -41,11 +43,12 @@ class CSATReportsAPI extends ApiClient {
inbox_id,
team_id,
rating,
label
},
});
}

download({ from, to, user_ids, inbox_id, team_id, rating } = {}) {
download({ from, to, user_ids, inbox_id, team_id, rating, label } = {}) {
return axios.get(`${this.url}/download`, {
params: {
since: from,
Expand All @@ -55,14 +58,15 @@ class CSATReportsAPI extends ApiClient {
inbox_id,
team_id,
rating,
label
},
});
}

getMetrics({ from, to, user_ids, inbox_id, team_id, rating } = {}) {
getMetrics({ from, to, user_ids, inbox_id, team_id, rating, label } = {}) {
// no ratings for metrics
return axios.get(`${this.url}/metrics`, {
params: { since: from, until: to, user_ids, inbox_id, team_id, rating },
params: { since: from, until: to, user_ids, inbox_id, team_id, rating, label },
});
}
}
Expand Down
18 changes: 17 additions & 1 deletion app/javascript/dashboard/api/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ class ReportsAPI extends ApiClient {
from,
to,
type = 'account',
selectedLabel,
selectedTeam,
selectedInbox,
selectedRating,
id,
groupBy,
businessHours,
Expand All @@ -22,6 +26,12 @@ class ReportsAPI extends ApiClient {
metric,
since: from,
until: to,
custom_filter: {
selected_label: selectedLabel,
selected_team: selectedTeam,
selected_inbox: selectedInbox,
selected_rating: selectedRating
},
type,
id,
group_by: groupBy,
Expand All @@ -32,11 +42,17 @@ class ReportsAPI extends ApiClient {
}

// eslint-disable-next-line default-param-last
getSummary(since, until, type = 'account', id, groupBy, businessHours) {
getSummary(since, until, type = 'account', selectedLabel, selectedTeam, selectedInbox, selectedRating, id, groupBy, businessHours) {
return axios.get(`${this.url}/summary`, {
params: {
since,
until,
custom_filter: {
selected_label: selectedLabel,
selected_team: selectedTeam,
selected_inbox: selectedInbox,
selected_rating: selectedRating
},
type,
id,
group_by: groupBy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
:show-agents-filter="true"
:show-inbox-filter="true"
:show-rating-filter="true"
:show-labels-filter="true"
:show-team-filter="isTeamsEnabled"
:show-business-hours-switch="false"
@filter-change="onFilterChange"
:multiple-labels="true"
:multiple-teams="true"
:multiple-inboxes="true"
:multiple-ratings="true"
/>
<woot-button
color-scheme="success"
Expand Down Expand Up @@ -55,9 +60,10 @@ export default {
from: 0,
to: 0,
userIds: [],
inbox: null,
team: null,
rating: null,
inbox: [],
team: [],
rating: [],
label: [],
groudByQuestions: false,
};
},
Expand All @@ -74,6 +80,7 @@ export default {
inbox_id: this.inbox,
team_id: this.team,
rating: this.rating,
label: this.label,
};
},
isTeamsEnabled() {
Expand Down Expand Up @@ -121,6 +128,7 @@ export default {
selectedInbox,
selectedTeam,
selectedRating,
selectedLabel
}) {
// do not track filter change on inital load
if (this.from !== 0 && this.to !== 0) {
Expand All @@ -132,10 +140,11 @@ export default {
this.from = from;
this.to = to;
this.userIds = selectedAgents.map(el => el.id);
this.inbox = selectedInbox?.id;
this.team = selectedTeam?.id;
this.rating = selectedRating?.value;
this.userIds = selectedAgents && selectedAgents.map(el => el.id);
this.inbox = selectedInbox &&selectedInbox.map(el => el.id);
this.team = selectedTeam && selectedTeam.map(el => el.id);
this.rating = selectedRating && selectedRating.map(el => el.value);
this.label = selectedLabel && selectedLabel.map(el => el.title);
this.getAllData();
},
Expand Down
Loading

0 comments on commit 7f45dff

Please sign in to comment.