From 5d9fb55370ccd9ea01043cbfe0e74f09569602e0 Mon Sep 17 00:00:00 2001 From: Liam <43280985+LiamAshdown@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:41:03 +0000 Subject: [PATCH] feat: Export contact improvements (#8895) This pull request enhances the export contacts feature by adding a confirmation step before exporting. Previously, clicking the export button would trigger the export action without confirmation. Additionally, it ensures that only the intended recipient receives the export email, addressing the previous behaviour where all administrators received it. Fixes: #8504 Co-authored-by: Sojan Jose --- .../api/v1/accounts/contacts_controller.rb | 2 +- .../dashboard/i18n/locale/en/contact.json | 8 +++++++- .../dashboard/contacts/components/Header.vue | 16 ++++++++++++++-- app/jobs/account/contacts_export_job.rb | 4 ++-- .../channel_notifications_mailer.rb | 5 +++-- .../api/v1/accounts/contacts_controller_spec.rb | 4 ++-- spec/jobs/account/contacts_export_job_spec.rb | 6 +++--- .../channel_notifications_mailer_spec.rb | 5 ++--- 8 files changed, 34 insertions(+), 16 deletions(-) diff --git a/app/controllers/api/v1/accounts/contacts_controller.rb b/app/controllers/api/v1/accounts/contacts_controller.rb index f424f3b66..98683ea25 100644 --- a/app/controllers/api/v1/accounts/contacts_controller.rb +++ b/app/controllers/api/v1/accounts/contacts_controller.rb @@ -46,7 +46,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController def export column_names = params['column_names'] - Account::ContactsExportJob.perform_later(Current.account.id, column_names) + Account::ContactsExportJob.perform_later(Current.account.id, column_names, Current.user.email) head :ok, message: I18n.t('errors.contacts.export.success') end diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index 594e34c4f..cae908016 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -79,7 +79,13 @@ "TITLE": "Export Contacts", "DESC": "Export contacts to a CSV file.", "SUCCESS_MESSAGE": "Export is in progress. You will be notified on email when the export file is ready to download.", - "ERROR_MESSAGE": "There was an error, please try again" + "ERROR_MESSAGE": "There was an error, please try again", + "CONFIRM": { + "TITLE": "Export Contacts", + "MESSAGE": "Are you sure you want to export all contacts?", + "YES": "Yes, Export", + "NO": "No, Cancel" + } }, "DELETE_NOTE": { "CONFIRM": { diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue index 4df4017b2..1b4fd90e0 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue @@ -113,6 +113,13 @@ + @@ -175,8 +182,13 @@ export default { toggleImport() { this.$emit('on-toggle-import'); }, - submitExport() { - this.$emit('on-export-submit'); + async submitExport() { + const ok = + await this.$refs.confirmExportContactsDialog.showConfirmation(); + + if (ok) { + this.$emit('on-export-submit'); + } }, submitSearch() { this.$emit('on-search-submit'); diff --git a/app/jobs/account/contacts_export_job.rb b/app/jobs/account/contacts_export_job.rb index 0ae8b3892..b8e9dbc96 100644 --- a/app/jobs/account/contacts_export_job.rb +++ b/app/jobs/account/contacts_export_job.rb @@ -1,13 +1,13 @@ class Account::ContactsExportJob < ApplicationJob queue_as :low - def perform(account_id, column_names) + def perform(account_id, column_names, email_to) account = Account.find(account_id) headers = valid_headers(column_names) generate_csv(account, headers) file_url = account_contact_export_url(account) - AdministratorNotifications::ChannelNotificationsMailer.with(account: account).contact_export_complete(file_url)&.deliver_later + AdministratorNotifications::ChannelNotificationsMailer.with(account: account).contact_export_complete(file_url, email_to)&.deliver_later end def generate_csv(account, headers) diff --git a/app/mailers/administrator_notifications/channel_notifications_mailer.rb b/app/mailers/administrator_notifications/channel_notifications_mailer.rb index 8c52a9bd3..6c0f7cee2 100644 --- a/app/mailers/administrator_notifications/channel_notifications_mailer.rb +++ b/app/mailers/administrator_notifications/channel_notifications_mailer.rb @@ -60,12 +60,13 @@ class AdministratorNotifications::ChannelNotificationsMailer < ApplicationMailer send_mail_with_liquid(to: admin_emails, subject: subject) and return end - def contact_export_complete(file_url) + def contact_export_complete(file_url, email_to) return unless smtp_config_set_or_development? @action_url = file_url subject = "Your contact's export file is available to download." - send_mail_with_liquid(to: admin_emails, subject: subject) and return + + send_mail_with_liquid(to: email_to, subject: subject) and return end private diff --git a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb index e5e298747..21511310b 100644 --- a/spec/controllers/api/v1/accounts/contacts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/contacts_controller_spec.rb @@ -197,7 +197,7 @@ RSpec.describe 'Contacts API', type: :request do let(:admin) { create(:user, account: account, role: :administrator) } it 'enqueues a contact export job' do - expect(Account::ContactsExportJob).to receive(:perform_later).with(account.id, nil).once + expect(Account::ContactsExportJob).to receive(:perform_later).with(account.id, nil, admin.email).once get "/api/v1/accounts/#{account.id}/contacts/export", headers: admin.create_new_auth_token, @@ -207,7 +207,7 @@ RSpec.describe 'Contacts API', type: :request do end it 'enqueues a contact export job with sent_columns' do - expect(Account::ContactsExportJob).to receive(:perform_later).with(account.id, %w[phone_number email]).once + expect(Account::ContactsExportJob).to receive(:perform_later).with(account.id, %w[phone_number email], admin.email).once get "/api/v1/accounts/#{account.id}/contacts/export", headers: admin.create_new_auth_token, diff --git a/spec/jobs/account/contacts_export_job_spec.rb b/spec/jobs/account/contacts_export_job_spec.rb index e597ff637..b395967b4 100644 --- a/spec/jobs/account/contacts_export_job_spec.rb +++ b/spec/jobs/account/contacts_export_job_spec.rb @@ -24,17 +24,17 @@ RSpec.describe Account::ContactsExportJob do allow(AdministratorNotifications::ChannelNotificationsMailer).to receive(:with).with(account: account).and_return(mailer) allow(mailer).to receive(:contact_export_complete) - described_class.perform_now(account.id, []) + described_class.perform_now(account.id, [], 'test@test.com') file_url = Rails.application.routes.url_helpers.rails_blob_url(account.contacts_export) expect(account.contacts_export).to be_present expect(file_url).to be_present - expect(mailer).to have_received(:contact_export_complete).with(file_url) + expect(mailer).to have_received(:contact_export_complete).with(file_url, 'test@test.com') end it 'generates valid data export file' do - described_class.perform_now(account.id, []) + described_class.perform_now(account.id, [], 'test@test.com') csv_data = CSV.parse(account.contacts_export.download, headers: true) emails = csv_data.pluck('email') diff --git a/spec/mailers/administrator_notifications/channel_notifications_mailer_spec.rb b/spec/mailers/administrator_notifications/channel_notifications_mailer_spec.rb index f67b8300c..944475fb2 100644 --- a/spec/mailers/administrator_notifications/channel_notifications_mailer_spec.rb +++ b/spec/mailers/administrator_notifications/channel_notifications_mailer_spec.rb @@ -10,7 +10,6 @@ RSpec.describe AdministratorNotifications::ChannelNotificationsMailer do before do allow(described_class).to receive(:new).and_return(class_instance) allow(class_instance).to receive(:smtp_config_set_or_development?).and_return(true) - Account::ContactsExportJob.perform_now(account.id, []) end describe 'slack_disconnect' do @@ -92,8 +91,8 @@ RSpec.describe AdministratorNotifications::ChannelNotificationsMailer do end describe 'contact_export_complete' do - let!(:file_url) { Rails.application.routes.url_helpers.rails_blob_url(account.contacts_export) } - let(:mail) { described_class.with(account: account).contact_export_complete(file_url).deliver_now } + let!(:file_url) { 'http://test.com/test' } + let(:mail) { described_class.with(account: account).contact_export_complete(file_url, administrator.email).deliver_now } it 'renders the subject' do expect(mail.subject).to eq("Your contact's export file is available to download.")