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 @@