mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-14 09:00:04 +00:00
Feat: Add SLAs per team
- Feat: Provide the ability to change SLAs for conversations; this will start a new deadline calculation from the time the SLA is set.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<form @submit="onSubmit" class="space-y-6">
|
||||
|
||||
<FormField name="emoji" v-slot="{ componentField }">
|
||||
<FormItem ref="emojiPickerContainer" class="relative">
|
||||
<FormLabel>Emoji</FormLabel>
|
||||
@@ -43,7 +42,7 @@
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
Round robin: Conversations are assigned to team members in a round-robin fashion. <br>
|
||||
Round robin: Conversations are assigned to team members in a round-robin fashion. <br />
|
||||
Manual: Conversations are to be picked by team members.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
@@ -89,7 +88,34 @@
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormDescription>Default business hours for the team, will be used to calculate SLA.</FormDescription>
|
||||
<FormDescription
|
||||
>Default business hours for the team, will be used to calculate SLA.</FormDescription
|
||||
>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<FormField v-slot="{ componentField }" name="sla_policy_id">
|
||||
<FormItem>
|
||||
<FormLabel>SLA policy</FormLabel>
|
||||
<FormControl>
|
||||
<Select v-bind="componentField">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select policy" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem v-for="sla in slaStore.options" :key="sla.value" :value="parseInt(sla.value)">
|
||||
{{ sla.label }}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormDescription
|
||||
>SLA policy to be auto applied to conversations, when conversations are assigned to this
|
||||
team.</FormDescription
|
||||
>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
@@ -127,12 +153,15 @@ import { Input } from '@/components/ui/input'
|
||||
import EmojiPicker from 'vue3-emoji-picker'
|
||||
import 'vue3-emoji-picker/css'
|
||||
import { handleHTTPError } from '@/utils/http'
|
||||
import { useSlaStore } from '@/stores/sla'
|
||||
import api from '@/api'
|
||||
|
||||
const emitter = useEmitter()
|
||||
const slaStore = useSlaStore()
|
||||
const timezones = computed(() => Intl.supportedValuesOf('timeZone'))
|
||||
const assignmentTypes = ['Round robin', 'Manual']
|
||||
const businessHours = ref([])
|
||||
const slaPolicies = ref([])
|
||||
|
||||
const props = defineProps({
|
||||
initialValues: { type: Object, required: false },
|
||||
@@ -161,39 +190,40 @@ const fetchBusinessHours = async () => {
|
||||
businessHours.value = response.data.data
|
||||
} catch (error) {
|
||||
// If unauthorized (no permission), show a toast message.
|
||||
const toastPayload = error.response.status === 403
|
||||
? {
|
||||
title: 'Unauthorized',
|
||||
variant: 'destructive',
|
||||
description: 'You do not have permission to view business hours.'
|
||||
}
|
||||
: {
|
||||
title: 'Could not fetch business hours',
|
||||
variant: 'destructive',
|
||||
description: handleHTTPError(error).message
|
||||
}
|
||||
const toastPayload =
|
||||
error.response.status === 403
|
||||
? {
|
||||
title: 'Unauthorized',
|
||||
variant: 'destructive',
|
||||
description: 'You do not have permission to view business hours.'
|
||||
}
|
||||
: {
|
||||
title: 'Could not fetch business hours',
|
||||
variant: 'destructive',
|
||||
description: handleHTTPError(error).message
|
||||
}
|
||||
emitter.emit(EMITTER_EVENTS.SHOW_TOAST, toastPayload)
|
||||
}
|
||||
}
|
||||
|
||||
const onSubmit = form.handleSubmit(values => {
|
||||
const onSubmit = form.handleSubmit((values) => {
|
||||
props.submitForm(values)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.initialValues,
|
||||
newValues => {
|
||||
(newValues) => {
|
||||
if (Object.keys(newValues).length === 0) return
|
||||
form.setValues(newValues)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
function toggleEmojiPicker () {
|
||||
function toggleEmojiPicker() {
|
||||
isEmojiPickerVisible.value = !isEmojiPickerVisible.value
|
||||
}
|
||||
|
||||
function onSelectEmoji (emoji) {
|
||||
function onSelectEmoji(emoji) {
|
||||
form.setFieldValue('emoji', emoji.i || emoji)
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -12,4 +12,5 @@ export const teamFormSchema = z.object({
|
||||
conversation_assignment_type: z.string({ required_error: 'Conversation assignment type is required.' }),
|
||||
timezone: z.string({ required_error: 'Timezone is required.' }),
|
||||
business_hours_id: z.number().optional().nullable(),
|
||||
sla_policy_id: z.number().optional().nullable(),
|
||||
})
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<div class="flex items-center mt-2 space-x-2">
|
||||
<SlaDisplay
|
||||
:dueAt="conversation.first_reply_due_at"
|
||||
:dueAt="conversation.first_response_due_at"
|
||||
:actualAt="conversation.first_reply_at"
|
||||
:label="'FRD'"
|
||||
:showSLAHit="false"
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="flex justify-start items-center space-x-2">
|
||||
<p class="font-medium">First reply at</p>
|
||||
<SlaDisplay
|
||||
:dueAt="conversation.first_reply_due_at"
|
||||
:dueAt="conversation.first_response_due_at"
|
||||
:actualAt="conversation.first_reply_at"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user