diff --git a/frappe/__init__.py b/frappe/__init__.py index ddade9062c..9a7f307b4f 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -460,7 +460,7 @@ def has_website_permission(doctype, ptype="read", doc=None, user=None, verbose=F doc = get_doc(doctype, doc) for method in hooks: - result = call(get_attr(method), doc=doc, ptype=ptype, user=user, verbose=verbose) + result = call(method, doc=doc, ptype=ptype, user=user, verbose=verbose) # if even a single permission check is Falsy if not result: return False @@ -789,6 +789,9 @@ def get_attr(method_string): def call(fn, *args, **kwargs): """Call a function and match arguments.""" + if isinstance(fn, basestring): + fn = get_attr(fn) + if hasattr(fn, 'fnargs'): fnargs = fn.fnargs else: diff --git a/frappe/desk/doctype/todo/todo.json b/frappe/desk/doctype/todo/todo.json index 2599a8dd23..cb1a3704a6 100644 --- a/frappe/desk/doctype/todo/todo.json +++ b/frappe/desk/doctype/todo/todo.json @@ -7,6 +7,7 @@ "custom": 0, "docstatus": 0, "doctype": "DocType", + "document_type": "Setup", "fields": [ { "allow_on_submit": 0, @@ -19,7 +20,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Description and Status", + "label": "", "length": 0, "no_copy": 0, "permlevel": 0, @@ -36,29 +37,55 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "description", - "fieldtype": "Text", + "default": "Open", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "Open\nClosed", + "permlevel": 0, + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "default": "Medium", + "fieldname": "priority", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Description", + "label": "Priority", "length": 0, "no_copy": 0, - "oldfieldname": "description", - "oldfieldtype": "Text", + "oldfieldname": "priority", + "oldfieldtype": "Data", + "options": "High\nMedium\nLow", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, - "print_width": "300px", "read_only": 0, "report_hide": 0, - "reqd": 1, + "reqd": 0, "search_index": 0, "set_only_once": 0, - "unique": 0, - "width": "300px" + "unique": 0 }, { "allow_on_submit": 0, @@ -87,18 +114,18 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "default": "Open", - "fieldname": "status", - "fieldtype": "Select", + "fieldname": "date", + "fieldtype": "Date", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 1, - "label": "Status", + "in_list_view": 0, + "label": "Due Date", "length": 0, "no_copy": 0, - "options": "Open\nClosed", + "oldfieldname": "date", + "oldfieldtype": "Date", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -113,20 +140,17 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "default": "Medium", - "fieldname": "priority", - "fieldtype": "Select", + "fieldname": "owner", + "fieldtype": "Link", "hidden": 0, - "ignore_user_permissions": 0, + "ignore_user_permissions": 1, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Priority", + "label": "Allocated To", "length": 0, "no_copy": 0, - "oldfieldname": "priority", - "oldfieldtype": "Data", - "options": "High\nMedium\nLow", + "options": "User", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -141,19 +165,18 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "date", - "fieldtype": "Date", + "fieldname": "description_section", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Due Date", + "label": "", "length": 0, "no_copy": 0, - "oldfieldname": "date", - "oldfieldtype": "Date", "permlevel": 0, + "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, @@ -167,26 +190,29 @@ "allow_on_submit": 0, "bold": 0, "collapsible": 0, - "fieldname": "owner", - "fieldtype": "Link", + "fieldname": "description", + "fieldtype": "Text Editor", "hidden": 0, - "ignore_user_permissions": 1, + "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, - "label": "Allocated To", + "label": "Description", "length": 0, "no_copy": 0, - "options": "User", + "oldfieldname": "description", + "oldfieldtype": "Text", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, + "print_width": "300px", "read_only": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, - "unique": 0 + "unique": 0, + "width": "300px" }, { "allow_on_submit": 0, @@ -370,14 +396,14 @@ "hide_heading": 0, "hide_toolbar": 0, "icon": "icon-check", - "idx": 0, + "idx": 2, "in_create": 0, "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-04-01 06:08:48.898505", + "modified": "2016-04-07 01:35:53.935024", "modified_by": "Administrator", "module": "Desk", "name": "ToDo", diff --git a/frappe/desk/search.py b/frappe/desk/search.py index 861388bae9..d0e4f7fc27 100644 --- a/frappe/desk/search.py +++ b/frappe/desk/search.py @@ -17,7 +17,7 @@ def search_link(doctype, txt, query=None, filters=None, page_len=20, searchfield # this is called by the search box @frappe.whitelist() def search_widget(doctype, txt, query=None, searchfield=None, start=0, - page_len=10, filters=None): + page_len=10, filters=None, as_dict=False): if isinstance(filters, basestring): import json filters = json.loads(filters) @@ -31,8 +31,8 @@ def search_widget(doctype, txt, query=None, searchfield=None, start=0, if query and query.split()[0].lower()!="select": # by method - frappe.response["values"] = frappe.get_attr(query)(doctype, txt, - searchfield, start, page_len, filters) + frappe.response["values"] = frappe.call(query, doctype, txt, + searchfield, start, page_len, filters, as_dict=as_dict) elif not query and doctype in standard_queries: # from standard queries search_widget(doctype, txt, standard_queries[doctype][0], @@ -89,7 +89,8 @@ def search_widget(doctype, txt, query=None, searchfield=None, start=0, limit_page_length=page_len, order_by="if(_relevance, _relevance, 99999), idx desc, modified desc".format(doctype), ignore_permissions = True if doctype == "DocType" else False, # for dynamic links - as_list=True) + as_dict=as_dict, + as_list=not as_dict) # remove _relevance from results frappe.response["values"] = [r[:-1] for r in values] diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index 56464096ca..f63632ea90 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -31,11 +31,14 @@ frappe.ui.form.Grid = Class.extend({ .appendTo(this.parent) .attr("data-fieldname", this.df.fieldname); - $(this.wrapper).find(".grid-add-row").click(function() { + this.wrapper.find(".grid-add-row").click(function() { me.add_new_row(null, null, true); return false; }); + this.custom_buttons = {}; + this.grid_buttons = this.wrapper.find('.grid-buttons'); + this.setup_allow_bulk_edit(); }, @@ -344,7 +347,23 @@ frappe.ui.form.Grid = Class.extend({ frappe.tools.downloadify(data, null, me.df.label); return false; }); - + }, + add_custom_button: function(label, click) { + // add / unhide a custom button + var btn = this.custom_buttons[label]; + if(!btn) { + btn = $('') + .css('margin-right', '10px') + .prependTo(this.grid_buttons) + .on('click', click); + this.custom_buttons[label] = btn; + } else { + btn.removeClass('hidden'); + } + }, + clear_custom_buttons: function() { + // hide all custom buttons + this.grid_buttons.find('.btn-custom').addClass('hidden'); } }); diff --git a/frappe/public/js/frappe/form/grid_body.html b/frappe/public/js/frappe/form/grid_body.html index 7b26b2a419..aa7b89e440 100644 --- a/frappe/public/js/frappe/form/grid_body.html +++ b/frappe/public/js/frappe/form/grid_body.html @@ -6,7 +6,7 @@