Merge branch 'staging' into develop
This commit is contained in:
commit
2de5dfdbb3
18 changed files with 146 additions and 57 deletions
|
|
@ -39,7 +39,7 @@ def get_message_urls(content):
|
|||
urls.append(text)
|
||||
|
||||
return urls
|
||||
|
||||
|
||||
def get_message_mentions(content):
|
||||
mentions = [ ]
|
||||
tokens = content.split(' ')
|
||||
|
|
@ -68,12 +68,12 @@ def get_message_meta(content):
|
|||
meta.content = content
|
||||
meta.urls = get_message_urls(content)
|
||||
meta.mentions = get_message_mentions(content)
|
||||
|
||||
|
||||
return meta
|
||||
|
||||
def sanitize_message_content(content):
|
||||
emojis = get_emojis()
|
||||
|
||||
|
||||
tokens = content.split(' ')
|
||||
for token in tokens:
|
||||
if token.startswith(':') and token.endswith(':'):
|
||||
|
|
@ -131,7 +131,7 @@ def get_new_chat_message(user, room, content, type = "Content"):
|
|||
@frappe.whitelist(allow_guest = True)
|
||||
def send(user, room, content, type = "Content"):
|
||||
mess = get_new_chat_message(user, room, content, type)
|
||||
|
||||
|
||||
frappe.publish_realtime('frappe.chat.message:create', mess, room = room,
|
||||
after_commit = True)
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ def seen(message, user = None):
|
|||
|
||||
room = mess.room
|
||||
resp = dict(message = message, data = dict(seen = json.loads(mess._seen)))
|
||||
|
||||
|
||||
frappe.publish_realtime('frappe.chat.message:update', resp, room = room, after_commit = True)
|
||||
|
||||
def history(room, fields = None, limit = 10, start = None, end = None):
|
||||
|
|
@ -159,7 +159,7 @@ def history(room, fields = None, limit = 10, start = None, end = None):
|
|||
],
|
||||
order_by = 'creation'
|
||||
)
|
||||
|
||||
|
||||
if not fields or 'seen' in fields:
|
||||
for m in mess:
|
||||
m['seen'] = json.loads(m._seen) if m._seen else [ ]
|
||||
|
|
@ -168,8 +168,26 @@ def history(room, fields = None, limit = 10, start = None, end = None):
|
|||
for m in mess:
|
||||
m['content'] = json.loads(m.content) if m.type in ["File"] else m.content
|
||||
|
||||
frappe.enqueue('frappe.chat.doctype.chat_message.chat_message.mark_messages_as_seen',
|
||||
message_names=[m.name for m in mess], user=frappe.session.user)
|
||||
|
||||
return mess
|
||||
|
||||
def mark_messages_as_seen(message_names, user):
|
||||
'''
|
||||
Marks chat messages as seen, updates the _seen for each message
|
||||
(should be run in background process)
|
||||
'''
|
||||
for name in message_names:
|
||||
seen = frappe.db.get_value('Chat Message', name, '_seen') or '[]'
|
||||
seen = json.loads(seen)
|
||||
seen.append(user)
|
||||
seen = json.dumps(seen)
|
||||
frappe.db.set_value('Chat Message', name, '_seen', seen, update_modified=False)
|
||||
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get(name, rooms = None, fields = None):
|
||||
rooms, fields = safe_json_loads(rooms, fields)
|
||||
|
|
|
|||
|
|
@ -53,3 +53,18 @@ class TestReport(unittest.TestCase):
|
|||
report = frappe.get_doc('Report', 'Test Report')
|
||||
|
||||
self.assertNotEquals(report.is_permitted(), True)
|
||||
|
||||
# test for the `_format` method if report data doesn't have sort_by parameter
|
||||
def test_format_method(self):
|
||||
if frappe.db.exists('Report', 'User Activity Report Without Sort'):
|
||||
frappe.delete_doc('Report', 'User Activity Report Without Sort')
|
||||
with open(os.path.join(os.path.dirname(__file__), 'user_activity_report_without_sort.json'), 'r') as f:
|
||||
frappe.get_doc(json.loads(f.read())).insert()
|
||||
|
||||
report = frappe.get_doc('Report', 'User Activity Report Without Sort')
|
||||
# this would raise an error without the fix added along with this test case
|
||||
columns, data = report.get_data()
|
||||
self.assertEqual(columns[0].get('label'), 'ID')
|
||||
self.assertEqual(columns[1].get('label'), 'User Type')
|
||||
self.assertTrue('Administrator' in [d[0] for d in data])
|
||||
frappe.delete_doc('Report', 'User Activity Report Without Sort')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"is_standard": "No",
|
||||
"javascript": null,
|
||||
"json": "{\"filters\":[],\"columns\":[[\"name\",\"User\"],[\"user_type\",\"User\"],[\"first_name\",\"User\"],[\"last_name\",\"User\"],[\"last_active\",\"User\"],[\"role\",\"Has Role\"]],\"sort_order\":\"desc\",\"sort_by_next\":null,\"sort_order_next\":\"desc\"}",
|
||||
"modified": "2018-12-17 18:27:07.728890",
|
||||
"module": "Core",
|
||||
"name": "User Activity Report Without Sort",
|
||||
"query": null,
|
||||
"ref_doctype": "User",
|
||||
"report_name": "User Activity Report Without Sort",
|
||||
"report_type": "Report Builder"
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ def get_notifications():
|
|||
notification_count[name] = count
|
||||
|
||||
return {
|
||||
"open_count_doctype": {},
|
||||
"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),
|
||||
"targets": get_notifications_for_targets(config, notification_percent),
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ def add_total_row(result, columns, meta = None):
|
|||
|
||||
|
||||
if fieldtype=="Link" and options == "Currency":
|
||||
total_row[i] = result[0][i]
|
||||
total_row[i] = result[0].get(fieldname) if isinstance(result[0], dict) else result[0][i]
|
||||
|
||||
for i in has_percent:
|
||||
total_row[i] = flt(total_row[i]) / len(result)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ source_link = "https://github.com/frappe/frappe"
|
|||
app_license = "MIT"
|
||||
|
||||
develop_version = '12.x.x-develop'
|
||||
staging_version = '11.0.3-beta.37'
|
||||
staging_version = '11.0.3-beta.38'
|
||||
|
||||
app_email = "info@frappe.io"
|
||||
|
||||
|
|
|
|||
|
|
@ -233,3 +233,4 @@ frappe.patches.v11_0.set_allow_self_approval_in_workflow
|
|||
execute:frappe.db.sql('ALTER table `tabSeries` ADD PRIMARY KEY IF NOT EXISTS (name)')
|
||||
frappe.patches.v11_0.migrate_report_settings_for_new_listview
|
||||
frappe.patches.v11_0.delete_all_prepared_reports
|
||||
frappe.patches.v11_0.fix_order_by_in_reports_json
|
||||
|
|
|
|||
22
frappe/patches/v11_0/fix_order_by_in_reports_json.py
Normal file
22
frappe/patches/v11_0/fix_order_by_in_reports_json.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import frappe, json
|
||||
|
||||
def execute():
|
||||
reports_data = frappe.get_all('Report',
|
||||
filters={'json': ['not like', '%%%"order_by": "`tab%%%'],
|
||||
'report_type': 'Report Builder', 'is_standard': 'No'}, fields=['name'])
|
||||
|
||||
for d in reports_data:
|
||||
doc = frappe.get_doc('Report', d.get('name'))
|
||||
json_data = json.loads(doc.get('json'))
|
||||
|
||||
parts = []
|
||||
if ('order_by' in json_data) and ('.' in json_data.get('order_by')):
|
||||
parts = json_data.get('order_by').split('.')
|
||||
|
||||
sort_by = parts[1].split(' ')
|
||||
|
||||
json_data['order_by'] = '`tab{0}`.`{1}`'.format(doc.ref_doctype, sort_by[0])
|
||||
json_data['order_by'] += ' {0}'.format(sort_by[1]) if len(sort_by) > 1 else ''
|
||||
|
||||
doc.json = json.dumps(json_data)
|
||||
doc.save()
|
||||
|
|
@ -1984,18 +1984,27 @@ class extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
if ( props.last_message )
|
||||
let is_unread = false
|
||||
if ( props.last_message ) {
|
||||
item.timestamp = frappe.chat.pretty_datetime(props.last_message.creation)
|
||||
is_unread = !props.last_message.seen.includes(frappe.session.user)
|
||||
}
|
||||
|
||||
return (
|
||||
h("li", null,
|
||||
h("a", { class: props.active ? "active": "", onclick: () => props.click(props) },
|
||||
h("a", { class: props.active ? "active": "", onclick: () => {
|
||||
props.last_message.seen.push(frappe.session.user)
|
||||
props.click(props)
|
||||
} },
|
||||
h("div", { class: "row" },
|
||||
h("div", { class: "col-xs-9" },
|
||||
h(frappe.Chat.Widget.MediaProfile, { ...item })
|
||||
),
|
||||
h("div", { class: "col-xs-3 text-right" },
|
||||
h("div", { class: "text-muted", style: { "font-size": "9px" } }, item.timestamp)
|
||||
[
|
||||
h("div", { class: "text-muted", style: { "font-size": "9px" } }, item.timestamp),
|
||||
is_unread ? h("span", { class: "indicator red" }) : null
|
||||
]
|
||||
),
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -974,16 +974,16 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
|
||||
|
||||
toggle_nothing_to_show(flag) {
|
||||
let message = __('Nothing to show');
|
||||
if(this.prepared_report) {
|
||||
message = __(`This is a background report.
|
||||
Please set the appropriate filters and then generate a new one.`);
|
||||
}
|
||||
let message = this.prepared_report
|
||||
? __('This is a background report. Please set the appropriate filters and then generate a new one.')
|
||||
: __('Nothing to show')
|
||||
|
||||
this.toggle_message(flag, message);
|
||||
if(flag){
|
||||
|
||||
if (flag && this.prepared_report) {
|
||||
this.prepared_report_action = "New";
|
||||
this.add_prepared_report_buttons();
|
||||
}
|
||||
this.add_prepared_report_buttons();
|
||||
}
|
||||
|
||||
toggle_message(flag, message) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
// http://codeguide.co - @mdo (Author of Bootstrap)
|
||||
|
||||
@import "common.less";
|
||||
@import "flex.less";
|
||||
@import {reference} "common.less";
|
||||
|
||||
// Typography
|
||||
@font-weight-bold: 700;
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
margin: @fab-margin;
|
||||
width: @fab-size;
|
||||
height: @fab-size;
|
||||
|
||||
|
||||
&.frappe-fab-lg
|
||||
{
|
||||
width: @fab-size-lg;
|
||||
|
|
@ -80,10 +80,10 @@
|
|||
{
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
right: 0px;
|
||||
margin: @chat-popper-margin;
|
||||
z-index: @chat-popper-z-index;
|
||||
|
||||
|
||||
& > .frappe-chat-popper-collapse
|
||||
{
|
||||
& > .panel
|
||||
|
|
@ -175,7 +175,7 @@
|
|||
right: 0px;
|
||||
overflow: auto;
|
||||
border-radius: 0px;
|
||||
|
||||
|
||||
.panel-heading
|
||||
{
|
||||
border-radius: 0px;
|
||||
|
|
@ -194,19 +194,19 @@
|
|||
{
|
||||
font-size: @chat-form-font-size;
|
||||
}
|
||||
|
||||
|
||||
.dropdown-menu
|
||||
{
|
||||
border-radius: @chat-form-menu-border-radius;
|
||||
}
|
||||
|
||||
|
||||
// Hints
|
||||
.hint-list.list-group
|
||||
{
|
||||
margin: 0px;
|
||||
max-height: @chat-form-list-group-height;
|
||||
overflow-y: auto;
|
||||
|
||||
|
||||
.hint-list-item.list-group-item:first-child, .hint-list-item.list-group-item:last-child
|
||||
{
|
||||
border-radius: 0px !important;
|
||||
|
|
@ -269,7 +269,7 @@
|
|||
{
|
||||
margin-right: @chat-base-spacing;
|
||||
}
|
||||
|
||||
|
||||
.avatar
|
||||
{
|
||||
width: 32px; height: 32px;
|
||||
|
|
@ -285,7 +285,7 @@
|
|||
.chat-form
|
||||
{
|
||||
border-top: @chat-form-border;
|
||||
|
||||
|
||||
.input-group-btn
|
||||
{
|
||||
.btn
|
||||
|
|
@ -294,7 +294,7 @@
|
|||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.form-control
|
||||
{
|
||||
line-height: 27px; // HACK: Makes input and placeholder centered within textarea. Also takes care of the input-btn
|
||||
|
|
@ -305,7 +305,7 @@
|
|||
padding-right: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
.fa
|
||||
{
|
||||
font-size: @chat-base-font-size-lg;
|
||||
|
|
@ -317,7 +317,7 @@
|
|||
|
||||
.chat-list
|
||||
{
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
// background: @chat-list-bg-color;
|
||||
overflow-y: scroll;
|
||||
|
||||
|
|
@ -334,22 +334,22 @@
|
|||
}
|
||||
|
||||
.cursor-pointer;
|
||||
|
||||
|
||||
border: none !important;
|
||||
padding: @chat-list-item-padding;
|
||||
background: transparent;
|
||||
|
||||
|
||||
.chat-bubble
|
||||
{
|
||||
max-width: @chat-bubble-max-width;
|
||||
display: inline-block;
|
||||
padding: @chat-bubble-padding;
|
||||
border-radius: @chat-bubble-border-radius;
|
||||
|
||||
|
||||
-webkit-box-shadow: @chat-bubble-box-shadow;
|
||||
-moz-box-shadow: @chat-bubble-box-shadow;
|
||||
box-shadow: @chat-bubble-box-shadow;
|
||||
|
||||
|
||||
@media (max-width : 768px) {
|
||||
min-width: @chat-bubble-min-width;
|
||||
}
|
||||
|
|
@ -372,7 +372,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.chat-bubble-r
|
||||
{
|
||||
text-align: right;
|
||||
|
|
@ -386,33 +386,33 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chat-bubble-author
|
||||
{
|
||||
font-size: @chat-bubble-author-font-size;
|
||||
|
||||
|
||||
a
|
||||
{
|
||||
.font-bold;
|
||||
|
||||
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chat-bubble-content
|
||||
{
|
||||
margin-bottom: @chat-bubble-content-margin-bottom;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
|
||||
.chat-bubble-meta
|
||||
{
|
||||
font-size: @chat-bubble-meta-font-size;
|
||||
|
||||
|
||||
& > .chat-bubble-check
|
||||
{
|
||||
margin-left: @chat-base-spacing;
|
||||
|
||||
|
||||
i
|
||||
{
|
||||
font-size: @chat-bubble-check-font-size;
|
||||
|
|
@ -439,4 +439,4 @@
|
|||
font-size: 10px;
|
||||
padding: 5px;
|
||||
// background-color: white;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ frappe.ready(function() {
|
|||
pathname: location.pathname,
|
||||
});
|
||||
data.web_form_name = frappe.web_form_name;
|
||||
data.pathname = location.pathname;
|
||||
btn.prop("disabled", true);
|
||||
return $.ajax({
|
||||
url:"/api/method/frappe.www.list.get",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
{%- if metatags -%}
|
||||
{%- for name in metatags %}
|
||||
<meta {% if name == 'og:title' or name == "og:image" or name == "og:type" or name == "og:description" %} property="{{ name }}" {% else %} name="{{ name }}" {% endif %} content="{{ metatags[name]|striptags|escape }}" data-html-block="meta_block">
|
||||
<meta {% if name == 'og:title' or name == "og:image" or name == "og:type" or name == "og:description" %} property="{{ name }}" {% else %} name="{{ name }}" {% endif %} content="{{ metatags[name]|striptags|escape }}">
|
||||
{%- endfor -%}
|
||||
<meta property="og:url" content="{{ frappe.utils.get_url(path) }}">
|
||||
<meta itemprop="datePublished" content="{{ frappe.format_date(published_on) }}">
|
||||
<meta itemprop="author" content="{{ blogger }}">
|
||||
<meta itemprop="name" content="{{ name }}" data-html-block="meta_block">
|
||||
<meta itemprop="description" content="{{ description }}" data-html-block="meta_block">
|
||||
<meta itemprop="image" content="{{ frappe.utils.get_url(metatags["image"]) }}" data-html-block="meta_block">
|
||||
<meta itemprop="name" content="{{ name }}">
|
||||
<meta itemprop="description" content="{{ description }}">
|
||||
<meta itemprop="image" content="{{ frappe.utils.get_url(metatags["image"]) }}">
|
||||
{%- endif -%}
|
||||
|
|
|
|||
|
|
@ -824,7 +824,8 @@ def get_filter(doctype, f):
|
|||
|
||||
if len(f) == 3:
|
||||
f = (doctype, f[0], f[1], f[2])
|
||||
|
||||
elif len(f) > 4:
|
||||
f = f[0:4]
|
||||
elif len(f) != 4:
|
||||
frappe.throw(frappe._("Filter must have 4 values (doctype, fieldname, operator, value): {0}").format(str(f)))
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
{%- block header -%} {{ header or "" }} {%- endblock -%}
|
||||
|
||||
{% block meta_block %}
|
||||
{% include "templates/includes/meta_block.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block hero %}{{ hero or "" }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ def get_context(context, **dict_params):
|
|||
context.update(get(**frappe.local.form_dict))
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def get(doctype, txt=None, limit_start=0, limit=20, **kwargs):
|
||||
def get(doctype, txt=None, limit_start=0, limit=20, pathname=None, **kwargs):
|
||||
"""Returns processed HTML page for a standard listing."""
|
||||
limit_start = cint(limit_start)
|
||||
raw_result = get_list_data(doctype, txt, limit_start, limit=limit + 1, **kwargs)
|
||||
|
|
@ -54,7 +54,8 @@ def get(doctype, txt=None, limit_start=0, limit=20, **kwargs):
|
|||
new_context.update(new_context.doc.as_dict())
|
||||
|
||||
if not frappe.flags.in_test:
|
||||
new_context["pathname"] = frappe.local.request.path.strip("/ ")
|
||||
pathname = pathname or frappe.local.request.path
|
||||
new_context["pathname"] = pathname.strip("/ ")
|
||||
new_context.update(list_context)
|
||||
set_route(new_context)
|
||||
rendered_row = frappe.render_template(row_template, new_context, is_path=True)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
"awesomplete": "^1.1.2",
|
||||
"cookie": "^0.3.1",
|
||||
"express": "^4.16.2",
|
||||
"frappe-datatable": "^1.7.0",
|
||||
"frappe-datatable": "^1.7.1",
|
||||
"frappe-gantt": "^0.1.0",
|
||||
"fuse.js": "^3.2.0",
|
||||
"highlight.js": "^9.12.0",
|
||||
|
|
|
|||
|
|
@ -1517,10 +1517,10 @@ forwarded@~0.1.2:
|
|||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
|
||||
|
||||
frappe-datatable@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.7.0.tgz#6cc950a69bdfd514fb61ab25b85fa68c3b33aee0"
|
||||
integrity sha512-CcCIf36eJMqzobc4rMT75zCCFKjfghJAR9rXiAP6h2uWdDKhb0U+rDjiFPweS54lv19tpTYF7Q/1SSx0Ih+Mfg==
|
||||
frappe-datatable@^1.7.1:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.7.1.tgz#5badb1138c7019e9dce50d6cbbd81c2fdc97e391"
|
||||
integrity sha512-ePD4IDaLDCZCrchqT+TsPquOdnm72oYxh/KYMPfYBxUGSzWUoi2uRgzQD4MBR+uq1WxJhFQNoXe/fD3yOqNNUQ==
|
||||
dependencies:
|
||||
hyperlist "^1.0.0-beta"
|
||||
lodash "^4.17.5"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue