1
0
forked from test/crm

refactor: show call log detail in call log modal

This commit is contained in:
Shariq Ansari 2024-05-30 14:00:12 +05:30
parent e7ca90df51
commit f5fa47bae0
3 changed files with 157 additions and 141 deletions

View File

@ -84,7 +84,9 @@
</div>
</template>
<template
v-if="callLog.type.label == 'Incoming' && !callLog.reference_docname"
v-if="
callLog.doc?.type.label == 'Incoming' && !callLog.doc?.reference_docname
"
#actions
>
<Button
@ -116,11 +118,12 @@ import {
createDocumentResource,
call,
} from 'frappe-ui'
import { getCallLogDetail } from '@/utils/callLog'
import { ref, computed, h, watch } from 'vue'
import { useRouter } from 'vue-router'
const props = defineProps({
callLog: {
name: {
type: Object,
default: {},
},
@ -130,60 +133,66 @@ const show = defineModel()
const showNoteModal = ref(false)
const router = useRouter()
const callNoteDoc = ref(null)
const callLog = ref({})
const detailFields = computed(() => {
if (!callLog.value.doc) return []
let details = [
{
icon: h(FeatherIcon, {
name: props.callLog.type.icon,
name: callLog.value.doc.type.icon,
class: 'h-3.5 w-3.5',
}),
name: 'type',
value: props.callLog.type.label + ' Call',
value: callLog.value.doc.type.label + ' Call',
},
{
icon: ContactsIcon,
name: 'receiver',
value: {
receiver: props.callLog.receiver,
caller: props.callLog.caller,
receiver: callLog.value.doc.receiver,
caller: callLog.value.doc.caller,
},
},
{
icon:
props.callLog.reference_doctype == 'CRM Lead' ? LeadsIcon : Dealsicon,
callLog.value.doc.reference_doctype == 'CRM Lead'
? LeadsIcon
: Dealsicon,
name: 'reference_doctype',
value: props.callLog.reference_doctype == 'CRM Lead' ? 'Lead' : 'Deal',
value:
callLog.value.doc.reference_doctype == 'CRM Lead' ? 'Lead' : 'Deal',
link: () => {
if (props.callLog.reference_doctype == 'CRM Lead') {
if (callLog.value.doc.reference_doctype == 'CRM Lead') {
router.push({
name: 'Lead',
params: { leadId: props.callLog.reference_docname },
params: { leadId: callLog.value.doc.reference_docname },
})
} else {
router.push({
name: 'Deal',
params: { dealId: props.callLog.reference_docname },
params: { dealId: callLog.value.doc.reference_docname },
})
}
},
condition: () => callLog.value.doc.reference_docname,
},
{
icon: CalendarIcon,
name: 'creation',
value: props.callLog.creation.label,
tooltip: props.callLog.creation.label,
value: callLog.value.doc.creation.label,
tooltip: callLog.value.doc.creation.label,
},
{
icon: DurationIcon,
name: 'duration',
value: props.callLog.duration.label,
value: callLog.value.doc.duration.label,
},
{
icon: CheckCircleIcon,
name: 'status',
value: props.callLog.status.label,
color: props.callLog.status.color,
value: callLog.value.doc.status.label,
color: callLog.value.doc.status.color,
},
{
icon: h(FeatherIcon, {
@ -191,7 +200,7 @@ const detailFields = computed(() => {
class: 'h-4 w-4 mt-2',
}),
name: 'recording_url',
value: props.callLog.recording_url,
value: callLog.value.doc.recording_url,
},
{
icon: NoteIcon,
@ -200,12 +209,14 @@ const detailFields = computed(() => {
},
]
return details.filter((detail) => detail.value)
return details
.filter((detail) => detail.value)
.filter((detail) => (detail.condition ? detail.condition() : true))
})
function createLead() {
call('crm.fcrm.doctype.crm_call_log.crm_call_log.create_lead_from_call_log', {
call_log: props.callLog,
call_log: callLog.value.doc,
}).then((d) => {
if (d) {
router.push({ name: 'Lead', params: { leadId: d } })
@ -215,12 +226,45 @@ function createLead() {
watch(show, (val) => {
if (val) {
callNoteDoc.value = createDocumentResource({
doctype: 'FCRM Note',
name: props.callLog.note,
fields: ['title', 'content'],
cache: ['note', props.callLog.note],
callLog.value = createDocumentResource({
doctype: 'CRM Call Log',
name: props.name,
fields: [
'name',
'caller',
'receiver',
'duration',
'type',
'status',
'from',
'to',
'note',
'recording_url',
'reference_doctype',
'reference_docname',
'creation',
],
cache: ['call_log', props.name],
auto: true,
transform: (doc) => {
for (const key in doc) {
doc[key] = getCallLogDetail(key, doc)
}
return doc
},
onSuccess: (doc) => {
if (!doc.note) {
callNoteDoc.value = null
return
}
callNoteDoc.value = createDocumentResource({
doctype: 'FCRM Note',
name: doc.note,
fields: ['title', 'content'],
cache: ['note', doc.note],
auto: true,
})
},
})
}
})

View File

@ -53,7 +53,7 @@
<CallLogModal
v-model="showCallLogModal"
v-model:reloadCallLogs="callLogs"
:callLog="callLog"
:name="selectedCallLog"
/>
</template>
@ -64,20 +64,10 @@ import LayoutHeader from '@/components/LayoutHeader.vue'
import ViewControls from '@/components/ViewControls.vue'
import CallLogsListView from '@/components/ListViews/CallLogsListView.vue'
import CallLogModal from '@/components/Modals/CallLogModal.vue'
import {
secondsToDuration,
dateFormat,
dateTooltipFormat,
timeAgo,
} from '@/utils'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
import { getCallLogDetail } from '@/utils/callLog'
import { Breadcrumbs } from 'frappe-ui'
import { computed, ref } from 'vue'
const { getUser } = usersStore()
const { getContact, getLeadContact } = contactsStore()
const breadcrumbs = [{ label: __('Call Logs'), route: { name: 'Call Logs' } }]
const callLogsListView = ref(null)
@ -94,119 +84,17 @@ const rows = computed(() => {
return callLogs.value?.data.data.map((callLog) => {
let _rows = {}
callLogs.value?.data.rows.forEach((row) => {
_rows[row] = callLog[row]
let incoming = callLog.type === 'Incoming'
if (row === 'caller') {
_rows[row] = {
label: incoming
? getContact(callLog.from)?.full_name ||
getLeadContact(callLog.from)?.full_name ||
'Unknown'
: getUser(callLog.caller).full_name,
image: incoming
? getContact(callLog.from)?.image ||
getLeadContact(callLog.from)?.image
: getUser(callLog.caller).user_image,
}
} else if (row === 'receiver') {
_rows[row] = {
label: incoming
? getUser(callLog.receiver).full_name
: getContact(callLog.to)?.full_name ||
getLeadContact(callLog.to)?.full_name ||
'Unknown',
image: incoming
? getUser(callLog.receiver).user_image
: getContact(callLog.to)?.image ||
getLeadContact(callLog.to)?.image,
}
} else if (row === 'duration') {
_rows[row] = {
label: secondsToDuration(callLog.duration),
icon: 'clock',
}
} else if (row === 'type') {
_rows[row] = {
label: callLog.type,
icon: incoming ? 'phone-incoming' : 'phone-outgoing',
}
} else if (row === 'status') {
_rows[row] = {
label: statusLabelMap[callLog.status],
color: statusColorMap[callLog.status],
}
} else if (['modified', 'creation'].includes(row)) {
_rows[row] = {
label: dateFormat(callLog[row], dateTooltipFormat),
timeAgo: __(timeAgo(callLog[row])),
}
}
_rows[row] = getCallLogDetail(row, callLog)
})
return _rows
})
})
const showCallLogModal = ref(false)
const callLog = ref({
name: '',
caller: '',
receiver: '',
duration: '',
type: '',
status: '',
from: '',
to: '',
note: '',
recording_url: '',
reference_doctype: '',
reference_docname: '',
creation: '',
})
const selectedCallLog = ref(null)
function showCallLog(name) {
let d = rows.value?.find((row) => row.name === name)
callLog.value = {
name: d.name,
caller: d.caller,
receiver: d.receiver,
duration: d.duration,
type: d.type,
status: d.status,
from: d.from,
to: d.to,
note: d.note,
recording_url: d.recording_url,
reference_doctype: d.reference_doctype,
reference_docname: d.reference_docname,
creation: d.creation,
}
selectedCallLog.value = name
showCallLogModal.value = true
}
const statusLabelMap = {
Completed: 'Completed',
Initiated: 'Initiated',
Busy: 'Declined',
Failed: 'Failed',
Queued: 'Queued',
Cancelled: 'Cancelled',
Ringing: 'Ringing',
'No Answer': 'Missed Call',
'In Progress': 'In Progress',
}
const statusColorMap = {
Completed: 'green',
Busy: 'orange',
Failed: 'red',
Initiated: 'gray',
Queued: 'gray',
Cancelled: 'gray',
Ringing: 'gray',
'No Answer': 'red',
'In Progress': 'blue',
}
</script>

View File

@ -0,0 +1,84 @@
import {
secondsToDuration,
dateFormat,
dateTooltipFormat,
timeAgo,
} from '@/utils'
import { usersStore } from '@/stores/users'
import { contactsStore } from '@/stores/contacts'
const { getUser } = usersStore()
const { getContact, getLeadContact } = contactsStore()
export function getCallLogDetail(row, log) {
let incoming = log.type === 'Incoming'
if (row === 'caller') {
return {
label: incoming
? getContact(log.from)?.full_name ||
getLeadContact(log.from)?.full_name ||
'Unknown'
: getUser(log.caller).full_name,
image: incoming
? getContact(log.from)?.image || getLeadContact(log.from)?.image
: getUser(log.caller).user_image,
}
} else if (row === 'receiver') {
return {
label: incoming
? getUser(log.receiver).full_name
: getContact(log.to)?.full_name ||
getLeadContact(log.to)?.full_name ||
'Unknown',
image: incoming
? getUser(log.receiver).user_image
: getContact(log.to)?.image || getLeadContact(log.to)?.image,
}
} else if (row === 'duration') {
return {
label: secondsToDuration(log.duration),
icon: 'clock',
}
} else if (row === 'type') {
return {
label: log.type,
icon: incoming ? 'phone-incoming' : 'phone-outgoing',
}
} else if (row === 'status') {
return {
label: statusLabelMap[log.status],
color: statusColorMap[log.status],
}
} else if (['modified', 'creation'].includes(row)) {
return {
label: dateFormat(log[row], dateTooltipFormat),
timeAgo: __(timeAgo(log[row])),
}
}
return log[row]
}
export const statusLabelMap = {
Completed: 'Completed',
Initiated: 'Initiated',
Busy: 'Declined',
Failed: 'Failed',
Queued: 'Queued',
Cancelled: 'Cancelled',
Ringing: 'Ringing',
'No Answer': 'Missed Call',
'In Progress': 'In Progress',
}
export const statusColorMap = {
Completed: 'green',
Busy: 'orange',
Failed: 'red',
Initiated: 'gray',
Queued: 'gray',
Cancelled: 'gray',
Ringing: 'gray',
'No Answer': 'red',
'In Progress': 'blue',
}