From 9ba5adfd60ce1399cd14a2453669554940a4d96c Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Tue, 19 Sep 2023 00:34:58 -0700 Subject: [PATCH] chore: Support multiple values for automation message content (#7871) Co-authored-by: Pranav Raj S Co-authored-by: Muhsin Keloth --- .../dashboard/helper/filterQueryGenerator.js | 31 ++++++++---- .../mixins/automations/methodsMixin.js | 6 +++ .../automation/EditAutomationRule.vue | 4 +- .../settings/automation/constants.js | 2 +- app/services/filter_service.rb | 21 +++++++-- .../conversations/filter_service_spec.rb | 47 +++++++++++++++++-- 6 files changed, 90 insertions(+), 21 deletions(-) diff --git a/app/javascript/dashboard/helper/filterQueryGenerator.js b/app/javascript/dashboard/helper/filterQueryGenerator.js index d70a30a6b641..b2eff3d84e6d 100644 --- a/app/javascript/dashboard/helper/filterQueryGenerator.js +++ b/app/javascript/dashboard/helper/filterQueryGenerator.js @@ -1,21 +1,34 @@ const setArrayValues = item => { return item.values[0]?.id ? item.values.map(val => val.id) : item.values; }; + +const generateValues = item => { + if (item.attribute_key === 'content') { + const values = item.values || ''; + return values.split(','); + } + if (Array.isArray(item.values)) { + return setArrayValues(item); + } + if (typeof item.values === 'object') { + return [item.values.id]; + } + if (!item.values) { + return []; + } + return [item.values]; +}; + const generatePayload = data => { // Make a copy of data to avoid vue data reactivity issues const filters = JSON.parse(JSON.stringify(data)); let payload = filters.map(item => { - if (Array.isArray(item.values)) { - item.values = setArrayValues(item); - } else if (typeof item.values === 'object') { - item.values = [item.values.id]; - } else if (!item.values) { - item.values = []; - } else { - item.values = [item.values]; - } + // If item key is content, we will split it using comma and return as array + // FIX ME: Make this generic option instead of using the key directly here + item.values = generateValues(item); return item; }); + // For every query added, the query_operator is set default to and so the // last query will have an extra query_operator, this would break the api. // Setting this to null for all query payload diff --git a/app/javascript/dashboard/mixins/automations/methodsMixin.js b/app/javascript/dashboard/mixins/automations/methodsMixin.js index 611d5ad386f6..723cef22c22b 100644 --- a/app/javascript/dashboard/mixins/automations/methodsMixin.js +++ b/app/javascript/dashboard/mixins/automations/methodsMixin.js @@ -199,6 +199,12 @@ export default { values: condition.values[0], }; } + if (inputType === 'comma_separated_plain_text') { + return { + ...condition, + values: condition.values.join(','), + }; + } return { ...condition, query_operator: condition.query_operator || 'and', diff --git a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue index 74dac7cf9e45..3ac4548685cf 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/automation/EditAutomationRule.vue @@ -52,7 +52,7 @@ {{ $t('AUTOMATION.ADD.FORM.CONDITIONS.LABEL') }}
> 'browser_language' IN (?) AND status IN (?)", ['en'], [1, 2]) - expect(result.length).to be conversations.count + expect(result[:count][:all_count]).to be conversations.count end it 'filter conversations by additional_attributes and status with pagination' do @@ -83,7 +82,45 @@ params[:page] = 2 result = filter_service.new(params, user_1).perform conversations = Conversation.where("additional_attributes ->> 'browser_language' IN (?) AND status IN (?)", ['en'], [1, 2]) - expect(result.length).to be conversations.count + expect(result[:count][:all_count]).to be conversations.count + end + + it 'filters items with contains filter_operator with values being an array' do + params[:payload] = [{ + attribute_key: 'browser_language', + filter_operator: 'contains', + values: %w[tr fr], + query_operator: '', + custom_attribute_type: '' + }.with_indifferent_access] + + create(:conversation, account: account, inbox: inbox, assignee: user_1, campaign_id: campaign_1.id, + status: 'pending', additional_attributes: { 'browser_language': 'fr' }) + create(:conversation, account: account, inbox: inbox, assignee: user_1, campaign_id: campaign_1.id, + status: 'pending', additional_attributes: { 'browser_language': 'tr' }) + + result = filter_service.new(params, user_1).perform + expect(result[:count][:all_count]).to be 2 + end + + it 'filters items with does not contain filter operator with values being an array' do + params[:payload] = [{ + attribute_key: 'browser_language', + filter_operator: 'does_not_contain', + values: %w[tr en], + query_operator: '', + custom_attribute_type: '' + }.with_indifferent_access] + + create(:conversation, account: account, inbox: inbox, assignee: user_1, campaign_id: campaign_1.id, + status: 'pending', additional_attributes: { 'browser_language': 'fr' }) + create(:conversation, account: account, inbox: inbox, assignee: user_1, campaign_id: campaign_1.id, + status: 'pending', additional_attributes: { 'browser_language': 'tr' }) + + result = filter_service.new(params, user_1).perform + + expect(result[:count][:all_count]).to be 1 + expect(result[:conversations].first.additional_attributes['browser_language']).to eq 'fr' end it 'filter conversations by additional_attributes with NOT_IN filter' do @@ -98,7 +135,7 @@ end it 'filter conversations by tags' do - unassigned_conversation.update_labels('support') + user_2_assigned_conversation.update_labels('support') params[:payload] = [ { attribute_key: 'assignee_id', @@ -119,7 +156,7 @@ }.with_indifferent_access ] result = filter_service.new(params, user_1).perform - expect(result.length).to be 2 + expect(result[:count][:all_count]).to be 1 end it 'filter conversations by is_present filter_operator' do