fix: create new contact from deals add contact

This commit is contained in:
Shariq Ansari 2023-11-11 22:56:44 +05:30
parent 50fceef0c3
commit d3d9caad5d
3 changed files with 100 additions and 33 deletions

View File

@ -9,7 +9,7 @@
label: editMode ? 'Update' : 'Create', label: editMode ? 'Update' : 'Create',
variant: 'solid', variant: 'solid',
disabled: !dirty, disabled: !dirty,
onClick: ({ close }) => updateContact(close), onClick: ({ close }) => editMode ? updateContact(close) : callInsertDoc(close),
}, },
], ],
}" }"
@ -42,11 +42,21 @@
/> />
</div> </div>
<FormControl <FormControl
type="text" type="autocomplete"
variant="outline" variant="outline"
size="md" size="md"
label="Organisation" label="Organisation"
v-model="_contact.company_name" :value="_contact.company_name"
:options="
organizations.data.map((d) => {
return {
label: d.name,
value: d.name,
}
})
"
@change="(e) => (_contact.company_name = e.value)"
placeholder="Select organization"
/> />
<div class="flex gap-4"> <div class="flex gap-4">
<FormControl <FormControl
@ -74,53 +84,72 @@
<script setup> <script setup>
import { FormControl, Dialog, call } from 'frappe-ui' import { FormControl, Dialog, call } from 'frappe-ui'
import { ref, defineModel, nextTick, watch, computed } from 'vue' import { ref, defineModel, nextTick, watch, computed } from 'vue'
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router'
import { organizationsStore } from '@/stores/organizations'
const props = defineProps({ const props = defineProps({
contact: { contact: {
type: Object, type: Object,
default: {}, default: {},
}, },
options: {
type: Object,
default: {
redirect: true,
afterInsert: () => {},
},
},
}) })
const router = useRouter() const router = useRouter()
const show = defineModel() const show = defineModel()
const contacts = defineModel('reloadContacts') const contacts = defineModel('reloadContacts')
const { organizations } = organizationsStore()
const editMode = ref(false) const editMode = ref(false)
let _contact = ref({}) let _contact = ref({})
async function updateContact(close) { async function updateContact(close) {
if (JSON.stringify(props.contact) === JSON.stringify(_contact.value)) { if (!dirty.value) {
close()
return return
} }
if (_contact.value.name) { let name = await callSetValue(values)
let d = await call('frappe.client.set_value', {
handleContactUpdate({ name }, close)
}
async function callSetValue(values) {
const d = await call('frappe.client.set_value', {
doctype: 'Contact',
name: _contact.value.name,
fieldname: values,
})
return d.name
}
async function callInsertDoc(close) {
const doc = await call('frappe.client.insert', {
doc: {
doctype: 'Contact', doctype: 'Contact',
name: _contact.value.name, ..._contact.value,
fieldname: _contact.value, },
})
doc.name && handleContactUpdate(doc, close)
}
function handleContactUpdate(doc, close) {
contacts.value?.reload()
if (doc.name && props.options.redirect) {
router.push({
name: 'Contact',
params: { contactId: doc.name },
}) })
if (d.name) {
contacts.value.reload()
}
} else {
let d = await call('frappe.client.insert', {
doc: {
doctype: 'Contact',
..._contact.value,
},
})
if (d.name) {
contacts.value.reload()
router.push({
name: 'Contact',
params: { contactId: d.name },
})
}
} }
close() close && close()
props.options.afterInsert && props.options.afterInsert(doc)
} }
const dirty = computed(() => { const dirty = computed(() => {
@ -134,7 +163,7 @@ watch(
editMode.value = false editMode.value = false
nextTick(() => { nextTick(() => {
_contact.value = { ...props.contact } _contact.value = { ...props.contact }
if (_contact.value.first_name) { if (_contact.value.name) {
editMode.value = true editMode.value = true
} }
}) })

View File

@ -57,13 +57,13 @@ const props = defineProps({
}, },
}) })
const router = useRouter()
const show = defineModel() const show = defineModel()
const organizations = defineModel('reloadOrganizations') const organizations = defineModel('reloadOrganizations')
const title = ref(null) const title = ref(null)
const editMode = ref(false) const editMode = ref(false)
let _organization = ref({}) let _organization = ref({})
const router = useRouter()
async function updateOrganization(close) { async function updateOrganization(close) {
const old = { ...props.organization } const old = { ...props.organization }

View File

@ -125,7 +125,7 @@
} }
}) })
" "
@change="(e) => addContact(e.value)" @change="(e) => e.value && addContact(e.value)"
> >
<template #target="{ togglePopover }"> <template #target="{ togglePopover }">
<Button <Button
@ -138,6 +138,29 @@
</template> </template>
</Button> </Button>
</template> </template>
<template #footer="{ value, close }">
<div>
<Button
variant="ghost"
class="w-full !justify-start"
label="Create one"
@click="
() => {
_contact = {
first_name: value,
company_name: deal.data.organization,
}
showContactModal = true
close()
}
"
>
<template #prefix>
<FeatherIcon name="plus" class="h-4" />
</template>
</Button>
</div>
</template>
</Autocomplete> </Autocomplete>
</div> </div>
</div> </div>
@ -339,7 +362,10 @@
class="mx-2 h-px border-t border-gray-200" class="mx-2 h-px border-t border-gray-200"
/> />
</div> </div>
<div v-else class="flex justify-center items-center text-base text-gray-600 h-20"> <div
v-else
class="flex h-20 items-center justify-center text-base text-gray-600"
>
No contacts added No contacts added
</div> </div>
</div> </div>
@ -359,6 +385,14 @@
afterInsert: (doc) => updateField('organization', doc.name), afterInsert: (doc) => updateField('organization', doc.name),
}" }"
/> />
<ContactModal
v-model="showContactModal"
:contact="_contact"
:options="{
redirect: false,
afterInsert: (doc) => addContact(doc.name),
}"
/>
</template> </template>
<script setup> <script setup>
import ActivityIcon from '@/components/Icons/ActivityIcon.vue' import ActivityIcon from '@/components/Icons/ActivityIcon.vue'
@ -374,6 +408,7 @@ import Toggler from '@/components/Toggler.vue'
import Activities from '@/components/Activities.vue' import Activities from '@/components/Activities.vue'
import UserAvatar from '@/components/UserAvatar.vue' import UserAvatar from '@/components/UserAvatar.vue'
import OrganizationModal from '@/components/Modals/OrganizationModal.vue' import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
import ContactModal from '@/components/Modals/ContactModal.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue' import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import { import {
dealStatuses, dealStatuses,
@ -560,14 +595,17 @@ const detailSections = computed(() => {
] ]
}) })
const showContactModal = ref(false)
const _contact = ref({})
async function addContact(value) { async function addContact(value) {
let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.add_contact', { let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.add_contact', {
deal: props.dealId, deal: props.dealId,
contact: value, contact: value,
}) })
if (d) { if (d) {
await contacts.reload()
deal.reload() deal.reload()
contacts.reload()
createToast({ createToast({
title: 'Contact added', title: 'Contact added',
icon: 'check', icon: 'check',