mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-03 04:27:53 +00:00
feat: Update API for contact avatar (#4719)
Added the ability to update the contact's avatar via API and Dashboard. - Contact create and update APIs can now accept avatar attachment parameters [form data]. - Contact create and update endpoints can now accept the avatar_url parameter.[json] - API endpoint to remove a contact avatar. - Updated Contact create/edit UI components with avatar support Fixes: #3428
This commit is contained in:
@@ -6,6 +6,33 @@ import types from '../../mutation-types';
|
||||
import ContactAPI from '../../../api/contacts';
|
||||
import AccountActionsAPI from '../../../api/accountActions';
|
||||
|
||||
const buildContactFormData = contactParams => {
|
||||
const formData = new FormData();
|
||||
const { additional_attributes = {}, ...contactProperties } = contactParams;
|
||||
Object.keys(contactProperties).forEach(key => {
|
||||
if (contactProperties[key]) {
|
||||
formData.append(key, contactProperties[key]);
|
||||
}
|
||||
});
|
||||
const {
|
||||
social_profiles,
|
||||
...additionalAttributesProperties
|
||||
} = additional_attributes;
|
||||
Object.keys(additionalAttributesProperties).forEach(key => {
|
||||
formData.append(
|
||||
`additional_attributes[${key}]`,
|
||||
additionalAttributesProperties[key]
|
||||
);
|
||||
});
|
||||
Object.keys(social_profiles).forEach(key => {
|
||||
formData.append(
|
||||
`additional_attributes[social_profiles][${key}]`,
|
||||
social_profiles[key]
|
||||
);
|
||||
});
|
||||
return formData;
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
search: async ({ commit }, { search, page, sortAttr, label }) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isFetching: true });
|
||||
@@ -52,10 +79,13 @@ export const actions = {
|
||||
}
|
||||
},
|
||||
|
||||
update: async ({ commit }, { id, ...updateObj }) => {
|
||||
update: async ({ commit }, { id, isFormData = false, ...contactParams }) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isUpdating: true });
|
||||
try {
|
||||
const response = await ContactAPI.update(id, updateObj);
|
||||
const response = await ContactAPI.update(
|
||||
id,
|
||||
isFormData ? buildContactFormData(contactParams) : contactParams
|
||||
);
|
||||
commit(types.EDIT_CONTACT, response.data.payload);
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isUpdating: false });
|
||||
} catch (error) {
|
||||
@@ -68,10 +98,12 @@ export const actions = {
|
||||
}
|
||||
},
|
||||
|
||||
create: async ({ commit }, userObject) => {
|
||||
create: async ({ commit }, { isFormData = false, ...contactParams }) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isCreating: true });
|
||||
try {
|
||||
const response = await ContactAPI.create(userObject);
|
||||
const response = await ContactAPI.create(
|
||||
isFormData ? buildContactFormData(contactParams) : contactParams
|
||||
);
|
||||
commit(types.SET_CONTACT_ITEM, response.data.payload.contact);
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isCreating: false });
|
||||
} catch (error) {
|
||||
@@ -83,6 +115,7 @@ export const actions = {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
import: async ({ commit }, file) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isCreating: true });
|
||||
try {
|
||||
@@ -95,6 +128,7 @@ export const actions = {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
delete: async ({ commit }, id) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isDeleting: true });
|
||||
try {
|
||||
@@ -122,6 +156,15 @@ export const actions = {
|
||||
}
|
||||
},
|
||||
|
||||
deleteAvatar: async ({ commit }, id) => {
|
||||
try {
|
||||
const response = await ContactAPI.destroyAvatar(id);
|
||||
commit(types.EDIT_CONTACT, response.data.payload);
|
||||
} catch (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
},
|
||||
|
||||
fetchContactableInbox: async ({ commit }, id) => {
|
||||
commit(types.SET_CONTACT_UI_FLAG, { isFetchingInboxes: true });
|
||||
try {
|
||||
|
||||
@@ -73,7 +73,13 @@ describe('#actions', () => {
|
||||
describe('#update', () => {
|
||||
it('sends correct mutations if API is success', async () => {
|
||||
axios.patch.mockResolvedValue({ data: { payload: contactList[0] } });
|
||||
await actions.update({ commit }, contactList[0]);
|
||||
await actions.update(
|
||||
{ commit },
|
||||
{
|
||||
id: contactList[0].id,
|
||||
contactParams: contactList[0],
|
||||
}
|
||||
);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_CONTACT_UI_FLAG, { isUpdating: true }],
|
||||
[types.EDIT_CONTACT, contactList[0]],
|
||||
@@ -101,9 +107,15 @@ describe('#actions', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
await expect(actions.update({ commit }, contactList[0])).rejects.toThrow(
|
||||
DuplicateContactException
|
||||
);
|
||||
await expect(
|
||||
actions.update(
|
||||
{ commit },
|
||||
{
|
||||
id: contactList[0].id,
|
||||
contactParams: contactList[0],
|
||||
}
|
||||
)
|
||||
).rejects.toThrow(DuplicateContactException);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_CONTACT_UI_FLAG, { isUpdating: true }],
|
||||
[types.SET_CONTACT_UI_FLAG, { isUpdating: false }],
|
||||
@@ -116,7 +128,12 @@ describe('#actions', () => {
|
||||
axios.post.mockResolvedValue({
|
||||
data: { payload: { contact: contactList[0] } },
|
||||
});
|
||||
await actions.create({ commit }, contactList[0]);
|
||||
await actions.create(
|
||||
{ commit },
|
||||
{
|
||||
contactParams: contactList[0],
|
||||
}
|
||||
);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_CONTACT_UI_FLAG, { isCreating: true }],
|
||||
[types.SET_CONTACT_ITEM, contactList[0]],
|
||||
@@ -142,9 +159,14 @@ describe('#actions', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
await expect(actions.create({ commit }, contactList[0])).rejects.toThrow(
|
||||
ExceptionWithMessage
|
||||
);
|
||||
await expect(
|
||||
actions.create(
|
||||
{ commit },
|
||||
{
|
||||
contactParams: contactList[0],
|
||||
}
|
||||
)
|
||||
).rejects.toThrow(ExceptionWithMessage);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.SET_CONTACT_UI_FLAG, { isCreating: true }],
|
||||
[types.SET_CONTACT_UI_FLAG, { isCreating: false }],
|
||||
@@ -299,4 +321,18 @@ describe('#actions', () => {
|
||||
expect(commit.mock.calls).toEqual([[types.CLEAR_CONTACT_FILTERS]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#deleteAvatar', () => {
|
||||
it('sends correct mutations if API is success', async () => {
|
||||
axios.delete.mockResolvedValue({ data: { payload: contactList[0] } });
|
||||
await actions.deleteAvatar({ commit }, contactList[0].id);
|
||||
expect(commit.mock.calls).toEqual([[types.EDIT_CONTACT, contactList[0]]]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.delete.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await expect(
|
||||
actions.deleteAvatar({ commit }, contactList[0].id)
|
||||
).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user