(cherry picked from commit db577afc568b56b49846773b16b638e0cf1444fa) # Conflicts: # frontend/src/components/Settings/AssignmentRules/AssigneeRules.vue # frontend/src/components/Settings/AssignmentRules/AssignmentRuleView.vue # frontend/src/components/Settings/AssignmentRules/AssignmentRules.vue
163 lines
5.2 KiB
Vue
163 lines
5.2 KiB
Vue
<template>
|
||
<div>
|
||
<div class="flex flex-col gap-1">
|
||
<span class="text-lg font-semibold text-ink-gray-8">{{
|
||
__('Assignee Rules')
|
||
}}</span>
|
||
<span class="text-p-sm text-ink-gray-6">
|
||
{{
|
||
__(
|
||
'Define who receives the {0} and how they’re distributed among agents.',
|
||
[documentType],
|
||
)
|
||
}}
|
||
</span>
|
||
</div>
|
||
<div class="mt-8 flex items-center justify-between gap-2">
|
||
<div>
|
||
<div class="text-base font-medium text-ink-gray-8">
|
||
{{
|
||
__('{0} Routing', [
|
||
assignmentRuleData.documentType == 'CRM Lead'
|
||
? __('Lead')
|
||
: __('Deal'),
|
||
])
|
||
}}
|
||
</div>
|
||
<div class="text-p-sm text-ink-gray-6 mt-1">
|
||
{{
|
||
__('Choose how {0} are distributed among selected assignees.', [
|
||
documentType,
|
||
])
|
||
}}
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<Popover placement="bottom-end">
|
||
<template #target="{ togglePopover }">
|
||
<div
|
||
class="flex items-center justify-between text-base rounded h-7 py-1.5 pl-2 pr-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-gray-modals hover:bg-surface-gray-3 focus:bg-surface-white focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full dark:[color-scheme:dark] select-none min-w-40"
|
||
@click="togglePopover()"
|
||
>
|
||
<div>
|
||
{{
|
||
documentRoutingOptions.find(
|
||
(option) => option.value == assignmentRuleData.rule,
|
||
)?.label
|
||
}}
|
||
</div>
|
||
<FeatherIcon name="chevron-down" class="size-4" />
|
||
</div>
|
||
</template>
|
||
<template #body="{ togglePopover }">
|
||
<div
|
||
class="p-1 text-ink-gray-7 mt-1 w-48 bg-white shadow-xl rounded"
|
||
>
|
||
<div
|
||
v-for="option in documentRoutingOptions"
|
||
:key="option.value"
|
||
class="p-2 cursor-pointer hover:bg-gray-50 text-sm flex items-center justify-between rounded"
|
||
@click="
|
||
() => {
|
||
assignmentRuleData.rule = option.value
|
||
togglePopover()
|
||
}
|
||
"
|
||
>
|
||
<span>
|
||
{{ option.label }}
|
||
</span>
|
||
<FeatherIcon
|
||
v-if="assignmentRuleData.rule == option.value"
|
||
name="check"
|
||
class="size-4"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</Popover>
|
||
</div>
|
||
</div>
|
||
<div class="mt-7 flex items-center justify-between gap-2">
|
||
<div>
|
||
<div class="text-base font-medium text-ink-gray-8">
|
||
{{ __('Assignees') }}
|
||
</div>
|
||
<div class="text-p-sm text-ink-gray-6 mt-1">
|
||
{{ __('Choose who receives the {0}.', [documentType]) }}
|
||
</div>
|
||
</div>
|
||
<AssigneeSearch @addAssignee="validateAssignmentRule('users')" />
|
||
</div>
|
||
<div class="mt-4 flex flex-wrap gap-2">
|
||
<div
|
||
v-for="user in users"
|
||
:key="user.name"
|
||
class="flex items-center gap-2 text-sm bg-surface-gray-2 rounded-md p-1 w-max px-2 select-none"
|
||
>
|
||
<Avatar :image="user.user_image" :label="user.full_name" size="sm" />
|
||
<div class="text-ink-gray-7">
|
||
{{ user.full_name }}
|
||
</div>
|
||
<Tooltip
|
||
v-if="user.email == assignmentRuleData.lastUser"
|
||
:text="__('Last user assigned by this rule')"
|
||
:hover-delay="0.35"
|
||
:placement="'top'"
|
||
>
|
||
<div
|
||
class="text-xs rounded-full select-none bg-blue-600 text-white p-0.5 px-2"
|
||
>
|
||
{{ __('Last') }}
|
||
</div>
|
||
</Tooltip>
|
||
<Button variant="ghost" icon="x" @click="removeAssignedUser(user)" />
|
||
</div>
|
||
</div>
|
||
<ErrorMessage :message="assignmentRuleErrors.users" />
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { Avatar, Button, ErrorMessage, Popover, Tooltip } from 'frappe-ui'
|
||
import AssigneeSearch from './AssigneeSearch.vue'
|
||
import { computed, inject } from 'vue'
|
||
import { usersStore } from '@/stores/users'
|
||
|
||
const { getUser } = usersStore()
|
||
const assignmentRuleData = inject('assignmentRuleData')
|
||
const assignmentRuleErrors = inject('assignmentRuleErrors')
|
||
const validateAssignmentRule = inject('validateAssignmentRule')
|
||
const documentType = computed(() =>
|
||
assignmentRuleData.value.documentType == 'CRM Lead'
|
||
? __('leads')
|
||
: __('deals'),
|
||
)
|
||
|
||
const documentRoutingOptions = [
|
||
{
|
||
label: 'Auto-rotate',
|
||
value: 'Round Robin',
|
||
},
|
||
{
|
||
label: 'Assign by workload',
|
||
value: 'Load Balancing',
|
||
},
|
||
]
|
||
|
||
const removeAssignedUser = (user) => {
|
||
assignmentRuleData.value.users = assignmentRuleData.value.users.filter(
|
||
(u) => u.user !== user.name,
|
||
)
|
||
validateAssignmentRule('users')
|
||
}
|
||
|
||
const users = computed(() => {
|
||
const _users = []
|
||
assignmentRuleData.value.users.forEach((user) => {
|
||
_users.push(getUser(user.user))
|
||
})
|
||
return _users
|
||
})
|
||
</script>
|