Просмотр исходного кода

refactor: frappe.views.CommunicationComposer

version-14
Sagar Vora 4 лет назад
committed by Suraj Shetty
Родитель
Сommit
3b4e40d6b1
2 измененных файлов: 245 добавлений и 252 удалений
  1. +1
    -1
      frappe/public/js/frappe/form/controls/multiselect.js
  2. +244
    -251
      frappe/public/js/frappe/views/communication.js

+ 1
- 1
frappe/public/js/frappe/form/controls/multiselect.js Просмотреть файл

@@ -68,7 +68,7 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
let data; let data;
if(this.df.get_data) { if(this.df.get_data) {
data = this.df.get_data(); data = this.df.get_data();
this.set_data(data);
if (data) this.set_data(data);
} else { } else {
data = this._super(); data = this._super();
} }


+ 244
- 251
frappe/public/js/frappe/views/communication.js Просмотреть файл

@@ -2,16 +2,15 @@
// MIT License. See license.txt // MIT License. See license.txt


frappe.last_edited_communication = {}; frappe.last_edited_communication = {};
frappe.standard_replies = {};
frappe.separator_element = '<div>---</div>';
const separator_element = '<div>---</div>';


frappe.views.CommunicationComposer = Class.extend({ frappe.views.CommunicationComposer = Class.extend({
init: function(opts) {
init(opts) {
$.extend(this, opts); $.extend(this, opts);
this.make(); this.make();
}, },
make: function() {
var me = this;
make() {
const me = this;


this.dialog = new frappe.ui.Dialog({ this.dialog = new frappe.ui.Dialog({
title: (this.title || this.subject || __("New Email")), title: (this.title || this.subject || __("New Email")),
@@ -19,56 +18,35 @@ frappe.views.CommunicationComposer = Class.extend({
fields: this.get_fields(), fields: this.get_fields(),
primary_action_label: __("Send"), primary_action_label: __("Send"),
size: 'large', size: 'large',
primary_action: function() {
me.delete_saved_draft();
primary_action() {
me.send_action(); me.send_action();
me.clear_cache();
},
secondary_action_label: __("Discard"),
secondary_action() {
me.dialog.hide();
me.clear_cache();
}, },
minimizable: true minimizable: true
}); });


this.dialog.sections[0].wrapper.addClass('to_section'); this.dialog.sections[0].wrapper.addClass('to_section');


['recipients', 'cc', 'bcc'].forEach(field => {
this.dialog.fields_dict[field].get_data = function() {
const data = me.dialog.fields_dict[field].get_value();
const txt = data.match(/[^,\s*]*$/)[0] || '';
let options = [];

frappe.call({
method: "frappe.email.get_contact_list",
args: {
txt: txt,
},
callback: (r) => {
options = r.message;
me.dialog.fields_dict[field].set_data(options);
}
});
return options;
}
});

this.prepare(); this.prepare();
this.dialog.show(); this.dialog.show();


if (this.frm) { if (this.frm) {
$(document).trigger('form-typing', [this.frm]); $(document).trigger('form-typing', [this.frm]);
} }

if (this.cc || this.bcc) {
this.toggle_more_options(true);
}
}, },


get_fields: function() {
let contactList = [];
let fields = [
get_fields() {
const fields = [
{ {
label: __("To"), label: __("To"),
fieldtype: "MultiSelect", fieldtype: "MultiSelect",
reqd: 0, reqd: 0,
fieldname: "recipients", fieldname: "recipients",
options: contactList
}, },
{ {
fieldtype: "Button", fieldtype: "Button",
@@ -87,13 +65,11 @@ frappe.views.CommunicationComposer = Class.extend({
label: __("CC"), label: __("CC"),
fieldtype: "MultiSelect", fieldtype: "MultiSelect",
fieldname: "cc", fieldname: "cc",
options: contactList
}, },
{ {
label: __("BCC"), label: __("BCC"),
fieldtype: "MultiSelect", fieldtype: "MultiSelect",
fieldname: "bcc", fieldname: "bcc",
options: contactList
}, },
{ {
label: __("Email Template"), label: __("Email Template"),
@@ -163,18 +139,16 @@ frappe.views.CommunicationComposer = Class.extend({
); );
}); });


if (frappe.boot.email_accounts && email_accounts.length > 1) {
fields = [
{
label: __("From"),
fieldtype: "Select",
reqd: 1,
fieldname: "sender",
options: email_accounts.map(function(e) {
return e.email_id;
})
}
].concat(fields);
if (email_accounts.length > 1) {
fields.unshift({
label: __("From"),
fieldtype: "Select",
reqd: 1,
fieldname: "sender",
options: email_accounts.map(function(e) {
return e.email_id;
})
});
} }


return fields; return fields;
@@ -183,56 +157,58 @@ frappe.views.CommunicationComposer = Class.extend({
toggle_more_options(show_options) { toggle_more_options(show_options) {
show_options = show_options || this.dialog.fields_dict.more_options.df.hidden; show_options = show_options || this.dialog.fields_dict.more_options.df.hidden;
this.dialog.set_df_property('more_options', 'hidden', !show_options); this.dialog.set_df_property('more_options', 'hidden', !show_options);
let label = frappe.utils.icon(show_options ? 'up-line': 'down');

const label = frappe.utils.icon(show_options ? 'up-line': 'down');
this.dialog.get_field('option_toggle_button').set_label(label); this.dialog.get_field('option_toggle_button').set_label(label);
}, },


prepare: function() {
prepare() {
this.setup_multiselect_queries();
this.setup_subject_and_recipients(); this.setup_subject_and_recipients();
this.setup_print_language(); this.setup_print_language();
this.setup_print(); this.setup_print();
this.setup_attach(); this.setup_attach();
this.setup_email(); this.setup_email();
this.setup_last_edited_communication();
this.setup_email_template(); this.setup_email_template();
this.setup_last_edited_communication();
this.set_values();
},


this.dialog.set_value("recipients", this.recipients || '');
this.dialog.set_value("cc", this.cc || '');
this.dialog.set_value("bcc", this.bcc || '');

if(this.dialog.fields_dict.sender) {
this.dialog.fields_dict.sender.set_value(this.sender || '');
}
this.dialog.fields_dict.subject.set_value(
frappe.utils.html2text(this.subject) || ''
);

this.setup_earlier_reply();
setup_multiselect_queries() {
['recipients', 'cc', 'bcc'].forEach(field => {
this.dialog.fields_dict[field].get_data = () => {
const data = this.dialog.fields_dict[field].get_value();
const txt = data.match(/[^,\s*]*$/)[0] || '';


if ('frm' in this && !this.is_a_reply) {
// set default email template for the first email in a document
this.dialog.set_value("email_template", this.frm.meta.default_email_template || '');
}
frappe.call({
method: "frappe.email.get_contact_list",
args: {txt},
callback: (r) => {
this.dialog.fields_dict[field].set_data(r.message);
}
});
}
});
}, },


setup_subject_and_recipients: function() {
setup_subject_and_recipients() {
this.subject = this.subject || ""; this.subject = this.subject || "";


if(!this.forward && !this.recipients && this.last_email) {
if (!this.forward && !this.recipients && this.last_email) {
this.recipients = this.last_email.sender; this.recipients = this.last_email.sender;
this.cc = this.last_email.cc; this.cc = this.last_email.cc;
this.bcc = this.last_email.bcc; this.bcc = this.last_email.bcc;
} }


if(!this.forward && !this.recipients) {
if (!this.forward && !this.recipients) {
this.recipients = this.frm && this.frm.timeline.get_recipient(); this.recipients = this.frm && this.frm.timeline.get_recipient();
} }


if(!this.subject && this.frm) {
if (!this.subject && this.frm) {
// get subject from last communication // get subject from last communication
var last = this.frm.timeline.get_last_email();
const last = this.frm.timeline.get_last_email();


if(last) {
if (last) {
this.subject = last.subject; this.subject = last.subject;
if(!this.recipients) { if(!this.recipients) {
this.recipients = last.sender; this.recipients = last.sender;
@@ -256,7 +232,7 @@ frappe.views.CommunicationComposer = Class.extend({
// always add an identifier to catch a reply // always add an identifier to catch a reply
// some email clients (outlook) may not send the message id to identify // 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 // the thread. So as a backup we use the name of the document as identifier
let identifier = `#${this.frm.doc.name}`;
const identifier = `#${this.frm.doc.name}`;
if (!this.subject.includes(identifier)) { if (!this.subject.includes(identifier)) {
this.subject = `${this.subject} (${identifier})`; this.subject = `${this.subject} (${identifier})`;
} }
@@ -267,34 +243,23 @@ frappe.views.CommunicationComposer = Class.extend({
} }
}, },


setup_email_template: function() {
var me = this;
setup_email_template() {
const me = this;


this.dialog.fields_dict["email_template"].df.onchange = () => { this.dialog.fields_dict["email_template"].df.onchange = () => {
var email_template = me.dialog.fields_dict.email_template.get_value();
if (email_template === '') {
return;
}

var prepend_reply = function(reply) {
if(me.reply_added===email_template) {
return;
}
var content_field = me.dialog.fields_dict.content;
var subject_field = me.dialog.fields_dict.subject;
var content = content_field.get_value() || "";
var subject = subject_field.get_value() || "";
const email_template = me.dialog.fields_dict.email_template.get_value();
if (!email_template) return;


var parts = content.split('<!-- salutation-ends -->');
function prepend_reply(reply) {
if (me.reply_added === email_template) return;


if(parts.length===2) {
content = [reply.message, "<br>", parts[1]];
} else {
content = [reply.message, "<br>", content];
}
const content_field = me.dialog.fields_dict.content;
const subject_field = me.dialog.fields_dict.subject;


content_field.set_value(content.join(''));
let content = content_field.get_value() || "";
content = content.split('<!-- salutation-ends -->')[1] || content;


content_field.set_value(`${reply.message}<br>${content}`);
subject_field.set_value(reply.subject); subject_field.set_value(reply.subject);


me.reply_added = email_template; me.reply_added = email_template;
@@ -307,83 +272,105 @@ frappe.views.CommunicationComposer = Class.extend({
doc: me.frm.doc, doc: me.frm.doc,
_lang: me.dialog.get_value("language_sel") _lang: me.dialog.get_value("language_sel")
}, },
callback: function(r) {
callback(r) {
prepend_reply(r.message); prepend_reply(r.message);
}, },
}); });
} }
}, },


setup_last_edited_communication: function() {
var me = this;
if (!this.doc){
if (cur_frm){
this.doc = cur_frm.doctype;
}else{
this.doc = "Inbox";
}
}
if (cur_frm && cur_frm.docname) {
this.key = cur_frm.docname;
setup_last_edited_communication() {
if (this.frm) {
this.doctype = this.frm.doctype;
this.key = this.frm.docname;
} else { } else {
this.key = "Inbox";
this.doctype = this.key = "Inbox";
} }
if(this.last_email) {

if (this.last_email) {
this.key = this.key + ":" + this.last_email.name; this.key = this.key + ":" + this.last_email.name;
} }
if(this.subject){

if (this.subject) {
this.key = this.key + ":" + this.subject; this.key = this.key + ":" + this.subject;
} }
this.dialog.onhide = function() {
var last_edited_communication = me.get_last_edited_communication();
$.extend(last_edited_communication, {
sender: me.dialog.get_value("sender"),
recipients: me.dialog.get_value("recipients"),
cc: me.dialog.get_value("cc"),
bcc: me.dialog.get_value("bcc"),
subject: me.dialog.get_value("subject"),
content: me.dialog.get_value("content"),
});


if (me.frm) {
$(document).trigger("form-stopped-typing", [me.frm]);
this.dialog.on_hide = () => {
$.extend(
this.get_last_edited_communication(true),
this.dialog.get_values(true)
);

if (this.frm) {
$(document).trigger("form-stopped-typing", [this.frm]);
} }
} }
},


this.dialog.on_page_show = function() {
if (!me.txt) {
var last_edited_communication = me.get_last_edited_communication();
if(last_edited_communication.content) {
me.dialog.set_value("sender", last_edited_communication.sender || "");
me.dialog.set_value("subject", last_edited_communication.subject || "");
me.dialog.set_value("recipients", last_edited_communication.recipients || "");
me.dialog.set_value("cc", last_edited_communication.cc || "");
me.dialog.set_value("bcc", last_edited_communication.bcc || "");
me.dialog.set_value("content", last_edited_communication.content || "");
}
}
get_last_edited_communication(clear) {
if (!frappe.last_edited_communication[this.doctype]) {
frappe.last_edited_communication[this.doctype] = {};
}


if (clear || !frappe.last_edited_communication[this.doctype][this.key]) {
frappe.last_edited_communication[this.doctype][this.key] = {};
console.log('cleared!');
} }


return frappe.last_edited_communication[this.doctype][this.key];
}, },


get_last_edited_communication: function() {
if (!frappe.last_edited_communication[this.doc]) {
frappe.last_edited_communication[this.doc] = {};
set_values: async function () {
for (const fieldname of ["recipients", "cc", "bcc", "sender"]) {
await this.dialog.set_value(fieldname, this[fieldname] || "");
} }


if(!frappe.last_edited_communication[this.doc][this.key]) {
frappe.last_edited_communication[this.doc][this.key] = {};
const subject = frappe.utils.html2text(this.subject) || '';
await this.dialog.set_value("subject", subject);

await this.set_values_from_last_edited_communication();
await this.set_content();

// set default email template for the first email in a document
if (this.frm && !this.is_a_reply && !this.content_set) {
const email_template = this.frm.meta.default_email_template || '';
await this.dialog.set_value("email_template", email_template);
} }


return frappe.last_edited_communication[this.doc][this.key];
for (const fieldname of ['email_template', 'cc', 'bcc']) {
if (this.dialog.get_value(fieldname)) {
this.toggle_more_options(true);
break;
}
}
}, },


selected_format: function() {
return this.dialog.fields_dict.select_print_format.input.value || (this.frm && this.frm.meta.default_print_format) || "Standard";
set_values_from_last_edited_communication: async function () {
if (this.txt) return;

const last_edited = this.get_last_edited_communication();
if (!last_edited.content) return;

// prevent re-triggering of email template
if (last_edited.email_template) {
const template_field = this.dialog.fields_dict.email_template;
await template_field.set_model_value(last_edited.email_template);
delete last_edited.email_template;
}

await this.dialog.set_values(last_edited);
this.content_set = true;
}, },


get_print_format: function(format) {
selected_format() {
return (
this.dialog.fields_dict.select_print_format.input.value
|| this.frm && this.frm.meta.default_print_format
|| "Standard"
);
},

get_print_format(format) {
if (!format) { if (!format) {
format = this.selected_format(); format = this.selected_format();
} }
@@ -395,9 +382,9 @@ frappe.views.CommunicationComposer = Class.extend({
} }
}, },


setup_print_language: function() {
var doc = this.doc || cur_frm.doc;
var fields = this.dialog.fields_dict;
setup_print_language() {
const doc = this.frm && this.frm.doc;
const fields = this.dialog.fields_dict;


//Load default print language from doctype //Load default print language from doctype
this.lang_code = doc.language this.lang_code = doc.language
@@ -407,7 +394,7 @@ frappe.views.CommunicationComposer = Class.extend({
} }


//On selection of language retrieve language code //On selection of language retrieve language code
var me = this;
const me = this;
$(fields.language_sel.input).change(function(){ $(fields.language_sel.input).change(function(){
me.lang_code = this.value me.lang_code = this.value
}) })
@@ -422,9 +409,9 @@ frappe.views.CommunicationComposer = Class.extend({
} }
}, },


setup_print: function() {
setup_print() {
// print formats // print formats
var fields = this.dialog.fields_dict;
const fields = this.dialog.fields_dict;


// toggle print format // toggle print format
$(fields.attach_document_print.input).click(function() { $(fields.attach_document_print.input).click(function() {
@@ -434,8 +421,8 @@ frappe.views.CommunicationComposer = Class.extend({
// select print format // select print format
$(fields.select_print_format.wrapper).toggle(false); $(fields.select_print_format.wrapper).toggle(false);


if (cur_frm) {
const print_formats = frappe.meta.get_print_formats(cur_frm.meta.name);
if (this.frm) {
const print_formats = frappe.meta.get_print_formats(this.frm.meta.name);
$(fields.select_print_format.input) $(fields.select_print_format.input)
.empty() .empty()
.add_options(print_formats) .add_options(print_formats)
@@ -446,9 +433,9 @@ frappe.views.CommunicationComposer = Class.extend({


}, },


setup_attach: function() {
var fields = this.dialog.fields_dict;
var attach = $(fields.select_attachments.wrapper);
setup_attach() {
const fields = this.dialog.fields_dict;
const attach = $(fields.select_attachments.wrapper);


if (!this.attachments) { if (!this.attachments) {
this.attachments = []; this.attachments = [];
@@ -493,7 +480,7 @@ frappe.views.CommunicationComposer = Class.extend({
this.render_attachment_rows(); this.render_attachment_rows();
}, },


render_attachment_rows: function(attachment) {
render_attachment_rows(attachment) {
const select_attachments = this.dialog.fields_dict.select_attachments; const select_attachments = this.dialog.fields_dict.select_attachments;
const attachment_rows = $(select_attachments.wrapper).find(".attach-list"); const attachment_rows = $(select_attachments.wrapper).find(".attach-list");
if (attachment) { if (attachment) {
@@ -536,9 +523,9 @@ frappe.views.CommunicationComposer = Class.extend({
</p>`); </p>`);
}, },


setup_email: function() {
setup_email() {
// email // email
var fields = this.dialog.fields_dict;
const fields = this.dialog.fields_dict;


if(this.attach_document_print) { if(this.attach_document_print) {
$(fields.attach_document_print.input).click(); $(fields.attach_document_print.input).click();
@@ -547,21 +534,20 @@ frappe.views.CommunicationComposer = Class.extend({


$(fields.send_me_a_copy.input).on('click', () => { $(fields.send_me_a_copy.input).on('click', () => {
// update send me a copy (make it sticky) // update send me a copy (make it sticky)
let val = fields.send_me_a_copy.get_value();
const val = fields.send_me_a_copy.get_value();
frappe.db.set_value('User', frappe.session.user, 'send_me_a_copy', val); frappe.db.set_value('User', frappe.session.user, 'send_me_a_copy', val);
frappe.boot.user.send_me_a_copy = val; frappe.boot.user.send_me_a_copy = val;
}); });


}, },


send_action: function() {
var me = this;
var btn = me.dialog.get_primary_btn();

var form_values = this.get_values();
send_action() {
const me = this;
const btn = me.dialog.get_primary_btn();
const form_values = this.get_values();
if(!form_values) return; if(!form_values) return;


var selected_attachments =
const selected_attachments =
$.map($(me.dialog.wrapper).find("[data-file-name]:checked"), function (element) { $.map($(me.dialog.wrapper).find("[data-file-name]:checked"), function (element) {
return $(element).attr("data-file-name"); return $(element).attr("data-file-name");
}); });
@@ -574,16 +560,16 @@ frappe.views.CommunicationComposer = Class.extend({
} }
}, },


get_values: function() {
var form_values = this.dialog.get_values();
get_values() {
const form_values = this.dialog.get_values();


// cc // cc
for ( var i=0, l=this.dialog.fields.length; i < l; i++ ) {
var df = this.dialog.fields[i];
for (let i = 0, l = this.dialog.fields.length; i < l; i++) {
const df = this.dialog.fields[i];


if ( df.is_cc_checkbox ) {
if (df.is_cc_checkbox) {
// concat in cc // concat in cc
if ( form_values[df.fieldname] ) {
if (form_values[df.fieldname]) {
form_values.cc = ( form_values.cc ? (form_values.cc + ", ") : "" ) + df.fieldname; form_values.cc = ( form_values.cc ? (form_values.cc + ", ") : "" ) + df.fieldname;
form_values.bcc = ( form_values.bcc ? (form_values.bcc + ", ") : "" ) + df.fieldname; form_values.bcc = ( form_values.bcc ? (form_values.bcc + ", ") : "" ) + df.fieldname;
} }
@@ -595,35 +581,40 @@ frappe.views.CommunicationComposer = Class.extend({
return form_values; return form_values;
}, },


save_as_draft: function() {
save_as_draft() {
if (this.dialog && this.frm) { if (this.dialog && this.frm) {
let message = this.dialog.get_value('content'); let message = this.dialog.get_value('content');
message = message.split(frappe.separator_element)[0];
message = message.split(separator_element)[0];
localforage.setItem(this.frm.doctype + this.frm.docname, message).catch(e => { localforage.setItem(this.frm.doctype + this.frm.docname, message).catch(e => {
if (e) { if (e) {
// silently fail // silently fail
console.log(e); // eslint-disable-line console.log(e); // eslint-disable-line
console.warn('[Communication] localStorage is full. Cannot save message as draft'); // eslint-disable-line
console.warn('[Communication] IndexedDB is full. Cannot save message as draft'); // eslint-disable-line
} }
}); });


} }
}, },


clear_cache() {
this.delete_saved_draft();
this.get_last_edited_communication(true);
},

delete_saved_draft() { delete_saved_draft() {
if (this.dialog && this.frm) { if (this.dialog && this.frm) {
localforage.removeItem(this.frm.doctype + this.frm.docname).catch(e => { localforage.removeItem(this.frm.doctype + this.frm.docname).catch(e => {
if (e) { if (e) {
// silently fail // silently fail
console.log(e); // eslint-disable-line console.log(e); // eslint-disable-line
console.warn('[Communication] localStorage is full. Cannot save message as draft'); // eslint-disable-line
console.warn('[Communication] IndexedDB is full. Cannot save message as draft'); // eslint-disable-line
} }
}); });
} }
}, },


send_email: function(btn, form_values, selected_attachments, print_html, print_format) {
var me = this;
send_email(btn, form_values, selected_attachments, print_html, print_format) {
const me = this;
me.dialog.hide(); me.dialog.hide();


if(!form_values.recipients) { if(!form_values.recipients) {
@@ -637,7 +628,7 @@ frappe.views.CommunicationComposer = Class.extend({
} }




if(cur_frm && !frappe.model.can_email(me.doc.doctype, cur_frm)) {
if(this.frm && !frappe.model.can_email(me.doc.doctype, this.frm)) {
frappe.msgprint(__("You are not allowed to send emails related to this document")); frappe.msgprint(__("You are not allowed to send emails related to this document"));
return; return;
} }
@@ -658,15 +649,17 @@ frappe.views.CommunicationComposer = Class.extend({
send_me_a_copy: form_values.send_me_a_copy, send_me_a_copy: form_values.send_me_a_copy,
print_format: print_format, print_format: print_format,
sender: form_values.sender, sender: form_values.sender,
sender_full_name: form_values.sender?frappe.user.full_name():undefined,
sender_full_name: form_values.sender
? frappe.user.full_name()
: undefined,
email_template: form_values.email_template, email_template: form_values.email_template,
attachments: selected_attachments, attachments: selected_attachments,
_lang : me.lang_code, _lang : me.lang_code,
read_receipt:form_values.send_read_receipt, read_receipt:form_values.send_read_receipt,
print_letterhead: me.is_print_letterhead_checked(), print_letterhead: me.is_print_letterhead_checked(),
}, },
btn: btn,
callback: function(r) {
btn,
callback(r) {
if(!r.exc) { if(!r.exc) {
frappe.utils.play_sound("email"); frappe.utils.play_sound("email");


@@ -678,8 +671,8 @@ frappe.views.CommunicationComposer = Class.extend({
if ((frappe.last_edited_communication[me.doc] || {})[me.key]) { if ((frappe.last_edited_communication[me.doc] || {})[me.key]) {
delete frappe.last_edited_communication[me.doc][me.key]; delete frappe.last_edited_communication[me.doc][me.key];
} }
if (cur_frm) {
cur_frm.reload_doc();
if (this.frm) {
this.frm.reload_doc();
} }


// try the success callback if it exists // try the success callback if it exists
@@ -707,7 +700,7 @@ frappe.views.CommunicationComposer = Class.extend({
}); });
}, },


is_print_letterhead_checked: function() {
is_print_letterhead_checked() {
if (this.frm && $(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){ if (this.frm && $(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){
return $(this.frm.wrapper).find('.print-letterhead').prop('checked') ? 1 : 0; return $(this.frm.wrapper).find('.print-letterhead').prop('checked') ? 1 : 0;
} else { } else {
@@ -716,96 +709,96 @@ frappe.views.CommunicationComposer = Class.extend({
} }
}, },


get_default_outgoing_email_account_signature: function() {
return frappe.db.get_value('Email Account', { 'default_outgoing': 1, 'add_signature': 1 }, 'signature');
},

setup_earlier_reply: async function() {
let fields = this.dialog.fields_dict;
let signature = frappe.boot.user.email_signature || "";

if (!signature) {
const res = await this.get_default_outgoing_email_account_signature();
signature = res.message.signature ? "<!-- signature-included -->" + res.message.signature : "";
}
set_content: async function() {
if (this.content_set) return;


if (signature && !frappe.utils.is_html(signature)) {
signature = signature.replace(/\n/g, "<br>");
let message = this.txt || "";
if (!message && this.frm) {
const { doctype, docname } = this.frm;
message = await localforage.getItem(doctype + docname) || "";
} }


if(this.txt) {
this.message = this.txt + (this.message ? ("<br><br>" + this.message) : "");
} else {
// saved draft in localStorage
const { doctype, docname } = this.frm || {};
if (doctype && docname) {
this.message = await localforage.getItem(doctype + docname) || '';
}
if (message) {
this.content_set = true;
} }


if(this.real_name) {
this.message = '<p>'+__('Dear') +' '
+ this.real_name + ",</p><!-- salutation-ends --><br>" + (this.message || "");
message += await this.get_signature();
if (this.real_name && !message.includes("<!-- salutation-ends -->")) {
message = `<p>${__('Dear')} ${this.real_name},</p>
<!-- salutation-ends --><br>${message}`;
} }


if(this.message && signature && this.message.includes(signature)) {
signature = "";
if (this.is_a_reply) {
message += this.get_earlier_reply();
} }


let reply = (this.message || "") + (signature ? ("<br>" + signature) : "");
let content = '';
await this.dialog.set_value("content", message);
},


if (this.is_a_reply === 'undefined') {
this.is_a_reply = true;
}
get_signature: async function () {
let signature = frappe.boot.user.email_signature;


if (this.is_a_reply) {
let last_email = this.last_email;
if (!signature) {
const response = await frappe.db.get_value(
'Email Account',
{'default_outgoing': 1, 'add_signature': 1},
'signature'
);


if (!last_email) {
last_email = this.frm && this.frm.timeline.get_last_email(true);
}
signature = response.message.signature;
}


if (!last_email) return;
if (!signature) return "";


let last_email_content = last_email.original_comment || last_email.content;
if (!frappe.utils.is_html(signature)) {
signature = signature.replace(/\n/g, "<br>");
}


// convert the email context to text as we are enclosing
// this inside <blockquote>
last_email_content = this.html2text(last_email_content).replace(/\n/g, '<br>');
return "<br><!-- signature-included -->" + signature;
},


// clip last email for a maximum of 20k characters
// to prevent the email content from getting too large
if (last_email_content.length > 20 * 1024) {
last_email_content += '<div>' + __('Message clipped') + '</div>' + last_email_content;
last_email_content = last_email_content.slice(0, 20 * 1024);
}
get_earlier_reply() {
const last_email = (
this.last_email
|| this.frm && this.frm.timeline.get_last_email(true)
);


let communication_date = last_email.communication_date || last_email.creation;
content = `
${reply}
<div><br></div>
${frappe.separator_element || ''}
<p>${__("On {0}, {1} wrote:", [frappe.datetime.global_date_format(communication_date) , last_email.sender])}</p>
<blockquote>
${last_email_content}
</blockquote>
`;
} else {
content = reply;
}
fields.content.set_value(content);
if (!last_email) return "";
let last_email_content = last_email.original_comment || last_email.content;

// convert the email context to text as we are enclosing
// this inside <blockquote>
last_email_content = this.html2text(last_email_content).replace(/\n/g, '<br>');

// clip last email for a maximum of 20k characters
// to prevent the email content from getting too large
if (last_email_content.length > 20 * 1024) {
last_email_content += '<div>' + __('Message clipped') + '</div>' + last_email_content;
last_email_content = last_email_content.slice(0, 20 * 1024);
}

const communication_date = last_email.communication_date || last_email.creation;
return `
<div><br></div>
${separator_element || ''}
<p>${__("On {0}, {1} wrote:", [
frappe.datetime.global_date_format(communication_date),
last_email.sender
])}</p>
<blockquote>
${last_email_content}
</blockquote>
`;
}, },


html2text: function(html) {
html2text(html) {
// convert HTML to text and try and preserve whitespace // convert HTML to text and try and preserve whitespace
var d = document.createElement( 'div' );
const d = document.createElement( 'div' );
d.innerHTML = html.replace(/<\/div>/g, '<br></div>') // replace end of blocks d.innerHTML = html.replace(/<\/div>/g, '<br></div>') // replace end of blocks
.replace(/<\/p>/g, '<br></p>') // replace end of paragraphs .replace(/<\/p>/g, '<br></p>') // replace end of paragraphs
.replace(/<br>/g, '\n'); .replace(/<br>/g, '\n');
let text = d.textContent;


// replace multiple empty lines with just one // replace multiple empty lines with just one
return text.replace(/\n{3,}/g, '\n\n');
return d.textContent.replace(/\n{3,}/g, '\n\n');
} }
}); });

Загрузка…
Отмена
Сохранить