[fix] text editor in firefox
This commit is contained in:
parent
0dff5607f2
commit
78995ceb3e
10 changed files with 110 additions and 47 deletions
|
|
@ -602,7 +602,7 @@ def set_value(doctype, docname, fieldname, value=None):
|
|||
import frappe.client
|
||||
return frappe.client.set_value(doctype, docname, fieldname, value)
|
||||
|
||||
def get_doc(arg1, arg2=None):
|
||||
def get_doc(*args, **kwargs):
|
||||
"""Return a `frappe.model.document.Document` object of the given type and name.
|
||||
|
||||
:param arg1: DocType name as string **or** document JSON.
|
||||
|
|
@ -619,7 +619,7 @@ def get_doc(arg1, arg2=None):
|
|||
|
||||
"""
|
||||
import frappe.model.document
|
||||
return frappe.model.document.get_doc(arg1, arg2)
|
||||
return frappe.model.document.get_doc(*args, **kwargs)
|
||||
|
||||
def get_last_doc(doctype):
|
||||
"""Get last created document of this type."""
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Communication(Document):
|
|||
"""create email flag queue"""
|
||||
if self.communication_type == "Communication" and self.communication_medium == "Email" \
|
||||
and self.sent_or_received == "Received" and self.uid and self.uid != -1:
|
||||
|
||||
|
||||
email_flag_queue = frappe.db.get_value("Email Flag Queue", {
|
||||
"communication": self.name,
|
||||
"is_completed": 0})
|
||||
|
|
@ -69,7 +69,7 @@ class Communication(Document):
|
|||
def after_insert(self):
|
||||
if not (self.reference_doctype and self.reference_name):
|
||||
return
|
||||
|
||||
|
||||
if self.reference_doctype == "Communication" and self.sent_or_received == "Sent":
|
||||
frappe.db.set_value("Communication", self.reference_name, "status", "Replied")
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ def has_permission(doc, ptype, user):
|
|||
if (doc.reference_doctype == "Communication" and doc.reference_name == doc.name) \
|
||||
or (doc.timeline_doctype == "Communication" and doc.timeline_name == doc.name):
|
||||
return
|
||||
|
||||
|
||||
if doc.reference_doctype and doc.reference_name:
|
||||
if frappe.has_permission(doc.reference_doctype, ptype="read", doc=doc.reference_name):
|
||||
return True
|
||||
|
|
@ -277,7 +277,9 @@ def get_permission_query_conditions_for_communication(user):
|
|||
|
||||
if not user: user = frappe.session.user
|
||||
|
||||
if "Super Email User" in frappe.get_roles(user):
|
||||
roles = frappe.get_roles(user)
|
||||
|
||||
if "Super Email User" in roles or "System Manager" in roles:
|
||||
return None
|
||||
else:
|
||||
accounts = frappe.get_all("User Email", filters={ "parent": user },
|
||||
|
|
|
|||
|
|
@ -166,9 +166,6 @@ def _notify(doc, print_html=None, print_format=None, attachments=None,
|
|||
|
||||
def update_parent_status(doc):
|
||||
"""Update status of parent document based on who is replying."""
|
||||
if doc.communication_type != "Communication":
|
||||
return
|
||||
|
||||
parent = doc.get_parent_doc()
|
||||
if not parent:
|
||||
return
|
||||
|
|
|
|||
23
frappe/desk/doctype/todo/test_todo.js
Normal file
23
frappe/desk/doctype/todo/test_todo.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: ToDo", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new ToDo
|
||||
() => frappe.tests.make('ToDo', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
|
|
@ -112,20 +112,18 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Color",
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
|
|
@ -142,18 +140,20 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Color",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
|
|
@ -544,7 +544,7 @@
|
|||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-05 12:54:58.044162",
|
||||
"modified": "2017-09-30 13:57:29.398598",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "ToDo",
|
||||
|
|
|
|||
|
|
@ -273,7 +273,6 @@ class EmailAccount(Document):
|
|||
"uid_reindexed": uid_reindexed
|
||||
}
|
||||
communication = self.insert_communication(msg, args=args)
|
||||
#self.notify_update()
|
||||
|
||||
except SentEmailInInbox:
|
||||
frappe.db.rollback()
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ from frappe.integrations.doctype.webhook import run_webhooks
|
|||
# once_only validation
|
||||
# methods
|
||||
|
||||
def get_doc(arg1, arg2=None):
|
||||
def get_doc(*args, **kwargs):
|
||||
"""returns a frappe.model.Document object.
|
||||
|
||||
:param arg1: Document dict or DocType name.
|
||||
:param arg2: [optional] document name.
|
||||
|
||||
There are two ways to call `get_doc`
|
||||
There are multiple ways to call `get_doc`
|
||||
|
||||
# will fetch the latest user object (with child table) from the database
|
||||
user = get_doc("User", "test@example.com")
|
||||
|
|
@ -39,23 +39,39 @@ def get_doc(arg1, arg2=None):
|
|||
{"role": "System Manager"}
|
||||
]
|
||||
})
|
||||
|
||||
# create new object with keyword arguments
|
||||
user = get_doc(doctype='User', email_id='test@example.com')
|
||||
"""
|
||||
if isinstance(arg1, BaseDocument):
|
||||
return arg1
|
||||
elif isinstance(arg1, string_types):
|
||||
doctype = arg1
|
||||
else:
|
||||
doctype = arg1.get("doctype")
|
||||
if args:
|
||||
if isinstance(args[0], BaseDocument):
|
||||
# already a document
|
||||
return args[0]
|
||||
elif isinstance(args[0], string_types):
|
||||
doctype = args[0]
|
||||
|
||||
elif isinstance(args[0], dict):
|
||||
# passed a dict
|
||||
kwargs = args[0]
|
||||
|
||||
else:
|
||||
raise ValueError('First non keyword argument must be a string or dict')
|
||||
|
||||
if kwargs:
|
||||
if 'doctype' in kwargs:
|
||||
doctype = kwargs['doctype']
|
||||
else:
|
||||
raise ValueError('"doctype" is a required key')
|
||||
|
||||
controller = get_controller(doctype)
|
||||
if controller:
|
||||
return controller(arg1, arg2)
|
||||
return controller(*args, **kwargs)
|
||||
|
||||
raise ImportError(arg1)
|
||||
raise ImportError(doctype)
|
||||
|
||||
class Document(BaseDocument):
|
||||
"""All controllers inherit from `Document`."""
|
||||
def __init__(self, arg1, arg2=None):
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Constructor.
|
||||
|
||||
:param arg1: DocType name as string or document **dict**
|
||||
|
|
@ -68,29 +84,37 @@ class Document(BaseDocument):
|
|||
self._default_new_docs = {}
|
||||
self.flags = frappe._dict()
|
||||
|
||||
if arg1 and isinstance(arg1, string_types):
|
||||
if not arg2:
|
||||
if args and args[0] and isinstance(args[0], string_types):
|
||||
# first arugment is doctype
|
||||
if len(args)==1:
|
||||
# single
|
||||
self.doctype = self.name = arg1
|
||||
self.doctype = self.name = args[0]
|
||||
else:
|
||||
self.doctype = arg1
|
||||
if isinstance(arg2, dict):
|
||||
self.doctype = args[0]
|
||||
if isinstance(args[1], dict):
|
||||
# filter
|
||||
self.name = frappe.db.get_value(arg1, arg2, "name")
|
||||
self.name = frappe.db.get_value(args[0], args[1], "name")
|
||||
if self.name is None:
|
||||
frappe.throw(_("{0} {1} not found").format(_(arg1), arg2), frappe.DoesNotExistError)
|
||||
frappe.throw(_("{0} {1} not found").format(_(args[0]), args[1]),
|
||||
frappe.DoesNotExistError)
|
||||
else:
|
||||
self.name = arg2
|
||||
self.name = args[1]
|
||||
|
||||
self.load_from_db()
|
||||
return
|
||||
|
||||
elif isinstance(arg1, dict):
|
||||
super(Document, self).__init__(arg1)
|
||||
if args and args[0] and isinstance(args[0], dict):
|
||||
# first argument is a dict
|
||||
kwargs = args[0]
|
||||
|
||||
if kwargs:
|
||||
# init base document
|
||||
super(Document, self).__init__(kwargs)
|
||||
self.init_valid_columns()
|
||||
|
||||
else:
|
||||
# incorrect arguments. let's not proceed.
|
||||
raise frappe.DataError("Document({0}, {1})".format(arg1, arg2))
|
||||
raise ValueError('Illegal arguments')
|
||||
|
||||
def reload(self):
|
||||
"""Reload document from database"""
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
this.setup_drag_drop();
|
||||
this.setup_image_dialog();
|
||||
this.setting_count = 0;
|
||||
|
||||
$(document).on('form-refresh', () => {
|
||||
// reset last keystroke when a new form is loaded
|
||||
this.last_keystroke_on = null;
|
||||
})
|
||||
},
|
||||
render_camera_button: (context) => {
|
||||
var ui = $.summernote.ui;
|
||||
|
|
@ -74,7 +79,7 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
me.parse_validate_and_set_in_model(value);
|
||||
},
|
||||
onKeydown: function(e) {
|
||||
me._last_change_on = new Date();
|
||||
me.last_keystroke_on = new Date();
|
||||
var key = frappe.ui.keys.get_key(e);
|
||||
// prevent 'New DocType (Ctrl + B)' shortcut in editor
|
||||
if(['ctrl+b', 'meta+b'].indexOf(key) !== -1) {
|
||||
|
|
@ -205,20 +210,30 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
|
||||
if(this.setting_count > 2) {
|
||||
// we don't understand how the internal triggers work,
|
||||
// so if someone is setting the value third time, then quit
|
||||
// so if someone is setting the value third time in 500ms,
|
||||
// then quit
|
||||
return;
|
||||
}
|
||||
|
||||
this.setting_count += 1;
|
||||
|
||||
let time_since_last_keystroke = moment() - moment(this._last_change_on);
|
||||
let time_since_last_keystroke = moment() - moment(this.last_keystroke_on);
|
||||
|
||||
if(!this._last_change_on || (time_since_last_keystroke > 3000)) {
|
||||
if(!this.last_keystroke_on || (time_since_last_keystroke > 3000)) {
|
||||
// if 3 seconds have passed since the last keystroke and
|
||||
// we have not set any value in the last 1 second, do this
|
||||
setTimeout(() => this.setting_count = 0, 500);
|
||||
this.editor.summernote('code', value || '');
|
||||
this.last_keystroke_on = null;
|
||||
} else {
|
||||
// user is probably still in the middle of typing
|
||||
// so lets not mess up the html by re-updating it
|
||||
// keep checking every second if our 3 second barrier
|
||||
// has been completed, so that we can refresh the html
|
||||
this._setting_value = setInterval(() => {
|
||||
if(time_since_last_keystroke > 3000) {
|
||||
// 3 seconds done! lets refresh
|
||||
// safe to update
|
||||
if(this.last_value !== this.get_input_value()) {
|
||||
// if not already in sync, reset
|
||||
this.editor.summernote('code', this.last_value || '');
|
||||
|
|
@ -226,6 +241,9 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
clearInterval(this._setting_value);
|
||||
this._setting_value = null;
|
||||
this.setting_count = 0;
|
||||
|
||||
// clear timestamp of last keystroke
|
||||
this.last_keystroke_on = null;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ frappe.socketio = {
|
|||
frappe.socketio.doc_subscribe(frm.doctype, frm.docname);
|
||||
});
|
||||
|
||||
$(document).on("form_refresh", function(e, frm) {
|
||||
$(document).on("form-refresh", function(e, frm) {
|
||||
if (frm.is_new()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ _f.Frm.prototype.render_form = function(is_a_different_doc) {
|
|||
|
||||
// trigger global trigger
|
||||
// to use this
|
||||
$(document).trigger('form_refresh', [this]);
|
||||
$(document).trigger('form-refresh', [this]);
|
||||
|
||||
// fields
|
||||
this.refresh_fields();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue