Merge branch 'develop' of http://github.com/frappe/frappe into develop
This commit is contained in:
commit
007b8fb6b9
220 changed files with 11474 additions and 9668 deletions
|
|
@ -1052,7 +1052,9 @@ def publish_realtime(*args, **kwargs):
|
|||
:param room: Room in which to publish update (default entire site)
|
||||
:param user: Transmit to user
|
||||
:param doctype: Transmit to doctype, docname
|
||||
:param docname: Transmit to doctype, docname"""
|
||||
:param docname: Transmit to doctype, docname
|
||||
:param after_commit: (default False) will emit after current transaction is committed
|
||||
"""
|
||||
import frappe.async
|
||||
|
||||
return frappe.async.publish_realtime(*args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
from __future__ import unicode_literals
|
||||
__version__ = "6.16.4"
|
||||
__version__ = "6.17.6"
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ def is_file_old(file_path):
|
|||
return ((time.time() - os.stat(file_path).st_mtime) > TASK_LOG_MAX_AGE)
|
||||
|
||||
|
||||
def publish_realtime(event=None, message=None, room=None, user=None, doctype=None, docname=None, now=False):
|
||||
def publish_realtime(event=None, message=None, room=None, user=None, doctype=None, docname=None, after_commit=False):
|
||||
"""Publish real-time updates
|
||||
|
||||
:param event: Event name, like `task_progress` etc. that will be handled by the client (default is `task_progress` if within task or `global`)
|
||||
|
|
@ -105,23 +105,24 @@ def publish_realtime(event=None, message=None, room=None, user=None, doctype=Non
|
|||
:param room: Room in which to publish update (default entire site)
|
||||
:param user: Transmit to user
|
||||
:param doctype: Transmit to doctype, docname
|
||||
:param docname: Transmit to doctype, docname"""
|
||||
:param docname: Transmit to doctype, docname
|
||||
:param after_commit: (default False) will emit after current transaction is committed"""
|
||||
if message is None:
|
||||
message = {}
|
||||
|
||||
if event is None:
|
||||
if frappe.local.task_id:
|
||||
if getattr(frappe.local, "task_id", None):
|
||||
event = "task_progress"
|
||||
else:
|
||||
event = "global"
|
||||
|
||||
if not room:
|
||||
if frappe.local.task_id:
|
||||
if getattr(frappe.local, "task_id", None):
|
||||
room = get_task_progress_room()
|
||||
if not "task_id" in message:
|
||||
message["task_id"] = frappe.local.task_id
|
||||
|
||||
now = True
|
||||
after_commit = False
|
||||
elif user:
|
||||
room = get_user_room(user)
|
||||
elif doctype and docname:
|
||||
|
|
@ -129,10 +130,10 @@ def publish_realtime(event=None, message=None, room=None, user=None, doctype=Non
|
|||
else:
|
||||
room = get_site_room()
|
||||
|
||||
if now:
|
||||
emit_via_redis(event, message, room)
|
||||
else:
|
||||
if after_commit:
|
||||
frappe.local.realtime_log.append([event, message, room])
|
||||
else:
|
||||
emit_via_redis(event, message, room)
|
||||
|
||||
def emit_via_redis(event, message, room):
|
||||
"""Publish real-time updates via redis
|
||||
|
|
@ -159,7 +160,7 @@ def put_log(line_no, line, task_id=None):
|
|||
"lines": {line_no: line}
|
||||
},
|
||||
"task_id": task_id
|
||||
}, room=task_progress_room, now=True)
|
||||
}, room=task_progress_room)
|
||||
r.hset(task_log_key, line_no, line)
|
||||
r.expire(task_log_key, 3600)
|
||||
|
||||
|
|
|
|||
4
frappe/change_log/v6/v6_17_0.md
Normal file
4
frappe/change_log/v6/v6_17_0.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
- Ability to **Like** a document, comment or communication
|
||||
- See notifications about likes that you received
|
||||
- View it on Activity feed
|
||||
- *Stars* have been converted to Likes
|
||||
|
|
@ -218,6 +218,7 @@ def migrate(context, rebuild_website=False):
|
|||
|
||||
clear_notifications()
|
||||
finally:
|
||||
frappe.publish_realtime("version-update")
|
||||
frappe.destroy()
|
||||
|
||||
if rebuild_website:
|
||||
|
|
@ -225,6 +226,7 @@ def migrate(context, rebuild_website=False):
|
|||
else:
|
||||
call_command(sync_www, context)
|
||||
|
||||
|
||||
def prepare_for_update():
|
||||
from frappe.sessions import clear_global_cache
|
||||
clear_global_cache()
|
||||
|
|
|
|||
|
|
@ -1,338 +1,338 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2012-08-08 10:40:11",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"allow_copy": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2012-08-08 10:40:11",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_type",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Email\nChat\nPhone\nSMS\nCreated\nSubmitted\nCancelled\nAssigned\nAssignment Completed\nComment\nWorkflow\nLabel\nAttachment\nAttachment Removed",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_type",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Email\nChat\nPhone\nSMS\nCreated\nSubmitted\nCancelled\nAssigned\nAssignment Completed\nComment\nWorkflow\nLabel\nAttachment\nAttachment Removed\nLike",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_by",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment By",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_by",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_by",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment By",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_by",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_by_fullname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment By Fullname",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_by_fullname",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_by_fullname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment By Fullname",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_by_fullname",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_time",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment Time",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_time",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_time",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Comment Time",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_time",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_doctype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Doctype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_doctype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Doctype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "comment_docname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Docname",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "comment_docname",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Comment Docname",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "comment_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "post_topic",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Post Topic",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "post_topic",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "post_topic",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Post Topic",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "post_topic",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "unsubscribed",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Unsubscribed",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "unsubscribed",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Unsubscribed",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 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,
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference DocType",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference DocType",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"description": "Reference DocType and Reference Name are used to render a comment as a link (href) to a Doc.",
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"description": "Reference DocType and Reference Name are used to render a comment as a link (href) to a Doc.",
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-comments",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-11-16 06:29:43.314568",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Comment",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-comments",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-12-26 06:29:43.314568",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Comment",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"title_field": "comment"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class Comment(Document):
|
|||
|
||||
if self.comment_type in ("Created", "Submitted", "Cancelled", "Label"):
|
||||
comment_type = "Label"
|
||||
elif self.comment_type == "Comment":
|
||||
comment_type = "Comment"
|
||||
elif self.comment_type in ("Comment", "Like"):
|
||||
comment_type = self.comment_type
|
||||
else:
|
||||
comment_type = "Info"
|
||||
|
||||
|
|
@ -32,7 +32,9 @@ class Comment(Document):
|
|||
"subject": self.comment,
|
||||
"doctype": self.comment_doctype,
|
||||
"name": self.comment_docname,
|
||||
"feed_type": comment_type
|
||||
"feed_type": comment_type,
|
||||
"reference_doctype": self.reference_doctype,
|
||||
"reference_name": self.reference_name
|
||||
}
|
||||
|
||||
def after_insert(self):
|
||||
|
|
@ -44,13 +46,15 @@ class Comment(Document):
|
|||
if self.comment_docname == frappe.session.user:
|
||||
message = self.as_dict()
|
||||
message['broadcast'] = True
|
||||
frappe.publish_realtime('new_message', message)
|
||||
frappe.publish_realtime('new_message', message, after_commit=True)
|
||||
else:
|
||||
# comment_docname contains the user who is addressed in the messages' page comment
|
||||
frappe.publish_realtime('new_message', self.as_dict(), user=self.comment_docname)
|
||||
frappe.publish_realtime('new_message', self.as_dict(),
|
||||
user=self.comment_docname, after_commit=True)
|
||||
else:
|
||||
frappe.publish_realtime('new_comment', self.as_dict(), doctype= self.comment_doctype,
|
||||
docname = self.comment_docname)
|
||||
frappe.publish_realtime('new_comment', self.as_dict(),
|
||||
doctype= self.comment_doctype, docname = self.comment_docname,
|
||||
after_commit=True)
|
||||
|
||||
self.notify_mentions()
|
||||
|
||||
|
|
@ -182,3 +186,6 @@ def on_doctype_update():
|
|||
frappe.db.commit()
|
||||
frappe.db.sql("""alter table `tabComment`
|
||||
add index comment_doctype_docname_index(comment_doctype, comment_docname)""")
|
||||
|
||||
if "_liked_by" not in frappe.db.get_table_columns("Comment"):
|
||||
add_column("Comment", "_liked_by", "Text")
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ frappe.ui.form.on("Communication", "refresh", function(frm) {
|
|||
}
|
||||
|
||||
if(frm.doc.status==="Open") {
|
||||
frm.add_custom_button("Close", function() {
|
||||
frm.add_custom_button(__("Close"), function() {
|
||||
frm.set_value("status", "Closed");
|
||||
frm.save();
|
||||
});
|
||||
} else if (frm.doc.status !== "Linked") {
|
||||
frm.add_custom_button("Reopen", function() {
|
||||
frm.add_custom_button(__("Reopen"), function() {
|
||||
frm.set_value("status", "Open");
|
||||
frm.save();
|
||||
});
|
||||
|
|
@ -30,7 +30,7 @@ frappe.ui.form.on("Communication", "refresh", function(frm) {
|
|||
|
||||
frappe.ui.form.on("Communication", "onload", function(frm) {
|
||||
if(frm.doc.content) {
|
||||
frm.doc.content = frappe.utils.remove_script_and_style(frm.doc.content);
|
||||
frm.doc.content = frappe.dom.remove_script_and_style(frm.doc.content);
|
||||
}
|
||||
frm.set_query("reference_doctype", function() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from frappe.utils.file_manager import get_file
|
|||
from frappe.email.bulk import check_bulk_limit
|
||||
import frappe.email.smtp
|
||||
from frappe import _
|
||||
from frappe.model.db_schema import add_column
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ class Communication(Document):
|
|||
comment["comment_type"] = comment["communication_medium"]
|
||||
|
||||
frappe.publish_realtime('new_comment', comment, doctype = self.reference_doctype,
|
||||
docname = self.reference_name)
|
||||
docname = self.reference_name, after_commit=True)
|
||||
|
||||
def on_update(self):
|
||||
"""Update parent status as `Open` or `Replied`."""
|
||||
|
|
@ -246,7 +247,6 @@ class Communication(Document):
|
|||
# if it is a fetched email, add follows to CC
|
||||
cc.append(self.get_owner_email())
|
||||
cc += self.get_assignees()
|
||||
cc += self.get_starrers()
|
||||
|
||||
if cc:
|
||||
# exclude email accounts, unfollows, recipients and unsubscribes
|
||||
|
|
@ -306,10 +306,6 @@ class Communication(Document):
|
|||
|
||||
return filtered
|
||||
|
||||
def get_starrers(self):
|
||||
"""Return list of users who have starred this document."""
|
||||
return [( get_formatted_email(user) or user ) for user in self.get_parent_doc().get_starred_by()]
|
||||
|
||||
def get_owner_email(self):
|
||||
owner = self.get_parent_doc().owner
|
||||
return get_formatted_email(owner) or owner
|
||||
|
|
@ -337,6 +333,9 @@ def on_doctype_update():
|
|||
"""Add index in `tabCommunication` for `(reference_doctype, reference_name)`"""
|
||||
frappe.db.add_index("Communication", ["reference_doctype", "reference_name"])
|
||||
|
||||
if "_liked_by" not in frappe.db.get_table_columns("Communication"):
|
||||
add_column("Communication", "_liked_by", "Text")
|
||||
|
||||
@frappe.whitelist()
|
||||
def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent",
|
||||
sender=None, recipients=None, communication_medium="Email", send_email=False,
|
||||
|
|
|
|||
|
|
@ -42,8 +42,13 @@ class DocShare(Document):
|
|||
frappe.throw(_('You need to have "Share" permission'), frappe.PermissionError)
|
||||
|
||||
def after_insert(self):
|
||||
self.get_doc().add_comment("Shared",
|
||||
_("{0} shared this document with {1}").format(get_fullname(self.owner), get_fullname(self.user)))
|
||||
doc = self.get_doc()
|
||||
owner = get_fullname(self.owner)
|
||||
|
||||
if self.everyone:
|
||||
doc.add_comment("Shared", _("{0} shared this document with everyone").format(owner))
|
||||
else:
|
||||
doc.add_comment("Shared", _("{0} shared this document with {1}").format(owner, get_fullname(self.user)))
|
||||
|
||||
def on_trash(self):
|
||||
if not self.flags.ignore_share_permission:
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
"options": "Module Def",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
|
|
@ -76,6 +78,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -101,11 +104,12 @@
|
|||
"oldfieldtype": "Check",
|
||||
"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,
|
||||
"set_only_once": 1,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
|
|
@ -122,6 +126,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -147,6 +152,7 @@
|
|||
"options": "\nDocument\nSetup\nSystem\nOther",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -169,6 +175,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -191,6 +198,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -213,6 +221,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -236,6 +245,7 @@
|
|||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -261,6 +271,7 @@
|
|||
"options": "DocField",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -283,6 +294,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -308,6 +320,7 @@
|
|||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -333,6 +346,7 @@
|
|||
"options": "\nTitle Case\nUPPER CASE",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -357,6 +371,7 @@
|
|||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -378,6 +393,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -401,6 +417,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -425,6 +442,7 @@
|
|||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -449,6 +467,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -473,6 +492,7 @@
|
|||
"options": "ASC\nDESC",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -496,6 +516,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -522,6 +543,7 @@
|
|||
"options": "DocPerm",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -544,6 +566,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -566,6 +589,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -590,6 +614,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -614,6 +639,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -636,6 +662,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -659,6 +686,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -683,6 +711,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -707,6 +736,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -731,6 +761,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -755,6 +786,7 @@
|
|||
"oldfieldtype": "Int",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -777,6 +809,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -801,6 +834,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -825,6 +859,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -849,6 +884,7 @@
|
|||
"oldfieldtype": "Check",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -871,6 +907,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -889,7 +926,7 @@
|
|||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-11-16 06:29:45.648699",
|
||||
"modified": "2016-01-11 01:54:58.471041",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "DocType",
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ class DocType(Document):
|
|||
|
||||
self.make_amendable()
|
||||
|
||||
if self.istable:
|
||||
self.allow_import = 0
|
||||
|
||||
def check_developer_mode(self):
|
||||
"""Throw exception if not developer mode or via patch"""
|
||||
if frappe.flags.in_patch:
|
||||
|
|
@ -274,7 +277,7 @@ def validate_fields(meta):
|
|||
frappe.throw(_("Max width for type Currency is 100px in row {0}").format(d.idx))
|
||||
|
||||
def check_in_list_view(d):
|
||||
if d.in_list_view and d.fieldtype!="Image" and (d.fieldtype in no_value_fields):
|
||||
if d.in_list_view and (d.fieldtype in no_value_fields):
|
||||
frappe.throw(_("'In List View' not allowed for type {0} in row {1}").format(d.fieldtype, d.idx))
|
||||
|
||||
def check_dynamic_link_options(d):
|
||||
|
|
|
|||
|
|
@ -1385,7 +1385,7 @@
|
|||
"istable": 0,
|
||||
"max_attachments": 5,
|
||||
"menu_index": 0,
|
||||
"modified": "2015-12-23 02:45:19.261689",
|
||||
"modified": "2016-01-08 04:50:48.919694",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "User",
|
||||
|
|
@ -1398,9 +1398,9 @@
|
|||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ def get_notification_config():
|
|||
"Comment": "frappe.core.notifications.get_unread_messages",
|
||||
"Error Snapshot": {"seen": 0, "parent_error_snapshot": None},
|
||||
},
|
||||
"for_other": {
|
||||
"Likes": "frappe.core.notifications.get_unseen_likes"
|
||||
}
|
||||
}
|
||||
|
||||
def get_things_todo():
|
||||
|
|
@ -41,3 +44,12 @@ def get_unread_messages():
|
|||
AND comment_docname = %s
|
||||
AND docstatus=0
|
||||
""", (frappe.session.user,))[0][0]
|
||||
|
||||
def get_unseen_likes():
|
||||
"""Returns count of unseen likes"""
|
||||
return frappe.db.sql("""select count(*) from `tabFeed`
|
||||
where
|
||||
feed_type='Like'
|
||||
and owner is not null and owner!=%(user)s
|
||||
and doc_owner=%(user)s
|
||||
and seen=0""", {"user": frappe.session.user})[0][0]
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ frappe.DataImportTool = Class.extend({
|
|||
|
||||
me.write_messages(r.messages);
|
||||
}
|
||||
}
|
||||
},
|
||||
is_private: true
|
||||
});
|
||||
|
||||
frappe.realtime.on("data_import_progress", function(data) {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,7 @@ def get_data_keys():
|
|||
|
||||
@frappe.whitelist()
|
||||
def get_doctypes():
|
||||
if "System Manager" in frappe.get_roles():
|
||||
return [r[0] for r in frappe.db.sql("""select name from `tabDocType`
|
||||
where allow_import = 1""")]
|
||||
else:
|
||||
return frappe.get_user()._get("can_import")
|
||||
return frappe.get_user()._get("can_import")
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_doctype_options():
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
|
|||
|
||||
# publish task_update
|
||||
frappe.publish_realtime("data_import_progress", {"progress": [i, total]},
|
||||
user=frappe.session.user, now=True)
|
||||
user=frappe.session.user)
|
||||
|
||||
try:
|
||||
doc = get_doc(row_idx)
|
||||
|
|
|
|||
|
|
@ -92,11 +92,9 @@ class CustomField(Document):
|
|||
# Create new peroperty setter if order changed
|
||||
if _idx and not existing_property_setter:
|
||||
field_idx = (_idx.index(self.insert_after) + 1) if (self.insert_after in _idx) else len(_idx)
|
||||
if field_idx < len(_idx):
|
||||
_idx[field_idx] = self.fieldname
|
||||
else:
|
||||
_idx.append(self.fieldname)
|
||||
|
||||
|
||||
_idx.insert(field_idx, self.fieldname)
|
||||
|
||||
frappe.make_property_setter({
|
||||
"doctype":self.dt,
|
||||
"doctype_or_field": "DocType",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ frappe.ui.form.on("Customize Form", {
|
|||
filters: [
|
||||
['DocType', 'issingle', '=', 0],
|
||||
['DocType', 'custom', '=', 0],
|
||||
['DocType', 'in_create', '=', 0],
|
||||
['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, UserRole, \
|
||||
Page, Page Role, Module Def, Print Format, Report, Customize Form, \
|
||||
Customize Form Field']
|
||||
|
|
|
|||
|
|
@ -19,31 +19,34 @@ def add_user_default(key, value, user=None, parenttype=None):
|
|||
def get_user_default(key, user=None):
|
||||
user_defaults = get_defaults(user or frappe.session.user)
|
||||
d = user_defaults.get(key, None)
|
||||
|
||||
if key != frappe.scrub(key):
|
||||
|
||||
if is_a_user_permission_key(key):
|
||||
if d and isinstance(d, (list, tuple)) and len(d)==1:
|
||||
# Use User Permission value when only when it has a single value
|
||||
d = d[0]
|
||||
|
||||
|
||||
else:
|
||||
d = user_defaults.get(frappe.scrub(key), None)
|
||||
|
||||
|
||||
return isinstance(d, (list, tuple)) and d[0] or d
|
||||
|
||||
def get_user_default_as_list(key, user=None):
|
||||
user_defaults = get_defaults(user or frappe.session.user)
|
||||
d = user_defaults.get(key, None)
|
||||
|
||||
if key != frappe.scrub(key):
|
||||
|
||||
if is_a_user_permission_key(key):
|
||||
if d and isinstance(d, (list, tuple)) and len(d)==1:
|
||||
# Use User Permission value when only when it has a single value
|
||||
d = [d[0]]
|
||||
|
||||
|
||||
else:
|
||||
d = user_defaults.get(frappe.scrub(key), None)
|
||||
|
||||
return (not isinstance(d, (list, tuple))) and [d] or d
|
||||
|
||||
def is_a_user_permission_key(key):
|
||||
return ":" not in key and key != frappe.scrub(key)
|
||||
|
||||
def get_user_permissions(user=None):
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "EV.#####",
|
||||
"creation": "2013-06-10 13:17:47",
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
|
|
@ -71,6 +73,7 @@
|
|||
"options": "Private\nPublic\nCancel",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
|
|
@ -94,6 +97,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -115,6 +119,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -137,6 +142,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
|
|
@ -159,6 +165,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -181,6 +188,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -202,6 +210,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -224,6 +233,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -246,6 +256,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -270,6 +281,7 @@
|
|||
"options": "\nEvery Day\nEvery Week\nEvery Month\nEvery Year",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -294,6 +306,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -315,6 +328,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -338,6 +352,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -361,6 +376,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -384,6 +400,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -407,6 +424,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -430,6 +448,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -453,6 +472,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -476,6 +496,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -497,6 +518,7 @@
|
|||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -521,6 +543,7 @@
|
|||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
|
|
@ -546,6 +569,7 @@
|
|||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -569,6 +593,7 @@
|
|||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "50%",
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
|
|
@ -596,6 +621,7 @@
|
|||
"options": "Event Role",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -621,6 +647,7 @@
|
|||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -646,6 +673,7 @@
|
|||
"options": "ref_type",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
|
|
@ -664,7 +692,7 @@
|
|||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-11-16 06:29:46.775883",
|
||||
"modified": "2016-01-08 04:50:37.240223",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Event",
|
||||
|
|
@ -697,9 +725,9 @@
|
|||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"import": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
|
|
|
|||
|
|
@ -1,204 +1,309 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2012-07-03 13:29:42",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "hash",
|
||||
"creation": "2012-07-03 13:29:42",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "feed_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Feed Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nComment\nLogin\nLabel\nInfo",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "feed_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Feed Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nComment\nLogin\nLabel\nInfo\nLike",
|
||||
"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,
|
||||
"fieldname": "doc_type",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Doc Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "doc_type",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Doc Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"fieldname": "doc_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Doc Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "doc_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Doc Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Subject",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Subject",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"fieldname": "full_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Full Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"fieldname": "full_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Full Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"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,
|
||||
"fieldname": "doc_owner",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Doc Owner",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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,
|
||||
"fieldname": "seen",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Seen",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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,
|
||||
"description": "Use this to provide alternative link to a feed record",
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference DocType",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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,
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Reference Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-rss",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-11-16 06:29:47.123186",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Feed",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-rss",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2015-12-30 02:48:03.860188",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Feed",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 1,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "All",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 1,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "All",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,13 @@ from frappe import _
|
|||
exclude_from_linked_with = True
|
||||
|
||||
class Feed(Document):
|
||||
pass
|
||||
no_feed_on_delete = True
|
||||
|
||||
def validate(self):
|
||||
if not (self.reference_doctype and self.reference_name):
|
||||
# reset both if even one is missing
|
||||
self.reference_doctype = self.reference_name = None
|
||||
|
||||
|
||||
def on_doctype_update():
|
||||
if not frappe.db.sql("""show index from `tabFeed`
|
||||
|
|
@ -24,9 +30,12 @@ def on_doctype_update():
|
|||
def get_permission_query_conditions(user):
|
||||
if not user: user = frappe.session.user
|
||||
|
||||
if not frappe.permissions.apply_user_permissions("Feed", "read", user):
|
||||
use_user_permissions = frappe.permissions.apply_user_permissions("Feed", "read", user)
|
||||
if not use_user_permissions:
|
||||
return ""
|
||||
|
||||
conditions = ['`tabFeed`.owner="{user}" or `tabFeed`.doc_owner="{user}"'.format(user=frappe.db.escape(user))]
|
||||
|
||||
user_permissions = frappe.defaults.get_user_permissions(user)
|
||||
can_read = frappe.get_user().get_can_read()
|
||||
|
||||
|
|
@ -34,19 +43,17 @@ def get_permission_query_conditions(user):
|
|||
list(set(can_read) - set(user_permissions.keys()))]
|
||||
|
||||
if not can_read_doctypes:
|
||||
return ""
|
||||
conditions += ["tabFeed.doc_type in ({})".format(", ".join(can_read_doctypes))]
|
||||
|
||||
conditions = ["tabFeed.doc_type in ({})".format(", ".join(can_read_doctypes))]
|
||||
if user_permissions:
|
||||
can_read_docs = []
|
||||
for doctype, names in user_permissions.items():
|
||||
for n in names:
|
||||
can_read_docs.append('"{}|{}"'.format(doctype, n))
|
||||
|
||||
if user_permissions:
|
||||
can_read_docs = []
|
||||
for doctype, names in user_permissions.items():
|
||||
for n in names:
|
||||
can_read_docs.append('"{}|{}"'.format(doctype, n))
|
||||
|
||||
if can_read_docs:
|
||||
conditions.append("concat_ws('|', tabFeed.doc_type, tabFeed.doc_name) in ({})".format(
|
||||
", ".join(can_read_docs)))
|
||||
if can_read_docs:
|
||||
conditions.append("concat_ws('|', tabFeed.doc_type, tabFeed.doc_name) in ({})".format(
|
||||
", ".join(can_read_docs)))
|
||||
|
||||
return "(" + " or ".join(conditions) + ")"
|
||||
|
||||
|
|
@ -83,7 +90,10 @@ def update_feed(doc, method=None):
|
|||
"doc_type": doctype,
|
||||
"doc_name": name,
|
||||
"subject": feed.subject,
|
||||
"full_name": get_fullname(doc.owner)
|
||||
"full_name": get_fullname(doc.owner),
|
||||
"doc_owner": frappe.db.get_value(doctype, name, "owner"),
|
||||
"reference_doctype": feed.reference_doctype,
|
||||
"reference_name": feed.reference_name
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
def login_feed(login_manager):
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@ def get_docinfo(doc=None, doctype=None, name=None):
|
|||
def get_user_permissions(meta):
|
||||
out = {}
|
||||
all_user_permissions = frappe.defaults.get_user_permissions()
|
||||
|
||||
|
||||
for m in meta:
|
||||
for df in m.get_fields_to_check_permissions(all_user_permissions):
|
||||
out[df.options] = list(set(all_user_permissions[df.options]))
|
||||
|
||||
|
||||
return out
|
||||
|
||||
def get_attachments(dt, dn):
|
||||
|
|
@ -108,7 +108,7 @@ def get_attachments(dt, dn):
|
|||
|
||||
def get_comments(dt, dn, limit=100):
|
||||
comments = frappe.db.sql("""select name, comment, comment_by, creation,
|
||||
reference_doctype, reference_name, comment_type, "Comment" as doctype
|
||||
reference_doctype, reference_name, comment_type, "Comment" as doctype, _liked_by
|
||||
from `tabComment`
|
||||
where comment_doctype=%s and comment_docname=%s
|
||||
order by creation desc limit %s""",
|
||||
|
|
@ -116,7 +116,7 @@ def get_comments(dt, dn, limit=100):
|
|||
|
||||
communications = frappe.db.sql("""select name,
|
||||
content as comment, sender as comment_by, creation,
|
||||
communication_medium as comment_type, subject, delivery_status,
|
||||
communication_medium as comment_type, subject, delivery_status, _liked_by,
|
||||
"Communication" as doctype
|
||||
from tabCommunication
|
||||
where reference_doctype=%s and reference_name=%s
|
||||
|
|
|
|||
103
frappe/desk/like.py
Normal file
103
frappe/desk/like.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""Allow adding of likes to documents"""
|
||||
|
||||
import frappe, json
|
||||
from frappe.model.db_schema import add_column
|
||||
from frappe import _
|
||||
from frappe.utils import get_link_to_form
|
||||
|
||||
@frappe.whitelist()
|
||||
def toggle_like(doctype, name, add=False):
|
||||
"""Adds / removes the current user in the `__liked_by` property of the given document.
|
||||
If column does not exist, will add it in the database.
|
||||
|
||||
The `_liked_by` property is always set from this function and is ignored if set via
|
||||
Document API
|
||||
|
||||
:param doctype: DocType of the document to like
|
||||
:param name: Name of the document to like
|
||||
:param add: `Yes` if like is to be added. If not `Yes` the like will be removed."""
|
||||
|
||||
_toggle_like(doctype, name, add)
|
||||
|
||||
def _toggle_like(doctype, name, add, user=None):
|
||||
"""Same as toggle_like but hides param `user` from API"""
|
||||
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
try:
|
||||
liked_by, owner = frappe.db.get_value(doctype, name, ["_liked_by", "owner"])
|
||||
|
||||
# CHANGED: Allow someone to like their own documents as it also works as a bookmark
|
||||
# if owner==frappe.session.user and add=="Yes":
|
||||
# frappe.throw(_("You cannot like something that you created"))
|
||||
|
||||
if liked_by:
|
||||
liked_by = json.loads(liked_by)
|
||||
else:
|
||||
liked_by = []
|
||||
|
||||
if add=="Yes":
|
||||
if user not in liked_by:
|
||||
liked_by.append(user)
|
||||
add_comment(doctype, name)
|
||||
|
||||
else:
|
||||
if user in liked_by:
|
||||
liked_by.remove(user)
|
||||
remove_like(doctype, name)
|
||||
|
||||
frappe.db.set_value(doctype, name, "_liked_by", json.dumps(liked_by), update_modified=False)
|
||||
|
||||
except Exception, e:
|
||||
if isinstance(e.args, (tuple, list)) and e.args and e.args[0]==1054:
|
||||
add_column(doctype, "_liked_by", "Text")
|
||||
_toggle_like(doctype, name, add, user)
|
||||
else:
|
||||
raise
|
||||
|
||||
def remove_like(doctype, name):
|
||||
"""Remove previous Like"""
|
||||
# remove Comment
|
||||
frappe.delete_doc("Comment", [c.name for c in frappe.get_all("Comment",
|
||||
filters={
|
||||
"comment_doctype": doctype,
|
||||
"comment_docname": name,
|
||||
"comment_by": frappe.session.user,
|
||||
"comment_type": "Like"
|
||||
}
|
||||
)], ignore_permissions=True)
|
||||
|
||||
# remove Feed
|
||||
frappe.delete_doc("Feed", [c.name for c in frappe.get_all("Feed",
|
||||
filters={
|
||||
"doc_type": doctype,
|
||||
"doc_name": name,
|
||||
"owner": frappe.session.user,
|
||||
"feed_type": "Like"
|
||||
}
|
||||
)], ignore_permissions=True)
|
||||
|
||||
def add_comment(doctype, name):
|
||||
doc = frappe.get_doc(doctype, name)
|
||||
|
||||
if doctype=="Comment":
|
||||
link = get_link_to_form(doc.comment_doctype, doc.comment_docname,
|
||||
"{0} {1}".format(_(doc.comment_doctype), doc.comment_docname))
|
||||
doc.add_comment("Like", _("Comment: {0} in {1}").format("<b>" + doc.comment + "</b>", link),
|
||||
reference_doctype=doc.comment_doctype, reference_name=doc.comment_docname)
|
||||
|
||||
elif doctype=="Communication":
|
||||
link = get_link_to_form(doc.reference_doctype, doc.reference_name,
|
||||
"{0} {1}".format(_(doc.reference_doctype), doc.reference_name))
|
||||
|
||||
doc.add_comment("Like", _("Communication: {0} in {1}").format("<b>" + doc.subject + "</b>", link),
|
||||
reference_doctype=doc.reference_doctype, reference_name=doc.reference_name)
|
||||
|
||||
else:
|
||||
doc.add_comment("Like", _("Liked"))
|
||||
|
|
@ -24,7 +24,9 @@ def get_notifications():
|
|||
return {
|
||||
"open_count_doctype": get_notifications_for_doctypes(config, notification_count),
|
||||
"open_count_module": get_notifications_for_modules(config, notification_count),
|
||||
"open_count_other": get_notifications_for_other(config, notification_count),
|
||||
"new_messages": get_new_messages()
|
||||
# "likes": get_count_of_new_likes()
|
||||
}
|
||||
|
||||
def get_new_messages():
|
||||
|
|
@ -48,19 +50,27 @@ def get_new_messages():
|
|||
|
||||
def get_notifications_for_modules(config, notification_count):
|
||||
"""Notifications for modules"""
|
||||
open_count_module = {}
|
||||
for m in config.for_module:
|
||||
return get_notifications_for("for_module", config, notification_count)
|
||||
|
||||
def get_notifications_for_other(config, notification_count):
|
||||
"""Notifications for other items"""
|
||||
return get_notifications_for("for_other", config, notification_count)
|
||||
|
||||
def get_notifications_for(notification_type, config, notification_count):
|
||||
open_count = {}
|
||||
notification_map = config.get(notification_type) or {}
|
||||
for m in notification_map:
|
||||
try:
|
||||
if m in notification_count:
|
||||
open_count_module[m] = notification_count[m]
|
||||
open_count[m] = notification_count[m]
|
||||
else:
|
||||
open_count_module[m] = frappe.get_attr(config.for_module[m])()
|
||||
open_count[m] = frappe.get_attr(notification_map[m])()
|
||||
|
||||
frappe.cache().hset("notification_count:" + m, frappe.session.user, open_count_module[m])
|
||||
frappe.cache().hset("notification_count:" + m, frappe.session.user, open_count[m])
|
||||
except frappe.PermissionError:
|
||||
frappe.msgprint("Permission Error in notifications for {0}".format(m))
|
||||
|
||||
return open_count_module
|
||||
return open_count
|
||||
|
||||
def get_notifications_for_doctypes(config, notification_count):
|
||||
"""Notifications for DocTypes"""
|
||||
|
|
@ -143,7 +153,7 @@ def get_notification_config():
|
|||
config = frappe._dict()
|
||||
for notification_config in frappe.get_hooks().notification_config:
|
||||
nc = frappe.get_attr(notification_config)()
|
||||
for key in ("for_doctype", "for_module", "for_module_doctypes"):
|
||||
for key in ("for_doctype", "for_module", "for_module_doctypes", "for_other"):
|
||||
config.setdefault(key, {})
|
||||
config[key].update(nc.get(key, {}))
|
||||
return config
|
||||
|
|
|
|||
|
|
@ -62,3 +62,12 @@
|
|||
width: 97% !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#page-activity .list-filters {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#page-activity .octicon-heart {
|
||||
color: #ff5858;
|
||||
margin: 0px 5px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,36 +18,73 @@ frappe.pages['activity'].on_page_load = function(wrapper) {
|
|||
|
||||
this.page.set_title(__("Activity"));
|
||||
|
||||
this.page.list = new frappe.ui.Listing({
|
||||
hide_refresh: true,
|
||||
page: this.page,
|
||||
method: 'frappe.desk.page.activity.activity.get_feed',
|
||||
parent: $("<div></div>").appendTo(this.page.main),
|
||||
render_row: function(row, data) {
|
||||
new frappe.activity.Feed(row, data);
|
||||
}
|
||||
});
|
||||
frappe.model.with_doctype("Feed", function() {
|
||||
me.page.list = new frappe.ui.Listing({
|
||||
hide_refresh: true,
|
||||
page: me.page,
|
||||
method: 'frappe.desk.page.activity.activity.get_feed',
|
||||
parent: $("<div></div>").appendTo(me.page.main),
|
||||
render_row: function(row, data) {
|
||||
new frappe.activity.Feed(row, data);
|
||||
},
|
||||
show_filters: true,
|
||||
doctype: "Feed",
|
||||
get_args: function() {
|
||||
if (frappe.route_options && frappe.route_options.show_likes) {
|
||||
delete frappe.route_options.show_likes;
|
||||
return {
|
||||
show_likes: true
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.page.list.run();
|
||||
me.page.list.run();
|
||||
|
||||
me.page.set_primary_action(__("Refresh"), function() {
|
||||
me.page.list.filter_list.clear_filters();
|
||||
me.page.list.run();
|
||||
}, "octicon octicon-sync");
|
||||
});
|
||||
|
||||
frappe.activity.render_plot(this.page);
|
||||
|
||||
this.page.main.on("click", ".activity-message", function() {
|
||||
var doctype = $(this).attr("data-doctype"),
|
||||
var reference_doctype = $(this).attr("data-reference-doctype"),
|
||||
reference_name = $(this).attr("data-reference-name"),
|
||||
doctype = $(this).attr("data-doctype"),
|
||||
docname = $(this).attr("data-docname");
|
||||
|
||||
if (doctype && docname) {
|
||||
frappe.set_route(["Form", doctype, docname]);
|
||||
frappe.set_route(["Form", reference_doctype || doctype, reference_name || docname]);
|
||||
|
||||
if (reference_doctype && reference_name) {
|
||||
frappe.route_options = {
|
||||
scroll_to: { "doctype": doctype, "name": docname }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.page.set_primary_action(__("Refresh"), function() { me.page.list.run(); }, "octicon octicon-sync");
|
||||
|
||||
// Build Report Button
|
||||
if(frappe.boot.user.can_get_report.indexOf("Feed")!=-1) {
|
||||
this.page.set_secondary_action(__('Build Report'), function() {
|
||||
this.page.add_menu_item(__('Build Report'), function() {
|
||||
frappe.set_route('Report', "Feed");
|
||||
}, 'icon-th');
|
||||
}, 'icon-th')
|
||||
}
|
||||
|
||||
this.page.add_menu_item(__('Show Likes'), function() {
|
||||
frappe.route_options = {
|
||||
show_likes: true
|
||||
};
|
||||
me.page.list.run();
|
||||
}, 'octicon octicon-heart');
|
||||
};
|
||||
|
||||
frappe.pages['activity'].on_page_show = function() {
|
||||
frappe.breadcrumbs.add("Desk");
|
||||
}
|
||||
|
||||
frappe.activity.last_feed_date = false;
|
||||
|
|
@ -69,7 +106,7 @@ frappe.activity.Feed = Class.extend({
|
|||
.find("a").addClass("grey");
|
||||
},
|
||||
scrub_data: function(data) {
|
||||
data.by = frappe.user_info(data.owner).fullname;
|
||||
data.by = frappe.user.full_name(data.owner);
|
||||
data.imgsrc = frappe.utils.get_file_link(frappe.user_info(data.owner).image);
|
||||
|
||||
data.icon = "icon-flag";
|
||||
|
|
|
|||
|
|
@ -3,14 +3,38 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import cint
|
||||
from frappe.desk.doctype.feed.feed import get_permission_query_conditions
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_feed(limit_start, limit_page_length):
|
||||
def get_feed(limit_start, limit_page_length, show_likes=False):
|
||||
"""get feed"""
|
||||
return frappe.get_list("Feed", fields=["name", "feed_type", "doc_type",
|
||||
"subject", "owner", "modified", "doc_name", "creation"],
|
||||
limit_start = limit_start, limit_page_length = limit_page_length,
|
||||
order_by="creation desc")
|
||||
# directly use the permission query condition function of feed
|
||||
match_conditions = get_permission_query_conditions(frappe.session.user)
|
||||
|
||||
result = frappe.db.sql("""select name, feed_type, doc_type, doc_name, subject,
|
||||
owner, modified, creation, seen, reference_doctype, reference_name
|
||||
from `tabFeed`
|
||||
where
|
||||
((feed_type='Like' and (owner=%(user)s or doc_owner=%(user)s)) or feed_type!='Like')
|
||||
{match_conditions}
|
||||
{show_likes}
|
||||
order by creation desc
|
||||
limit %(limit_start)s, %(limit_page_length)s"""
|
||||
.format(match_conditions="and {0}".format(match_conditions) if match_conditions else "",
|
||||
show_likes="and feed_type='Like'" if show_likes else ""),
|
||||
{
|
||||
"user": frappe.session.user,
|
||||
"limit_start": cint(limit_start),
|
||||
"limit_page_length": cint(limit_page_length)
|
||||
}, as_dict=True)
|
||||
|
||||
if show_likes:
|
||||
# mark likes as seen!
|
||||
frappe.db.sql("update `tabFeed` set seen=1 where feed_type='Like' and doc_owner=%s", frappe.session.user)
|
||||
frappe.local.flags.commit = True
|
||||
|
||||
return result
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_months_activity():
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
<div class="row activity-row" data-creation="{%= creation.split(" ")[0] + " 00:00:00" %}">
|
||||
<div class="col-xs-3 text-right activity-date"><span class="{%= date_class %}">
|
||||
{%= date_sep || "" %}</span></div>
|
||||
<div class="col-xs-9 activity-message" data-doctype="{%= doc_type %}" data-docname="{%= doc_name %}"
|
||||
<div class="col-xs-9 activity-message"
|
||||
data-doctype="{%= doc_type %}"
|
||||
data-docname="{%= doc_name %}"
|
||||
data-reference-doctype="{{ reference_doctype }}"
|
||||
data-reference-name="{{ reference_name }}"
|
||||
title="{%= by %} / {%= dateutil.str_to_user(creation) %}">
|
||||
<span class="avatar avatar-small">
|
||||
<img src="{%= imgsrc %}">
|
||||
<div class="avatar-frame" style="background-image: url({{ imgsrc }});"></div>
|
||||
<!-- <img src="{%= imgsrc %}"> -->
|
||||
</span>
|
||||
<span class="small">
|
||||
{% if (feed_type==="Login") { %}
|
||||
|
|
@ -15,6 +20,13 @@
|
|||
{%= __("Commented on {0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
|
||||
{% } else if (doc_type && !feed_type) { %}
|
||||
{%= __("Updated {0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
|
||||
{% } else if (feed_type==="Like" && doc_type) { %}
|
||||
{%= by %} <i class="octicon octicon-heart"></i>
|
||||
{% if (in_list(["Comment", "Communication"], doc_type)) { %}
|
||||
{%= subject %}
|
||||
{% } else { %}
|
||||
{%= link %}
|
||||
{% } %}
|
||||
{% } else if (doc_type) { %}
|
||||
{%= __("{0}: {1}", [link, "<strong>" + subject + "</strong>"]) %}
|
||||
{% } else { %}
|
||||
|
|
|
|||
|
|
@ -74,12 +74,12 @@ def install_app(name):
|
|||
frappe.throw(_("You cannot install this app"))
|
||||
|
||||
frappe.publish_realtime("install_app_progress", {"status": _("Installing App {0}").format(name)},
|
||||
user=frappe.session.user, now=True)
|
||||
user=frappe.session.user)
|
||||
|
||||
frappe.installer.install_app(name)
|
||||
|
||||
frappe.publish_realtime("install_app_progress", {"status": _("{0} Installed").format(name)},
|
||||
user=frappe.session.user, now=True)
|
||||
user=frappe.session.user)
|
||||
|
||||
def get_app(name):
|
||||
"""Get app using git clone and install it in bench environment"""
|
||||
|
|
@ -89,7 +89,7 @@ def get_app(name):
|
|||
raise frappe.ValidationError
|
||||
|
||||
frappe.publish_realtime("install_app_progress", {"status": _("Downloading App {0}").format(name)},
|
||||
user=frappe.session.user, now=True)
|
||||
user=frappe.session.user)
|
||||
|
||||
args = [find_executable('bench'), 'get-app', name, app_listing[name]['repo_url']]
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ frappe.pages.messages.on_page_load = function(parent) {
|
|||
frappe.pages.messages.on_page_show = function() {
|
||||
// clear title prefix
|
||||
frappe.utils.set_title_prefix("");
|
||||
|
||||
frappe.breadcrumbs.add("Desk");
|
||||
}
|
||||
|
||||
frappe.desk.pages.Messages = Class.extend({
|
||||
|
|
|
|||
|
|
@ -262,9 +262,14 @@ function load_frappe_slides() {
|
|||
frappe.wiz.welcome.data = r.message;
|
||||
frappe.wiz.welcome.setup_fields(slide);
|
||||
|
||||
slide.get_field("language")
|
||||
.set_input(frappe.wiz.welcome.data.default_language || "english")
|
||||
.trigger("change");
|
||||
var language_field = slide.get_field("language");
|
||||
language_field.set_input(frappe.wiz.welcome.data.default_language || "english");
|
||||
|
||||
if (!frappe.wiz._from_load_messages) {
|
||||
language_field.$input.trigger("change");
|
||||
}
|
||||
|
||||
delete frappe.wiz._from_load_messages;
|
||||
|
||||
moment.locale("en");
|
||||
}
|
||||
|
|
@ -289,6 +294,7 @@ function load_frappe_slides() {
|
|||
},
|
||||
callback: function(r) {
|
||||
// TODO save values!
|
||||
frappe.wiz._from_load_messages = true;
|
||||
|
||||
// reset all slides so that labels are translated
|
||||
frappe.wiz.slides = [];
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""Allow adding of stars to documents"""
|
||||
|
||||
import frappe, json
|
||||
from frappe.model.db_schema import add_column
|
||||
|
||||
@frappe.whitelist()
|
||||
def toggle_star(doctype, name, add=False):
|
||||
"""Adds / removes the current user in the `__starred_by` property of the given document.
|
||||
If column does not exist, will add it in the database.
|
||||
|
||||
The `_starred_by` property is always set from this function and is ignored if set via
|
||||
Document API
|
||||
|
||||
:param doctype: DocType of the document to star
|
||||
:param name: Name of the document to star
|
||||
:param add: `Yes` if star is to be added. If not `Yes` the star will be removed."""
|
||||
|
||||
_toggle_star(doctype, name, add)
|
||||
|
||||
def _toggle_star(doctype, name, add=False, user=None):
|
||||
"""Same as toggle_star but hides param `user` from API"""
|
||||
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
try:
|
||||
starred_by = frappe.db.get_value(doctype, name, "_starred_by")
|
||||
if starred_by:
|
||||
starred_by = json.loads(starred_by)
|
||||
else:
|
||||
starred_by = []
|
||||
|
||||
if add=="Yes":
|
||||
if user not in starred_by:
|
||||
starred_by.append(user)
|
||||
else:
|
||||
if user in starred_by:
|
||||
starred_by.remove(user)
|
||||
|
||||
frappe.db.sql("""update `tab{0}` set `_starred_by`=%s where name=%s""".format(doctype),
|
||||
(json.dumps(starred_by), name))
|
||||
|
||||
except Exception, e:
|
||||
if e.args[0]==1054:
|
||||
add_column(doctype, "_starred_by", "Text")
|
||||
_toggle_star(doctype, name, add, user)
|
||||
else:
|
||||
raise
|
||||
BIN
frappe/docs/assets/img/add-vat-number-in-purchase-order.png
Normal file
BIN
frappe/docs/assets/img/add-vat-number-in-purchase-order.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
frappe/docs/assets/img/add-vat-number-in-supplier.png
Normal file
BIN
frappe/docs/assets/img/add-vat-number-in-supplier.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
BIN
frappe/docs/assets/img/vat-number-fetched.png
Normal file
BIN
frappe/docs/assets/img/vat-number-fetched.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
|
|
@ -77,6 +77,22 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.core.notifications.get_unseen_likes" href="#frappe.core.notifications.get_unseen_likes" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.core.notifications.<b>get_unseen_likes</b>
|
||||
<i class="text-muted">()</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Returns count of unseen likes</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- autodoc -->
|
||||
96
frappe/docs/current/api/desk/frappe.desk.like.html
Normal file
96
frappe/docs/current/api/desk/frappe.desk.like.html
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<!-- title: frappe.desk.like --><div class="dev-header">
|
||||
|
||||
<a class="btn btn-default btn-sm" disabled style="margin-bottom: 10px;">
|
||||
Version 6.x.x</a>
|
||||
|
||||
|
||||
<a class="btn btn-default btn-sm" href="https://github.com/frappe/frappe/blob/develop/frappe/desk/like.py"
|
||||
target="_blank" style="margin-left: 10px; margin-bottom: 10px;"><i class="octicon octicon-mark-github"></i> Source</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.like._toggle_like" href="#frappe.desk.like._toggle_like" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.like.<b>_toggle_like</b>
|
||||
<i class="text-muted">(doctype, name, add, user=None)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Same as toggle_like but hides param <code>user</code> from API</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.like.add_comment" href="#frappe.desk.like.add_comment" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.like.<b>add_comment</b>
|
||||
<i class="text-muted">(doctype, name)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.like.remove_like" href="#frappe.desk.like.remove_like" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.like.<b>remove_like</b>
|
||||
<i class="text-muted">(doctype, name)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Remove previous Like</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p><span class="label label-info">Public API</span>
|
||||
<br><code>/api/method/frappe.desk.like.toggle_like</code>
|
||||
</p>
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.like.toggle_like" href="#frappe.desk.like.toggle_like" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.like.<b>toggle_like</b>
|
||||
<i class="text-muted">(doctype, name, add=False)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Adds / removes the current user in the <code>__liked_by</code> property of the given document.
|
||||
If column does not exist, will add it in the database.</p>
|
||||
|
||||
<p>The <code>_liked_by</code> property is always set from this function and is ignored if set via
|
||||
Document API</p>
|
||||
|
||||
<p><strong>Parameters:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>doctype</code></strong> - DocType of the document to like</li>
|
||||
<li><strong><code>name</code></strong> - Name of the document to like</li>
|
||||
<li><strong><code>add</code></strong> - <code>Yes</code> if like is to be added. If not <code>Yes</code> the like will be removed.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- autodoc -->
|
||||
|
|
@ -131,6 +131,22 @@
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.notifications.get_notifications_for" href="#frappe.desk.notifications.get_notifications_for" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.notifications.<b>get_notifications_for</b>
|
||||
<i class="text-muted">(notification_type, config, notification_count)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.notifications.get_notifications_for_doctypes" href="#frappe.desk.notifications.get_notifications_for_doctypes" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -159,6 +175,22 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.notifications.get_notifications_for_other" href="#frappe.desk.notifications.get_notifications_for_other" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.notifications.<b>get_notifications_for_other</b>
|
||||
<i class="text-muted">(config, notification_count)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Notifications for other items</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- autodoc -->
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<!-- title: frappe.desk.star --><div class="dev-header">
|
||||
|
||||
<a class="btn btn-default btn-sm" disabled style="margin-bottom: 10px;">
|
||||
Version 6.x.x</a>
|
||||
|
||||
|
||||
<a class="btn btn-default btn-sm" href="https://github.com/frappe/frappe/blob/develop/frappe/desk/star.py"
|
||||
target="_blank" style="margin-left: 10px; margin-bottom: 10px;"><i class="octicon octicon-mark-github"></i> Source</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.star._toggle_star" href="#frappe.desk.star._toggle_star" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.star.<b>_toggle_star</b>
|
||||
<i class="text-muted">(doctype, name, add=False, user=None)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Same as toggle_star but hides param <code>user</code> from API</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p><span class="label label-info">Public API</span>
|
||||
<br><code>/api/method/frappe.desk.star.toggle_star</code>
|
||||
</p>
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.desk.star.toggle_star" href="#frappe.desk.star.toggle_star" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.desk.star.<b>toggle_star</b>
|
||||
<i class="text-muted">(doctype, name, add=False)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Adds / removes the current user in the <code>__starred_by</code> property of the given document.
|
||||
If column does not exist, will add it in the database.</p>
|
||||
|
||||
<p>The <code>_starred_by</code> property is always set from this function and is ignored if set via
|
||||
Document API</p>
|
||||
|
||||
<p><strong>Parameters:</strong></p>
|
||||
|
||||
<ul>
|
||||
<li><strong><code>doctype</code></strong> - DocType of the document to star</li>
|
||||
<li><strong><code>name</code></strong> - Name of the document to star</li>
|
||||
<li><strong><code>add</code></strong> - <code>Yes</code> if star is to be added. If not <code>Yes</code> the star will be removed.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- autodoc -->
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
frappe.desk.calendar
|
||||
frappe.desk.desk_page
|
||||
frappe.desk
|
||||
frappe.desk.like
|
||||
frappe.desk.moduleview
|
||||
frappe.desk.notifications
|
||||
frappe.desk.query_builder
|
||||
|
|
@ -8,5 +9,4 @@ frappe.desk.query_report
|
|||
frappe.desk.report_dump
|
||||
frappe.desk.reportview
|
||||
frappe.desk.search
|
||||
frappe.desk.star
|
||||
frappe.desk.tags
|
||||
|
|
@ -284,7 +284,7 @@
|
|||
<a name="frappe.sessions.clear_sessions" href="#frappe.sessions.clear_sessions" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.sessions.<b>clear_sessions</b>
|
||||
<i class="text-muted">(user=None, keep_current=False)</i>
|
||||
<i class="text-muted">(user=None, keep_current=False, device=None)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,20 @@
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="add_comment_count" href="#add_comment_count" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>add_comment_count</b>
|
||||
<i class="text-muted">(self, result)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="add_limit" href="#add_limit" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -156,7 +170,7 @@
|
|||
<a name="execute" href="#execute" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>execute</b>
|
||||
<i class="text-muted">(self, query=None, fields=None, filters=None, or_filters=None, docstatus=None, group_by=None, order_by=None, limit_start=False, limit_page_length=None, as_list=False, with_childnames=False, debug=False, ignore_permissions=False, user=None)</i>
|
||||
<i class="text-muted">(self, query=None, fields=None, filters=None, or_filters=None, docstatus=None, group_by=None, order_by=None, limit_start=False, limit_page_length=None, as_list=False, with_childnames=False, debug=False, ignore_permissions=False, user=None, with_comment_count=False)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ all values (including child documents) from the database.</p>
|
|||
<a name="add_comment" href="#add_comment" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>add_comment</b>
|
||||
<i class="text-muted">(self, comment_type, text=None, comment_by=None)</i>
|
||||
<i class="text-muted">(self, comment_type, text=None, comment_by=None, reference_doctype=None, reference_name=None)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Add a comment to this document.</p>
|
||||
|
||||
|
|
@ -280,6 +280,20 @@ timestamps don't match.</p>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="get_liked_by" href="#get_liked_by" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>get_liked_by</b>
|
||||
<i class="text-muted">(self)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="get_permlevel_access" href="#get_permlevel_access" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -308,20 +322,6 @@ timestamps don't match.</p>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="get_starred_by" href="#get_starred_by" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>get_starred_by</b>
|
||||
<i class="text-muted">(self)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="get_url" href="#get_url" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<a name="frappe.utils.bench_helper.app_group" href="#frappe.utils.bench_helper.app_group" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.utils.bench_helper.<b>app_group</b>
|
||||
<i class="text-muted">(ctx, site=False, force=False, verbose=False, profile=False)</i>
|
||||
<i class="text-muted">()</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -926,6 +926,22 @@ Ported from PrettyDate by John Resig</p>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.utils.data.to_markdown" href="#frappe.utils.data.to_markdown" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.utils.data.<b>to_markdown</b>
|
||||
<i class="text-muted">(html)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.utils.data.to_timedelta" href="#frappe.utils.data.to_timedelta" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
|
|||
|
|
@ -64,22 +64,6 @@
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.render.build_json" href="#frappe.website.render.build_json" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.render.<b>build_json</b>
|
||||
<i class="text-muted">(path)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.render.build_page" href="#frappe.website.render.build_page" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -144,22 +128,6 @@
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.render.is_ajax" href="#frappe.website.render.is_ajax" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.render.<b>is_ajax</b>
|
||||
<i class="text-muted">()</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.render.render" href="#frappe.website.render.render" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
<!-- title: frappe.website.template --><div class="dev-header">
|
||||
|
||||
<a class="btn btn-default btn-sm" disabled style="margin-bottom: 10px;">
|
||||
Version 6.x.x</a>
|
||||
|
||||
|
||||
<a class="btn btn-default btn-sm" href="https://github.com/frappe/frappe/blob/develop/frappe/website/template.py"
|
||||
target="_blank" style="margin-left: 10px; margin-bottom: 10px;"><i class="octicon octicon-mark-github"></i> Source</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.add_hero" href="#frappe.website.template.add_hero" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>add_hero</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Add a hero element if specified in content or hooks.
|
||||
Hero elements get full page width.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.add_index" href="#frappe.website.template.add_index" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>add_index</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Add index, next button if <code>{index}</code>, <code>{next}</code> is present.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.build_template" href="#frappe.website.template.build_template" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>build_template</b>
|
||||
<i class="text-muted">(context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Returns a dict of block name and its rendered content</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.render_blocks" href="#frappe.website.template.render_blocks" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>render_blocks</b>
|
||||
<i class="text-muted">(template_path, out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Build the template block by block from the main template.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.separate_style_and_script" href="#frappe.website.template.separate_style_and_script" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>separate_style_and_script</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Extract <code>style</code> and <code>script</code> tags into separate blocks</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.set_breadcrumbs" href="#frappe.website.template.set_breadcrumbs" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>set_breadcrumbs</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Build breadcrumbs template (deprecated)</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.set_sidebar" href="#frappe.website.template.set_sidebar" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>set_sidebar</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Include sidebar (deprecated)</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="frappe.website.template.set_title_and_header" href="#frappe.website.template.set_title_and_header" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
frappe.website.template.<b>set_title_and_header</b>
|
||||
<i class="text-muted">(out, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Extract and set title and header from content or context.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- autodoc -->
|
||||
|
|
@ -3,6 +3,5 @@ frappe.website
|
|||
frappe.website.render
|
||||
frappe.website.router
|
||||
frappe.website.statics
|
||||
frappe.website.template
|
||||
frappe.website.utils
|
||||
frappe.website.website_generator
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
Version
|
||||
</td>
|
||||
<td>
|
||||
<code>6.16.3</code>
|
||||
<code>6.17.3</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ Comment
|
|||
Workflow
|
||||
Label
|
||||
Attachment
|
||||
Attachment Removed</pre>
|
||||
Attachment Removed
|
||||
Like</pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
|
|
|||
|
|
@ -571,20 +571,6 @@ Recipient Unsubscribed</pre>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="get_starrers" href="#get_starrers" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>get_starrers</b>
|
||||
<i class="text-muted">(self)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Return list of users who have starred this document.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="notify" href="#notify" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
|
|||
|
|
@ -1068,9 +1068,9 @@ Website User</pre>
|
|||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="send_password_notifcation" href="#send_password_notifcation" class="text-muted small">
|
||||
<a name="send_password_notification" href="#send_password_notification" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>send_password_notifcation</b>
|
||||
<b>send_password_notification</b>
|
||||
<i class="text-muted">(self, new_password)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@
|
|||
Comment
|
||||
Login
|
||||
Label
|
||||
Info</pre>
|
||||
Info
|
||||
Like</pre>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
|
@ -116,6 +117,55 @@ Info</pre>
|
|||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td>7</td>
|
||||
<td ><code>doc_owner</code></td>
|
||||
<td >
|
||||
Data</td>
|
||||
<td >
|
||||
Doc Owner
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td>8</td>
|
||||
<td ><code>seen</code></td>
|
||||
<td >
|
||||
Check</td>
|
||||
<td >
|
||||
Seen
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td>9</td>
|
||||
<td ><code>reference_doctype</code></td>
|
||||
<td >
|
||||
Data</td>
|
||||
<td >
|
||||
Reference DocType
|
||||
<p class="text-muted small">
|
||||
Use this to provide alternative link to a feed record</p>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr >
|
||||
<td>10</td>
|
||||
<td ><code>reference_name</code></td>
|
||||
<td >
|
||||
Data</td>
|
||||
<td >
|
||||
Reference Name
|
||||
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
|
@ -138,6 +188,20 @@ Info</pre>
|
|||
</div>
|
||||
<div style="padding-left: 30px;">
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="validate" href="#validate" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>validate</b>
|
||||
<i class="text-muted">(self)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p><span class="text-muted">No docs</span></p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
|
|
|
|||
|
|
@ -423,6 +423,35 @@ Right</pre>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="add_hero" href="#add_hero" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>add_hero</b>
|
||||
<i class="text-muted">(self, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Add a hero element if specified in content or hooks.
|
||||
Hero elements get full page width.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="add_index" href="#add_index" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>add_index</b>
|
||||
<i class="text-muted">(self, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Add index, next button if <code>{index}</code>, <code>{next}</code> is present.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="check_for_redirect" href="#check_for_redirect" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -507,6 +536,20 @@ Right</pre>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="set_breadcrumbs" href="#set_breadcrumbs" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>set_breadcrumbs</b>
|
||||
<i class="text-muted">(self, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Build breadcrumbs template (deprecated)</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="set_metatags" href="#set_metatags" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
@ -521,6 +564,20 @@ Right</pre>
|
|||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="set_title_and_header" href="#set_title_and_header" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
<b>set_title_and_header</b>
|
||||
<i class="text-muted">(self, context)</i>
|
||||
</p>
|
||||
<div class="docs-attr-desc"><p>Extract and set title and header from content or context.</p>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="docs-attr-name">
|
||||
<a name="validate" href="#validate" class="text-muted small">
|
||||
<i class="icon-link small" style="color: #ccc;"></i></a>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,15 @@
|
|||
Let's say, there is a custom field "VAT Number" in Supplier master, which should be fetched in Purchase Order document.
|
||||
<br>
|
||||
<br>Steps:
|
||||
<br>1. Create a Custom Field <b>"VAT Number"</b> for <b>Supplier</b> document with <b>Field Type</b> as <b>Data</b>.
|
||||
<br>
|
||||
<img src="/files/supplier_vat_number.png" height="202" width="607"><br>2. Create another Custom Field <b>"VAT Number"</b> for Purchase Order document. But in this case, enter <b>Field Type</b> as <b>Read Only</b> and <b>Options</b> as <b>supplier.vat_number</b>.
|
||||
<br> <img src="/files/po_vat_number.png" height="264" width="611"><br>3. Refresh the system using <b>Help -> Clear Cache</b>.
|
||||
<br>4. Now on selection of Supplier in new Purchase Order form, "VAT Number" will be fetched automatically from Supplier master.
|
||||
<br>5. The above procedure should be replicated, for all other supplier related transactions.
|
||||
<br>
|
||||
<br>Note:
|
||||
<br>
|
||||
<blockquote>If field type of "VAT Number" in Purchase Order is other than `Read Only`, then to fetch the value, a small piece of Custom Script need to be written.
|
||||
<br>i. Go to Setup -> Customize -> Custom Script.
|
||||
<br>ii. Select DocType as `Purchase Order`.
|
||||
<br>iii. Add Script `cur_frm.add_fetch('supplier', 'vat_number', 'vat_number')`
|
||||
<br>iv. Save the Custom Script.
|
||||
<br>v. Clear cache before testing.
|
||||
<br>
|
||||
</blockquote>
|
||||
# Fetch a Field Value from a Document into a Transaction
|
||||
|
||||
Let's say, there is a custom field "VAT Number" in Supplier, which should be fetched in Purchase Order.
|
||||
|
||||
#### Steps:
|
||||
|
||||
1. Create a Custom Field **VAT Number** for *Supplier* document with *Field Type* as **Data**.
|
||||
<img class="screenshot" src="{{ docs_base_url }}/assets/img/add-vat-number-in-supplier.png">
|
||||
|
||||
1. Create another Custom Field **VAT Number** for *Purchase Order* document, but in this case with *Field Type* as **Read Only** or check **Read Only** checkbox. Set the **Options** as `supplier.vat_number`.
|
||||
<img class="screenshot" src="{{ docs_base_url }}/assets/img/add-vat-number-in-purchase-order.png">
|
||||
|
||||
1. Go to the user menu and click "Reload".
|
||||
1. Now, on selection of Supplier in a new Purchase Order, **VAT Number** will be fetched automatically from the selected Supplier.
|
||||
<img class="screenshot" src="{{ docs_base_url }}/assets/img/vat-number-fetched.png">
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
|||
import frappe
|
||||
from frappe.utils.pdf import get_pdf
|
||||
from frappe.email.smtp import get_outgoing_email_account
|
||||
from frappe.utils import get_url, scrub_urls, strip, expand_relative_urls, cint, split_emails
|
||||
from frappe.utils import get_url, scrub_urls, strip, expand_relative_urls, cint, split_emails, to_markdown
|
||||
import email.utils
|
||||
from markdown2 import markdown
|
||||
|
||||
|
|
@ -89,12 +89,7 @@ class EMail:
|
|||
|
||||
def set_html_as_text(self, html):
|
||||
"""return html2text"""
|
||||
import HTMLParser
|
||||
from html2text import html2text
|
||||
try:
|
||||
self.set_text(html2text(html))
|
||||
except HTMLParser.HTMLParseError:
|
||||
pass
|
||||
self.set_text(to_markdown(html))
|
||||
|
||||
def set_message(self, message, mime_type='text/html', as_attachment=0, filename='attachment.html'):
|
||||
"""Append the message with MIME content to the root node (as attachment)"""
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd."
|
|||
app_description = "Full stack web framework with Python, Javascript, MariaDB, Redis, Node"
|
||||
|
||||
app_icon = "octicon octicon-circuit-board"
|
||||
app_version = "6.16.4"
|
||||
app_version = "6.17.6"
|
||||
app_color = "orange"
|
||||
source_link = "https://github.com/frappe/frappe"
|
||||
app_license = "MIT"
|
||||
|
|
@ -45,12 +45,6 @@ website_route_rules = [
|
|||
{"from_route": "/blog/<category>", "to_route": "Blog Post"}
|
||||
]
|
||||
|
||||
website_context = {
|
||||
"hero": {
|
||||
"blog": "templates/includes/blog/hero.html"
|
||||
}
|
||||
}
|
||||
|
||||
write_file_keys = ["file_url", "file_name"]
|
||||
|
||||
notification_config = "frappe.core.notifications.get_notification_config"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ default_fields = ('doctype','name','owner','creation','modified','modified_by',
|
|||
integer_docfield_properties = ("reqd", "search_index", "in_list_view", "permlevel",
|
||||
"hidden", "read_only", "ignore_user_permissions", "allow_on_submit", "report_hide",
|
||||
"in_filter", "no_copy", "print_hide", "unique")
|
||||
optional_fields = ("_user_tags", "_comments", "_assign", "_starred_by")
|
||||
optional_fields = ("_user_tags", "_comments", "_assign", "_liked_by")
|
||||
|
||||
def rename(doctype, old, new, debug=False):
|
||||
import frappe.model.rename_doc
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ class BaseDocument(object):
|
|||
if k in default_fields:
|
||||
del doc[k]
|
||||
|
||||
for key in ("_user_tags", "__islocal", "__onload", "_starred_by", "__run_link_triggers"):
|
||||
for key in ("_user_tags", "__islocal", "__onload", "_liked_by", "__run_link_triggers"):
|
||||
if self.get(key):
|
||||
doc[key] = self.get(key)
|
||||
|
||||
|
|
@ -372,6 +372,12 @@ class BaseDocument(object):
|
|||
if self.get(df.fieldname) in (None, []) or not strip_html(cstr(self.get(df.fieldname))).strip():
|
||||
missing.append((df.fieldname, get_msg(df)))
|
||||
|
||||
# check for missing parent and parenttype
|
||||
if self.meta.istable:
|
||||
for fieldname in ("parent", "parenttype"):
|
||||
if not self.get(fieldname):
|
||||
missing.append((fieldname, get_msg(frappe._dict(label=fieldname))))
|
||||
|
||||
return missing
|
||||
|
||||
def get_invalid_links(self, is_submittable=False):
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class DatabaseQuery(object):
|
|||
def execute(self, query=None, fields=None, filters=None, or_filters=None,
|
||||
docstatus=None, group_by=None, order_by=None, limit_start=False,
|
||||
limit_page_length=None, as_list=False, with_childnames=False, debug=False,
|
||||
ignore_permissions=False, user=None):
|
||||
ignore_permissions=False, user=None, with_comment_count=False):
|
||||
if not ignore_permissions and not frappe.has_permission(self.doctype, "read", user=user):
|
||||
raise frappe.PermissionError, self.doctype
|
||||
|
||||
|
|
@ -45,9 +45,14 @@ class DatabaseQuery(object):
|
|||
self.user = user or frappe.session.user
|
||||
|
||||
if query:
|
||||
return self.run_custom_query(query)
|
||||
result = self.run_custom_query(query)
|
||||
else:
|
||||
return self.build_and_run()
|
||||
result = self.build_and_run()
|
||||
|
||||
if with_comment_count and not as_list and self.doctype:
|
||||
self.add_comment_count(result)
|
||||
|
||||
return result
|
||||
|
||||
def build_and_run(self):
|
||||
args = self.prepare_args()
|
||||
|
|
@ -444,3 +449,21 @@ class DatabaseQuery(object):
|
|||
return 'limit %s, %s' % (self.limit_start, self.limit_page_length)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def add_comment_count(self, result):
|
||||
for r in result:
|
||||
if not r.name:
|
||||
continue
|
||||
|
||||
if "_comments" in r:
|
||||
comment_count = len(json.loads(r._comments or "[]"))
|
||||
else:
|
||||
comment_count = cint(frappe.db.get_value("Comment",
|
||||
filters={"comment_doctype": self.doctype, "comment_docname": r.name, "comment_type": "Comment"},
|
||||
fieldname="count(name)"))
|
||||
|
||||
communication_count = cint(frappe.db.get_value("Communication",
|
||||
filters={"reference_doctype": self.doctype, "reference_name": r.name},
|
||||
fieldname="count(name)"))
|
||||
|
||||
r._comment_count = comment_count + communication_count
|
||||
|
|
|
|||
|
|
@ -649,11 +649,11 @@ class Document(BaseDocument):
|
|||
def notify_update(self):
|
||||
"""Publish realtime that the current document is modified"""
|
||||
frappe.publish_realtime("doc_update", {"modified": self.modified, "doctype": self.doctype, "name": self.name},
|
||||
doctype=self.doctype, docname=self.name)
|
||||
doctype=self.doctype, docname=self.name, after_commit=True)
|
||||
|
||||
if not self.meta.get("read_only") and not self.meta.get("issingle") and \
|
||||
not self.meta.get("istable"):
|
||||
frappe.publish_realtime("list_update", {"doctype": self.doctype})
|
||||
frappe.publish_realtime("list_update", {"doctype": self.doctype}, after_commit=True)
|
||||
|
||||
|
||||
def check_no_back_links_exist(self):
|
||||
|
|
@ -764,7 +764,7 @@ class Document(BaseDocument):
|
|||
"""Returns Desk URL for this document. `/desk#Form/{doctype}/{name}`"""
|
||||
return "/desk#Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name)
|
||||
|
||||
def add_comment(self, comment_type, text=None, comment_by=None):
|
||||
def add_comment(self, comment_type, text=None, comment_by=None, reference_doctype=None, reference_name=None):
|
||||
"""Add a comment to this document.
|
||||
|
||||
:param comment_type: e.g. `Comment`. See Comment for more info."""
|
||||
|
|
@ -774,7 +774,9 @@ class Document(BaseDocument):
|
|||
"comment_type": comment_type,
|
||||
"comment_doctype": self.doctype,
|
||||
"comment_docname": self.name,
|
||||
"comment": text or _(comment_type)
|
||||
"comment": text or _(comment_type),
|
||||
"reference_doctype": reference_doctype,
|
||||
"reference_name": reference_name
|
||||
}).insert(ignore_permissions=True)
|
||||
return comment
|
||||
|
||||
|
|
@ -782,10 +784,10 @@ class Document(BaseDocument):
|
|||
"""Returns signature (hash) for private URL."""
|
||||
return hashlib.sha224(get_datetime_str(self.creation)).hexdigest()
|
||||
|
||||
def get_starred_by(self):
|
||||
starred_by = getattr(self, "_starred_by", None)
|
||||
if starred_by:
|
||||
return json.loads(starred_by)
|
||||
def get_liked_by(self):
|
||||
liked_by = getattr(self, "_liked_by", None)
|
||||
if liked_by:
|
||||
return json.loads(liked_by)
|
||||
else:
|
||||
return []
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ def update_property_setters(doctype, old_fieldname, new_fieldname):
|
|||
where doc_type=%s and field_name=%s""", (new_fieldname, doctype, old_fieldname))
|
||||
|
||||
idx_property = frappe.db.sql("""select name, value from `tabProperty Setter`
|
||||
where doc_type=%s and property = '_idx' and value like '%%%s%%'""",
|
||||
where doc_type='%s' and property = '_idx' and value like '%%%s%%'""" %
|
||||
(doctype, old_fieldname), as_dict=1)
|
||||
|
||||
if idx_property:
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ execute:frappe.db.sql("""update tabComment set comment = substr(comment, 6, loca
|
|||
frappe.patches.v5_0.fix_feed
|
||||
frappe.patches.v5_0.update_shared
|
||||
execute:frappe.reload_doc("core", "doctype", "docshare") #2015-07-21
|
||||
frappe.patches.v6_16.star_to_like
|
||||
frappe.patches.v5_0.bookmarks_to_stars
|
||||
frappe.patches.v5_0.style_settings_to_website_theme
|
||||
frappe.patches.v5_0.rename_ref_type_fieldnames
|
||||
|
|
@ -112,3 +113,5 @@ execute:frappe.create_folder(os.path.join(frappe.local.site_path, 'private', 'fi
|
|||
frappe.patches.v6_15.remove_property_setter_for_previous_field #2015-12-29
|
||||
frappe.patches.v6_15.set_username
|
||||
execute:frappe.permissions.reset_perms("Error Snapshot")
|
||||
frappe.patches.v6_16.feed_doc_owner
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from __future__ import unicode_literals
|
|||
import json
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
from frappe.desk.star import _toggle_star
|
||||
from frappe.desk.like import _toggle_like
|
||||
|
||||
def execute():
|
||||
for user in frappe.get_all("User"):
|
||||
|
|
@ -29,4 +29,4 @@ def execute():
|
|||
or int(frappe.db.get_value("DocType", doctype, "issingle") or 0)
|
||||
or not frappe.db.table_exists(doctype)):
|
||||
continue
|
||||
_toggle_star(doctype, docname, add="Yes", user=username)
|
||||
_toggle_like(doctype, docname, add="Yes", user=username)
|
||||
|
|
|
|||
0
frappe/patches/v6_16/__init__.py
Normal file
0
frappe/patches/v6_16/__init__.py
Normal file
32
frappe/patches/v6_16/feed_doc_owner.py
Normal file
32
frappe/patches/v6_16/feed_doc_owner.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doctype("Feed")
|
||||
|
||||
frappe.db.sql("update `tabFeed` set seen=1")
|
||||
|
||||
for doctype, name in frappe.db.sql("""select distinct doc_type, doc_name from `tabFeed`
|
||||
where
|
||||
(doc_type is not null and doc_type != '')
|
||||
and (doc_name is not null and doc_name != '')
|
||||
and doc_type != 'Feed'
|
||||
for update"""):
|
||||
|
||||
owner = frappe.db.get_value(doctype, name, "owner")
|
||||
|
||||
if not owner:
|
||||
continue
|
||||
|
||||
frappe.db.sql("""update `tabFeed`
|
||||
set doc_owner=%(owner)s
|
||||
where
|
||||
doc_type=%(doctype)s
|
||||
and doc_name=%(name)s
|
||||
and (doc_owner is null or doc_owner = '')""".format(doctype=doctype), {
|
||||
"doctype": doctype,
|
||||
"name": name,
|
||||
"owner": owner
|
||||
})
|
||||
|
||||
frappe.db.commit()
|
||||
18
frappe/patches/v6_16/star_to_like.py
Normal file
18
frappe/patches/v6_16/star_to_like.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.db_schema import add_column
|
||||
|
||||
def execute():
|
||||
frappe.reload_doctype("Feed")
|
||||
|
||||
frappe.db.sql("""update `tabSingles` set field='_liked_by' where field='_starred_by'""")
|
||||
frappe.db.commit()
|
||||
|
||||
for table in frappe.db.get_tables():
|
||||
columns = [r[0] for r in frappe.db.sql("DESC `{0}`".format(table))]
|
||||
if "_starred_by" in columns:
|
||||
frappe.db.sql_ddl("""alter table `{0}` change `_starred_by` `_liked_by` Text """.format(table))
|
||||
|
||||
for doctype in ("Comment", "Communication"):
|
||||
if not frappe.db.has_column(doctype, "_liked_by"):
|
||||
add_column(doctype, "_liked_by", "Text")
|
||||
|
|
@ -2,20 +2,19 @@
|
|||
"css/frappe-web.css": [
|
||||
"public/css/font-awesome.css",
|
||||
"public/css/octicons/octicons.css",
|
||||
"public/css/nprogress.css",
|
||||
"public/css/website.css"
|
||||
],
|
||||
"js/frappe-web.min.js": [
|
||||
"public/js/lib/bootstrap.min.js",
|
||||
"public/js/frappe/provide.js",
|
||||
"public/js/frappe/misc/number_format.js",
|
||||
"public/js/lib/nprogress.js",
|
||||
"public/js/frappe/translate.js",
|
||||
"public/js/frappe/misc/pretty_date.js",
|
||||
"public/js/lib/moment/moment.min.js",
|
||||
"public/js/lib/highlight.pack.js",
|
||||
"public/js/frappe/class.js",
|
||||
"public/js/lib/microtemplate.js",
|
||||
"public/js/frappe/query_string.js",
|
||||
"website/js/website.js",
|
||||
"public/js/lib/socket.io.min.js"
|
||||
],
|
||||
|
|
@ -25,6 +24,16 @@
|
|||
"public/js/frappe/ui/editor.html",
|
||||
"public/js/frappe/ui/editor.js"
|
||||
],
|
||||
"js/dialog.min.js": [
|
||||
"public/js/frappe/dom.js",
|
||||
"public/js/frappe/ui/modal.html",
|
||||
"public/js/frappe/form/formatters.js",
|
||||
"public/js/frappe/form/layout.js",
|
||||
"public/js/frappe/ui/field_group.js",
|
||||
"public/js/frappe/form/control.js",
|
||||
"public/js/frappe/form/link_selector.js",
|
||||
"public/js/frappe/ui/dialog.js"
|
||||
],
|
||||
"css/desk.min.css": [
|
||||
"public/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css",
|
||||
"public/css/bootstrap.css",
|
||||
|
|
@ -38,7 +47,6 @@
|
|||
"public/css/sidebar.css",
|
||||
"public/css/page.css",
|
||||
"public/css/tree.css",
|
||||
"public/css/nprogress.css",
|
||||
"public/css/desktop.css",
|
||||
"public/css/form.css",
|
||||
"public/css/mobile.css"
|
||||
|
|
@ -49,7 +57,6 @@
|
|||
"public/js/lib/tag-it.min.js",
|
||||
"public/js/lib/notify.js",
|
||||
"public/js/lib/bootstrap.min.js",
|
||||
"public/js/lib/nprogress.js",
|
||||
"public/js/lib/moment/moment-with-locales.min.js",
|
||||
"public/js/lib/moment/moment-timezone-with-data.min.js",
|
||||
"public/js/lib/socket.io.min.js",
|
||||
|
|
@ -84,7 +91,6 @@
|
|||
"public/js/frappe/form/control.js",
|
||||
"public/js/frappe/form/link_selector.js",
|
||||
"public/js/frappe/ui/dialog.js",
|
||||
"public/js/frappe/ui/button.js",
|
||||
"public/js/frappe/ui/app_icon.js",
|
||||
|
||||
"public/js/frappe/model/model.js",
|
||||
|
|
@ -121,6 +127,7 @@
|
|||
|
||||
"public/js/frappe/change_log.html",
|
||||
"public/js/frappe/desk.js",
|
||||
"public/js/frappe/query_string.js",
|
||||
|
||||
"public/html/error_object.html",
|
||||
"public/html/error_snapshot.html"
|
||||
|
|
@ -180,7 +187,8 @@
|
|||
"public/js/frappe/ui/filters/filters.js",
|
||||
"public/js/frappe/ui/filters/edit_filter.html",
|
||||
"public/js/frappe/ui/tags.js",
|
||||
"public/js/frappe/ui/star.js",
|
||||
"public/js/frappe/ui/like.js",
|
||||
"public/js/frappe/ui/liked_by.html",
|
||||
"public/html/print_template.html",
|
||||
"public/js/frappe/list/doclistview.js",
|
||||
"public/js/frappe/list/list_sidebar.js",
|
||||
|
|
|
|||
|
|
@ -43,3 +43,12 @@
|
|||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
.avatar-frame {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding: 50% 0px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ a.badge-hover:active .badge {
|
|||
background-color: #D8DFE5;
|
||||
}
|
||||
.msgprint {
|
||||
margin: 15px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
.msgprint pre {
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ a.badge-hover:active .badge {
|
|||
background-color: #D8DFE5;
|
||||
}
|
||||
.msgprint {
|
||||
margin: 15px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
.msgprint pre {
|
||||
|
|
@ -546,3 +547,11 @@ ul.linked-with-list li {
|
|||
border-bottom: 1px solid #d1d8dd;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.liked-by-popover {
|
||||
min-width: 200px;
|
||||
margin-top: -10px;
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
.liked-by-popover li {
|
||||
margin: 15px 0px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,8 +61,7 @@
|
|||
.empty-section {
|
||||
display: none !important;
|
||||
}
|
||||
.shaded-section,
|
||||
.timeline-item:nth-child(even) {
|
||||
.shaded-section {
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
.modal .form-layout {
|
||||
|
|
@ -87,37 +86,165 @@
|
|||
background-color: #e74c3c;
|
||||
}
|
||||
.timeline {
|
||||
border: 1px solid #d1d8dd;
|
||||
margin: 30px 0px;
|
||||
}
|
||||
.timeline .timeline-head .comment-input {
|
||||
height: auto;
|
||||
}
|
||||
.timeline-item {
|
||||
margin-top: 0px;
|
||||
padding: 15px 30px 7px;
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
}
|
||||
.timeline-item .icon-fixed-width {
|
||||
text-align: center;
|
||||
}
|
||||
.timeline-item blockquote {
|
||||
font-size: inherit;
|
||||
}
|
||||
.timeline-item:last-child {
|
||||
border-bottom: 0px;
|
||||
.timeline-items {
|
||||
position: relative;
|
||||
}
|
||||
.timeline-item .reply {
|
||||
margin-top: 5px;
|
||||
.timeline {
|
||||
position: relative;
|
||||
}
|
||||
.timeline::before {
|
||||
content: " ";
|
||||
border-left: 1px solid #d1d8dd;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: -124px;
|
||||
left: 43px;
|
||||
z-index: -1;
|
||||
}
|
||||
@media (max-width: 991px) {
|
||||
.timeline::before {
|
||||
bottom: -64px;
|
||||
}
|
||||
}
|
||||
.timeline-item.user-content {
|
||||
margin: 30px 0px 30px 30px;
|
||||
}
|
||||
.timeline-item.user-content .media-body {
|
||||
border: 1px solid #d1d8dd;
|
||||
border-radius: 2px;
|
||||
margin-left: -7px;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
.timeline-item.user-content .comment-header {
|
||||
background-color: #fafbfc;
|
||||
padding: 7px 15px;
|
||||
margin: 0px;
|
||||
color: #8D99A6;
|
||||
border-bottom: 1px solid #EBEFF2;
|
||||
}
|
||||
.timeline-item.user-content .comment-header .octicon-heart {
|
||||
color: #ff5858;
|
||||
cursor: pointer;
|
||||
}
|
||||
.timeline-item.user-content .reply {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
.timeline-item.user-content .reply > div > p:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
.timeline-item.user-content .reply > div > p:last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.timeline-item.user-content .close-btn-container {
|
||||
padding: 2px 15px;
|
||||
}
|
||||
.timeline-item.user-content .comment-likes {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.timeline-item.user-content .media-body:after,
|
||||
.timeline-item.user-content .media-body:before {
|
||||
right: 100%;
|
||||
top: 15px;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.timeline-item.user-content .media-body:after {
|
||||
border-color: rgba(136, 183, 213, 0);
|
||||
border-right-color: #fafbfc;
|
||||
border-width: 6px;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.timeline-item.user-content .media-body:before {
|
||||
border-color: rgba(194, 225, 245, 0);
|
||||
border-right-color: #d1d8dd;
|
||||
border-width: 7px;
|
||||
margin-top: -7px;
|
||||
}
|
||||
.timeline-item.notification-content {
|
||||
padding-left: 30px;
|
||||
margin: 30px 0px;
|
||||
position: relative;
|
||||
color: #8D99A6;
|
||||
}
|
||||
.timeline-item.notification-content * {
|
||||
color: #8D99A6;
|
||||
}
|
||||
.timeline-item.notification-content .icon-fixed-width {
|
||||
margin-left: 36px;
|
||||
}
|
||||
.timeline-item.notification-content .octicon-heart {
|
||||
color: #ff5858 !important;
|
||||
}
|
||||
.timeline-item.notification-content::before {
|
||||
content: " ";
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-color: #d1d8dd;
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
border-radius: 50%;
|
||||
top: 5px;
|
||||
}
|
||||
.timeline-item .reply-link {
|
||||
padding: 0px 7px;
|
||||
}
|
||||
.timeline-item h6,
|
||||
.timeline-head h6 {
|
||||
margin-top: 6px;
|
||||
padding-left: 7px;
|
||||
}
|
||||
.timeline-head {
|
||||
background-color: white;
|
||||
border: 1px solid #d1d8dd;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.timeline-head .comment-input-header {
|
||||
background-color: #fafbfc;
|
||||
padding: 15px 30px;
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
padding: 7px 15px;
|
||||
border-bottom: 1px solid #EBEFF2;
|
||||
}
|
||||
.timeline-head .comment-input-container {
|
||||
padding: 15px;
|
||||
}
|
||||
.timeline-head .comment-input {
|
||||
border-color: #EBEFF2;
|
||||
max-width: 100%;
|
||||
}
|
||||
.timeline-head .comment-input:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.timeline-head {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
.timeline-new-email {
|
||||
margin: 30px 0px;
|
||||
padding: 0px 65px;
|
||||
position: relative;
|
||||
}
|
||||
.timeline-new-email::before {
|
||||
content: " ";
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-color: #d1d8dd;
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
border-radius: 50%;
|
||||
top: 5px;
|
||||
}
|
||||
.form-footer h5 {
|
||||
margin: 15px 0px;
|
||||
|
|
|
|||
|
|
@ -48,3 +48,11 @@
|
|||
.indicator-right.darkgrey::after {
|
||||
background: #b8c2cc;
|
||||
}
|
||||
.indicator.yellow::before,
|
||||
.indicator-right.yellow::after {
|
||||
background: #FEEF72;
|
||||
}
|
||||
.indicator.light-blue::before,
|
||||
.indicator-right.light-blue::after {
|
||||
background: #7CD6FD;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,13 @@
|
|||
.doclist-row {
|
||||
font-size: 12px;
|
||||
}
|
||||
.doclist-row .likes-count {
|
||||
display: inline-block;
|
||||
width: 15px;
|
||||
margin-left: -5px;
|
||||
color: #8D99A6;
|
||||
font-size: 12px;
|
||||
}
|
||||
.doclist-row .docstatus .octicon {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
|
@ -134,14 +141,14 @@
|
|||
margin: 0px -15px;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
.listview-main-section .icon-star {
|
||||
.listview-main-section .octicon-heart {
|
||||
cursor: pointer;
|
||||
}
|
||||
.list-row-head .icon-star {
|
||||
vertical-align: middle;
|
||||
.list-row-head .octicon-heart {
|
||||
margin-right: 13px;
|
||||
}
|
||||
.star-action.icon-star {
|
||||
color: #ffdb4c;
|
||||
.like-action.octicon-heart {
|
||||
color: #ff5858;
|
||||
}
|
||||
.list-id {
|
||||
font-weight: bold;
|
||||
|
|
@ -163,3 +170,8 @@
|
|||
display: none;
|
||||
}
|
||||
}
|
||||
.list-comment-count {
|
||||
display: inline-block;
|
||||
width: 37px;
|
||||
text-align: left;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,20 +330,6 @@ body {
|
|||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
}
|
||||
.timeline {
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
}
|
||||
.timeline .timeline-head {
|
||||
padding: 7px 15px;
|
||||
}
|
||||
.timeline .timeline-item {
|
||||
padding: 15px;
|
||||
border-bottom: 1px dashed #d1d8dd;
|
||||
}
|
||||
.timeline .timeline-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.list-row {
|
||||
padding: 13px 15px !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@
|
|||
min-width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
background-color: #ff5858;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
.navbar-new-comments-true {
|
||||
background-color: #ff5858;
|
||||
}
|
||||
#navbar-search {
|
||||
width: 300px;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
/* Make clicks pass-through */
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
-webkit-pointer-events: none;
|
||||
}
|
||||
|
||||
/* Make the entire page show a busy cursor */
|
||||
.nprogress-busy body {
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #36414C;
|
||||
|
||||
position: fixed;
|
||||
z-index: 1050;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#nprogress .peg {
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
width: 100px;
|
||||
height: 100%;
|
||||
/*box-shadow: 0 0 10px #2ecc71, 0 0 5px #2ecc71;*/
|
||||
opacity: 1.0;
|
||||
|
||||
-webkit-transform: rotate(3deg) translate(0px, -4px);
|
||||
-moz-transform: rotate(3deg) translate(0px, -4px);
|
||||
-ms-transform: rotate(3deg) translate(0px, -4px);
|
||||
-o-transform: rotate(3deg) translate(0px, -4px);
|
||||
transform: rotate(3deg) translate(0px, -4px);
|
||||
}
|
||||
|
||||
/* Remove these to get rid of the spinner
|
||||
#nprogress .spinner {
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1050;
|
||||
top: 7px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#nprogress .spinner-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
|
||||
border: solid 2px transparent;
|
||||
border-top-color: #fff;
|
||||
border-left-color: #fff;
|
||||
border-radius: 10px;
|
||||
|
||||
-webkit-animation: nprogress-spinner 400ms linear infinite;
|
||||
-moz-animation: nprogress-spinner 400ms linear infinite;
|
||||
-ms-animation: nprogress-spinner 400ms linear infinite;
|
||||
-o-animation: nprogress-spinner 400ms linear infinite;
|
||||
animation: nprogress-spinner 400ms linear infinite;
|
||||
}
|
||||
|
||||
@-webkit-keyframes nprogress-spinner {
|
||||
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-moz-keyframes nprogress-spinner {
|
||||
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-o-keyframes nprogress-spinner {
|
||||
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-ms-keyframes nprogress-spinner {
|
||||
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes nprogress-spinner {
|
||||
0% { transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}*/
|
||||
|
|
@ -161,6 +161,10 @@ body[data-route^="Module"] .main-menu .form-sidebar {
|
|||
.form-sidebar .form-viewers .shared-with-everyone .octicon {
|
||||
color: #36414C !important;
|
||||
}
|
||||
.form-sidebar .liked-by .octicon-heart {
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.form-sidebar .form-shared .share-doc-btn:hover,
|
||||
.form-sidebar .form-shared .share-doc-btn:focus,
|
||||
.form-sidebar .form-shared .share-doc-btn:active {
|
||||
|
|
@ -174,6 +178,7 @@ body[data-route^="Module"] .main-menu .form-sidebar {
|
|||
.sidebar-left .form-sidebar .form-tags,
|
||||
.sidebar-left .form-sidebar .assignment-row,
|
||||
.sidebar-left .form-sidebar .form-shared,
|
||||
.sidebar-left .form-sidebar .liked-by,
|
||||
.sidebar-left .form-sidebar .modified-by,
|
||||
.sidebar-left .form-sidebar .created-by,
|
||||
.sidebar-left .form-sidebar .tags-label,
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ a.badge-hover:active .badge {
|
|||
background-color: #D8DFE5;
|
||||
}
|
||||
.msgprint {
|
||||
margin: 15px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
.msgprint pre {
|
||||
|
|
@ -264,6 +265,15 @@ a.no-decoration:active {
|
|||
height: 0;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
.avatar-frame {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding: 50% 0px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.indicator,
|
||||
.indicator-right {
|
||||
background: none;
|
||||
|
|
@ -314,6 +324,14 @@ a.no-decoration:active {
|
|||
.indicator-right.darkgrey::after {
|
||||
background: #b8c2cc;
|
||||
}
|
||||
.indicator.yellow::before,
|
||||
.indicator-right.yellow::after {
|
||||
background: #FEEF72;
|
||||
}
|
||||
.indicator.light-blue::before,
|
||||
.indicator-right.light-blue::after {
|
||||
background: #7CD6FD;
|
||||
}
|
||||
.navbar-brand {
|
||||
max-width: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ frappe.defaults = {
|
|||
get_user_default: function(key) {
|
||||
var defaults = frappe.boot.user.defaults;
|
||||
var d = defaults[key];
|
||||
if(!d && (key !== frappe.model.scrub(key)))
|
||||
if(!d && frappe.defaults.is_a_user_permission_key(key))
|
||||
d = defaults[frappe.model.scrub(key)];
|
||||
if($.isArray(d)) d = d[0];
|
||||
return d;
|
||||
|
|
@ -13,8 +13,8 @@ frappe.defaults = {
|
|||
get_user_defaults: function(key) {
|
||||
var defaults = frappe.boot.user.defaults;
|
||||
var d = defaults[key];
|
||||
|
||||
if (key !== frappe.model.scrub(key)) {
|
||||
|
||||
if (frappe.defaults.is_a_user_permission_key(key)) {
|
||||
if (d && $.isArray(d) && d.length===1) {
|
||||
// Use User Permission value when only when it has a single value
|
||||
d = d[0];
|
||||
|
|
@ -52,14 +52,14 @@ frappe.defaults = {
|
|||
get_default: function(key) {
|
||||
var defaults = frappe.boot.user.defaults;
|
||||
var value = defaults[key];
|
||||
if (key !== frappe.model.scrub(key)) {
|
||||
if (frappe.defaults.is_a_user_permission_key(key)) {
|
||||
if (value && $.isArray(value) && value.length===1) {
|
||||
value = value[0];
|
||||
} else {
|
||||
value = defaults[frappe.model.scrub(key)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(value) {
|
||||
try {
|
||||
return JSON.parse(value)
|
||||
|
|
@ -68,6 +68,11 @@ frappe.defaults = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
is_a_user_permission_key: function(key) {
|
||||
return key.indexOf(":")===-1 && key !== frappe.model.scrub(key);
|
||||
},
|
||||
|
||||
get_user_permissions: function() {
|
||||
return frappe.defaults.user_permissions;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -70,6 +70,14 @@ frappe.Application = Class.extend({
|
|||
frappe.csrf_token = data.csrf_token;
|
||||
}
|
||||
});
|
||||
|
||||
frappe.realtime.on("version-update", function() {
|
||||
var dialog = frappe.msgprint(__("The application has been updated to a new version, please refresh this page"));
|
||||
dialog.set_primary_action("Refresh", function() {
|
||||
location.reload(true);
|
||||
});
|
||||
dialog.get_close_btn().toggle(false);
|
||||
});
|
||||
},
|
||||
|
||||
load_bootinfo: function() {
|
||||
|
|
@ -80,7 +88,7 @@ frappe.Application = Class.extend({
|
|||
this.check_metadata_cache_status();
|
||||
this.set_globals();
|
||||
this.sync_pages();
|
||||
moment.locale(frappe.boot.lang);
|
||||
moment.locale("en");
|
||||
moment.user_utc_offset = moment().utcOffset();
|
||||
if(frappe.boot.timezone_info) {
|
||||
moment.tz.add(frappe.boot.timezone_info);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,18 @@ frappe.dom = {
|
|||
// execute the script globally
|
||||
document.getElementsByTagName('head')[0].appendChild(el);
|
||||
},
|
||||
remove_script_and_style: function(txt) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = txt;
|
||||
["script", "style", "noscript", "title", "meta", "base", "head"].forEach(function(e, i) {
|
||||
var elements = div.getElementsByTagName(e);
|
||||
var i = elements.length;
|
||||
while (i--) {
|
||||
elements[i].parentNode.removeChild(elements[i]);
|
||||
}
|
||||
});
|
||||
return div.innerHTML;
|
||||
},
|
||||
set_style: function(txt, id) {
|
||||
if(!txt) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -102,9 +102,11 @@ frappe.ui.form.Control = Class.extend({
|
|||
undefined;
|
||||
},
|
||||
set_model_value: function(value) {
|
||||
if(frappe.model.set_value(this.doctype, this.docname, this.df.fieldname,
|
||||
value, this.df.fieldtype)) {
|
||||
this.last_value = value;
|
||||
if(this.doctype) {
|
||||
if(frappe.model.set_value(this.doctype, this.docname, this.df.fieldname,
|
||||
value, this.df.fieldtype)) {
|
||||
this.last_value = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
@ -1153,10 +1155,6 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
select: function(event, ui) {
|
||||
me.autocomplete_open = false;
|
||||
|
||||
if(ui.item.action) {
|
||||
ui.item.action.apply(me);
|
||||
}
|
||||
|
||||
// prevent selection on tab
|
||||
var TABKEY = 9;
|
||||
if(event.keyCode === TABKEY) {
|
||||
|
|
@ -1165,6 +1163,11 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
return false;
|
||||
}
|
||||
|
||||
if(ui.item.action) {
|
||||
ui.item.value = "";
|
||||
ui.item.action.apply(me);
|
||||
}
|
||||
|
||||
if(me.frm && me.frm.doc) {
|
||||
me.selected = true;
|
||||
me.parse_validate_and_set_in_model(ui.item.value);
|
||||
|
|
@ -1383,7 +1386,7 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
},
|
||||
_set_input: function(value) {
|
||||
if(value == null) value = "";
|
||||
value = frappe.utils.remove_script_and_style(value);
|
||||
value = frappe.dom.remove_script_and_style(value);
|
||||
this.editor.set_input(value);
|
||||
this.md_editor.val(value);
|
||||
this.last_value = value;
|
||||
|
|
|
|||
|
|
@ -1,37 +1,21 @@
|
|||
<div class="timeline">
|
||||
<div class="timeline-head">
|
||||
<h6 class="text-muted">{%= __("Add a comment") %}</h6>
|
||||
<div>
|
||||
<textarea style="height: 80px" style="margin-top: 10px;"
|
||||
class="form-control"></textarea>
|
||||
<div class="comment-input-header">
|
||||
<span class="small text-muted">{%= __("Add a comment") %}</span>
|
||||
<button class="btn btn-default btn-comment btn-xs pull-right">
|
||||
{%= __("Comment") %}
|
||||
</button>
|
||||
</div>
|
||||
<div class="comment-input-container">
|
||||
<textarea class="form-control comment-input"></textarea>
|
||||
<input type="data" class="hidden mention-input">
|
||||
</div>
|
||||
<div class="media">
|
||||
<span class="pull-left avatar avatar-medium">
|
||||
<img class="media-object" src="{%= image %}">
|
||||
</span>
|
||||
<div class="media-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<h6>{%= __("You") %}</h6>
|
||||
</div>
|
||||
<div class="col-xs-8 text-right" style="margin-top: 2px;">
|
||||
<button class="btn btn-primary btn-go btn-xs pull-right">
|
||||
{%= __("Comment") %}
|
||||
</button>
|
||||
<div class="checkbox text-muted small pull-right"
|
||||
style="margin-top: 3px; margin-right: 15px;">
|
||||
<label>
|
||||
<input type="checkbox" class="is-email" style="margin-top: 1px;">
|
||||
{%= __("Email") %}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="timeline-new-email">
|
||||
<button class="btn btn-default btn-new-email btn-xs">
|
||||
{%= __("New Email") %}
|
||||
</button>
|
||||
</div>
|
||||
<div class="timeline-items">
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,33 +14,31 @@ frappe.ui.form.Comments = Class.extend({
|
|||
this.list = this.wrapper.find(".timeline-items");
|
||||
this.input = this.wrapper.find(".form-control");
|
||||
|
||||
this.button = this.wrapper.find(".btn-go")
|
||||
this.comment_button = this.wrapper.find(".btn-comment")
|
||||
.on("click", function() {
|
||||
if(me.wrapper.find(".is-email").prop("checked")) {
|
||||
new frappe.views.CommunicationComposer({
|
||||
doc: me.frm.doc,
|
||||
txt: frappe.markdown(me.input.val()),
|
||||
frm: me.frm,
|
||||
recipients: me.get_recipient()
|
||||
})
|
||||
} else {
|
||||
me.add_comment(this);
|
||||
}
|
||||
me.add_comment(this);
|
||||
});
|
||||
|
||||
this.input.keydown("meta+return ctrl+return", function(e) {
|
||||
me.button.trigger("click");
|
||||
me.comment_button.trigger("click");
|
||||
});
|
||||
|
||||
this.email_check = this.wrapper.find(".timeline-head input[type='checkbox']")
|
||||
.on("change", function() {
|
||||
me.button.html($(this).prop("checked") ? __("Compose") : __("Comment"));
|
||||
this.email_button = this.wrapper.find(".btn-new-email")
|
||||
.on("click", function() {
|
||||
new frappe.views.CommunicationComposer({
|
||||
doc: me.frm.doc,
|
||||
txt: frappe.markdown(me.input.val()),
|
||||
frm: me.frm,
|
||||
recipients: me.get_recipient()
|
||||
})
|
||||
});
|
||||
|
||||
this.list.on("click", ".toggle-blockquote", function() {
|
||||
$(this).parent().siblings("blockquote").toggleClass("hidden");
|
||||
});
|
||||
|
||||
this.setup_comment_like();
|
||||
|
||||
this.setup_mentions();
|
||||
},
|
||||
|
||||
|
|
@ -116,7 +114,7 @@ frappe.ui.form.Comments = Class.extend({
|
|||
|
||||
prepare_comment: function(c) {
|
||||
if((c.comment_type || "Comment") === "Comment" && frappe.model.can_delete("Comment")) {
|
||||
c["delete"] = '<a class="close" href="#">×</a>';
|
||||
c["delete"] = '<a class="close" href="#"><i class="octicon octicon-trashcan"></i></a>';
|
||||
} else {
|
||||
c["delete"] = "";
|
||||
}
|
||||
|
|
@ -130,7 +128,7 @@ frappe.ui.form.Comments = Class.extend({
|
|||
c.image = frappe.user_info(c.comment_by).image
|
||||
|| frappe.get_gravatar(c.comment_by);
|
||||
c.comment_on = comment_when(c.creation);
|
||||
c.fullname = frappe.user_info(c.comment_by).fullname;
|
||||
c.fullname = frappe.user.full_name(c.comment_by);
|
||||
|
||||
if(c.attachments && typeof c.attachments==="string")
|
||||
c.attachments = JSON.parse(c.attachments);
|
||||
|
|
@ -150,7 +148,7 @@ frappe.ui.form.Comments = Class.extend({
|
|||
if(c.comment_type=="Email") {
|
||||
c.comment = c.comment.split("<!-- original-reply -->")[0];
|
||||
c.comment = frappe.utils.strip_original_content(c.comment);
|
||||
c.comment = frappe.utils.remove_script_and_style(c.comment);
|
||||
c.comment = frappe.dom.remove_script_and_style(c.comment);
|
||||
|
||||
c.original_comment = c.comment;
|
||||
c.comment = frappe.utils.toggle_blockquote(c.comment);
|
||||
|
|
@ -167,6 +165,15 @@ frappe.ui.form.Comments = Class.extend({
|
|||
if(c.comment_type==="Comment") {
|
||||
c.comment_html = c.comment_html.replace(/(^|\W)(@\w+)/g, "$1<b>$2</b>");
|
||||
}
|
||||
|
||||
if (in_list(["Comment", "Email"], c.comment_type)) {
|
||||
c.user_content = true;
|
||||
if (!$.isArray(c._liked_by)) {
|
||||
c._liked_by = JSON.parse(c._liked_by || "[]");
|
||||
}
|
||||
|
||||
c.liked_by_user = c._liked_by.indexOf(user)!==-1;
|
||||
}
|
||||
}
|
||||
},
|
||||
set_icon_and_color: function(c) {
|
||||
|
|
@ -186,7 +193,8 @@ frappe.ui.form.Comments = Class.extend({
|
|||
"Attachment": "octicon octicon-cloud-upload",
|
||||
"Attachment Removed": "octicon octicon-trashcan",
|
||||
"Shared": "octicon octicon-eye",
|
||||
"Unshared": "octicon octicon-circle-slash"
|
||||
"Unshared": "octicon octicon-circle-slash",
|
||||
"Like": "octicon octicon-heart"
|
||||
}[c.comment_type]
|
||||
|
||||
c.color = {
|
||||
|
|
@ -348,10 +356,13 @@ frappe.ui.form.Comments = Class.extend({
|
|||
|
||||
this.mention_input = this.wrapper.find(".mention-input");
|
||||
|
||||
var source = Object.keys(username_user_map);
|
||||
source.sort();
|
||||
|
||||
this.mention_input.autocomplete({
|
||||
minLength: 0,
|
||||
autoFocus: true,
|
||||
source: Object.keys(username_user_map),
|
||||
source: source,
|
||||
select: function(event, ui) {
|
||||
var value = ui.item.value;
|
||||
var textarea_value = me.input.val();
|
||||
|
|
@ -467,9 +478,21 @@ frappe.ui.form.Comments = Class.extend({
|
|||
me.mention_widget.trigger(me.enter);
|
||||
|
||||
// prevent default
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (e.which==me.codes.TAB) {
|
||||
me.comment_button.focus();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
setup_comment_like: function() {
|
||||
this.wrapper.on("click", ".comment-likes .octicon-heart", frappe.ui.click_toggle_like);
|
||||
|
||||
frappe.ui.setup_like_popover(this.wrapper, ".comment-likes");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
<div class="media timeline-item" data-name="{%= data.name %}">
|
||||
<div class="media timeline-item {% if (data.user_content) { %} user-content {% } else { %} notification-content {% } %}" data-doctype="{{ data.doctype }}" data-name="{%= data.name %}">
|
||||
{% if (data.user_content) { %}
|
||||
<span class="pull-left avatar avatar-medium">
|
||||
<img class="media-object" src="{%= data.image %}">
|
||||
<div class="avatar-frame" style="background-image: url({%= data.image %})"></div>
|
||||
</span>
|
||||
<div class="pull-left media-body" style="max-width: calc(100% - 41px); padding-right: 0px;">
|
||||
<div>
|
||||
<div class="pull-right">
|
||||
{% } %}
|
||||
|
||||
<div class="pull-left media-body" style="max-width: calc(100% - 50px); padding-right: 0px;">
|
||||
<div class="media-content-wrapper">
|
||||
<div class="pull-right close-btn-container">
|
||||
<span class="small text-muted">
|
||||
{%= data.delete %}
|
||||
</span>
|
||||
</div>
|
||||
{% if(data.doctype=="Communication" || data.comment_type=="Comment") { %}
|
||||
<h6>
|
||||
<div class="comment-header small">
|
||||
<i class="{%= data.icon %} icon-fixed-width"></i>
|
||||
<span title="{%= data.comment_by %}">{%= data.fullname %}</span>
|
||||
<span class="text-muted" style="font-weight: normal;">
|
||||
|
|
@ -47,14 +50,23 @@
|
|||
<a class="text-muted reply-link pull-right"
|
||||
data-name="{%= data.name %}">{%= __("Reply") %}</a>
|
||||
{% } %}
|
||||
</h6>
|
||||
<span class="comment-likes" data-liked-by=\'{{ JSON.stringify(data._liked_by) }}\'>
|
||||
<i class="octicon octicon-heart like-action
|
||||
{% if (!data.liked_by_user) { %}
|
||||
text-extra-muted not-liked
|
||||
{% } %} "
|
||||
data-doctype="{%= data.doctype %}"
|
||||
data-name="{%= data.name %}"></i>
|
||||
<span class="likes-count text-muted">{{ data._liked_by.length }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="reply">
|
||||
<div>
|
||||
{%= data.comment_html %}
|
||||
</div>
|
||||
</div>
|
||||
{% } else if(in_list(["Assignment Completed", "Assigned", "Shared", "Unshared"], data.comment_type)) { %}
|
||||
<h6>
|
||||
<div class="small">
|
||||
<i class="{%= data.icon %} icon-fixed-width"></i>
|
||||
{% if(data.reference_doctype && data.reference_name) { %}
|
||||
<a href="#Form/{%= data.reference_doctype %}/{%= data.reference_name %}">
|
||||
|
|
@ -65,14 +77,19 @@
|
|||
{% } %}
|
||||
<span class="text-muted" style="font-weight: normal;">
|
||||
– {%= data.comment_on %}</span>
|
||||
</h6>
|
||||
</div>
|
||||
{% } else { %}
|
||||
<h6>
|
||||
<div class="small">
|
||||
<i class="{%= data.icon %} icon-fixed-width"></i>
|
||||
<span title="{%= data.comment_by %}">{%= data.fullname %}</span> {%= data.comment %}
|
||||
<span class="text-muted" style="font-weight: normal;">
|
||||
– {%= data.comment_on %}</span>
|
||||
</h6>
|
||||
{% if (data.comment_type == "Like") { %}
|
||||
<span title="{%= data.comment_by %}">{%= __("Liked by {0}", [data.fullname]) %}</span>
|
||||
{% } else { %}
|
||||
<span title="{%= data.comment_by %}">{%= data.fullname %}</span>
|
||||
{%= data.comment %}
|
||||
{% } %}
|
||||
<span class="text-muted" style="font-weight: normal;">
|
||||
– {%= data.comment_on %}</span>
|
||||
</div>
|
||||
{% } %}
|
||||
{% if(data.attachments && data.attachments.length) { %}
|
||||
<div style="margin: 10px 0px">
|
||||
|
|
|
|||
|
|
@ -45,6 +45,12 @@
|
|||
<li class="form-viewers"></li>
|
||||
</ul>
|
||||
<ul class="list-unstyled sidebar-menu text-muted">
|
||||
<li class="liked-by-parent">
|
||||
<span class="liked-by">
|
||||
<i class="octicon octicon-heart like-action text-extra-muted"></i>
|
||||
<span class="like-count"></span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="modified-by"></li>
|
||||
<li class="created-by"></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ frappe.form.formatters = {
|
|||
|
||||
return frappe.form.formatters.Data(value);
|
||||
},
|
||||
StarredBy: function(value) {
|
||||
LikedBy: function(value) {
|
||||
var html = "";
|
||||
$.each(JSON.parse(value || "[]"), function(i, v) {
|
||||
if(v) html+= '<span class="avatar avatar-small" \
|
||||
|
|
@ -202,7 +202,7 @@ frappe.format = function(value, df, options, doc) {
|
|||
var formatted = formatter(value, df, options, doc);
|
||||
|
||||
if (typeof formatted == "string")
|
||||
formatted = frappe.utils.remove_script_and_style(formatted);
|
||||
formatted = frappe.dom.remove_script_and_style(formatted);
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -236,11 +236,12 @@ frappe.ui.form.Layout = Class.extend({
|
|||
grid_row = null;
|
||||
prev = null,
|
||||
fields = me.fields_list,
|
||||
in_grid = false;
|
||||
in_grid = false,
|
||||
focused = false;
|
||||
|
||||
// in grid
|
||||
if(doctype != me.doctype) {
|
||||
grid_row =me.get_open_grid_row()
|
||||
grid_row = me.get_open_grid_row();
|
||||
fields = grid_row.layout.fields_list;
|
||||
}
|
||||
|
||||
|
|
@ -254,38 +255,43 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
break;
|
||||
}
|
||||
if(i==len-1) {
|
||||
// last field in this group
|
||||
if(grid_row) {
|
||||
// in grid
|
||||
if(grid_row.doc.idx==grid_row.grid.grid_rows.length) {
|
||||
// last row, close it and find next field
|
||||
grid_row.toggle_view(false, function() {
|
||||
me.handle_tab(grid_row.grid.df.parent, grid_row.grid.df.fieldname);
|
||||
})
|
||||
} else {
|
||||
// next row
|
||||
grid_row.grid.grid_rows[grid_row.doc.idx].toggle_view(true);
|
||||
}
|
||||
} else {
|
||||
$(this.primary_button).focus();
|
||||
}
|
||||
} else {
|
||||
me.focus_on_next_field(i, fields);
|
||||
if(i < len-1) {
|
||||
focused = me.focus_on_next_field(i, fields);
|
||||
}
|
||||
|
||||
break;
|
||||
if (focused) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fields[i].disp_status==="Write")
|
||||
if(this.is_visible(fields[i]))
|
||||
prev = fields[i];
|
||||
}
|
||||
|
||||
if (!focused) {
|
||||
// last field in this group
|
||||
if(grid_row) {
|
||||
// in grid
|
||||
if(grid_row.doc.idx==grid_row.grid.grid_rows.length) {
|
||||
// last row, close it and find next field
|
||||
grid_row.toggle_view(false, function() {
|
||||
grid_row.grid.frm.layout.handle_tab(grid_row.grid.df.parent, grid_row.grid.df.fieldname);
|
||||
})
|
||||
} else {
|
||||
// next row
|
||||
grid_row.grid.grid_rows[grid_row.doc.idx].toggle_view(true);
|
||||
}
|
||||
} else {
|
||||
$(this.primary_button).focus();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
focus_on_next_field: function(start_idx, fields) {
|
||||
// loop to find next eligible fields
|
||||
for(var i= start_idx + 1, len = fields.length; i < len; i++) {
|
||||
var field = fields[i];
|
||||
if(field.disp_status==="Write") {
|
||||
if(this.is_visible(field)) {
|
||||
if(field.df.fieldtype==="Table") {
|
||||
// open table grid
|
||||
if(!(field.grid.grid_rows && field.grid.grid_rows.length)) {
|
||||
|
|
@ -294,14 +300,18 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
// show grid row (if exists)
|
||||
field.grid.grid_rows[0].show_form();
|
||||
return true;
|
||||
|
||||
} else if(!in_list(frappe.model.no_value_type, field.df.fieldtype)) {
|
||||
this.set_focus(field);
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
is_visible: function(field) {
|
||||
return field.disp_status==="Write" && (field.$wrapper && field.$wrapper.is(":visible"))
|
||||
},
|
||||
set_focus: function(field) {
|
||||
// next is table, show the table
|
||||
if(field.df.fieldtype=="Table") {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ frappe.ui.form.Sidebar = Class.extend({
|
|||
this.make_shared();
|
||||
this.make_viewers();
|
||||
this.make_tags();
|
||||
this.make_like();
|
||||
|
||||
this.bind_events();
|
||||
|
||||
|
|
@ -37,6 +38,12 @@ frappe.ui.form.Sidebar = Class.extend({
|
|||
$(".offcanvas").removeClass("active-left active-right");
|
||||
frappe.ui.scroll(me.frm.footer.wrapper.find(".form-comments"), true);
|
||||
});
|
||||
|
||||
this.like_icon.on("click", function() {
|
||||
frappe.ui.toggle_like(me.like_icon, me.frm.doctype, me.frm.doc.name, function() {
|
||||
me.refresh_like();
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
|
|
@ -55,6 +62,8 @@ frappe.ui.form.Sidebar = Class.extend({
|
|||
this.sidebar.find(".created-by").html(__("{0} created this {1}",
|
||||
["<strong>" + frappe.user.full_name(this.frm.doc.owner) + "</strong>",
|
||||
"<br>" + comment_when(this.frm.doc.creation)]));
|
||||
|
||||
this.refresh_like();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -113,4 +122,26 @@ frappe.ui.form.Sidebar = Class.extend({
|
|||
this.user_actions.addClass("hide")
|
||||
this.user_actions.find(".user-action-row").remove();
|
||||
},
|
||||
|
||||
make_like: function() {
|
||||
this.like_wrapper = this.sidebar.find(".liked-by");
|
||||
this.like_icon = this.sidebar.find(".liked-by .octicon-heart");
|
||||
this.like_count = this.sidebar.find(".liked-by .like-count");
|
||||
frappe.ui.setup_like_popover(this.sidebar.find(".liked-by-parent"), ".liked-by");
|
||||
},
|
||||
|
||||
refresh_like: function() {
|
||||
if (!this.like_icon) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.like_wrapper.attr("data-liked-by", this.frm.doc._liked_by);
|
||||
|
||||
this.like_icon.toggleClass("text-extra-muted not-liked",
|
||||
!frappe.ui.is_liked(this.frm.doc))
|
||||
.attr("data-doctype", this.frm.doctype)
|
||||
.attr("data-name", this.frm.doc.name);
|
||||
|
||||
this.like_count.text(JSON.parse(this.frm.doc._liked_by || "[]").length);
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ frappe.ui.form.Toolbar = Class.extend({
|
|||
this.page.clear_user_actions();
|
||||
this.show_title_as_dirty();
|
||||
this.set_primary_action();
|
||||
this.refresh_star();
|
||||
|
||||
if(this.frm.meta.hide_toolbar) {
|
||||
this.page.hide_menu();
|
||||
|
|
@ -23,26 +22,25 @@ frappe.ui.form.Toolbar = Class.extend({
|
|||
if(this.frm.doc.__islocal) {
|
||||
this.page.hide_menu();
|
||||
this.print_icon && this.print_icon.addClass("hide");
|
||||
this.star_icon && this.star_icon.addClass("hide");
|
||||
} else {
|
||||
this.page.show_menu();
|
||||
this.print_icon && this.print_icon.removeClass("hide");
|
||||
this.star_icon && this.star_icon.removeClass("hide");
|
||||
}
|
||||
}
|
||||
},
|
||||
set_title: function() {
|
||||
if(this.frm.meta.title_field) {
|
||||
var title = (this.frm.doc[this.frm.meta.title_field] || "").trim() || __(this.frm.docname);
|
||||
var title = (this.frm.doc[this.frm.meta.title_field] || "").trim() || this.frm.docname;
|
||||
if(this.frm.doc.__islocal || title === this.frm.docname || this.frm.meta.autoname==="hash") {
|
||||
this.page.set_title_sub("");
|
||||
} else {
|
||||
this.page.set_title_sub(this.frm.docname);
|
||||
}
|
||||
} else {
|
||||
var title = __(this.frm.docname);
|
||||
var title = this.frm.docname;
|
||||
}
|
||||
var me = this;
|
||||
title = __(title);
|
||||
this.page.set_title(title);
|
||||
if(this.frm.meta.title_field) {
|
||||
frappe.utils.set_title(title + " - " + this.frm.docname);
|
||||
|
|
@ -97,13 +95,6 @@ frappe.ui.form.Toolbar = Class.extend({
|
|||
this.page.clear_indicator();
|
||||
}
|
||||
},
|
||||
refresh_star: function() {
|
||||
this.star_icon &&
|
||||
this.star_icon.toggleClass("text-extra-muted not-starred",
|
||||
!frappe.ui.is_starred(this.frm.doc))
|
||||
.attr("data-doctype", this.frm.doctype)
|
||||
.attr("data-name", this.frm.doc.name);
|
||||
},
|
||||
make_menu: function() {
|
||||
var me = this;
|
||||
var p = this.frm.perm[0];
|
||||
|
|
@ -117,13 +108,6 @@ frappe.ui.form.Toolbar = Class.extend({
|
|||
me.frm.print_doc();});
|
||||
}
|
||||
|
||||
// star
|
||||
if(!this.frm.meta.issingle) {
|
||||
this.star_icon = this.page.add_action_icon("icon-star", function() {
|
||||
frappe.ui.toggle_star(me.star_icon, me.frm.doctype, me.frm.doc.name);
|
||||
}).removeClass("text-muted").find(".icon-star").addClass("star-action");
|
||||
}
|
||||
|
||||
// email
|
||||
if(frappe.model.can_email(null, me.frm) && me.frm.doc.docstatus < 2) {
|
||||
this.page.add_menu_item(__("Email"), function() {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
this.setup_filterable();
|
||||
this.init_filters();
|
||||
this.init_headers();
|
||||
this.init_star();
|
||||
this.init_like();
|
||||
this.init_select_all();
|
||||
},
|
||||
|
||||
|
|
@ -168,9 +168,9 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
}
|
||||
});
|
||||
this.$page.find(".result-list").on("click", ".list-row-left", function(e) {
|
||||
// don't open in case of checkbox, star, filterable
|
||||
// don't open in case of checkbox, like, filterable
|
||||
if ((e.target.className || "").indexOf("filterable")!==-1
|
||||
|| (e.target.className || "").indexOf("icon-star")!==-1
|
||||
|| (e.target.className || "").indexOf("octicon-heart")!==-1
|
||||
|| e.target.type==="checkbox") {
|
||||
return;
|
||||
}
|
||||
|
|
@ -307,8 +307,8 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
}
|
||||
}
|
||||
|
||||
this.list_header.find(".list-starred-by-me")
|
||||
.toggleClass("text-extra-muted not-starred", !this.is_star_filtered());
|
||||
this.list_header.find(".list-liked-by-me")
|
||||
.toggleClass("text-extra-muted not-liked", !this.is_star_filtered());
|
||||
|
||||
this.last_updated_on = new Date();
|
||||
this.dirty = false;
|
||||
|
|
@ -355,6 +355,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
filters: this.filter_list.get_filters(),
|
||||
order_by: this.listview.order_by || undefined,
|
||||
group_by: this.listview.group_by || undefined,
|
||||
with_comment_count: true
|
||||
}
|
||||
|
||||
// apply default filters, if specified for a listing
|
||||
|
|
@ -368,15 +369,15 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
this.filter_list.add_filter(this.doctype, "_assign", 'like', '%' + user + '%');
|
||||
this.run();
|
||||
},
|
||||
starred_by_me: function() {
|
||||
this.filter_list.add_filter(this.doctype, "_starred_by", 'like', '%' + user + '%');
|
||||
liked_by_me: function() {
|
||||
this.filter_list.add_filter(this.doctype, "_liked_by", 'like', '%' + user + '%');
|
||||
this.run();
|
||||
},
|
||||
remove_starred_by_me: function() {
|
||||
this.filter_list.get_filter("_starred_by").remove();
|
||||
remove_liked_by_me: function() {
|
||||
this.filter_list.get_filter("_liked_by").remove();
|
||||
},
|
||||
is_star_filtered: function() {
|
||||
return this.filter_list.filter_exists(this.doctype, "_starred_by", 'like', '%' + user + '%');
|
||||
return this.filter_list.filter_exists(this.doctype, "_liked_by", 'like', '%' + user + '%');
|
||||
},
|
||||
init_menu: function() {
|
||||
var me = this;
|
||||
|
|
@ -453,19 +454,20 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
}, true)
|
||||
},
|
||||
|
||||
init_star: function() {
|
||||
init_like: function() {
|
||||
var me = this;
|
||||
this.$page.find(".result-list").on("click", ".star-action", function() {
|
||||
frappe.ui.toggle_star($(this), me.doctype, $(this).attr("data-name"));
|
||||
return false;
|
||||
});
|
||||
this.list_header.find(".list-starred-by-me").on("click", function() {
|
||||
this.$page.find(".result-list").on("click", ".like-action", frappe.ui.click_toggle_like);
|
||||
this.list_header.find(".list-liked-by-me").on("click", function() {
|
||||
if (me.is_star_filtered()) {
|
||||
me.remove_starred_by_me();
|
||||
me.remove_liked_by_me();
|
||||
} else {
|
||||
me.starred_by_me();
|
||||
me.liked_by_me();
|
||||
}
|
||||
});
|
||||
|
||||
if (!frappe.dom.is_touchscreen()) {
|
||||
frappe.ui.setup_like_popover(this.$page.find(".result-list"), ".liked-by");
|
||||
}
|
||||
},
|
||||
|
||||
init_select_all: function() {
|
||||
|
|
@ -576,7 +578,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
return false;
|
||||
} else {
|
||||
// second filter set for this field
|
||||
if(fieldname=='_user_tags' || fieldname=="_starred_by") {
|
||||
if(fieldname=='_user_tags' || fieldname=="_liked_by") {
|
||||
// and for tags
|
||||
this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label);
|
||||
} else {
|
||||
|
|
@ -587,7 +589,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
|
|||
} else {
|
||||
// no filter for this item,
|
||||
// setup one
|
||||
if(fieldname=='_user_tags' || fieldname=="_starred_by") {
|
||||
if(fieldname=='_user_tags' || fieldname=="_liked_by") {
|
||||
this.filter_list.add_filter(this.doctype, fieldname, 'like', '%' + label);
|
||||
} else {
|
||||
this.filter_list.add_filter(this.doctype, fieldname, '=', label);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
{% } %}
|
||||
{% } else if(col.fieldtype==="Select") { %}
|
||||
<span class="filterable indicator {%= frappe.utils.guess_colour(value) %}"
|
||||
data-filter="{%= col.fieldname %},=,{%= value %}">{%= value %}</span>
|
||||
data-filter="{%= col.fieldname %},=,{%= value %}">{%= __(value) %}</span>
|
||||
{% } else if(col.fieldtype==="Link") { %}
|
||||
<a class="filterable h6 text-muted grey"
|
||||
data-filter="{%= col.fieldname %},=,{%= value %}">{%= value %}</a>
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@
|
|||
title="{%= __("Select All") %}">
|
||||
{% } %}
|
||||
|
||||
<i class="icon-fixed-width icon-star text-extra-muted not-starred star-action list-starred-by-me"
|
||||
title="{%= __("Starred By Me") %}"></i>
|
||||
<i class="icon-fixed-width octicon octicon-heart text-extra-muted not-liked like-action list-liked-by-me"
|
||||
title="{%= __("Likes") %}"></i>
|
||||
|
||||
{% } %}
|
||||
|
||||
<span class="list-value">{%= col.title || col.label || "" %}</span>
|
||||
<span class="list-value">{%= __(col.title) || __(col.label) || "" %}</span>
|
||||
</div>
|
||||
{% } %}
|
||||
{% } %}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,12 @@
|
|||
|
||||
<!-- comment -->
|
||||
<div class="list-col col-sm-2 col-xs-2
|
||||
text-right list-row-right">
|
||||
<div class="visible-xs pull-right list-row-indicator">{%= list.get_indicator_dot(data) %}</div>
|
||||
<div class="hidden-xs pull-right">
|
||||
text-right list-row-right" style="padding-left:0px">
|
||||
<div class="visible-xs list-row-indicator">{%= list.get_indicator_dot(data) %}</div>
|
||||
<div class="hidden-xs">
|
||||
<span class="list-row-modified text-muted">
|
||||
{%= comment_when(data.modified, true) %}
|
||||
</span>
|
||||
{% if (data._assign_list.length) { %}
|
||||
<span class="filterable"
|
||||
data-filter="_assign,like,%{%= data._assign_list[data._assign_list.length - 1] %}%">
|
||||
|
|
@ -33,14 +36,11 @@
|
|||
{% } else { %}
|
||||
<span class="avatar avatar-small avatar-empty"></span>
|
||||
{% } %}
|
||||
<span class="h6 {% if(!data._comments_list.length) { %}text-extra-muted{% } %}">
|
||||
<span class="list-comment-count small
|
||||
{% if(!data._comment_count) { %} text-extra-muted {% } else { %} text-muted {% } %}">
|
||||
<i class="octicon octicon-comment-discussion"></i>
|
||||
{%= data._comments_list.length || 0 %}
|
||||
{%= (data._comment_count > 99 ? "99+" : data._comment_count) || 0 %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="pull-right list-row-modified">
|
||||
<span class="text-muted">
|
||||
{%= comment_when(data.modified, true) %}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@
|
|||
<input class="list-delete" type="checkbox"
|
||||
style="margin: 0 7px 0 0; vertical-align: middle;">
|
||||
{% } %}
|
||||
<i class="icon-star
|
||||
{% if (_starred_by.indexOf(_user)===-1) { %}
|
||||
text-extra-muted not-starred
|
||||
{% }%}
|
||||
icon-fixed-width star-action"
|
||||
data-name="{{ _name }}" data-doctype="{{ doctype }}">
|
||||
</i>
|
||||
<span class="liked-by" data-liked-by=\'{{ JSON.stringify(_liked_by) }}\'>
|
||||
<i class="octicon octicon-heart
|
||||
{% if (_liked_by.indexOf(_user)===-1) { %}
|
||||
text-extra-muted not-liked
|
||||
{% }%}
|
||||
icon-fixed-width like-action"
|
||||
data-name="{{ _name }}" data-doctype="{{ doctype }}">
|
||||
</i>
|
||||
<span class="likes-count">{{ (_liked_by.length > 9 ? "9+" : _liked_by.length) || "" }}</span>
|
||||
</span>
|
||||
<a class="grey list-id"
|
||||
style="margin-right: 7px;"
|
||||
href="#Form/{{ _doctype_encoded }}/{{ _name_encoded }}"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ frappe.views.ListView = Class.extend({
|
|||
}
|
||||
|
||||
$.each(['name', 'owner', 'docstatus', '_user_tags', '_comments', 'modified',
|
||||
'modified_by', '_assign', '_starred_by'],
|
||||
'modified_by', '_assign', '_liked_by'],
|
||||
function(i, fieldname) { add_field(fieldname); })
|
||||
|
||||
// add title field
|
||||
|
|
@ -266,7 +266,7 @@ frappe.views.ListView = Class.extend({
|
|||
var indicator = frappe.get_indicator(doc, this.doctype);
|
||||
if(indicator) {
|
||||
return '<span class="indicator '+indicator[1]+' filterable" data-filter="'
|
||||
+indicator[2]+'">'+indicator[0]+'<span>';
|
||||
+indicator[2]+'">'+__(indicator[0])+'<span>';
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -277,15 +277,15 @@ frappe.views.ListView = Class.extend({
|
|||
if (!indicator) {
|
||||
return "";
|
||||
}
|
||||
return '<span class="indicator '+indicator[1]+'" title="'+indicator[0]+'"></span>';
|
||||
return '<span class="indicator '+indicator[1]+'" title="'+__(indicator[0])+'"></span>';
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
if(data.modified)
|
||||
this.prepare_when(data, data.modified);
|
||||
|
||||
data._starred_by = data._starred_by ?
|
||||
JSON.parse(data._starred_by) : [];
|
||||
data._liked_by = data._liked_by ?
|
||||
JSON.parse(data._liked_by) : [];
|
||||
|
||||
data._checkbox = (frappe.model.can_delete(this.doctype) || this.settings.selectable) && !this.no_delete
|
||||
|
||||
|
|
@ -311,7 +311,6 @@ frappe.views.ListView = Class.extend({
|
|||
}
|
||||
data._user = user;
|
||||
|
||||
data._comments_list = data._comments ? JSON.parse(data._comments) : [];
|
||||
data._tags = $.map((data._user_tags || "").split(","),
|
||||
function(v) { return v ? v : null; });
|
||||
data._assign_list = data._assign ? JSON.parse(data._assign) : [];
|
||||
|
|
|
|||
|
|
@ -50,18 +50,6 @@ frappe.utils = {
|
|||
return txt.toLowerCase().substr(0,7)=='http://'
|
||||
|| txt.toLowerCase().substr(0,8)=='https://'
|
||||
},
|
||||
remove_script_and_style: function(txt) {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML = txt;
|
||||
["script", "style", "noscript", "title", "meta", "base", "head"].forEach(function(e, i) {
|
||||
var elements = div.getElementsByTagName(e);
|
||||
var i = elements.length;
|
||||
while (i--) {
|
||||
elements[i].parentNode.removeChild(elements[i]);
|
||||
}
|
||||
});
|
||||
return div.innerHTML;
|
||||
},
|
||||
toggle_blockquote: function(txt) {
|
||||
if (!txt) return txt;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue