diff --git a/frappe/public/js/frappe/form/footer/form_timeline.js b/frappe/public/js/frappe/form/footer/form_timeline.js index 0070d384d7..203859a144 100644 --- a/frappe/public/js/frappe/form/footer/form_timeline.js +++ b/frappe/public/js/frappe/form/footer/form_timeline.js @@ -429,13 +429,13 @@ class FormTimeline extends BaseTimeline { } if (this.frm.doctype === "Communication") { - args.txt = ""; + args.message = ""; args.last_email = this.frm.doc; args.recipients = this.frm.doc.sender; args.subject = __("Re: {0}", [this.frm.doc.subject]); } else { const comment_value = frappe.markdown(this.frm.comment_box.get_value()); - args.txt = strip_html(comment_value) ? comment_value : ''; + args.message = strip_html(comment_value) ? comment_value : ''; } new frappe.views.CommunicationComposer(args); diff --git a/frappe/public/js/frappe/ui/field_group.js b/frappe/public/js/frappe/ui/field_group.js index 479c020fbb..eb3dcc4f89 100644 --- a/frappe/public/js/frappe/ui/field_group.js +++ b/frappe/public/js/frappe/ui/field_group.js @@ -137,6 +137,10 @@ frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout { }); } + has_field(fieldname) { + return !!this.fields_dict[fieldname]; + } + set_input(key, val) { return this.set_value(key, val); } diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 1d219a7044..90d81c10e5 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -100,6 +100,17 @@ frappe.views.CommunicationComposer = class { 300 ) }, + { + fieldtype: "Button", + label: __("Add Signature"), + fieldname: 'add_signature', + hidden: 1, + click: async () => { + let sender_email = this.dialog.get_value('sender') || ""; + this.content_set = false; + await this.set_content(sender_email); + } + }, { fieldtype: "Section Break" }, { label: __("Send me a copy"), @@ -146,14 +157,16 @@ frappe.views.CommunicationComposer = class { }); if (email_accounts.length) { + this.user_email_accounts = email_accounts.map(function(e) { + return e.email_id; + }); + fields.unshift({ label: __("From"), fieldtype: "Select", reqd: 1, fieldname: "sender", - options: email_accounts.map(function(e) { - return e.email_id; - }) + options: this.user_email_accounts }); } @@ -177,9 +190,15 @@ frappe.views.CommunicationComposer = class { this.setup_email(); this.setup_email_template(); this.setup_last_edited_communication(); + this.setup_add_signature_button(); this.set_values(); } + setup_add_signature_button() { + let has_sender = this.dialog.has_field('sender'); + this.dialog.set_df_property('add_signature', 'hidden', !has_sender); + } + setup_multiselect_queries() { ['recipients', 'cc', 'bcc'].forEach(field => { this.dialog.fields_dict[field].get_data = () => { @@ -239,7 +258,9 @@ frappe.views.CommunicationComposer = class { // some email clients (outlook) may not send the message id to identify // the thread. So as a backup we use the name of the document as identifier const identifier = `#${this.frm.doc.name}`; - if (!this.subject.includes(identifier)) { + + // converting to str for int names + if (!cstr(this.subject).includes(identifier)) { this.subject = `${this.subject} (${identifier})`; } } @@ -350,7 +371,7 @@ frappe.views.CommunicationComposer = class { } async set_values_from_last_edited_communication() { - if (this.txt || this.message) return; + if (this.message) return; const last_edited = this.get_last_edited_communication(); if (!last_edited.content) return; @@ -709,10 +730,10 @@ frappe.views.CommunicationComposer = class { } } - async set_content() { + async set_content(sender_email) { if (this.content_set) return; - let message = this.txt || this.message || ""; + let message = this.message || ""; if (!message && this.frm) { const { doctype, docname } = this.frm; message = await localforage.getItem(doctype + docname) || ""; @@ -722,26 +743,41 @@ frappe.views.CommunicationComposer = class { this.content_set = true; } - message += await this.get_signature(); + message += await this.get_signature(sender_email || null); - if (this.is_a_reply) { + if (this.is_a_reply && !this.reply_set) { message += this.get_earlier_reply(); } await this.dialog.set_value("content", message); } - async get_signature() { + async get_signature(sender_email) { let signature = frappe.boot.user.email_signature; if (!signature) { - const response = await frappe.db.get_value( - 'Email Account', - {'default_outgoing': 1, 'add_signature': 1}, - 'signature' - ); + let filters = { + 'add_signature': 1 + }; - signature = response.message.signature; + if (sender_email) { + filters['email_id'] = sender_email; + } else { + filters['default_outgoing'] = 1; + } + + const email = await frappe.db.get_list("Email Account", { + filters: filters, + fields: ['signature', 'email_id'], + limit: 1 + }); + + signature = email && email[0].signature; + + if (this.user_email_accounts && + this.user_email_accounts.includes(email[0].email_id)) { + this.dialog.set_value('sender', email[0].email_id); + } } if (!signature) return ""; @@ -754,6 +790,8 @@ frappe.views.CommunicationComposer = class { } get_earlier_reply() { + this.reply_set = false; + const last_email = ( this.last_email || this.frm && this.frm.timeline.get_last_email(true) @@ -777,6 +815,8 @@ frappe.views.CommunicationComposer = class { last_email.communication_date || last_email.creation ); + this.reply_set = true; + return `

${separator_element || ''} diff --git a/frappe/public/scss/common/modal.scss b/frappe/public/scss/common/modal.scss index c9217a075e..0de34f4ae4 100644 --- a/frappe/public/scss/common/modal.scss +++ b/frappe/public/scss/common/modal.scss @@ -210,16 +210,22 @@ body.modal-open[style^="padding-right"] { form { display: flex; align-items: center; - .frappe-control:first-child { - flex: 1; - margin-bottom: 0px; - } - .frappe-control:last-child { - margin-left: 10px; - margin-bottom: -24px; - button { - // same as form-control input - height: calc(1.5em + .75rem + 2px); + + .frappe-control { + &[data-fieldname="sender"] { + flex: 1; + margin-bottom: 0px; + } + &[data-fieldname="recipients"] { + margin-left: 10px; + } + &[data-fieldname="option_toggle_button"] { + margin-left: 10px; + margin-bottom: -24px; + button { + // same as form-control input + height: calc(1.5em + .75rem + 2px); + } } } }