chore: Clean up
This commit is contained in:
+3
-27
@@ -1,13 +1,10 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
// import { useStore, useMapGetter } from 'dashboard/composables/store';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import camelcaseKeys from 'camelcase-keys';
|
||||
|
||||
import ContactAPI from 'dashboard/api/contacts';
|
||||
import { debounce } from '@chatwoot/utils';
|
||||
import { searchContacts } from 'dashboard/components-next/NewConversation/helpers/composeConversationHelper.js';
|
||||
|
||||
import ComposeNewConversation from 'dashboard/components-next/NewConversation/ComposeNewConversation.vue';
|
||||
|
||||
@@ -20,36 +17,15 @@ const showComposeNewConversation = ref(false);
|
||||
|
||||
const contactId = computed(() => route.params.contactId || null);
|
||||
|
||||
const generateContactQuery = ({ query }) => {
|
||||
return {
|
||||
payload: [
|
||||
{
|
||||
attribute_key: 'email',
|
||||
filter_operator: 'contains',
|
||||
values: [query],
|
||||
attribute_model: 'standard',
|
||||
custom_attribute_type: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const onContactSearch = debounce(
|
||||
async query => {
|
||||
isSearching.value = true;
|
||||
contacts.value = [];
|
||||
try {
|
||||
const {
|
||||
data: { payload },
|
||||
} = await ContactAPI.filter(
|
||||
undefined,
|
||||
'name',
|
||||
generateContactQuery({ query })
|
||||
);
|
||||
contacts.value = camelcaseKeys(payload, { deep: true });
|
||||
contacts.value = await searchContacts(query);
|
||||
isSearching.value = false;
|
||||
} catch (error) {
|
||||
useAlert(t('CONTACTS_LAYOUT.SIDEBAR.MERGE.SEARCH_ERROR_MESSAGE'));
|
||||
useAlert(t('COMPOSE_NEW_CONVERSATION.CONTACT_SEARCH.ERROR_MESSAGE'));
|
||||
} finally {
|
||||
isSearching.value = false;
|
||||
}
|
||||
|
||||
+25
@@ -131,7 +131,32 @@ export const prepareWhatsAppMessagePayload = ({
|
||||
};
|
||||
};
|
||||
|
||||
export const generateContactQuery = ({ query }) => {
|
||||
return {
|
||||
payload: [
|
||||
{
|
||||
attribute_key: 'email',
|
||||
filter_operator: 'contains',
|
||||
values: [query],
|
||||
attribute_model: 'standard',
|
||||
custom_attribute_type: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
// API Calls
|
||||
export const searchContacts = async query => {
|
||||
const {
|
||||
data: { payload },
|
||||
} = await ContactAPI.filter(
|
||||
undefined,
|
||||
'name',
|
||||
generateContactQuery({ query })
|
||||
);
|
||||
return camelcaseKeys(payload, { deep: true });
|
||||
};
|
||||
|
||||
export const createNewContact = async email => {
|
||||
const payload = {
|
||||
name: getCapitalizedNameFromEmail(email),
|
||||
|
||||
+120
@@ -201,7 +201,127 @@ describe('composeConversationHelper', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateContactQuery', () => {
|
||||
it('generates correct query structure for contact search', () => {
|
||||
const query = 'test@example.com';
|
||||
const expected = {
|
||||
payload: [
|
||||
{
|
||||
attribute_key: 'email',
|
||||
filter_operator: 'contains',
|
||||
values: [query],
|
||||
attribute_model: 'standard',
|
||||
custom_attribute_type: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(helpers.generateContactQuery({ query })).toEqual(expected);
|
||||
});
|
||||
|
||||
it('handles empty query', () => {
|
||||
const expected = {
|
||||
payload: [
|
||||
{
|
||||
attribute_key: 'email',
|
||||
filter_operator: 'contains',
|
||||
values: [''],
|
||||
attribute_model: 'standard',
|
||||
custom_attribute_type: '',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(helpers.generateContactQuery({ query: '' })).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('API calls', () => {
|
||||
describe('searchContacts', () => {
|
||||
it('searches contacts and returns camelCase results', async () => {
|
||||
const mockPayload = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
phone_number: '+1234567890',
|
||||
created_at: '2023-01-01',
|
||||
},
|
||||
];
|
||||
|
||||
ContactAPI.filter.mockResolvedValue({
|
||||
data: { payload: mockPayload },
|
||||
});
|
||||
|
||||
const result = await helpers.searchContacts('john');
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
id: 1,
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
phoneNumber: '+1234567890',
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(ContactAPI.filter).toHaveBeenCalledWith(
|
||||
undefined,
|
||||
'name',
|
||||
helpers.generateContactQuery({ query: 'john' })
|
||||
);
|
||||
});
|
||||
|
||||
it('handles empty search results', async () => {
|
||||
ContactAPI.filter.mockResolvedValue({
|
||||
data: { payload: [] },
|
||||
});
|
||||
|
||||
const result = await helpers.searchContacts('nonexistent');
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('transforms nested objects to camelCase', async () => {
|
||||
const mockPayload = [
|
||||
{
|
||||
id: 1,
|
||||
contact_inboxes: [
|
||||
{
|
||||
inbox_id: 1,
|
||||
source_id: 'source1',
|
||||
created_at: '2023-01-01',
|
||||
},
|
||||
],
|
||||
custom_attributes: {
|
||||
custom_field_name: 'value',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
ContactAPI.filter.mockResolvedValue({
|
||||
data: { payload: mockPayload },
|
||||
});
|
||||
|
||||
const result = await helpers.searchContacts('test');
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
id: 1,
|
||||
contactInboxes: [
|
||||
{
|
||||
inboxId: 1,
|
||||
sourceId: 'source1',
|
||||
createdAt: '2023-01-01',
|
||||
},
|
||||
],
|
||||
customAttributes: {
|
||||
customFieldName: 'value',
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createNewContact', () => {
|
||||
it('creates new contact with capitalized name', async () => {
|
||||
const mockContact = { id: 1, name: 'John', email: 'john@example.com' };
|
||||
|
||||
@@ -597,5 +597,11 @@
|
||||
"SEARCH_EMPTY_STATE_TITLE": "No contacts matches your search 🔍",
|
||||
"LIST_EMPTY_STATE_TITLE": "No contacts available in this view 📋"
|
||||
}
|
||||
},
|
||||
|
||||
"COMPOSE_NEW_CONVERSATION": {
|
||||
"CONTACT_SEARCH": {
|
||||
"ERROR_MESSAGE": "Could not search for contacts. Please try again later."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user