fix: show response by in sla status badge if in due state
refactored code
This commit is contained in:
parent
d41219b446
commit
be40a3fddc
@ -139,6 +139,7 @@ class CRMDeal(Document):
|
|||||||
"mobile_no",
|
"mobile_no",
|
||||||
"deal_owner",
|
"deal_owner",
|
||||||
"sla_status",
|
"sla_status",
|
||||||
|
"response_by",
|
||||||
"first_response_time",
|
"first_response_time",
|
||||||
"first_responded_on",
|
"first_responded_on",
|
||||||
"modified",
|
"modified",
|
||||||
|
|||||||
@ -219,6 +219,7 @@ class CRMLead(Document):
|
|||||||
"lead_owner",
|
"lead_owner",
|
||||||
"first_name",
|
"first_name",
|
||||||
"sla_status",
|
"sla_status",
|
||||||
|
"response_by",
|
||||||
"first_response_time",
|
"first_response_time",
|
||||||
"first_responded_on",
|
"first_responded_on",
|
||||||
"modified",
|
"modified",
|
||||||
|
|||||||
@ -51,6 +51,7 @@
|
|||||||
'creation',
|
'creation',
|
||||||
'first_response_time',
|
'first_response_time',
|
||||||
'first_responded_on',
|
'first_responded_on',
|
||||||
|
'response_by',
|
||||||
].includes(column.key)
|
].includes(column.key)
|
||||||
"
|
"
|
||||||
class="truncate text-base"
|
class="truncate text-base"
|
||||||
@ -62,11 +63,11 @@
|
|||||||
class="truncate text-base"
|
class="truncate text-base"
|
||||||
>
|
>
|
||||||
<Badge
|
<Badge
|
||||||
v-if="item.label"
|
v-if="item.value"
|
||||||
:variant="'subtle'"
|
:variant="'subtle'"
|
||||||
:theme="item.color"
|
:theme="item.color"
|
||||||
size="md"
|
size="md"
|
||||||
:label="item.label"
|
:label="item.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="column.type === 'Check'">
|
<div v-else-if="column.type === 'Check'">
|
||||||
|
|||||||
@ -60,6 +60,7 @@
|
|||||||
'creation',
|
'creation',
|
||||||
'first_response_time',
|
'first_response_time',
|
||||||
'first_responded_on',
|
'first_responded_on',
|
||||||
|
'response_by',
|
||||||
].includes(column.key)
|
].includes(column.key)
|
||||||
"
|
"
|
||||||
class="truncate text-base"
|
class="truncate text-base"
|
||||||
@ -71,11 +72,11 @@
|
|||||||
class="truncate text-base"
|
class="truncate text-base"
|
||||||
>
|
>
|
||||||
<Badge
|
<Badge
|
||||||
v-if="item.label"
|
v-if="item.value"
|
||||||
:variant="'subtle'"
|
:variant="'subtle'"
|
||||||
:theme="item.color"
|
:theme="item.color"
|
||||||
size="md"
|
size="md"
|
||||||
:label="item.label"
|
:label="item.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="column.type === 'Check'">
|
<div v-else-if="column.type === 'Check'">
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
<div
|
<div
|
||||||
v-for="field in fields"
|
v-for="field in fields"
|
||||||
:key="field.label"
|
:key="field.label"
|
||||||
class="flex items-center gap-2 px-3 text-base leading-5 first:mt-3"
|
class="flex items-center gap-2 px-3 leading-5 first:mt-3"
|
||||||
>
|
>
|
||||||
<div class="w-[106px] shrink-0 text-gray-600">
|
<div class="w-[106px] shrink-0 text-sm text-gray-600">
|
||||||
{{ field.label }}
|
{{ field.label }}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid min-h-[28px] flex-1 items-center overflow-hidden">
|
<div class="grid min-h-[28px] flex-1 text-base items-center overflow-hidden">
|
||||||
<FormControl
|
<FormControl
|
||||||
v-if="
|
v-if="
|
||||||
[
|
[
|
||||||
|
|||||||
@ -389,15 +389,6 @@ const deal = createResource({
|
|||||||
params: { name: props.dealId },
|
params: { name: props.dealId },
|
||||||
cache: ['deal', props.dealId],
|
cache: ['deal', props.dealId],
|
||||||
auto: true,
|
auto: true,
|
||||||
onSuccess: (data) => {
|
|
||||||
if (
|
|
||||||
data.response_by &&
|
|
||||||
data.sla_status == 'First Response Due' &&
|
|
||||||
new Date(data.response_by) < new Date()
|
|
||||||
) {
|
|
||||||
updateField('sla_status', 'Failed')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const reload = ref(false)
|
const reload = ref(false)
|
||||||
|
|||||||
@ -156,14 +156,25 @@ const rows = computed(() => {
|
|||||||
color: getDealStatus(deal.status)?.iconColorClass,
|
color: getDealStatus(deal.status)?.iconColorClass,
|
||||||
}
|
}
|
||||||
} else if (row == 'sla_status') {
|
} else if (row == 'sla_status') {
|
||||||
|
let value = deal.sla_status
|
||||||
|
let tooltipText = value
|
||||||
|
let color =
|
||||||
|
deal.sla_status == 'Failed'
|
||||||
|
? 'red'
|
||||||
|
: deal.sla_status == 'Fulfilled'
|
||||||
|
? 'green'
|
||||||
|
: 'orange'
|
||||||
|
if (value == 'First Response Due') {
|
||||||
|
value = timeAgo(deal.response_by)
|
||||||
|
tooltipText = dateFormat(deal.response_by, dateTooltipFormat)
|
||||||
|
if (new Date(deal.response_by) < new Date()) {
|
||||||
|
color = 'red'
|
||||||
|
}
|
||||||
|
}
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
label: deal.sla_status,
|
label: tooltipText,
|
||||||
color:
|
value: value,
|
||||||
deal.sla_status === 'Failed'
|
color: color,
|
||||||
? 'red'
|
|
||||||
: deal.sla_status === 'Fulfilled'
|
|
||||||
? 'green'
|
|
||||||
: 'gray',
|
|
||||||
}
|
}
|
||||||
} else if (row == 'deal_owner') {
|
} else if (row == 'deal_owner') {
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
@ -175,15 +186,18 @@ const rows = computed(() => {
|
|||||||
label: dateFormat(deal[row], dateTooltipFormat),
|
label: dateFormat(deal[row], dateTooltipFormat),
|
||||||
timeAgo: timeAgo(deal[row]),
|
timeAgo: timeAgo(deal[row]),
|
||||||
}
|
}
|
||||||
} else if (['first_response_time', 'first_responded_on'].includes(row)) {
|
} else if (
|
||||||
|
['first_response_time', 'first_responded_on', 'response_by'].includes(
|
||||||
|
row
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
let field = row == 'response_by' ? 'response_by' : 'first_responded_on'
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
label: deal.first_responded_on
|
label: deal[field] ? dateFormat(deal[field], dateTooltipFormat) : '',
|
||||||
? dateFormat(deal.first_responded_on, dateTooltipFormat)
|
|
||||||
: '',
|
|
||||||
timeAgo: deal[row]
|
timeAgo: deal[row]
|
||||||
? row == 'first_responded_on'
|
? row == 'first_response_time'
|
||||||
? timeAgo(deal[row])
|
? formatTime(deal[row])
|
||||||
: formatTime(deal[row])
|
: timeAgo(deal[row])
|
||||||
: '',
|
: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,69 +141,16 @@
|
|||||||
</FileUploader>
|
</FileUploader>
|
||||||
<div v-if="lead.data.sla_status" class="flex flex-col gap-2 border-b p-5">
|
<div v-if="lead.data.sla_status" class="flex flex-col gap-2 border-b p-5">
|
||||||
<div
|
<div
|
||||||
v-if="lead.data.sla_status == 'First Response Due'"
|
v-for="s in slaSection"
|
||||||
|
:key="s.label"
|
||||||
class="flex items-center gap-4 text-base leading-5"
|
class="flex items-center gap-4 text-base leading-5"
|
||||||
>
|
>
|
||||||
<div class="w-[106px] text-gray-600">Response By</div>
|
<div class="w-[106px] text-gray-600">{{ s.label }}</div>
|
||||||
<Tooltip
|
<Tooltip :text="s.tooltipText" class="cursor-pointer">
|
||||||
:text="dateFormat(lead.data.response_by, 'ddd, MMM D, YYYY h:mm A')"
|
<div v-if="!s.isBadge">{{ s.value }}</div>
|
||||||
class="cursor-pointer"
|
<Badge v-else :label="s.value" variant="subtle" :theme="s.color" />
|
||||||
>
|
|
||||||
{{ timeAgo(lead.data.response_by) }}
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
v-if="lead.data.sla_status == 'Fulfilled'"
|
|
||||||
class="flex items-center gap-4 text-base leading-5"
|
|
||||||
>
|
|
||||||
<div class="w-[106px] text-gray-600">Fulfilled In</div>
|
|
||||||
<Tooltip
|
|
||||||
:text="
|
|
||||||
dateFormat(
|
|
||||||
lead.data.first_responded_on,
|
|
||||||
'ddd, MMM D, YYYY h:mm A'
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="cursor-pointer"
|
|
||||||
>
|
|
||||||
{{ formatTime(lead.data.first_response_time) }}
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
lead.data.sla_status == 'Failed' && lead.data.first_responded_on
|
|
||||||
"
|
|
||||||
class="flex items-center gap-4 text-base leading-5"
|
|
||||||
>
|
|
||||||
<div class="w-[106px] text-gray-600">Fulfilled In</div>
|
|
||||||
<Tooltip
|
|
||||||
:text="
|
|
||||||
dateFormat(
|
|
||||||
lead.data.first_responded_on,
|
|
||||||
'ddd, MMM D, YYYY h:mm A'
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="cursor-pointer"
|
|
||||||
>
|
|
||||||
{{ formatTime(lead.data.first_response_time) }}
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-4 text-base leading-5">
|
|
||||||
<div class="w-[106px] text-gray-600">Status</div>
|
|
||||||
<div class="">
|
|
||||||
<Badge
|
|
||||||
:label="lead.data.sla_status"
|
|
||||||
variant="outline"
|
|
||||||
:theme="
|
|
||||||
lead.data.sla_status === 'Failed'
|
|
||||||
? 'red'
|
|
||||||
: lead.data.sla_status === 'Fulfilled'
|
|
||||||
? 'green'
|
|
||||||
: 'gray'
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 flex-col justify-between overflow-hidden">
|
<div class="flex flex-1 flex-col justify-between overflow-hidden">
|
||||||
<div class="flex flex-col overflow-y-auto">
|
<div class="flex flex-col overflow-y-auto">
|
||||||
@ -259,6 +206,7 @@ import {
|
|||||||
dateFormat,
|
dateFormat,
|
||||||
timeAgo,
|
timeAgo,
|
||||||
formatTime,
|
formatTime,
|
||||||
|
dateTooltipFormat,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import { contactsStore } from '@/stores/contacts'
|
import { contactsStore } from '@/stores/contacts'
|
||||||
@ -298,15 +246,6 @@ const lead = createResource({
|
|||||||
params: { name: props.leadId },
|
params: { name: props.leadId },
|
||||||
cache: ['lead', props.leadId],
|
cache: ['lead', props.leadId],
|
||||||
auto: true,
|
auto: true,
|
||||||
onSuccess: (data) => {
|
|
||||||
if (
|
|
||||||
data.response_by &&
|
|
||||||
data.sla_status == 'First Response Due' &&
|
|
||||||
new Date(data.response_by) < new Date()
|
|
||||||
) {
|
|
||||||
updateField('sla_status', 'Failed')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const reload = ref(false)
|
const reload = ref(false)
|
||||||
@ -441,4 +380,41 @@ function updateField(name, value, callback) {
|
|||||||
callback?.()
|
callback?.()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let slaSection = computed(() => {
|
||||||
|
let sections = []
|
||||||
|
if (lead.data.first_response_time) {
|
||||||
|
sections.push({
|
||||||
|
label: 'Fulfilled In',
|
||||||
|
value: formatTime(lead.data.first_response_time),
|
||||||
|
tooltipText: dateFormat(lead.data.first_responded_on, dateTooltipFormat),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let status = lead.data.sla_status
|
||||||
|
let tooltipText = status
|
||||||
|
let color =
|
||||||
|
lead.data.sla_status == 'Failed'
|
||||||
|
? 'red'
|
||||||
|
: lead.data.sla_status == 'Fulfilled'
|
||||||
|
? 'green'
|
||||||
|
: 'orange'
|
||||||
|
|
||||||
|
if (status == 'First Response Due') {
|
||||||
|
status = timeAgo(lead.data.response_by)
|
||||||
|
tooltipText = dateFormat(lead.data.response_by, dateTooltipFormat)
|
||||||
|
if (new Date(lead.data.response_by) < new Date()) {
|
||||||
|
color = 'red'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sections.push({
|
||||||
|
label: 'Status',
|
||||||
|
isBadge: true,
|
||||||
|
value: status,
|
||||||
|
tooltipText: tooltipText,
|
||||||
|
color: color,
|
||||||
|
})
|
||||||
|
return sections
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -155,14 +155,25 @@ const rows = computed(() => {
|
|||||||
color: getLeadStatus(lead.status)?.iconColorClass,
|
color: getLeadStatus(lead.status)?.iconColorClass,
|
||||||
}
|
}
|
||||||
} else if (row == 'sla_status') {
|
} else if (row == 'sla_status') {
|
||||||
|
let value = lead.sla_status
|
||||||
|
let tooltipText = value
|
||||||
|
let color =
|
||||||
|
lead.sla_status == 'Failed'
|
||||||
|
? 'red'
|
||||||
|
: lead.sla_status == 'Fulfilled'
|
||||||
|
? 'green'
|
||||||
|
: 'orange'
|
||||||
|
if (value == 'First Response Due') {
|
||||||
|
value = timeAgo(lead.response_by)
|
||||||
|
tooltipText = dateFormat(lead.response_by, dateTooltipFormat)
|
||||||
|
if (new Date(lead.response_by) < new Date()) {
|
||||||
|
color = 'red'
|
||||||
|
}
|
||||||
|
}
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
label: lead.sla_status,
|
label: tooltipText,
|
||||||
color:
|
value: value,
|
||||||
lead.sla_status === 'Failed'
|
color: color,
|
||||||
? 'red'
|
|
||||||
: lead.sla_status === 'Fulfilled'
|
|
||||||
? 'green'
|
|
||||||
: 'gray',
|
|
||||||
}
|
}
|
||||||
} else if (row == 'lead_owner') {
|
} else if (row == 'lead_owner') {
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
@ -174,15 +185,18 @@ const rows = computed(() => {
|
|||||||
label: dateFormat(lead[row], dateTooltipFormat),
|
label: dateFormat(lead[row], dateTooltipFormat),
|
||||||
timeAgo: timeAgo(lead[row]),
|
timeAgo: timeAgo(lead[row]),
|
||||||
}
|
}
|
||||||
} else if (['first_response_time', 'first_responded_on'].includes(row)) {
|
} else if (
|
||||||
|
['first_response_time', 'first_responded_on', 'response_by'].includes(
|
||||||
|
row
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
let field = row == 'response_by' ? 'response_by' : 'first_responded_on'
|
||||||
_rows[row] = {
|
_rows[row] = {
|
||||||
label: lead.first_responded_on
|
label: lead[field] ? dateFormat(lead[field], dateTooltipFormat) : '',
|
||||||
? dateFormat(lead.first_responded_on, dateTooltipFormat)
|
|
||||||
: '',
|
|
||||||
timeAgo: lead[row]
|
timeAgo: lead[row]
|
||||||
? row == 'first_responded_on'
|
? row == 'first_response_time'
|
||||||
? timeAgo(lead[row])
|
? formatTime(lead[row])
|
||||||
: formatTime(lead[row])
|
: timeAgo(lead[row])
|
||||||
: '',
|
: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user