Publish current project state

This commit is contained in:
2026-09-14 10:47:21 +08:00
parent 0dd188c46f
commit 4ad56ee9f8
186 changed files with 6289 additions and 1657 deletions
@@ -17,6 +17,8 @@ export const getters = {
getContactLabels: $state => id => {
return $state.records[Number(id)] || [];
},
hasContactLabels: $state => id =>
Object.prototype.hasOwnProperty.call($state.records, Number(id)),
};
export const actions = {
@@ -7,6 +7,7 @@ export const state = {
uiFlags: {
isFetching: false,
isCreating: false,
isUpdating: false,
isDeleting: false,
},
};
@@ -51,6 +52,18 @@ export const actions = {
}
},
async update({ commit }, { noteId, contactId, content }) {
commit(types.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: true });
try {
const { data } = await ContactNotesAPI.update(contactId, noteId, content);
commit(types.EDIT_CONTACT_NOTE, { contactId, data });
} catch (error) {
throw new Error(error);
} finally {
commit(types.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: false });
}
},
async delete({ commit }, { noteId, contactId }) {
commit(types.SET_CONTACT_NOTES_UI_FLAG, { isDeleting: true });
try {
@@ -82,6 +95,12 @@ export const mutations = {
const contactNotes = $state.records[contactId] || [];
$state.records[contactId] = [...contactNotes, data];
},
[types.EDIT_CONTACT_NOTE]($state, { data, contactId }) {
const contactNotes = $state.records[contactId] || [];
$state.records[contactId] = contactNotes.map(note =>
note.id === data.id ? data : note
);
},
[types.DELETE_CONTACT_NOTE]($state, { noteId, contactId }) {
const contactNotes = $state.records[contactId];
const withoutDeletedNote = contactNotes.filter(note => note.id !== noteId);
@@ -1,4 +1,8 @@
import { CONVERSATION_PRIORITY_ORDER } from 'shared/constants/messages';
import {
ROLE_AGENT,
ROLE_ADMINISTRATOR,
} from 'dashboard/constants/permissions.js';
export const findPendingMessageIndex = (chat, message) => {
const { echo_id: tempMessageId } = message;
@@ -79,9 +83,9 @@ export const applyRoleFilter = (
) => {
// the role === "agent" check is typically not correct on it's own
// the backend handles this by checking the custom_role_id at the user model
// here however, the `getUserRole` returns "custom_role" if the id is present,
// here however, `getUserRole` returns the custom-role constant if the id is present,
// so we can check the role === "agent" directly
if (['administrator', 'agent'].includes(role)) {
if ([ROLE_ADMINISTRATOR, ROLE_AGENT].includes(role)) {
return true;
}
@@ -54,6 +54,37 @@ describe('#actions', () => {
});
});
describe('#update', () => {
it('sends correct actions if API is success', async () => {
axios.patch.mockResolvedValue({ data: { id: 2, content: 'updated' } });
await actions.update(
{ commit },
{ contactId: 1, noteId: 2, content: 'updated' }
);
expect(commit.mock.calls).toEqual([
[types.default.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: true }],
[
types.default.EDIT_CONTACT_NOTE,
{ contactId: 1, data: { id: 2, content: 'updated' } },
],
[types.default.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: false }],
]);
});
it('sends correct actions if API is error', async () => {
axios.patch.mockRejectedValue({ message: 'Incorrect header' });
await expect(
actions.update(
{ commit },
{ contactId: 1, noteId: 2, content: 'updated' }
)
).rejects.toThrow(Error);
expect(commit.mock.calls).toEqual([
[types.default.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: true }],
[types.default.SET_CONTACT_NOTES_UI_FLAG, { isUpdating: false }],
]);
});
});
describe('#delete', () => {
it('sends correct actions if API is success', async () => {
axios.delete.mockResolvedValue({ data: notesData[0] });
@@ -24,6 +24,16 @@ describe('#mutations', () => {
expect(state.records[1]).toEqual([allNotes[0], allNotes[1]]);
});
});
describe('#EDIT_CONTACT_NOTE', () => {
it('replaces an existing note', () => {
const state = { records: { 1: [{ id: 2, content: 'old' }] } };
mutations[types.EDIT_CONTACT_NOTE](state, {
contactId: 1,
data: { id: 2, content: 'new' },
});
expect(state.records[1]).toEqual([{ id: 2, content: 'new' }]);
});
});
describe('#DELETE_CONTACT_NOTE', () => {
it('Delete existing note from records', () => {
const state = { records: { 1: [{ id: 2 }] } };