mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
feat: Agent assignment index page (#12364)
This commit is contained in:
@@ -36,9 +36,12 @@ const handleClick = () => {
|
||||
<li
|
||||
v-for="feature in features"
|
||||
: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 }}
|
||||
</li>
|
||||
</ul>
|
||||
@@ -422,6 +422,12 @@ const menuItems = computed(() => {
|
||||
icon: 'i-lucide-users',
|
||||
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',
|
||||
label: t('SIDEBAR.INBOXES'),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export const FEATURE_FLAGS = {
|
||||
AGENT_BOTS: 'agent_bots',
|
||||
AGENT_MANAGEMENT: 'agent_management',
|
||||
ASSIGNMENT_V2: 'assignment_v2',
|
||||
AUTO_RESOLVE_CONVERSATIONS: 'auto_resolve_conversations',
|
||||
AUTOMATIONS: 'automations',
|
||||
CAMPAIGNS: 'campaigns',
|
||||
|
||||
@@ -330,6 +330,7 @@
|
||||
"REPORTS_LABEL": "Labels",
|
||||
"REPORTS_INBOX": "Inbox",
|
||||
"REPORTS_TEAM": "Team",
|
||||
"AGENT_ASSIGNMENT": "Agent Assignment",
|
||||
"SET_AVAILABILITY_TITLE": "Set yourself as",
|
||||
"SET_YOUR_AVAILABILITY": "Set your availability",
|
||||
"SLA": "SLA",
|
||||
@@ -418,5 +419,31 @@
|
||||
"SWITCH_TO_REPLY": "Switch to Reply",
|
||||
"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 agent from './agents/agent.routes';
|
||||
import assignmentPolicy from './assignmentPolicy/assignmentPolicy.routes';
|
||||
import agentBot from './agentBots/agentBot.routes';
|
||||
import attributes from './attributes/attributes.routes';
|
||||
import automation from './automation/automation.routes';
|
||||
@@ -44,6 +45,7 @@ export default {
|
||||
},
|
||||
...account.routes,
|
||||
...agent.routes,
|
||||
...assignmentPolicy.routes,
|
||||
...agentBot.routes,
|
||||
...attributes.routes,
|
||||
...automation.routes,
|
||||
|
||||
Reference in New Issue
Block a user