refactor: removed contact store from Deal Page

This commit is contained in:
Shariq Ansari 2024-03-19 15:28:47 +05:30
parent 831e6ee499
commit 951494a21c
2 changed files with 79 additions and 27 deletions

View File

@ -32,3 +32,35 @@ def get_deal(name):
deal["_form_script"] = get_form_script('CRM Deal') deal["_form_script"] = get_form_script('CRM Deal')
deal["_assign"] = get_assigned_users("CRM Deal", deal.name) deal["_assign"] = get_assigned_users("CRM Deal", deal.name)
return deal return deal
@frappe.whitelist()
def get_deal_contacts(name):
contacts = frappe.get_all(
"CRM Contacts",
filters={"parenttype": "CRM Deal", "parent": name},
fields=["contact", "is_primary"],
)
deal_contacts = []
for contact in contacts:
is_primary = contact.is_primary
contact = frappe.get_doc("Contact", contact.contact).as_dict()
def get_primary_email(contact):
for email in contact.email_ids:
if email.is_primary:
return email.email_id
return contact.email_ids[0].email_id if contact.email_ids else ""
def get_primary_mobile_no(contact):
for phone in contact.phone_nos:
if phone.is_primary:
return phone.phone
return contact.phone_nos[0].phone if contact.phone_nos else ""
_contact = {
"name": contact.name,
"image": contact.image,
"full_name": contact.full_name,
"email": get_primary_email(contact),
"mobile_no": get_primary_mobile_no(contact),
"is_primary": is_primary,
}
deal_contacts.append(_contact)
return deal_contacts

View File

