feat: Add filter APIs for Contacts and Conversations (#3264)

This commit is contained in:
Tejaswini Chile
2021-11-01 12:27:04 +04:00
committed by GitHub
parent 68fa694268
commit 372bd75028
13 changed files with 470 additions and 19 deletions
+44
View File
@@ -0,0 +1,44 @@
class Contacts::FilterService < FilterService
def perform
@contacts = contact_query_builder
{
contacts: @contacts,
count: {
all_count: @contacts.count
}
}
end
def contact_query_builder
contact_filters = @filters['contacts']
@params[:payload].each_with_index do |query_hash, current_index|
current_filter = contact_filters[query_hash['attribute_key']]
@query_string += contact_query_string(current_filter, query_hash, current_index)
end
base_relation.where(@query_string, @filter_values.with_indifferent_access)
end
def contact_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash[:attribute_key]
query_operator = query_hash[:query_operator]
filter_operator_value = filter_operation(query_hash, current_index)
case current_filter['attribute_type']
when 'additional_attributes'
" contacts.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
if attribute_key == 'labels'
" tags.id #{filter_operator_value} #{query_operator} "
else
" contacts.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
end
end
def base_relation
Current.account.contacts.left_outer_joins(:labels)
end
end
@@ -0,0 +1,59 @@
class Conversations::FilterService < FilterService
def perform
@conversations = conversation_query_builder
mine_count, unassigned_count, all_count, = set_count_for_all_conversations
assigned_count = all_count - unassigned_count
{
conversations: conversations,
count: {
mine_count: mine_count,
assigned_count: assigned_count,
unassigned_count: unassigned_count,
all_count: all_count
}
}
end
def conversation_query_builder
conversation_filters = @filters['conversations']
@params[:payload].each_with_index do |query_hash, current_index|
current_filter = conversation_filters[query_hash['attribute_key']]
@query_string += conversation_query_string(current_filter, query_hash, current_index)
end
base_relation.where(@query_string, @filter_values.with_indifferent_access)
end
def conversation_query_string(current_filter, query_hash, current_index)
attribute_key = query_hash[:attribute_key]
query_operator = query_hash[:query_operator]
filter_operator_value = filter_operation(query_hash, current_index)
case current_filter['attribute_type']
when 'additional_attributes'
" conversations.additional_attributes ->> '#{attribute_key}' #{filter_operator_value} #{query_operator} "
when 'standard'
if attribute_key == 'labels'
" tags.id #{filter_operator_value} #{query_operator} "
else
" conversations.#{attribute_key} #{filter_operator_value} #{query_operator} "
end
end
end
def base_relation
Current.account.conversations.left_outer_joins(:labels)
end
def current_page
@params[:page] || 1
end
def conversations
@conversations = @conversations.includes(
:taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team
)
@conversations.latest.page(current_page)
end
end
+50
View File
@@ -0,0 +1,50 @@
require 'json'
class FilterService
def initialize(params, user)
@params = params
@user = user
file = File.read('./lib/filters/filter_keys.json')
@filters = JSON.parse(file)
@query_string = ''
@filter_values = {}
end
def perform; end
def filter_operation(query_hash, current_index)
case query_hash[:filter_operator]
when 'equal_to'
@filter_values["value_#{current_index}"] = filter_values(query_hash)
"IN (:value_#{current_index})"
when 'not_equal_to'
@filter_values["value_#{current_index}"] = filter_values(query_hash)
"NOT IN (:value_#{current_index})"
when 'contains'
@filter_values["value_#{current_index}"] = "%#{filter_values(query_hash)}%"
"LIKE :value_#{current_index}"
when 'does_not_contain'
@filter_values["value_#{current_index}"] = "%#{filter_values(query_hash)}%"
"NOT LIKE :value_#{current_index}"
else
@filter_values["value_#{current_index}"] = filter_values(query_hash).to_s
"= :value_#{current_index}"
end
end
def filter_values(query_hash)
if query_hash['attribute_key'] == 'status'
query_hash['values'].map { |x| Conversation.statuses[x.to_sym] }
else
query_hash['values']
end
end
def set_count_for_all_conversations
[
@conversations.assigned_to(@user).count,
@conversations.unassigned.count,
@conversations.count
]
end
end