fix: show call log details in modal

This commit is contained in:
Shariq Ansari 2024-05-02 14:33:18 +05:30
parent ceb54a2d36
commit d9a2d7098a
5 changed files with 258 additions and 4 deletions

View File

@ -69,6 +69,10 @@ class CRMCallLog(Document):
"duration",
"from",
"to",
"note",
"recording_url",
"reference_doctype",
"reference_docname",
"creation",
]
return {'columns': columns, 'rows': rows}

View File

@ -0,0 +1,23 @@
<template>
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_3668_69185)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M14.25 8C14.25 11.4518 11.4518 14.25 8 14.25C4.54822 14.25 1.75 11.4518 1.75 8C1.75 4.54822 4.54822 1.75 8 1.75C11.4518 1.75 14.25 4.54822 14.25 8ZM15.25 8C15.25 12.0041 12.0041 15.25 8 15.25C3.99594 15.25 0.75 12.0041 0.75 8C0.75 3.99594 3.99594 0.75 8 0.75C12.0041 0.75 15.25 3.99594 15.25 8ZM11.2909 5.98482C11.4666 5.77175 11.4363 5.45663 11.2232 5.28096C11.0101 5.1053 10.695 5.13561 10.5193 5.34868L7.07001 9.53239L5.72845 7.79857C5.55946 7.58018 5.24543 7.54012 5.02703 7.70911C4.80863 7.8781 4.76858 8.19214 4.93756 8.41053L6.66217 10.6394C6.7552 10.7596 6.89788 10.831 7.04988 10.8334C7.20188 10.8357 7.3467 10.7688 7.4434 10.6515L11.2909 5.98482Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_3668_69185">
<rect width="16" height="16" fill="white" />
</clipPath>
</defs>
</svg>
</template>

View File

@ -3,10 +3,7 @@
:columns="columns"
:rows="rows"
:options="{
getRowRoute: (row) => ({
name: 'Call Log',
params: { callLogId: row.name },
}),
onRowClick: (row) => emit('showCallLog', row.name),
selectable: options.selectable,
showTooltip: options.showTooltip,
resizeColumn: options.resizeColumn,

View File

