diff --git a/app/javascript/dashboard/api/contacts.js b/app/javascript/dashboard/api/contacts.js index 0ed9bb101..a6415cb37 100644 --- a/app/javascript/dashboard/api/contacts.js +++ b/app/javascript/dashboard/api/contacts.js @@ -52,6 +52,14 @@ class ContactAPI extends ApiClient { )}`; return axios.get(requestURL); } + + importContacts(file) { + const formData = new FormData(); + formData.append('import_file', file); + return axios.post(`${this.url}/import`, formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + } } export default new ContactAPI(); diff --git a/app/javascript/dashboard/api/specs/contacts.spec.js b/app/javascript/dashboard/api/specs/contacts.spec.js index 0c0a21125..03a71ca11 100644 --- a/app/javascript/dashboard/api/specs/contacts.spec.js +++ b/app/javascript/dashboard/api/specs/contacts.spec.js @@ -59,6 +59,18 @@ describe('#ContactsAPI', () => { '/api/v1/contacts/search?include_contact_inboxes=false&page=1&sort=date&q=leads&labels[]=customer-support' ); }); + + it('#importContacts', () => { + const file = 'file'; + contactAPI.importContacts(file); + expect(context.axiosMock.post).toHaveBeenCalledWith( + '/api/v1/contacts/import', + expect.any(FormData), + { + headers: { 'Content-Type': 'multipart/form-data' }, + } + ); + }); }); }); diff --git a/app/javascript/dashboard/assets/scss/_utility-helpers.scss b/app/javascript/dashboard/assets/scss/_utility-helpers.scss new file mode 100644 index 000000000..60fecb994 --- /dev/null +++ b/app/javascript/dashboard/assets/scss/_utility-helpers.scss @@ -0,0 +1,3 @@ +.margin-right-small { + margin-right: var(--space-small); +} diff --git a/app/javascript/dashboard/assets/scss/widgets/_modal.scss b/app/javascript/dashboard/assets/scss/widgets/_modal.scss index 8c4e656c4..a017f776a 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_modal.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_modal.scss @@ -71,7 +71,8 @@ @include padding($space-large); } - form { + form, + .modal-content { @include padding($space-large); align-self: center; diff --git a/app/javascript/dashboard/i18n/locale/en/contact.json b/app/javascript/dashboard/i18n/locale/en/contact.json index d08b363ff..44f241e79 100644 --- a/app/javascript/dashboard/i18n/locale/en/contact.json +++ b/app/javascript/dashboard/i18n/locale/en/contact.json @@ -54,6 +54,19 @@ "TITLE": "Create new contact", "DESC": "Add basic information details about the contact." }, + "IMPORT_CONTACTS": { + "BUTTON_LABEL": "Import", + "TITLE": "Import Contacts", + "DESC": "Import contacts through a CSV file.", + "DOWNLOAD_LABEL": "Download a sample csv.", + "FORM": { + "LABEL": "CSV File", + "SUBMIT": "Import", + "CANCEL": "Cancel" + }, + "SUCCESS_MESSAGE": "Contacts saved successfully", + "ERROR_MESSAGE": "There was an error, please try again" + }, "DELETE_CONTACT": { "BUTTON_LABEL": "Delete Contact", "TITLE": "Delete contact", @@ -255,4 +268,4 @@ "ERROR_MESSAGE": "Could not merge contcts, try again!" } } -} +} \ No newline at end of file diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue index ada19502e..4ac5c0fc7 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/ContactsView.vue @@ -7,6 +7,7 @@ this-selected-contact-id="" :on-input-search="onInputSearch" :on-toggle-create="onToggleCreate" + :on-toggle-import="onToggleImport" :header-title="label" /> + + + @@ -41,6 +45,7 @@ import ContactsTable from './ContactsTable'; import ContactInfoPanel from './ContactInfoPanel'; import CreateContact from 'dashboard/routes/dashboard/conversation/contact/CreateContact'; import TableFooter from 'dashboard/components/widgets/TableFooter'; +import ImportContacts from './ImportContacts.vue'; const DEFAULT_PAGE = 1; @@ -51,6 +56,7 @@ export default { TableFooter, ContactInfoPanel, CreateContact, + ImportContacts, }, props: { label: { type: String, default: '' }, @@ -59,6 +65,7 @@ export default { return { searchQuery: '', showCreateModal: false, + showImportModal: false, selectedContactId: '', sortConfig: { name: 'asc' }, }; @@ -168,6 +175,9 @@ export default { onToggleCreate() { this.showCreateModal = !this.showCreateModal; }, + onToggleImport() { + this.showImportModal = !this.showImportModal; + }, onSortChange(params) { this.sortConfig = params; this.fetchContacts(this.meta.currentPage); diff --git a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue index 93e471a76..008bf2c34 100644 --- a/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue +++ b/app/javascript/dashboard/routes/dashboard/contacts/components/Header.vue @@ -29,11 +29,20 @@ {{ $t('CREATE_CONTACT.BUTTON_LABEL') }} + + + {{ $t('IMPORT_CONTACTS.BUTTON_LABEL') }} + @@ -41,7 +50,6 @@