feat(conversations): complete manual AI takeover

This commit is contained in:
2026-08-12 21:16:49 +08:00
committed by Rogee
parent 4be52e05c7
commit 4bf6ba6b20
22 changed files with 266 additions and 54 deletions
@@ -8,7 +8,7 @@ class AssignableAgents extends ApiClient {
get(inboxIds) {
return axios.get(this.url, {
params: { inbox_ids: inboxIds },
params: { inbox_ids: inboxIds, include_agent_bots: true },
});
}
}
@@ -62,9 +62,10 @@ class ConversationApi extends ApiClient {
});
}
assignAgent({ conversationId, agentId }) {
assignAgent({ conversationId, agentId, assigneeType }) {
return axios.post(`${this.url}/${conversationId}/assignments`, {
assignee_id: agentId,
assignee_type: assigneeType,
});
}
@@ -23,6 +23,7 @@ describe('#AssignableAgentsAPI', () => {
expect(axiosMock.get).toHaveBeenCalledWith('/api/v1/assignable_agents', {
params: {
inbox_ids: [1],
include_agent_bots: true,
},
});
});
@@ -90,11 +90,16 @@ describe('#ConversationAPI', () => {
});
it('#assignAgent', () => {
conversationAPI.assignAgent({ conversationId: 12, agentId: 34 });
conversationAPI.assignAgent({
conversationId: 12,
agentId: 34,
assigneeType: 'AgentBot',
});
expect(axiosMock.post).toHaveBeenCalledWith(
`/api/v1/conversations/12/assignments`,
{
assignee_id: 34,
assignee_type: 'AgentBot',
}
);
});
@@ -41,7 +41,9 @@ const assignableAgentsList = useMapGetter(
'inboxAssignableAgents/getAssignableAgents'
);
const assignableAgents = computed(() =>
assignableAgentsList.value(props.selectedInboxes.join(','))
assignableAgentsList
.value(props.selectedInboxes.join(','))
.filter(agent => agent.assignee_type !== 'AgentBot')
);
const agentMenuItems = computed(() => {
@@ -59,13 +59,25 @@ export function useBulkActions() {
// Same method used in context menu, conversationId being passed from there.
async function onAssignAgent(agent, conversationId = null) {
try {
await store.dispatch('bulkActions/process', {
type: 'Conversation',
ids: conversationId || selectedConversations.value,
fields: {
assignee_id: agent.id,
},
});
if (conversationId && agent.assignee_type === 'AgentBot') {
await Promise.all(
conversationId.map(id =>
store.dispatch('assignAgent', {
conversationId: id,
agentId: agent.id,
assigneeType: agent.assignee_type,
})
)
);
} else {
await store.dispatch('bulkActions/process', {
type: 'Conversation',
ids: conversationId || selectedConversations.value,
fields: {
assignee_id: agent.id,
},
});
}
store.dispatch('bulkActions/clearSelectedConversationIds');
if (conversationId) {
useAlert(
@@ -38,7 +38,7 @@ export const getAgentsByUpdatedPresence = (
currentAccountId
) => {
const agentsWithDynamicPresenceUpdate = agents.map(item =>
item.id === currentUser.id
item.assignee_type !== 'AgentBot' && item.id === currentUser.id
? {
...item,
availability_status: currentUser.accounts.find(
@@ -93,6 +93,7 @@ export default {
.dispatch('assignAgent', {
conversationId: this.currentChat.id,
agentId,
assigneeType: agent?.assignee_type,
})
.then(() => {
useAlert(this.$t('CONVERSATION.CHANGE_AGENT'));
@@ -219,11 +219,15 @@ const actions = {
}
},
assignAgent: async ({ dispatch }, { conversationId, agentId }) => {
assignAgent: async (
{ dispatch },
{ conversationId, agentId, assigneeType }
) => {
try {
const response = await ConversationApi.assignAgent({
conversationId,
agentId,
assigneeType,
});
dispatch('setCurrentChatAssignee', {
conversationId,