@ -155,7 +155,14 @@
/> />
<div v-else> <div v-else>
<div <div
v-if="section.contacts.length" v-if="deal_contacts?.loading"
class="flex min-h-10 flex-1 items-center justify-center gap-3 text-base text-gray-500"
>
<LoadingIndicator class="h-4 w-4" />
<span>Loading...</span>
</div>
<div
v-else-if="section.contacts.length"
v-for="(contact, i) in section.contacts" v-for="(contact, i) in section.contacts"
:key="contact.name" :key="contact.name"
> >
@ -173,12 +180,12 @@
@click="toggle()" @click="toggle()"
> >
<Avatar <Avatar
:label="getContactByName(contact.name).full_name" :label="contact.full_name"
:image="getContactByName(contact.name).image" :image="contact.image"
size="md" size="md"
/> />
<div class="truncate"> <div class="truncate">
{{ getContactByName(contact.name).full_name }} {{ contact.full_name }}
</div> </div>
<Badge <Badge
v-if="contact.is_primary" v-if="contact.is_primary"
@ -189,7 +196,7 @@
/> />
</div> </div>
<div class="flex items-center"> <div class="flex items-center">
<Dropdown :options="contactOptions(contact)"> <Dropdown :options="contactOptions(contact.name)">
<Button variant="ghost"> <Button variant="ghost">
<FeatherIcon <FeatherIcon
name="more-horizontal" name="more-horizontal"
@ -223,11 +230,11 @@
> >
<div class="flex items-center gap-3 pb-1.5 pl-1 pt-4"> <div class="flex items-center gap-3 pb-1.5 pl-1 pt-4">
<EmailIcon class="h-4 w-4" /> <EmailIcon class="h-4 w-4" />
{{ getContactByName(contact.name).email_id }} {{ contact.email }}
</div> </div>
<div class="flex items-center gap-3 p-1 py-1.5"> <div class="flex items-center gap-3 p-1 py-1.5">
<PhoneIcon class="h-4 w-4" /> <PhoneIcon class="h-4 w-4" />
{{ getContactByName(contact.name).mobile_no }} {{ contact.mobile_no }}
</div> </div>
</div> </div>
</Section> </Section>
@ -277,6 +284,7 @@
/> />
</template> </template>
<script setup> <script setup>
import LoadingIndicator from '@/components/Icons/LoadingIndicator.vue'
import ActivityIcon from '@/components/Icons/ActivityIcon.vue' import ActivityIcon from '@/components/Icons/ActivityIcon.vue'
import EmailIcon from '@/components/Icons/EmailIcon.vue' import EmailIcon from '@/components/Icons/EmailIcon.vue'
import PhoneIcon from '@/components/Icons/PhoneIcon.vue' import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
@ -305,7 +313,6 @@ import {
errorMessage, errorMessage,
} from '@/utils' } from '@/utils'
import { globalStore } from '@/stores/global' import { globalStore } from '@/stores/global'
import { contactsStore } from '@/stores/contacts'
import { organizationsStore } from '@/stores/organizations' import { organizationsStore } from '@/stores/organizations'
import { statusesStore } from '@/stores/statuses' import { statusesStore } from '@/stores/statuses'
import { import {
@ -321,7 +328,6 @@ import { ref, computed, h, onMounted } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const { $dialog, makeCall } = globalStore() const { $dialog, makeCall } = globalStore()
const { getContactByName, contacts } = contactsStore()
const { organizations, getOrganization } = organizationsStore() const { organizations, getOrganization } = organizationsStore()
const { statusOptions, getDealStatus } = statusesStore() const { statusOptions, getDealStatus } = statusesStore()
const router = useRouter() const router = useRouter()
@ -381,7 +387,6 @@ function updateDeal(fieldname, value, callback) {
auto: true, auto: true,
onSuccess: () => { onSuccess: () => {
deal.reload() deal.reload()
contacts.reload()
reload.value = true reload.value = true
createToast({ createToast({
title: 'Deal updated', title: 'Deal updated',
@ -451,7 +456,7 @@ const tabs = [
const detailSections = computed(() => { const detailSections = computed(() => {
let data = deal.data let data = deal.data
if (!data) return [] if (!data) return []
return getParsedFields(data.doctype_fields, data.contacts) return getParsedFields(data.doctype_fields, deal_contacts.data)
}) })
function getParsedFields(sections, contacts) { function getParsedFields(sections, contacts) {
@ -461,7 +466,11 @@ function getParsedFields(sections, contacts) {
section.contacts = section.contacts =
contacts?.map((contact) => { contacts?.map((contact) => {
return { return {
name: contact.contact, name: contact.name,
full_name: contact.full_name,
email: contact.email,
mobile_no: contact.mobile_no,
image: contact.image,
is_primary: contact.is_primary, is_primary: contact.is_primary,
opened: false, opened: false,
} }
@ -494,7 +503,7 @@ function contactOptions(contact) {
{ {
label: 'Delete', label: 'Delete',
icon: 'trash-2', icon: 'trash-2',
onClick: () => removeContact(contact.name), onClick: () => removeContact(contact),
}, },
] ]
@ -502,7 +511,7 @@ function contactOptions(contact) {
options.push({ options.push({
label: 'Set as Primary Contact', label: 'Set as Primary Contact',
icon: h(SuccessIcon, { class: 'h-4 w-4' }), icon: h(SuccessIcon, { class: 'h-4 w-4' }),
onClick: () => setPrimaryContact(contact.name), onClick: () => setPrimaryContact(contact),
}) })
} }
@ -515,7 +524,7 @@ async function addContact(contact) {
contact, contact,
}) })
if (d) { if (d) {
deal.reload() deal_contacts.reload()
createToast({ createToast({
title: 'Contact added', title: 'Contact added',
icon: 'check', icon: 'check',
@ -530,7 +539,7 @@ async function removeContact(contact) {
contact, contact,
}) })
if (d) { if (d) {
deal.reload() deal_contacts.reload()
createToast({ createToast({
title: 'Contact removed', title: 'Contact removed',
icon: 'check', icon: 'check',
@ -545,8 +554,7 @@ async function setPrimaryContact(contact) {
contact, contact,
}) })
if (d) { if (d) {
await contacts.reload() deal_contacts.reload()
deal.reload()
createToast({ createToast({
title: 'Primary contact set', title: 'Primary contact set',
icon: 'check', icon: 'check',
@ -555,16 +563,28 @@ async function setPrimaryContact(contact) {
} }
} }
const deal_contacts = createResource({
url: 'crm.fcrm.doctype.crm_deal.api.get_deal_contacts',
params: { name: props.dealId },
cache: ['deal_contacts', props.dealId],
auto: true,
})
function triggerCall() { function triggerCall() {
let primaryContact = deal.data.contacts.find((c) => c.is_primary) let primaryContact = deal_contacts.data?.find((c) => c.is_primary)
let contact = primaryContact let mobile_no = primaryContact.mobile_no || null
? getContactByName(primaryContact.contact)
: deal.data.contacts[0] if (!primaryContact) {
? getContactByName(deal.data.contacts[0].contact) errorMessage('No primary contact set')
: null return
primaryContact }
? makeCall(contact.mobile_no)
: errorMessage('No primary contact set') if (!mobile_no) {
errorMessage('No mobile number set')
return
}
makeCall(mobile_no)
} }
function updateField(name, value, callback) { function updateField(name, value, callback) {