fix: intercept data tab's before save and side panel's before field change to show lost reason modal

This commit is contained in:
Shariq Ansari 2025-07-02 15:28:21 +05:30
parent d89c304b13
commit 391844512a
6 changed files with 57 additions and 17 deletions

View File

@ -368,6 +368,7 @@
<DataFields <DataFields
:doctype="doctype" :doctype="doctype"
:docname="doc.data.name" :docname="doc.data.name"
@beforeSave="(data) => emit('beforeSave', data)"
@afterSave="(data) => emit('afterSave', data)" @afterSave="(data) => emit('afterSave', data)"
/> />
</div> </div>
@ -518,7 +519,7 @@ const props = defineProps({
}, },
}) })
const emit = defineEmits(['afterSave']) const emit = defineEmits(['beforeSave', 'afterSave'])
const route = useRoute() const route = useRoute()

View File

@ -66,7 +66,7 @@ import LoadingIndicator from '@/components/Icons/LoadingIndicator.vue'
import { usersStore } from '@/stores/users' import { usersStore } from '@/stores/users'
import { useDocument } from '@/data/document' import { useDocument } from '@/data/document'
import { isMobileView } from '@/composables/settings' import { isMobileView } from '@/composables/settings'
import { ref, watch } from 'vue' import { ref, watch, getCurrentInstance } from 'vue'
const props = defineProps({ const props = defineProps({
doctype: { doctype: {
@ -79,10 +79,13 @@ const props = defineProps({
}, },
}) })
const emit = defineEmits(['afterSave']) const emit = defineEmits(['beforeSave', 'afterSave'])
const { isManager } = usersStore() const { isManager } = usersStore()
const instance = getCurrentInstance()
const attrs = instance?.vnode?.props ?? {}
const showDataFieldsModal = ref(false) const showDataFieldsModal = ref(false)
const { document } = useDocument(props.doctype, props.docname) const { document } = useDocument(props.doctype, props.docname)
@ -107,9 +110,15 @@ function saveChanges() {
return acc return acc
}, {}) }, {})
document.save.submit(null, { const hasListener = attrs['onBeforeSave'] !== undefined
onSuccess: () => emit('afterSave', changes),
}) if (hasListener) {
emit('beforeSave', changes)
} else {
document.save.submit(null, {
onSuccess: () => emit('afterSave', changes),
})
}
} }
watch( watch(

View File

@ -61,8 +61,8 @@ const props = defineProps({
const show = defineModel() const show = defineModel()
const lostReason = ref('') const lostReason = ref(props.deal.doc.lost_reason || '')
const lostNotes = ref('') const lostNotes = ref(props.deal.doc.lost_notes || '')
const error = ref('') const error = ref('')
function cancel() { function cancel() {

View File

@ -400,7 +400,7 @@ import { getFormat, evaluateDependsOnValue } from '@/utils'
import { flt } from '@/utils/numberFormat.js' import { flt } from '@/utils/numberFormat.js'
import { Tooltip, DateTimePicker, DatePicker } from 'frappe-ui' import { Tooltip, DateTimePicker, DatePicker } from 'frappe-ui'
import { useDocument } from '@/data/document' import { useDocument } from '@/data/document'
import { ref, computed } from 'vue' import { ref, computed, getCurrentInstance } from 'vue'
const props = defineProps({ const props = defineProps({
sections: { sections: {
@ -424,7 +424,7 @@ const props = defineProps({
}, },
}) })
const emit = defineEmits(['afterFieldChange', 'reload']) const emit = defineEmits(['beforeFieldChange', 'afterFieldChange', 'reload'])
const { getFormattedPercent, getFormattedFloat, getFormattedCurrency } = const { getFormattedPercent, getFormattedFloat, getFormattedCurrency } =
getMeta(props.doctype) getMeta(props.doctype)
@ -496,18 +496,23 @@ function parsedField(field) {
return _field return _field
} }
const instance = getCurrentInstance()
const attrs = instance?.vnode?.props ?? {}
async function fieldChange(value, df) { async function fieldChange(value, df) {
if (props.preview) return if (props.preview) return
await triggerOnChange(df.fieldname, value) await triggerOnChange(df.fieldname, value)
document.save.submit(null, { const hasListener = attrs['onBeforeFieldChange'] !== undefined
onSuccess: () => {
emit('afterFieldChange', { if (hasListener) {
[df.fieldname]: value, emit('beforeFieldChange', { [df.fieldname]: value })
}) } else {
}, document.save.submit(null, {
}) onSuccess: () => emit('afterFieldChange', { [df.fieldname]: value }),
})
}
} }
function parsedSection(section, editButtonAdded) { function parsedSection(section, editButtonAdded) {

View File

@ -61,6 +61,7 @@
v-model:reload="reload" v-model:reload="reload"
v-model:tabIndex="tabIndex" v-model:tabIndex="tabIndex"
v-model="deal" v-model="deal"
@beforeSave="beforeStatusChange"
@afterSave="reloadAssignees" @afterSave="reloadAssignees"
/> />
</template> </template>
@ -158,6 +159,7 @@
doctype="CRM Deal" doctype="CRM Deal"
:docname="deal.data.name" :docname="deal.data.name"
@reload="sections.reload" @reload="sections.reload"
@beforeFieldChange="beforeStatusChange"
@afterFieldChange="reloadAssignees" @afterFieldChange="reloadAssignees"
> >
<template #actions="{ section }"> <template #actions="{ section }">
@ -792,6 +794,16 @@ function setLostReason() {
showLostReasonModal.value = true showLostReasonModal.value = true
} }
function beforeStatusChange(data) {
if (data?.hasOwnProperty('status') && data.status == 'Lost') {
setLostReason()
} else {
document.save.submit(null, {
onSuccess: () => reloadAssignees(data),
})
}
}
function reloadAssignees(data) { function reloadAssignees(data) {
if (data?.hasOwnProperty('deal_owner')) { if (data?.hasOwnProperty('deal_owner')) {
assignees.reload() assignees.reload()

View File

@ -79,6 +79,7 @@
doctype="CRM Deal" doctype="CRM Deal"
:docname="deal.data.name" :docname="deal.data.name"
@reload="sections.reload" @reload="sections.reload"
@beforeFieldChange="beforeStatusChange"
@afterFieldChange="reloadAssignees" @afterFieldChange="reloadAssignees"
> >
<template #actions="{ section }"> <template #actions="{ section }">
@ -223,6 +224,8 @@
v-model:reload="reload" v-model:reload="reload"
v-model:tabIndex="tabIndex" v-model:tabIndex="tabIndex"
v-model="deal" v-model="deal"
@beforeSave="beforeStatusChange"
@afterSave="reloadAssignees"
/> />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
@ -651,6 +654,16 @@ function setLostReason() {
showLostReasonModal.value = true showLostReasonModal.value = true
} }
function beforeStatusChange(data) {
if (data?.hasOwnProperty('status') && data.status == 'Lost') {
setLostReason()
} else {
document.save.submit(null, {
onSuccess: () => reloadAssignees(data),
})
}
}
function reloadAssignees(data) { function reloadAssignees(data) {
if (data?.hasOwnProperty('deal_owner')) { if (data?.hasOwnProperty('deal_owner')) {
assignees.reload() assignees.reload()