From 0fa716c56d7ad92a0b57bef8b166830ff2a47412 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 15 Mar 2017 09:57:51 +0530 Subject: [PATCH] [kanban] private kanban board for Note, create new project for Task --- .../doctype/kanban_board/kanban_board.json | 51 ++++++++++++++++-- .../desk/doctype/kanban_board/kanban_board.py | 31 +++++++++++ frappe/desk/form/meta.py | 6 +-- frappe/hooks.py | 2 + frappe/public/js/frappe/list/list_sidebar.js | 53 +++++++++++++------ 5 files changed, 121 insertions(+), 22 deletions(-) diff --git a/frappe/desk/doctype/kanban_board/kanban_board.json b/frappe/desk/doctype/kanban_board/kanban_board.json index 5f2191bc64..cb8f4ba809 100644 --- a/frappe/desk/doctype/kanban_board/kanban_board.json +++ b/frappe/desk/doctype/kanban_board/kanban_board.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 1, "autoname": "field:kanban_board_name", @@ -22,6 +23,8 @@ "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Kanban Board Name", @@ -49,6 +52,8 @@ "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, "label": "Reference DocType", @@ -77,6 +82,8 @@ "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Field Name", @@ -104,6 +111,8 @@ "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -130,6 +139,8 @@ "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Columns", @@ -155,9 +166,11 @@ "columns": 0, "fieldname": "filters", "fieldtype": "Text", - "hidden": 0, + "hidden": 1, "ignore_user_permissions": 0, "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Filters", @@ -174,20 +187,49 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "private", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Private", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-02-09 12:23:30.059564", - "modified_by": "Administrator", + "modified": "2017-03-14 23:02:13.267243", + "modified_by": "faris@erpnext.com", "module": "Desk", "name": "Kanban Board", "name_case": "", @@ -217,6 +259,7 @@ "quick_entry": 0, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, diff --git a/frappe/desk/doctype/kanban_board/kanban_board.py b/frappe/desk/doctype/kanban_board/kanban_board.py index ae77d6fbac..c282bbd126 100644 --- a/frappe/desk/doctype/kanban_board/kanban_board.py +++ b/frappe/desk/doctype/kanban_board/kanban_board.py @@ -11,10 +11,29 @@ from frappe.model.document import Document class KanbanBoard(Document): def validate(self): + self.validate_column_name() + + def validate_column_name(self): for column in self.columns: if not column.column_name: frappe.msgprint(frappe._("Column Name cannot be empty"), raise_exception=True) +def get_permission_query_conditions(user): + if not user: user = frappe.session.user + + if user == "Administrator": + return "" + + return """(`tabKanban Board`.private=0 or `tabKanban Board`.owner="{user}")""".format(user=user) + +def has_permission(doc, ptype, user): + if doc.private == 0 or user == "Administrator": + return True + + if user == doc.owner: + return True + + return False @frappe.whitelist() def add_column(board_name, column_title): @@ -118,6 +137,18 @@ def quick_kanban_board(doctype, board_name, field_name): doc.kanban_board_name = board_name doc.reference_doctype = doctype doc.field_name = field_name + + if doctype == 'Task': + project = frappe.new_doc('Project') + project.project_name = board_name + project.status = 'Open' + project.save() + + doc.filters = '[["Task","project","=","{0}"]]'.format(board_name) + + if doctype == 'Note': + doc.private = 1 + doc.save() return doc diff --git a/frappe/desk/form/meta.py b/frappe/desk/form/meta.py index 39b5c670cc..0f81582182 100644 --- a/frappe/desk/form/meta.py +++ b/frappe/desk/form/meta.py @@ -176,12 +176,12 @@ class FormMeta(Meta): self.load_kanban_column_fields() def load_kanban_boards(self): - kanban_boards = frappe.get_all( - 'Kanban Board', fields=['name', 'filters', 'reference_doctype'], filters={'reference_doctype': self.name}) + kanban_boards = frappe.get_list( + 'Kanban Board', fields=['name', 'filters', 'reference_doctype', 'private'], filters={'reference_doctype': self.name}) self.set("__kanban_boards", kanban_boards, as_value=True) def load_kanban_column_fields(self): - values = frappe.get_all( + values = frappe.get_list( 'Kanban Board', fields=['field_name'], filters={'reference_doctype': self.name}) diff --git a/frappe/hooks.py b/frappe/hooks.py index 0f5cbb27bf..4013240ea8 100755 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -78,6 +78,7 @@ permission_query_conditions = { "ToDo": "frappe.desk.doctype.todo.todo.get_permission_query_conditions", "User": "frappe.core.doctype.user.user.get_permission_query_conditions", "Note": "frappe.desk.doctype.note.note.get_permission_query_conditions", + "Kanban Board": "frappe.desk.doctype.kanban_board.kanban_board.get_permission_query_conditions", "Contact": "frappe.geo.address_and_contact.get_permission_query_conditions_for_contact", "Address": "frappe.geo.address_and_contact.get_permission_query_conditions_for_address" } @@ -87,6 +88,7 @@ has_permission = { "ToDo": "frappe.desk.doctype.todo.todo.has_permission", "User": "frappe.core.doctype.user.user.has_permission", "Note": "frappe.desk.doctype.note.note.has_permission", + "Kanban Board": "frappe.desk.doctype.kanban_board.kanban_board.has_permission", "Contact": "frappe.geo.address_and_contact.has_permission", "Address": "frappe.geo.address_and_contact.has_permission", "Communication": "frappe.core.doctype.communication.communication.has_permission", diff --git a/frappe/public/js/frappe/list/list_sidebar.js b/frappe/public/js/frappe/list/list_sidebar.js index 4618f56210..55641c4f7f 100644 --- a/frappe/public/js/frappe/list/list_sidebar.js +++ b/frappe/public/js/frappe/list/list_sidebar.js @@ -130,16 +130,18 @@ frappe.views.ListSidebar = Class.extend({ $('').appendTo($dropdown); divider = true; } - $(`
  • ${__(board.name)}
  • `).appendTo($dropdown); + $(`
  • + ${__(board.name)} + ${board.private ? '' : ''} +
  • `).appendTo($dropdown); }); $dropdown.find('.new-kanban-board').click(function() { // frappe.new_doc('Kanban Board', {reference_doctype: me.doctype}); var select_fields = frappe.get_meta(me.doctype) .fields.filter(function(df) { - return df.fieldtype === 'Select'; - }).map(function(df) { - return df.fieldname; + return df.fieldtype === 'Select' && + df.fieldname !== 'kanban_column'; }); var fields = [ @@ -149,45 +151,61 @@ frappe.views.ListSidebar = Class.extend({ label: __('Kanban Board Name'), reqd: 1 } - ] + ]; if(select_fields.length > 0) { fields = fields.concat([{ fieldtype: 'Select', fieldname: 'field_name', label: __('Columns based on'), - options: select_fields.join('\n'), + options: select_fields.map(df => df.label).join('\n'), default: select_fields[0] }, { fieldtype: 'Check', fieldname: 'custom_column', - label: __('Add Custom Column Field'), + label: __('Custom Column'), default: 0, onchange: function(e) { var checked = d.get_value('custom_column'); if(checked) { - d.get_input('field_name').prop('disabled', true); + $(d.body).find('.frappe-control[data-fieldname="field_name"]').hide(); } else { - d.get_input('field_name').prop('disabled', null); + $(d.body).find('.frappe-control[data-fieldname="field_name"]').show(); } } }]); } + if(me.doctype === 'Task') { + fields[0].description = __('A new Project with this name will be created'); + } + + if(me.doctype === 'Note') { + fields[0].description = __('This Kanban Board will be private'); + } + var d = new frappe.ui.Dialog({ title: __('New Kanban Board'), fields: fields, - primary_action: function() { - var values = d.get_values(); + primary_action_label: __('Save'), + primary_action: function(values) { + var custom_column = values.custom_column !== undefined ? values.custom_column : 1; + + if(custom_column) { + var field_name = 'kanban_column'; + } else { + var field_name = + select_fields + .find(df => df.label === values.field_name) + .fieldname; + } me.add_custom_column_field(custom_column) .then(function(custom_column) { - var f = custom_column ? - 'kanban_column' : values.field_name; - return me.make_kanban_board(values.board_name, f) + return me.make_kanban_board(values.board_name, field_name) }) .then(function() { d.hide(); @@ -231,11 +249,16 @@ frappe.views.ListSidebar = Class.extend({ field_name: field_name }, callback: function(r) { + var kb = r.message; + if(kb.filters) { + frappe.provide('frappe.kanban_filters'); + frappe.kanban_filters[kb.kanban_board_name] = kb.filters; + } frappe.set_route( 'List', me.doctype, 'Kanban', - r.message.kanban_board_name + kb.kanban_board_name ); } });