diff --git a/frontend/src/components/Activities/CallArea.vue b/frontend/src/components/Activities/CallArea.vue index d7771879..4a1ae469 100644 --- a/frontend/src/components/Activities/CallArea.vue +++ b/frontend/src/components/Activities/CallArea.vue @@ -1,5 +1,5 @@ @@ -24,11 +25,74 @@ import NestedPopover from '@/components/NestedPopover.vue' import MultipleAvatar from '@/components/MultipleAvatar.vue' import AssignToBody from '@/components/AssignToBody.vue' +import { useDocument } from '@/data/document' +import { toast } from 'frappe-ui' +import { computed } from 'vue' const props = defineProps({ - data: Object, doctype: String, + docname: String, }) +const { document } = useDocument(props.doctype, props.docname) + const assignees = defineModel() + +const ownerField = computed(() => { + if (props.doctype === 'CRM Lead') { + return 'lead_owner' + } else if (props.doctype === 'CRM Deal') { + return 'deal_owner' + } else { + return null + } +}) + +async function saveAssignees( + addedAssignees, + removedAssignees, + addAssignees, + removeAssignees, +) { + removedAssignees.length && (await removeAssignees.submit(removedAssignees)) + addedAssignees.length && (await addAssignees.submit(addedAssignees)) + + const nextAssignee = assignees.value.find( + (a) => a.name !== document.doc[ownerField.value], + ) + + let owner = ownerField.value.replace('_', ' ') + + if ( + document.doc[ownerField.value] && + removedAssignees.includes(document.doc[ownerField.value]) + ) { + document.doc[ownerField.value] = nextAssignee ? nextAssignee.name : '' + document.save.submit() + + if (nextAssignee) { + toast.info( + __( + 'Since you removed {0} from the assignee, the {0} has been changed to the next available assignee {1}.', + [owner, nextAssignee.label || nextAssignee.name], + ), + ) + } else { + toast.info( + __( + 'Since you removed {0} from the assignee, the {0} has also been removed.', + [owner], + ), + ) + } + } else if (!document.doc[ownerField.value] && nextAssignee) { + document.doc[ownerField.value] = nextAssignee ? nextAssignee.name : '' + toast.info( + __('Since you added a new assignee, the {0} has been set to {1}.', [ + owner, + nextAssignee.label || nextAssignee.name, + ]), + ) + } +} diff --git a/frontend/src/components/AssignToBody.vue b/frontend/src/components/AssignToBody.vue index 223d1fb4..675417cf 100644 --- a/frontend/src/components/AssignToBody.vue +++ b/frontend/src/components/AssignToBody.vue @@ -74,22 +74,26 @@ import UserAvatar from '@/components/UserAvatar.vue' import Link from '@/components/Controls/Link.vue' import { usersStore } from '@/stores/users' import { capture } from '@/telemetry' -import { Tooltip, call, Switch, toast } from 'frappe-ui' -import { ref, computed, watch } from 'vue' +import { Tooltip, Switch, toast, createResource } from 'frappe-ui' +import { ref, watch } from 'vue' const props = defineProps({ - doc: { - type: Object, - default: null, - }, doctype: { type: String, default: '', }, + docname: { + type: Object, + default: null, + }, open: { type: Boolean, default: false, }, + onUpdate: { + type: Function, + default: null, + }, }) const emit = defineEmits(['reload']) @@ -102,12 +106,6 @@ const error = ref('') const { users, getUser } = usersStore() -const owner = computed(() => { - if (!props.doc) return '' - if (props.doctype == 'CRM Lead') return props.doc.lead_owner - return props.doc.deal_owner -}) - const removeValue = (value) => { if (value === getUser('').name) { assignToMe.value = false @@ -119,6 +117,10 @@ const removeValue = (value) => { } const addValue = (value) => { + if (value === getUser('').name) { + assignToMe.value = true + } + error.value = '' let obj = { name: value, @@ -155,6 +157,9 @@ watch( ) async function updateAssignees() { + if (JSON.stringify(oldAssignees.value) === JSON.stringify(assignees.value)) + return + const removedAssignees = oldAssignees.value .filter( (assignee) => !assignees.value.find((a) => a.name === assignee.name), @@ -167,23 +172,45 @@ async function updateAssignees() { ) .map((assignee) => assignee.name) - if (removedAssignees.length) { - await call('crm.api.doc.remove_assignments', { - doctype: props.doctype, - name: props.doc.name, - assignees: removedAssignees, - }) - toast.success(__('Assignees removed successfully.')) - } - - if (addedAssignees.length) { - capture('assign_to', { doctype: props.doctype }) - call('frappe.desk.form.assign_to.add', { - doctype: props.doctype, - name: props.doc.name, - assign_to: addedAssignees, - }) - toast.success(__('Assignees added successfully.')) + if (props.onUpdate) { + props.onUpdate( + addedAssignees, + removedAssignees, + addAssignees, + removeAssignees, + ) + } else { + if (removedAssignees.length) { + await removeAssignees.submit(removedAssignees) + } + if (addedAssignees.length) { + addAssignees.submit(addedAssignees) + } } } + +const addAssignees = createResource({ + url: 'frappe.desk.form.assign_to.add', + makeParams: (addedAssignees) => ({ + doctype: props.doctype, + name: props.docname, + assign_to: addedAssignees, + }), + onSuccess: () => { + capture('assign_to', { doctype: props.doctype }) + toast.success(__('Assignees added successfully.')) + }, +}) + +const removeAssignees = createResource({ + url: 'crm.api.doc.remove_assignments', + makeParams: (removedAssignees) => ({ + doctype: props.doctype, + name: props.docname, + assignees: removedAssignees, + }), + onSuccess: () => { + toast.success(__('Assignees removed successfully.')) + }, +}) diff --git a/frontend/src/pages/Deal.vue b/frontend/src/pages/Deal.vue index 7c8e9605..80212a72 100644 --- a/frontend/src/pages/Deal.vue +++ b/frontend/src/pages/Deal.vue @@ -16,7 +16,7 @@ v-if="document.actions?.length" :actions="document.actions" /> - + - + - +
- +