diff --git a/crm/api/activities.py b/crm/api/activities.py index 449b579a..3ccb173c 100644 --- a/crm/api/activities.py +++ b/crm/api/activities.py @@ -2,6 +2,7 @@ import json import frappe from frappe import _ +from frappe.utils.caching import redis_cache from frappe.desk.form.load import get_docinfo @frappe.whitelist() @@ -98,6 +99,7 @@ def get_deal_activities(name): "recipients": communication.recipients, "cc": communication.cc, "bcc": communication.bcc, + "attachments": get_attachments(communication.name), "read_by_recipient": communication.read_by_recipient, }, "is_lead": False, @@ -185,6 +187,7 @@ def get_lead_activities(name): "recipients": communication.recipients, "cc": communication.cc, "bcc": communication.bcc, + "attachments": get_attachments(communication.name), "read_by_recipient": communication.read_by_recipient, }, "is_lead": True, @@ -196,6 +199,14 @@ def get_lead_activities(name): return activities +@redis_cache() +def get_attachments(name): + return frappe.db.get_all( + "File", + filters={"attached_to_doctype": "Communication", "attached_to_name": name}, + fields=["name", "file_name", "file_url", "file_size", "is_private"], + ) + def handle_multiple_versions(versions): activities = [] grouped_versions = [] diff --git a/frontend/package.json b/frontend/package.json index 61faae06..ce000952 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,7 @@ "@vueuse/integrations": "^10.3.0", "feather-icons": "^4.28.0", "frappe-ui": "^0.1.17", + "mime": "^4.0.1", "pinia": "^2.0.33", "socket.io-client": "^4.7.2", "sortablejs": "^1.15.0", diff --git a/frontend/src/components/Activities.vue b/frontend/src/components/Activities.vue index fb91d84b..1fd23977 100644 --- a/frontend/src/components/Activities.vue +++ b/frontend/src/components/Activities.vue @@ -326,6 +326,14 @@ +
+ +
+ + + + + + + + + + + diff --git a/frontend/src/components/CommunicationArea.vue b/frontend/src/components/CommunicationArea.vue index a7b60318..a8cfe737 100644 --- a/frontend/src/components/CommunicationArea.vue +++ b/frontend/src/components/CommunicationArea.vue @@ -39,6 +39,8 @@ }" :editable="showCommunicationBox" v-model="doc.data" + v-model:attachments="attachments" + :doctype="doctype" placeholder="Add a reply..." />
@@ -51,6 +53,13 @@ import { usersStore } from '@/stores/users' import { call } from 'frappe-ui' import { ref, watch, computed, defineModel } from 'vue' +const props = defineProps({ + doctype: { + type: String, + default: 'CRM Lead', + }, +}) + const doc = defineModel() const reload = defineModel('reload') @@ -62,6 +71,7 @@ const showCommunicationBox = ref(false) const newEmail = ref('') const newEmailEditor = ref(null) const sendEmailRef = ref(null) +const attachments = ref([]); watch( () => showCommunicationBox.value, @@ -81,18 +91,14 @@ const onNewEmailChange = (value) => { } async function sendMail() { - let doctype = 'CRM Lead' - if (doc.value.data.lead) { - doctype = 'CRM Deal' - } - await call('frappe.core.doctype.communication.email.make', { recipients: doc.value.data.email, + attachments: attachments.value.map((x) => x.name), cc: '', bcc: '', subject: 'Email from Agent', content: newEmail.value, - doctype: doctype, + doctype: props.doctype, name: doc.value.data.name, send_email: 1, sender: getUser().name, diff --git a/frontend/src/components/Controls/Link.vue b/frontend/src/components/Controls/Link.vue index d09cd224..d351db3c 100644 --- a/frontend/src/components/Controls/Link.vue +++ b/frontend/src/components/Controls/Link.vue @@ -85,6 +85,7 @@ const text = ref('') watchDebounced( () => autocomplete.value?.query, (val) => { + val = val || '' if (text.value === val) return text.value = val options.update({ diff --git a/frontend/src/components/EmailEditor.vue b/frontend/src/components/EmailEditor.vue index 624869a2..d1437538 100644 --- a/frontend/src/components/EmailEditor.vue +++ b/frontend/src/components/EmailEditor.vue @@ -9,7 +9,7 @@ :editable="editable" >