From 6085b1eed9a2d988bc97da313e53410b26c17cd7 Mon Sep 17 00:00:00 2001
From: phot0n
Date: Mon, 4 Apr 2022 18:30:33 +0530
Subject: [PATCH 1/6] 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
(cherry picked from commit b9af0ac37e47cc54bc77aa97794927ba2bb51aeb)
---
.../js/frappe/form/footer/form_timeline.js | 4 +-
frappe/public/js/frappe/ui/field_group.js | 10 +++++
.../public/js/frappe/views/communication.js | 43 ++++++++++++++-----
3 files changed, 45 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 fcd4326eb80f..083e1a4beedd 100644
--- a/frappe/public/js/frappe/form/footer/form_timeline.js
+++ b/frappe/public/js/frappe/form/footer/form_timeline.js
@@ -422,13 +422,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 df56fe7b8448..db03bf0a6a04 100644
--- a/frappe/public/js/frappe/ui/field_group.js
+++ b/frappe/public/js/frappe/ui/field_group.js
@@ -129,8 +129,18 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
resolve();
}
});
+<<<<<<< HEAD
},
set_input: function(key, val) {
+=======
+ }
+
+ has_field(fieldname) {
+ return !!this.fields_dict[fieldname];
+ }
+
+ set_input(key, val) {
+>>>>>>> b9af0ac37e (feat(minor): use specific email signature via from field)
return this.set_value(key, val);
},
set_values: function(dict) {
diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js
index b33cd1a3f181..25ee79c86d57 100755
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -95,7 +95,7 @@ frappe.views.CommunicationComposer = class {
fieldname: "content",
onchange: frappe.utils.debounce(
this.save_as_draft.bind(this),
- 300
+ 500
)
},
{ fieldtype: "Section Break" },
@@ -151,7 +151,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;
+ }
});
}
@@ -237,7 +244,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})`;
}
}
@@ -349,7 +358,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;
@@ -708,10 +717,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) || "";
@@ -721,7 +730,7 @@ frappe.views.CommunicationComposer = class {
this.content_set = true;
}
- message += await this.get_signature();
+ message += await this.get_signature(sender_email || null);
const SALUTATION_END_COMMENT = "";
if (this.real_name && !message.includes(SALUTATION_END_COMMENT)) {
@@ -732,20 +741,30 @@ frappe.views.CommunicationComposer = class {
`;
}
- 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'
);
@@ -762,6 +781,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)
@@ -785,6 +806,8 @@ frappe.views.CommunicationComposer = class {
last_email.communication_date || last_email.creation
);
+ this.reply_set = true;
+
return `
${separator_element || ''}
From 3b6a50b2ab1a7bca4c0d8b9b571c0d32c61908f6 Mon Sep 17 00:00:00 2001
From: Shariq Ansari
Date: Thu, 7 Apr 2022 12:57:11 +0530
Subject: [PATCH 2/6] fix: added add signature button if multiple sender emails
available
(cherry picked from commit 0a1595e94e5bd1af7c44bcf4fbd45f3d14438100)
---
.../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 25ee79c86d57..c74cb3183ce0 100755
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -98,6 +98,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"),
@@ -144,21 +155,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
});
}
@@ -182,9 +188,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 = () => {
@@ -752,23 +764,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 0e0eb008368271b460580f269491df494be11899 Mon Sep 17 00:00:00 2001
From: Shariq Ansari
Date: Mon, 11 Apr 2022 13:07:52 +0530
Subject: [PATCH 3/6] style: Added gap between from and to field
(cherry picked from commit 1e63475b2ae6bfced2a473f7554f8963b2b43681)
---
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 44510b4b4328..b6208e6e2f6b 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);
+ }
}
}
}
From f3277067c92da3b6f58adee2bd032fce70e874ab Mon Sep 17 00:00:00 2001
From: Shariq Ansari <30859809+shariquerik@users.noreply.github.com>
Date: Mon, 11 Apr 2022 13:53:40 +0530
Subject: [PATCH 4/6] fix: resolved conflicts
---
frappe/public/js/frappe/ui/field_group.js | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/frappe/public/js/frappe/ui/field_group.js b/frappe/public/js/frappe/ui/field_group.js
index db03bf0a6a04..5aa590d281be 100644
--- a/frappe/public/js/frappe/ui/field_group.js
+++ b/frappe/public/js/frappe/ui/field_group.js
@@ -129,18 +129,11 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
resolve();
}
});
-<<<<<<< HEAD
},
- set_input: function(key, val) {
-=======
- }
-
- has_field(fieldname) {
+ has_field: function(fieldname) {
return !!this.fields_dict[fieldname];
- }
-
- set_input(key, val) {
->>>>>>> b9af0ac37e (feat(minor): use specific email signature via from field)
+ },
+ set_input: function(key, val) {
return this.set_value(key, val);
},
set_values: function(dict) {
From 7feafd9eecc51f10d43cd2539119e543492c1b87 Mon Sep 17 00:00:00 2001
From: Shariq Ansari <30859809+shariquerik@users.noreply.github.com>
Date: Mon, 11 Apr 2022 14:05:58 +0530
Subject: [PATCH 5/6] fix: reverting arrow function to normal function
---
frappe/public/js/frappe/views/communication.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js
index c74cb3183ce0..38fbcc95a752 100755
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -103,7 +103,7 @@ frappe.views.CommunicationComposer = class {
label: __("Add Signature"),
fieldname: 'add_signature',
hidden: 1,
- click: async () => {
+ click: async function() {
let sender_email = this.dialog.get_value('sender') || "";
this.content_set = false;
await this.set_content(sender_email);
From e31395ef327e9d2f8f087f49a3351ee6a3c16fbe Mon Sep 17 00:00:00 2001
From: fproldan
Date: Fri, 10 Jan 2025 13:20:00 +0000
Subject: [PATCH 6/6] fix
---
.../public/js/frappe/views/communication.js | 58 +++++++++----------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js
index 38fbcc95a752..b6dd4cac263a 100755
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -34,7 +34,7 @@ frappe.views.CommunicationComposer = class {
minimizable: true
});
- this.dialog.sections[0].wrapper.addClass('to_section');
+ $(this.dialog.$wrapper.find(".form-section").get(0)).addClass('to_section');
this.prepare();
this.dialog.show();
@@ -95,7 +95,7 @@ frappe.views.CommunicationComposer = class {
fieldname: "content",
onchange: frappe.utils.debounce(
this.save_as_draft.bind(this),
- 500
+ 300
)
},
{
@@ -103,11 +103,11 @@ frappe.views.CommunicationComposer = class {
label: __("Add Signature"),
fieldname: 'add_signature',
hidden: 1,
- click: async function() {
+ click: async function () {
let sender_email = this.dialog.get_value('sender') || "";
this.content_set = false;
await this.set_content(sender_email);
- }
+ }.bind(this)
},
{ fieldtype: "Section Break" },
{
@@ -166,6 +166,10 @@ frappe.views.CommunicationComposer = class {
fieldname: "sender",
options: this.user_email_accounts
});
+ //Preselect email senders if there is only one
+ if (this.user_email_accounts.length==1) {
+ this['sender'] = this.user_email_accounts
+ }
}
return fields;
@@ -193,8 +197,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() {
@@ -282,7 +286,6 @@ frappe.views.CommunicationComposer = class {
const subject_field = me.dialog.fields_dict.subject;
let content = content_field.get_value() || "";
- content = content.split('')[1] || content;
content_field.set_value(`${reply.message}
${content}`);
subject_field.set_value(reply.subject);
@@ -744,15 +747,6 @@ frappe.views.CommunicationComposer = class {
message += await this.get_signature(sender_email || null);
- const SALUTATION_END_COMMENT = "";
- if (this.real_name && !message.includes(SALUTATION_END_COMMENT)) {
- message = `
- ${__('Dear {0},', [this.real_name], 'Salutation in new email')},
- ${SALUTATION_END_COMMENT}
- ${message}
- `;
- }
-
if (this.is_a_reply && !this.reply_set) {
message += this.get_earlier_reply();
}
@@ -774,17 +768,23 @@ frappe.views.CommunicationComposer = class {
filters['default_outgoing'] = 1;
}
- const email = await frappe.db.get_list("Email Account", {
+ const email_accounts = await frappe.db.get_list("Email Account", {
filters: filters,
fields: ['signature', 'email_id'],
limit: 1
});
- signature = email && email[0].signature;
+ let filtered_email = null;
+ if (email_accounts.length) {
+ signature = email_accounts[0].signature;
+ filtered_email = email_accounts[0].email_id;
+ }
- if (this.user_email_accounts &&
- this.user_email_accounts.includes(email[0].email_id)) {
- this.dialog.set_value('sender', email[0].email_id);
+ if (!sender_email && filtered_email) {
+ if (this.user_email_accounts &&
+ this.user_email_accounts.includes(filtered_email)) {
+ this.dialog.set_value('sender', filtered_email);
+ }
}
}
@@ -794,7 +794,7 @@ frappe.views.CommunicationComposer = class {
signature = signature.replace(/\n/g, "
");
}
- return "
" + signature;
+ return "
" + signature;
}
get_earlier_reply() {
@@ -839,12 +839,12 @@ frappe.views.CommunicationComposer = class {
html2text(html) {
// convert HTML to text and try and preserve whitespace
- const d = document.createElement( 'div' );
- d.innerHTML = html.replace(/<\/div>/g, '
') // replace end of blocks
- .replace(/<\/p>/g, '
') // replace end of paragraphs
- .replace(/
/g, '\n');
+ html = html
+ .replace(/<\/div>/g, "
") // replace end of blocks
+ .replace(/<\/p>/g, "
") // replace end of paragraphs
+ .replace(/
/g, "\n");
- // replace multiple empty lines with just one
- return d.textContent.replace(/\n{3,}/g, '\n\n');
+ const text = frappe.utils.html2text(html);
+ return text.replace(/\n{3,}/g, "\n\n");
}
-};
+};
\ No newline at end of file