feat: Add assign team option to the context menu (#5153)
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
parent
9bea84e2b5
commit
fc9699d993
11 changed files with 121 additions and 23 deletions
|
@ -121,6 +121,7 @@
|
|||
@select-conversation="selectConversation"
|
||||
@de-select-conversation="deSelectConversation"
|
||||
@assign-agent="onAssignAgent"
|
||||
@assign-team="onAssignTeam"
|
||||
@assign-label="onAssignLabels"
|
||||
@update-conversation-status="toggleConversationStatus"
|
||||
@context-menu-toggle="onContextMenuToggle"
|
||||
|
@ -618,11 +619,44 @@ export default {
|
|||
},
|
||||
});
|
||||
this.selectedConversations = [];
|
||||
if (conversationId) {
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'CONVERSATION.CARD_CONTEXT_MENU.API.AGENT_ASSIGNMENT.SUCCESFUL',
|
||||
{
|
||||
agentName: agent.name,
|
||||
conversationId,
|
||||
}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.showAlert(this.$t('BULK_ACTION.ASSIGN_SUCCESFUL'));
|
||||
}
|
||||
} catch (err) {
|
||||
this.showAlert(this.$t('BULK_ACTION.ASSIGN_FAILED'));
|
||||
}
|
||||
},
|
||||
async onAssignTeam(team, conversationId = null) {
|
||||
try {
|
||||
await this.$store.dispatch('assignTeam', {
|
||||
conversationId,
|
||||
teamId: team.id,
|
||||
});
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'CONVERSATION.CARD_CONTEXT_MENU.API.TEAM_ASSIGNMENT.SUCCESFUL',
|
||||
{
|
||||
team: team.name,
|
||||
conversationId,
|
||||
}
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
this.showAlert(
|
||||
this.$t('CONVERSATION.CARD_CONTEXT_MENU.API.TEAM_ASSIGNMENT.FAILED')
|
||||
);
|
||||
}
|
||||
},
|
||||
// Same method used in context menu, conversationId being passed from there.
|
||||
async onAssignLabels(labels, conversationId = null) {
|
||||
try {
|
||||
|
@ -634,7 +668,19 @@ export default {
|
|||
},
|
||||
});
|
||||
this.selectedConversations = [];
|
||||
if (conversationId) {
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'CONVERSATION.CARD_CONTEXT_MENU.API.LABEL_ASSIGNMENT.SUCCESFUL',
|
||||
{
|
||||
labelName: labels[0],
|
||||
conversationId,
|
||||
}
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.showAlert(this.$t('BULK_ACTION.LABELS.ASSIGN_SUCCESFUL'));
|
||||
}
|
||||
} catch (err) {
|
||||
this.showAlert(this.$t('BULK_ACTION.LABELS.ASSIGN_FAILED'));
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
@update-conversation="onUpdateConversation"
|
||||
@assign-agent="onAssignAgent"
|
||||
@assign-label="onAssignLabel"
|
||||
@assign-team="onAssignTeam"
|
||||
/>
|
||||
</woot-context-menu>
|
||||
</div>
|
||||
|
@ -352,6 +353,10 @@ export default {
|
|||
this.$emit('assign-label', [label.title], [this.chat.id]);
|
||||
this.closeContextMenu();
|
||||
},
|
||||
async onAssignTeam(team) {
|
||||
this.$emit('assign-team', team, this.chat.id);
|
||||
this.closeContextMenu();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:key="option.key"
|
||||
:option="option"
|
||||
variant="icon"
|
||||
@click.native="toggleStatus(option.key, null)"
|
||||
@click="toggleStatus(option.key, null)"
|
||||
/>
|
||||
</template>
|
||||
<menu-item-with-submenu :option="snoozeMenuConfig">
|
||||
|
@ -14,7 +14,7 @@
|
|||
v-for="(option, i) in snoozeMenuConfig.options"
|
||||
:key="i"
|
||||
:option="option"
|
||||
@click.native="snoozeConversation(option.snoozedUntil)"
|
||||
@click="snoozeConversation(option.snoozedUntil)"
|
||||
/>
|
||||
</menu-item-with-submenu>
|
||||
<menu-item-with-submenu :option="labelMenuConfig">
|
||||
|
@ -24,7 +24,7 @@
|
|||
:key="label.id"
|
||||
:option="generateMenuLabelConfig(label, 'label')"
|
||||
variant="label"
|
||||
@click.native="$emit('assign-label', label)"
|
||||
@click="$emit('assign-label', label)"
|
||||
/>
|
||||
</template>
|
||||
</menu-item-with-submenu>
|
||||
|
@ -36,10 +36,18 @@
|
|||
:key="agent.id"
|
||||
:option="generateMenuLabelConfig(agent, 'agent')"
|
||||
variant="agent"
|
||||
@click.native="$emit('assign-agent', agent)"
|
||||
@click="$emit('assign-agent', agent)"
|
||||
/>
|
||||
</template>
|
||||
</menu-item-with-submenu>
|
||||
<menu-item-with-submenu :option="teamMenuConfig">
|
||||
<menu-item
|
||||
v-for="team in teams"
|
||||
:key="team.id"
|
||||
:option="generateMenuLabelConfig(team, 'team')"
|
||||
@click="$emit('assign-team', team)"
|
||||
/>
|
||||
</menu-item-with-submenu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -119,11 +127,17 @@ export default {
|
|||
icon: 'person-add',
|
||||
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.ASSIGN_AGENT'),
|
||||
},
|
||||
teamMenuConfig: {
|
||||
key: 'team',
|
||||
icon: 'people-team-add',
|
||||
label: this.$t('CONVERSATION.CARD_CONTEXT_MENU.ASSIGN_TEAM'),
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
labels: 'labels/getLabels',
|
||||
teams: 'teams/getTeams',
|
||||
assignableAgentsUiFlags: 'inboxAssignableAgents/getUIFlags',
|
||||
}),
|
||||
assignableAgents() {
|
||||
|
@ -160,6 +174,7 @@ export default {
|
|||
...(type === 'text' && { label: option.label }),
|
||||
...(type === 'label' && { label: option.title }),
|
||||
...(type === 'agent' && { label: option.name }),
|
||||
...(type === 'team' && { label: option.name }),
|
||||
};
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="menu">
|
||||
<div class="menu" @click.stop="$emit('click')">
|
||||
<fluent-icon
|
||||
v-if="variant === 'icon' && option.icon"
|
||||
:icon="option.icon"
|
||||
|
@ -18,7 +18,7 @@
|
|||
size="20px"
|
||||
class="agent-thumbnail"
|
||||
/>
|
||||
<p class="menu-label">{{ option.label }}</p>
|
||||
<p class="menu-label truncate-text">{{ option.label }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -45,14 +45,16 @@ export default {
|
|||
.menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
flex-wrap: nowrap;
|
||||
width: calc(var(--space-mega) * 2);
|
||||
padding: var(--space-smaller);
|
||||
border-radius: var(--border-radius-small);
|
||||
min-width: calc(var(--space-mega) * 2);
|
||||
overflow: hidden;
|
||||
|
||||
.menu-label {
|
||||
margin: 0;
|
||||
font-size: var(--font-size-mini);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
|
|
|
@ -72,7 +72,22 @@
|
|||
},
|
||||
"ASSIGN_AGENT": "Assign agent",
|
||||
"ASSIGN_LABEL": "Assign label",
|
||||
"AGENTS_LOADING": "Loading agents..."
|
||||
"AGENTS_LOADING": "Loading agents...",
|
||||
"ASSIGN_TEAM": "Assign team",
|
||||
"API": {
|
||||
"AGENT_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Conversation id %{conversationId} assigned to \"%{agentName}\"",
|
||||
"FAILED": "Couldn't assign agent. Please try again."
|
||||
},
|
||||
"LABEL_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Assigned label #%{labelName} to conversation id %{conversationId}",
|
||||
"FAILED": "Couldn't assign label. Please try again."
|
||||
},
|
||||
"TEAM_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Assigned team \"%{team}\" to conversation id %{conversationId}",
|
||||
"FAILED": "Couldn't assign team. Please try again."
|
||||
}
|
||||
}
|
||||
},
|
||||
"FOOTER": {
|
||||
"MESSAGE_SIGN_TOOLTIP": "Message signature",
|
||||
|
|
|
@ -111,13 +111,11 @@ export default {
|
|||
return this.currentChat.meta.team;
|
||||
},
|
||||
set(team) {
|
||||
const conversationId = this.currentChat.id;
|
||||
const teamId = team ? team.id : 0;
|
||||
this.$store.dispatch('setCurrentChatTeam', team);
|
||||
this.$store.dispatch('setCurrentChatTeam', { team, conversationId });
|
||||
this.$store
|
||||
.dispatch('assignTeam', {
|
||||
conversationId: this.currentChat.id,
|
||||
teamId,
|
||||
})
|
||||
.dispatch('assignTeam', { conversationId, teamId })
|
||||
.then(() => {
|
||||
this.showAlert(this.$t('CONVERSATION.CHANGE_TEAM'));
|
||||
});
|
||||
|
|
|
@ -121,14 +121,14 @@ const actions = {
|
|||
conversationId,
|
||||
teamId,
|
||||
});
|
||||
dispatch('setCurrentChatTeam', response.data);
|
||||
dispatch('setCurrentChatTeam', { team: response.data, conversationId });
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
}
|
||||
},
|
||||
|
||||
setCurrentChatTeam({ commit }, team) {
|
||||
commit(types.ASSIGN_TEAM, team);
|
||||
setCurrentChatTeam({ commit }, { team, conversationId }) {
|
||||
commit(types.ASSIGN_TEAM, { team, conversationId });
|
||||
},
|
||||
|
||||
toggleStatus: async (
|
||||
|
|
|
@ -68,8 +68,8 @@ export const mutations = {
|
|||
Vue.set(chat.meta, 'assignee', assignee);
|
||||
},
|
||||
|
||||
[types.ASSIGN_TEAM](_state, team) {
|
||||
const [chat] = getSelectedChatConversation(_state);
|
||||
[types.ASSIGN_TEAM](_state, { team, conversationId }) {
|
||||
const [chat] = _state.allConversations.filter(c => c.id === conversationId);
|
||||
Vue.set(chat.meta, 'team', team);
|
||||
},
|
||||
|
||||
|
|
|
@ -327,10 +327,13 @@ describe('#actions', () => {
|
|||
axios.post.mockResolvedValue({
|
||||
data: { id: 1, name: 'Team' },
|
||||
});
|
||||
await actions.setCurrentChatTeam({ commit }, { id: 1, name: 'Team' });
|
||||
await actions.setCurrentChatTeam(
|
||||
{ commit },
|
||||
{ team: { id: 1, name: 'Team' }, conversationId: 1 }
|
||||
);
|
||||
expect(commit).toHaveBeenCalledTimes(1);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
['ASSIGN_TEAM', { id: 1, name: 'Team' }],
|
||||
['ASSIGN_TEAM', { team: { id: 1, name: 'Team' }, conversationId: 1 }],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,6 +37,19 @@ describe('#mutations', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#ASSIGN_TEAM', () => {
|
||||
it('clears current chat window', () => {
|
||||
const state = { allConversations: [{ id: 1, meta: {} }] };
|
||||
mutations[types.ASSIGN_TEAM](state, {
|
||||
team: { id: 1, name: 'Team 1' },
|
||||
conversationId: 1,
|
||||
});
|
||||
expect(state.allConversations).toEqual([
|
||||
{ id: 1, meta: { team: { id: 1, name: 'Team 1' } } },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#SET_CURRENT_CHAT_WINDOW', () => {
|
||||
it('set current chat window', () => {
|
||||
const state = { selectedChatId: 1 };
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
"panel-contract-outline": "M14.193 14.751a.75.75 0 0 0 1.059.056l2.5-2.25a.75.75 0 0 0 0-1.114l-2.5-2.25a.75.75 0 0 0-1.004 1.115l1.048.942H11.75a.75.75 0 1 0 0 1.5h3.546l-1.048.942a.75.75 0 0 0-.055 1.06ZM2 6.75A2.75 2.75 0 0 1 4.75 4h14.5A2.75 2.75 0 0 1 22 6.75v10.5A2.75 2.75 0 0 1 19.25 20H4.75A2.75 2.75 0 0 1 2 17.25V6.75ZM9 5.5v13h10.25c.69 0 1.25-.56 1.25-1.25V6.75c0-.69-.56-1.25-1.25-1.25H9Z",
|
||||
"pen-outline": "M7.5 2.75a.75.75 0 0 0-1.5 0v3a1.75 1.75 0 0 0 1.543 1.738L6.527 9.993a3.868 3.868 0 0 0 .119 3.143l3.99 7.95c.283.566.803.914 1.364.914s1.08-.348 1.365-.913l3.99-7.951c.481-.96.526-2.137.118-3.143l-1.016-2.505A1.75 1.75 0 0 0 18 5.75v-3a.75.75 0 0 0-1.5 0v3a.25.25 0 0 1-.25.25h-8.5a.25.25 0 0 1-.25-.25v-3Zm7.343 4.75 1.24 3.057c.247.61.217 1.336-.07 1.906l-3.263 6.504v-6.668a1.5 1.5 0 1 0-1.5 0v6.668l-3.264-6.504a2.368 2.368 0 0 1-.069-1.906L9.157 7.5h5.686Z",
|
||||
"people-outline": "M4 13.999 13 14a2 2 0 0 1 1.995 1.85L15 16v1.5C14.999 21 11.284 22 8.5 22c-2.722 0-6.335-.956-6.495-4.27L2 17.5v-1.501c0-1.054.816-1.918 1.85-1.995L4 14ZM15.22 14H20c1.054 0 1.918.816 1.994 1.85L22 16v1c-.001 3.062-2.858 4-5 4a7.16 7.16 0 0 1-2.14-.322c.336-.386.607-.827.802-1.327A6.19 6.19 0 0 0 17 19.5l.267-.006c.985-.043 3.086-.363 3.226-2.289L20.5 17v-1a.501.501 0 0 0-.41-.492L20 15.5h-4.051a2.957 2.957 0 0 0-.595-1.34L15.22 14H20h-4.78ZM4 15.499l-.1.01a.51.51 0 0 0-.254.136.506.506 0 0 0-.136.253l-.01.101V17.5c0 1.009.45 1.722 1.417 2.242.826.445 2.003.714 3.266.753l.317.005.317-.005c1.263-.039 2.439-.308 3.266-.753.906-.488 1.359-1.145 1.412-2.057l.005-.186V16a.501.501 0 0 0-.41-.492L13 15.5l-9-.001ZM8.5 3a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9Zm9 2a3.5 3.5 0 1 1 0 7 3.5 3.5 0 0 1 0-7Zm-9-.5c-1.654 0-3 1.346-3 3s1.346 3 3 3 3-1.346 3-3-1.346-3-3-3Zm9 2c-1.103 0-2 .897-2 2s.897 2 2 2 2-.897 2-2-.897-2-2-2Z",
|
||||
"people-team-add-outline": "M17.5 12a5.5 5.5 0 1 1 0 11a5.5 5.5 0 0 1 0-11Zm0 2l-.09.007a.5.5 0 0 0-.402.402L17 14.5V17h-2.502l-.09.008a.5.5 0 0 0-.402.402l-.008.09l.008.09a.5.5 0 0 0 .402.402l.09.008H17v2.503l.008.09a.5.5 0 0 0 .402.402l.09.008l.09-.008a.5.5 0 0 0 .402-.402l.008-.09V18l2.504.001l.09-.008a.5.5 0 0 0 .402-.402l.008-.09l-.008-.09a.5.5 0 0 0-.403-.402l-.09-.008H18v-2.5l-.008-.09a.5.5 0 0 0-.402-.403L17.5 14Zm-3.246-4c.835 0 1.563.454 1.951 1.13a6.44 6.44 0 0 0-1.518.509a.736.736 0 0 0-.433-.139H9.752a.75.75 0 0 0-.75.75v4.249c0 1.41.974 2.594 2.286 2.915a6.42 6.42 0 0 0 .735 1.587l-.02-.001a4.501 4.501 0 0 1-4.501-4.501V12.25A2.25 2.25 0 0 1 9.752 10h4.502Zm-6.848 0a3.243 3.243 0 0 0-.817 1.5H4.25a.75.75 0 0 0-.75.75v2.749a2.501 2.501 0 0 0 3.082 2.433c.085.504.24.985.453 1.432A4.001 4.001 0 0 1 2 14.999V12.25a2.25 2.25 0 0 1 2.096-2.245L4.25 10h3.156Zm12.344 0A2.25 2.25 0 0 1 22 12.25v.56A6.478 6.478 0 0 0 17.5 11l-.245.005A3.21 3.21 0 0 0 16.6 10h3.15ZM18.5 4a2.5 2.5 0 1 1 0 5a2.5 2.5 0 0 1 0-5ZM12 3a3 3 0 1 1 0 6a3 3 0 0 1 0-6ZM5.5 4a2.5 2.5 0 1 1 0 5a2.5 2.5 0 0 1 0-5Zm13 1.5a1 1 0 1 0 0 2a1 1 0 0 0 0-2Zm-6.5-1a1.5 1.5 0 1 0 0 3a1.5 1.5 0 0 0 0-3Zm-6.5 1a1 1 0 1 0 0 2a1 1 0 0 0 0-2Z",
|
||||
"people-team-outline": "M14.754 10c.966 0 1.75.784 1.75 1.75v4.749a4.501 4.501 0 0 1-9.002 0V11.75c0-.966.783-1.75 1.75-1.75h5.502Zm0 1.5H9.252a.25.25 0 0 0-.25.25v4.749a3.001 3.001 0 0 0 6.002 0V11.75a.25.25 0 0 0-.25-.25ZM3.75 10h3.381a2.738 2.738 0 0 0-.618 1.5H3.75a.25.25 0 0 0-.25.25v3.249a2.501 2.501 0 0 0 3.082 2.433c.085.504.24.985.453 1.432A4.001 4.001 0 0 1 2 14.999V11.75c0-.966.784-1.75 1.75-1.75Zm13.125 0h3.375c.966 0 1.75.784 1.75 1.75V15a4 4 0 0 1-5.03 3.866c.214-.448.369-.929.455-1.433A2.5 2.5 0 0 0 20.5 15v-3.25a.25.25 0 0 0-.25-.25h-2.757a2.738 2.738 0 0 0-.618-1.5ZM12 3a3 3 0 1 1 0 6 3 3 0 0 1 0-6Zm6.5 1a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5Zm-13 0a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5Zm6.5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm6.5 1a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm-13 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2Z",
|
||||
"person-add-outline": "M17.5 12a5.5 5.5 0 1 1 0 11a5.5 5.5 0 0 1 0-11zm-5.477 2a6.47 6.47 0 0 0-.709 1.5H4.253a.749.749 0 0 0-.75.75v.577c0 .535.192 1.053.54 1.46c1.253 1.469 3.22 2.214 5.957 2.214c.597 0 1.157-.035 1.68-.106c.246.495.553.954.912 1.367c-.795.16-1.66.24-2.592.24c-3.146 0-5.532-.906-7.098-2.74a3.75 3.75 0 0 1-.898-2.435v-.578A2.249 2.249 0 0 1 4.253 14h7.77zm5.477 0l-.09.008a.5.5 0 0 0-.402.402L17 14.5V17h-2.496l-.09.008a.5.5 0 0 0-.402.402l-.008.09l.008.09a.5.5 0 0 0 .402.402l.09.008H17L17 20.5l.008.09a.5.5 0 0 0 .402.402l.09.008l.09-.008a.5.5 0 0 0 .402-.402L18 20.5V18h2.504l.09-.008a.5.5 0 0 0 .402-.402l.008-.09l-.008-.09a.5.5 0 0 0-.402-.402l-.09-.008H18L18 14.5l-.008-.09a.5.5 0 0 0-.402-.402L17.5 14zM10 2.005a5 5 0 1 1 0 10a5 5 0 0 1 0-10zm0 1.5a3.5 3.5 0 1 0 0 7a3.5 3.5 0 0 0 0-7z",
|
||||
"person-assign-outline": "M11.313 15.5a6.471 6.471 0 0 1 .709-1.5h-7.77a2.249 2.249 0 0 0-2.249 2.25v.577c0 .892.319 1.756.899 2.435c1.566 1.834 3.952 2.74 7.098 2.74c.931 0 1.796-.08 2.592-.24a6.51 6.51 0 0 1-.913-1.366c-.524.07-1.083.105-1.68.105c-2.737 0-4.703-.745-5.957-2.213a2.25 2.25 0 0 1-.539-1.461v-.578a.75.75 0 0 1 .75-.749h7.06ZM10 2.005a5 5 0 1 1 0 10a5 5 0 0 1 0-10Zm0 1.5a3.5 3.5 0 1 0 0 7a3.5 3.5 0 0 0 0-7ZM23 17.5a5.5 5.5 0 1 1-11 0a5.5 5.5 0 0 1 11 0Zm-4.647-2.853a.5.5 0 0 0-.707.707L19.293 17H15a.5.5 0 1 0 0 1h4.293l-1.647 1.647a.5.5 0 0 0 .707.707l2.5-2.5a.497.497 0 0 0 .147-.345V17.5a.498.498 0 0 0-.15-.357l-2.497-2.496Z",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue