From b9af0ac37e47cc54bc77aa97794927ba2bb51aeb Mon Sep 17 00:00:00 2001 From: phot0n Date: Mon, 4 Apr 2022 18:30:33 +0530 Subject: [PATCH 1/4] feat(minor): use specific email signature via from field * fix: increase debounce timeout so that events dont clash * fix: signature getting appended multiple time upon dialog open/close --- .../js/frappe/form/footer/form_timeline.js | 4 +- frappe/public/js/frappe/ui/field_group.js | 4 ++ .../public/js/frappe/views/communication.js | 43 ++++++++++++++----- 3 files changed, 39 insertions(+), 12 deletions(-) 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 1936f5115e..178d1a65cb 100644 --- a/frappe/public/js/frappe/ui/field_group.js +++ b/frappe/public/js/frappe/ui/field_group.js @@ -138,6 +138,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..2c420dd1be 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -97,7 +97,7 @@ frappe.views.CommunicationComposer = class { fieldname: "content", onchange: frappe.utils.debounce( this.save_as_draft.bind(this), - 300 + 500 ) }, { fieldtype: "Section Break" }, @@ -153,7 +153,14 @@ frappe.views.CommunicationComposer = class { fieldname: "sender", options: email_accounts.map(function(e) { return e.email_id; - }) + }), + change: async () => { + let sender_email = this.dialog.get_value("sender"); + this.reply_set = !!sender_email; + this.content_set = sender_email && this.sender && this.sender != sender_email; + await this.set_content(sender_email); + this.sender = sender_email; + } }); } @@ -239,7 +246,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 +359,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 +718,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,22 +731,32 @@ 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) { + let filters = {}; + if (sender_email) { + filters['email_id'] = sender_email; + } else { + if (this.dialog.has_field("sender")) return ""; + + filters['default_outgoing'] = 1; + } + filters['add_signature'] = 1; + const response = await frappe.db.get_value( 'Email Account', - {'default_outgoing': 1, 'add_signature': 1}, + filters, 'signature' ); @@ -754,6 +773,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 +798,8 @@ frappe.views.CommunicationComposer = class { last_email.communication_date || last_email.creation ); + this.reply_set = true; + return `

${separator_element || ''} From 0a1595e94e5bd1af7c44bcf4fbd45f3d14438100 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 7 Apr 2022 12:57:11 +0530 Subject: [PATCH 2/4] fix: added add signature button if multiple sender emails available --- .../public/js/frappe/views/communication.js | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 2c420dd1be..6cfebd7ec8 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 { 500 ) }, + { + 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,21 +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; - }), - change: async () => { - let sender_email = this.dialog.get_value("sender"); - this.reply_set = !!sender_email; - this.content_set = sender_email && this.sender && this.sender != sender_email; - await this.set_content(sender_email); - this.sender = sender_email; - } + options: this.user_email_accounts }); } @@ -184,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 is_sender = this.dialog.has_field('sender'); + this.dialog.set_df_property('add_signature', 'hidden', !is_sender); + } + setup_multiselect_queries() { ['recipients', 'cc', 'bcc'].forEach(field => { this.dialog.fields_dict[field].get_data = () => { @@ -744,23 +756,28 @@ frappe.views.CommunicationComposer = class { let signature = frappe.boot.user.email_signature; if (!signature) { - let filters = {}; + let filters = { + 'add_signature': 1 + }; + if (sender_email) { filters['email_id'] = sender_email; } else { - if (this.dialog.has_field("sender")) return ""; - filters['default_outgoing'] = 1; } - filters['add_signature'] = 1; - const response = await frappe.db.get_value( - 'Email Account', - filters, - 'signature' - ); + const email = await frappe.db.get_list("Email Account", { + filters: filters, + fields: ['signature', 'email_id'], + limit: 1 + }); - signature = response.message.signature; + 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 ""; From 7679d5e82cc5e596ba78075649f211f7da81090f Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Thu, 7 Apr 2022 13:07:04 +0530 Subject: [PATCH 3/4] chore: better variable name --- frappe/public/js/frappe/views/communication.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 6cfebd7ec8..90d81c10e5 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -97,7 +97,7 @@ frappe.views.CommunicationComposer = class { fieldname: "content", onchange: frappe.utils.debounce( this.save_as_draft.bind(this), - 500 + 300 ) }, { @@ -195,8 +195,8 @@ frappe.views.CommunicationComposer = class { } setup_add_signature_button() { - let is_sender = this.dialog.has_field('sender'); - this.dialog.set_df_property('add_signature', 'hidden', !is_sender); + let has_sender = this.dialog.has_field('sender'); + this.dialog.set_df_property('add_signature', 'hidden', !has_sender); } setup_multiselect_queries() { From 1e63475b2ae6bfced2a473f7554f8963b2b43681 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Mon, 11 Apr 2022 13:07:52 +0530 Subject: [PATCH 4/4] style: Added gap between from and to field --- frappe/public/scss/common/modal.scss | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) 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); + } } } }