-
-
-
-
-
-
- {{ $t('CONTACT_PROFILE.LOADING') }}
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/javascript/dashboard/routes/dashboard/contacts/pages/ContactsIndex.vue b/app/javascript/dashboard/routes/dashboard/contacts/pages/ContactsIndex.vue
index af18ea684..a491d0829 100644
--- a/app/javascript/dashboard/routes/dashboard/contacts/pages/ContactsIndex.vue
+++ b/app/javascript/dashboard/routes/dashboard/contacts/pages/ContactsIndex.vue
@@ -133,6 +133,7 @@ const fetchSavedOrAppliedFilteredContact = async (payload, page = 1) => {
};
const searchContacts = debounce(async (value, page = 1) => {
+ await store.dispatch('contacts/clearContactFilters');
searchValue.value = value;
if (!value) {
diff --git a/app/javascript/dashboard/routes/dashboard/contacts/routes.js b/app/javascript/dashboard/routes/dashboard/contacts/routes.js
index 7bbefa4a4..ea5238a3b 100644
--- a/app/javascript/dashboard/routes/dashboard/contacts/routes.js
+++ b/app/javascript/dashboard/routes/dashboard/contacts/routes.js
@@ -1,44 +1,60 @@
-/* eslint arrow-body-style: 0 */
import { frontendURL } from '../../../helper/URLHelper';
import ContactsIndex from './pages/ContactsIndex.vue';
import ContactManageView from './pages/ContactManageView.vue';
+const commonMeta = {
+ permissions: ['administrator', 'agent', 'contact_manage'],
+};
+
export const routes = [
{
path: frontendURL('accounts/:accountId/contacts'),
component: ContactsIndex,
- name: 'contacts_dashboard_index',
- meta: {
- permissions: ['administrator', 'agent', 'contact_manage'],
- },
- },
-
- {
- path: frontendURL('accounts/:accountId/contacts/segments/:segmentId'),
- component: ContactsIndex,
- name: 'contacts_dashboard_segments_index',
- meta: {
- permissions: ['administrator', 'agent', 'contact_manage'],
- },
- },
-
- {
- path: frontendURL('accounts/:accountId/contacts/labels/:label'),
- component: ContactsIndex,
- name: 'contacts_dashboard_labels_index',
- meta: {
- permissions: ['administrator', 'agent', 'contact_manage'],
- },
+ meta: commonMeta,
+ children: [
+ {
+ path: '',
+ name: 'contacts_dashboard_index',
+ component: ContactsIndex,
+ meta: commonMeta,
+ },
+ {
+ path: 'segments/:segmentId',
+ name: 'contacts_dashboard_segments_index',
+ component: ContactsIndex,
+ meta: commonMeta,
+ },
+ {
+ path: 'labels/:label',
+ name: 'contacts_dashboard_labels_index',
+ component: ContactsIndex,
+ meta: commonMeta,
+ },
+ ],
},
{
path: frontendURL('accounts/:accountId/contacts/:contactId'),
- name: 'contacts_edit',
- meta: {
- permissions: ['administrator', 'agent', 'contact_manage'],
- },
component: ContactManageView,
- props: route => {
- return { contactId: route.params.contactId };
- },
+ meta: commonMeta,
+ children: [
+ {
+ path: '',
+ name: 'contacts_edit',
+ component: ContactManageView,
+ meta: commonMeta,
+ },
+ {
+ path: 'segments/:segmentId',
+ name: 'contacts_edit_segment',
+ component: ContactManageView,
+ meta: commonMeta,
+ },
+ {
+ path: 'labels/:label',
+ name: 'contacts_edit_label',
+ component: ContactManageView,
+ meta: commonMeta,
+ },
+ ],
},
];
diff --git a/app/javascript/dashboard/store/modules/attributes.js b/app/javascript/dashboard/store/modules/attributes.js
index c7cb771a5..3d0cd78bd 100644
--- a/app/javascript/dashboard/store/modules/attributes.js
+++ b/app/javascript/dashboard/store/modules/attributes.js
@@ -35,6 +35,12 @@ export const getters = {
record => record.attribute_model === attributeModel
);
},
+ getAttributesByModelType: _state => attributeModel => {
+ const records = _state.records.filter(
+ record => record.attribute_model === attributeModel
+ );
+ return camelcaseKeys(records, { deep: true });
+ },
};
export const actions = {
diff --git a/app/javascript/dashboard/store/modules/contactConversations.js b/app/javascript/dashboard/store/modules/contactConversations.js
index 795578e63..55dfcf441 100644
--- a/app/javascript/dashboard/store/modules/contactConversations.js
+++ b/app/javascript/dashboard/store/modules/contactConversations.js
@@ -1,6 +1,7 @@
import * as types from '../mutation-types';
import ContactAPI from '../../api/contacts';
import ConversationApi from '../../api/conversations';
+import camelcaseKeys from 'camelcase-keys';
export const createMessagePayload = (payload, message) => {
const { content, cc_emails, bcc_emails } = message;
@@ -74,6 +75,10 @@ export const getters = {
getContactConversation: $state => id => {
return $state.records[Number(id)] || [];
},
+ getAllConversationsByContactId: $state => id => {
+ const records = $state.records[Number(id)] || [];
+ return camelcaseKeys(records, { deep: true });
+ },
};
export const actions = {
diff --git a/app/javascript/dashboard/store/modules/contactNotes.js b/app/javascript/dashboard/store/modules/contactNotes.js
index 2a82981a3..005a4f113 100644
--- a/app/javascript/dashboard/store/modules/contactNotes.js
+++ b/app/javascript/dashboard/store/modules/contactNotes.js
@@ -1,5 +1,6 @@
import types from '../mutation-types';
import ContactNotesAPI from '../../api/contactNotes';
+import camelcaseKeys from 'camelcase-keys';
export const state = {
records: {},
@@ -18,6 +19,11 @@ export const getters = {
getUIFlags(_state) {
return _state.uiFlags;
},
+ getAllNotesByContactId: _state => contactId => {
+ const records = _state.records[contactId] || [];
+ const contactNotes = records.sort((r1, r2) => r2.id - r1.id);
+ return camelcaseKeys(contactNotes);
+ },
};
export const actions = {
diff --git a/app/javascript/dashboard/store/modules/contacts/actions.js b/app/javascript/dashboard/store/modules/contacts/actions.js
index 5b67029c0..a78b66cba 100644
--- a/app/javascript/dashboard/store/modules/contacts/actions.js
+++ b/app/javascript/dashboard/store/modules/contacts/actions.js
@@ -34,7 +34,7 @@ const buildContactFormData = contactParams => {
return formData;
};
-export const raiseContactCreateErrors = error => {
+export const handleContactOperationErrors = error => {
if (error.response?.status === 422) {
throw new DuplicateContactException(error.response.data.attributes);
} else if (error.response?.data?.message) {
@@ -91,9 +91,12 @@ export const actions = {
},
update: async ({ commit }, { id, isFormData = false, ...contactParams }) => {
- const decamelizedContactParams = decamelizeKeys(contactParams, {
- deep: true,
- });
+ const { avatar, customAttributes, ...paramsToDecamelize } = contactParams;
+ const decamelizedContactParams = {
+ ...decamelizeKeys(paramsToDecamelize),
+ ...(customAttributes && { custom_attributes: customAttributes }),
+ ...(avatar && { avatar }),
+ };
commit(types.SET_CONTACT_UI_FLAG, { isUpdating: true });
try {
const response = await ContactAPI.update(
@@ -106,11 +109,7 @@ export const actions = {
commit(types.SET_CONTACT_UI_FLAG, { isUpdating: false });
} catch (error) {
commit(types.SET_CONTACT_UI_FLAG, { isUpdating: false });
- if (error.response?.status === 422) {
- throw new DuplicateContactException(error.response.data.attributes);
- } else {
- throw new Error(error);
- }
+ handleContactOperationErrors(error);
}
},
@@ -132,7 +131,7 @@ export const actions = {
return response.data.payload.contact;
} catch (error) {
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
- return raiseContactCreateErrors(error);
+ return handleContactOperationErrors(error);
}
},
diff --git a/app/javascript/dashboard/store/modules/contacts/getters.js b/app/javascript/dashboard/store/modules/contacts/getters.js
index 06278d878..5a75ac091 100644
--- a/app/javascript/dashboard/store/modules/contacts/getters.js
+++ b/app/javascript/dashboard/store/modules/contacts/getters.js
@@ -17,6 +17,13 @@ export const getters = {
const contact = $state.records[id];
return contact || {};
},
+ getContactById: $state => id => {
+ const contact = $state.records[id];
+ return camelcaseKeys(contact || {}, {
+ deep: true,
+ stopPaths: ['custom_attributes'],
+ });
+ },
getMeta: $state => {
return $state.meta;
},
diff --git a/app/javascript/dashboard/store/modules/inboxes.js b/app/javascript/dashboard/store/modules/inboxes.js
index 8e1dbb301..001cc237e 100644
--- a/app/javascript/dashboard/store/modules/inboxes.js
+++ b/app/javascript/dashboard/store/modules/inboxes.js
@@ -7,6 +7,7 @@ import FBChannel from '../../api/channel/fbChannel';
import TwilioChannel from '../../api/channel/twilioChannel';
import { throwErrorMessage } from '../utils/api';
import AnalyticsHelper from '../../helper/AnalyticsHelper';
+import camelcaseKeys from 'camelcase-keys';
import { ACCOUNT_EVENTS } from '../../helper/AnalyticsHelper/events';
const buildInboxData = inboxParams => {
@@ -92,6 +93,12 @@ export const getters = {
);
return inbox || {};
},
+ getInboxById: $state => inboxId => {
+ const [inbox] = $state.records.filter(
+ record => record.id === Number(inboxId)
+ );
+ return camelcaseKeys(inbox || {}, { deep: true });
+ },
getUIFlags($state) {
return $state.uiFlags;
},