@ -0,0 +1,185 @@
<template>
<Dialog v-model="show">
<template #body-title>
<div class="flex items-center gap-3">
<h3 class="text-2xl font-semibold leading-6 text-gray-900">
{{ __('Call Details') }}
</h3>
</div>
</template>
<template #body-content>
<div class="flex flex-col gap-3.5">
<div
v-for="field in detailFields"
:key="field.name"
class="flex h-7 items-center gap-2 text-base text-gray-800"
>
<div class="grid w-7 place-content-center">
<component :is="field.icon" />
</div>
<div v-if="field.name == 'receiver'" class="flex items-center gap-1">
<Avatar
:image="field.value.caller.image"
:label="field.value.caller.label"
size="sm"
/>
<div class="ml-1 flex flex-col gap-1">
{{ field.value.caller.label }}
</div>
<FeatherIcon
name="arrow-right"
class="mx-1 h-4 w-4 text-gray-600"
/>
<Avatar
:image="field.value.receiver.image"
:label="field.value.receiver.label"
size="sm"
/>
<div class="ml-1 flex flex-col gap-1">
{{ field.value.receiver.label }}
</div>
</div>
<Tooltip v-else-if="field.tooltip" :text="field.tooltip">
{{ field.value }}
</Tooltip>
<div v-else-if="field.name == 'recording_url'">
<audio class="audio-control" controls :src="field.value"></audio>
</div>
<div v-else :class="field.color ? `text-${field.color}-600` : ''">
{{ field.value }}
</div>
<div v-if="field.link">
<ArrowUpRightIcon
class="h-4 w-4 shrink-0 cursor-pointer text-gray-600 hover:text-gray-800"
@click="() => field.link()"
/>
</div>
</div>
</div>
</template>
</Dialog>
</template>
<script setup>
import ArrowUpRightIcon from '@/components/Icons/ArrowUpRightIcon.vue'
import DurationIcon from '@/components/Icons/DurationIcon.vue'
import ContactsIcon from '@/components/Icons/ContactsIcon.vue'
import LeadsIcon from '@/components/Icons/LeadsIcon.vue'
import Dealsicon from '@/components/Icons/DealsIcon.vue'
import CalendarIcon from '@/components/Icons/CalendarIcon.vue'
import NoteIcon from '@/components/Icons/NoteIcon.vue'
import CheckCircleIcon from '@/components/Icons/CheckCircleIcon.vue'
// import NoteModal from '@/components/Modals/NoteModal.vue'
import { FeatherIcon, Avatar, Tooltip, createResource } from 'frappe-ui'
import { ref, computed, h } from 'vue'
import { useRouter } from 'vue-router'
const props = defineProps({
callLog: {
type: Object,
default: {},
},
})
const show = defineModel()
const router = useRouter()
const detailFields = computed(() => {
let details = [
{
icon: h(FeatherIcon, {
name: props.callLog.type.icon,
class: 'h-3.5 w-3.5',
}),
name: 'type',
value: props.callLog.type.label + ' Call',
},
{
icon: ContactsIcon,
name: 'receiver',
value: {
receiver: props.callLog.receiver,
caller: props.callLog.caller,
},
},
{
icon:
props.callLog.reference_doctype == 'CRM Lead' ? LeadsIcon : Dealsicon,
name: 'reference_doctype',
value: props.callLog.reference_doctype == 'CRM Lead' ? 'Lead' : 'Deal',
link: () => {
if (props.callLog.reference_doctype == 'CRM Lead') {
router.push({
name: 'Lead',
params: { leadId: props.callLog.reference_docname },
})
} else {
router.push({
name: 'Deal',
params: { dealId: props.callLog.reference_docname },
})
}
},
},
{
icon: CalendarIcon,
name: 'creation',
value: props.callLog.creation.label,
tooltip: props.callLog.creation.label,
},
{
icon: DurationIcon,
name: 'duration',
value: props.callLog.duration.label,
},
{
icon: CheckCircleIcon,
name: 'status',
value: props.callLog.status.label,
color: props.callLog.status.color,
},
{
icon: h(FeatherIcon, {
name: 'play',
class: 'h-3.5 w-3.5',
}),
name: 'recording_url',
value: props.callLog.recording_url,
},
{
icon: NoteIcon,
name: 'note',
value: props.callLog.note,
},
]
return details.filter((detail) => detail.value)
})
async function updateNote(_note) {
if (_note.title || _note.content) {
let d = await call('frappe.client.set_value', {
doctype: 'CRM Note',
name: _callLog.data?.note,
fieldname: _note,
})
if (d.name) {
_callLog.reload()
}
}
}
</script>
<style scoped>
.audio-control {
height: 40px;
outline: none;
border-radius: 10px;
border: 1px solid gray;
cursor: pointer;
}
.audio-control::-webkit-media-controls-panel {
background-color: white;
}
</style>

View File

@ -31,6 +31,7 @@
rowCount: callLogs.data.row_count,
totalCount: callLogs.data.total_count,
}"
@showCallLog="showCallLog"
@loadMore="() => loadMore++"
@columnWidthUpdated="() => triggerResize++"
@updatePageCount="(count) => (updatedPageCount = count)"
@ -47,6 +48,11 @@
<span>{{ __('No Logs Found') }}</span>
</div>
</div>
<CallLogModal
v-model="showCallLogModal"
v-model:reloadCallLogs="callLogs"
:callLog="callLog"
/>
</template>
<script setup>
@ -55,6 +61,7 @@ import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
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,
@ -139,6 +146,44 @@ const rows = computed(() => {
})
})
const showCallLogModal = ref(false)
const callLog = ref({
name: '',
caller: '',
receiver: '',
duration: '',
type: '',
status: '',
from: '',
to: '',
note: '',
recording_url: '',
reference_doctype: '',
reference_docname: '',
creation: '',
})
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,
}
showCallLogModal.value = true
}
const statusLabelMap = {
Completed: 'Completed',
Initiated: 'Initiated',