feat: Agent assignment index page (#12364)
This commit is contained in:
@@ -36,9 +36,12 @@ const handleClick = () => {
|
|||||||
<li
|
<li
|
||||||
v-for="feature in features"
|
v-for="feature in features"
|
||||||
:key="feature.id"
|
:key="feature.id"
|
||||||
class="flex items-center gap-3"
|
class="flex items-center gap-3 text-sm"
|
||||||
>
|
>
|
||||||
<Icon :icon="feature.icon" class="text-n-slate-11 size-4" />
|
<Icon
|
||||||
|
:icon="feature.icon"
|
||||||
|
class="text-n-slate-11 size-4 flex-shrink-0"
|
||||||
|
/>
|
||||||
{{ feature.label }}
|
{{ feature.label }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -422,6 +422,12 @@ const menuItems = computed(() => {
|
|||||||
icon: 'i-lucide-users',
|
icon: 'i-lucide-users',
|
||||||
to: accountScopedRoute('settings_teams_list'),
|
to: accountScopedRoute('settings_teams_list'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Settings Agent Assignment',
|
||||||
|
label: t('SIDEBAR.AGENT_ASSIGNMENT'),
|
||||||
|
icon: 'i-lucide-user-cog',
|
||||||
|
to: accountScopedRoute('assignment_policy_index'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Settings Inboxes',
|
name: 'Settings Inboxes',
|
||||||
label: t('SIDEBAR.INBOXES'),
|
label: t('SIDEBAR.INBOXES'),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export const FEATURE_FLAGS = {
|
export const FEATURE_FLAGS = {
|
||||||
AGENT_BOTS: 'agent_bots',
|
AGENT_BOTS: 'agent_bots',
|
||||||
AGENT_MANAGEMENT: 'agent_management',
|
AGENT_MANAGEMENT: 'agent_management',
|
||||||
|
ASSIGNMENT_V2: 'assignment_v2',
|
||||||
AUTO_RESOLVE_CONVERSATIONS: 'auto_resolve_conversations',
|
AUTO_RESOLVE_CONVERSATIONS: 'auto_resolve_conversations',
|
||||||
AUTOMATIONS: 'automations',
|
AUTOMATIONS: 'automations',
|
||||||
CAMPAIGNS: 'campaigns',
|
CAMPAIGNS: 'campaigns',
|
||||||
|
|||||||
@@ -330,6 +330,7 @@
|
|||||||
"REPORTS_LABEL": "Labels",
|
"REPORTS_LABEL": "Labels",
|
||||||
"REPORTS_INBOX": "Inbox",
|
"REPORTS_INBOX": "Inbox",
|
||||||
"REPORTS_TEAM": "Team",
|
"REPORTS_TEAM": "Team",
|
||||||
|
"AGENT_ASSIGNMENT": "Agent Assignment",
|
||||||
"SET_AVAILABILITY_TITLE": "Set yourself as",
|
"SET_AVAILABILITY_TITLE": "Set yourself as",
|
||||||
"SET_YOUR_AVAILABILITY": "Set your availability",
|
"SET_YOUR_AVAILABILITY": "Set your availability",
|
||||||
"SLA": "SLA",
|
"SLA": "SLA",
|
||||||
@@ -418,5 +419,31 @@
|
|||||||
"SWITCH_TO_REPLY": "Switch to Reply",
|
"SWITCH_TO_REPLY": "Switch to Reply",
|
||||||
"TOGGLE_SNOOZE_DROPDOWN": "Toggle snooze dropdown"
|
"TOGGLE_SNOOZE_DROPDOWN": "Toggle snooze dropdown"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"ASSIGNMENT_POLICY": {
|
||||||
|
"INDEX": {
|
||||||
|
"HEADER": {
|
||||||
|
"TITLE": "Agent assignment",
|
||||||
|
"DESCRIPTION": "Define policies to effectively manage workload and route conversations based on the needs of inboxes and agents. Learn more here"
|
||||||
|
},
|
||||||
|
"ASSIGNMENT_POLICY": {
|
||||||
|
"TITLE": "Assignment policy",
|
||||||
|
"DESCRIPTION": "Manage how conversations get assigned in inboxes.",
|
||||||
|
"FEATURES": [
|
||||||
|
"Assign by conversations evenly or by available capacity",
|
||||||
|
"Add fair distribution rules to avoid overloading any agent",
|
||||||
|
"Add inboxes to a policy - one policy per inbox"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"AGENT_CAPACITY_POLICY": {
|
||||||
|
"TITLE": "Agent capacity policy",
|
||||||
|
"DESCRIPTION": "Manage workload for agents.",
|
||||||
|
"FEATURES": [
|
||||||
|
"Define maximum conversations per inbox",
|
||||||
|
"Create exceptions based on labels and time",
|
||||||
|
"Add agents to a policy - one policy per agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import BaseSettingsHeader from '../components/BaseSettingsHeader.vue';
|
||||||
|
import SettingsLayout from '../SettingsLayout.vue';
|
||||||
|
import AssignmentCard from 'dashboard/components-next/AssignmentPolicy/AssignmentCard/AssignmentCard.vue';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const agentAssignments = computed(() => [
|
||||||
|
{
|
||||||
|
key: 'assignment_policy',
|
||||||
|
title: t('ASSIGNMENT_POLICY.INDEX.ASSIGNMENT_POLICY.TITLE'),
|
||||||
|
description: t('ASSIGNMENT_POLICY.INDEX.ASSIGNMENT_POLICY.DESCRIPTION'),
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-circle-fading-arrow-up',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.ASSIGNMENT_POLICY.FEATURES.0'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-scale',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.ASSIGNMENT_POLICY.FEATURES.1'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-inbox',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.ASSIGNMENT_POLICY.FEATURES.2'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'agent_capacity_policy',
|
||||||
|
title: t('ASSIGNMENT_POLICY.INDEX.AGENT_CAPACITY_POLICY.TITLE'),
|
||||||
|
description: t('ASSIGNMENT_POLICY.INDEX.AGENT_CAPACITY_POLICY.DESCRIPTION'),
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-glass-water',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.AGENT_CAPACITY_POLICY.FEATURES.0'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-circle-minus',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.AGENT_CAPACITY_POLICY.FEATURES.1'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'i-lucide-users-round',
|
||||||
|
label: t('ASSIGNMENT_POLICY.INDEX.AGENT_CAPACITY_POLICY.FEATURES.2'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleClick = key => {
|
||||||
|
router.push({ name: key });
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SettingsLayout :no-records-found="false" class="gap-10">
|
||||||
|
<template #header>
|
||||||
|
<BaseSettingsHeader
|
||||||
|
:title="$t('ASSIGNMENT_POLICY.INDEX.HEADER.TITLE')"
|
||||||
|
:description="$t('ASSIGNMENT_POLICY.INDEX.HEADER.DESCRIPTION')"
|
||||||
|
feature-name="assignment-policy"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #body>
|
||||||
|
<div class="grid grid-cols-1 2xl:grid-cols-2 gap-6">
|
||||||
|
<AssignmentCard
|
||||||
|
v-for="item in agentAssignments"
|
||||||
|
:key="item.key"
|
||||||
|
:title="item.title"
|
||||||
|
:description="item.description"
|
||||||
|
:features="item.features"
|
||||||
|
@click="handleClick(item.key)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</SettingsLayout>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { FEATURE_FLAGS } from '../../../../featureFlags';
|
||||||
|
import { frontendURL } from '../../../../helper/URLHelper';
|
||||||
|
import SettingsWrapper from '../SettingsWrapper.vue';
|
||||||
|
import AssignmentPolicyIndex from './Index.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: frontendURL('accounts/:accountId/settings/assignment-policy'),
|
||||||
|
component: SettingsWrapper,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirect: to => {
|
||||||
|
return { name: 'assignment_policy_index', params: to.params };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'index',
|
||||||
|
name: 'assignment_policy_index',
|
||||||
|
component: AssignmentPolicyIndex,
|
||||||
|
meta: {
|
||||||
|
featureFlag: FEATURE_FLAGS.ASSIGNMENT_V2,
|
||||||
|
permissions: ['administrator'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
|
|
||||||
import account from './account/account.routes';
|
import account from './account/account.routes';
|
||||||
import agent from './agents/agent.routes';
|
import agent from './agents/agent.routes';
|
||||||
|
import assignmentPolicy from './assignmentPolicy/assignmentPolicy.routes';
|
||||||
import agentBot from './agentBots/agentBot.routes';
|
import agentBot from './agentBots/agentBot.routes';
|
||||||
import attributes from './attributes/attributes.routes';
|
import attributes from './attributes/attributes.routes';
|
||||||
import automation from './automation/automation.routes';
|
import automation from './automation/automation.routes';
|
||||||
@@ -44,6 +45,7 @@ export default {
|
|||||||
},
|
},
|
||||||
...account.routes,
|
...account.routes,
|
||||||
...agent.routes,
|
...agent.routes,
|
||||||
|
...assignmentPolicy.routes,
|
||||||
...agentBot.routes,
|
...agentBot.routes,
|
||||||
...attributes.routes,
|
...attributes.routes,
|
||||||
...automation.routes,
|
...automation.routes,
|
||||||
|
|||||||
Reference in New Issue
Block a user