Merge branch 'develop' of https://github.com/frappe/frappe into auto-generate-rtl-style

This commit is contained in:
Suraj Shetty 2021-07-05 12:04:04 +05:30
commit 3d3d8bdfca
25 changed files with 97 additions and 73 deletions

View file

@ -105,3 +105,5 @@ jobs:
- name: UI Tests
run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests frappe --headless --parallel --ci-build-id $GITHUB_RUN_ID
env:
CYPRESS_RECORD_KEY: 4a48f41c-11b3-425b-aa88-c58048fa69eb

View file

@ -4,13 +4,10 @@
# the repo. Unless a later match takes precedence,
* @frappe/frappe-review-team
website/ @prssanna
web_form/ @prssanna
templates/ @surajshetty3416
www/ @surajshetty3416
integrations/ @leela
patches/ @surajshetty3416
dashboard/ @prssanna
email/ @leela
event_streaming/ @ruchamahabal
data_import* @netchampfaris

View file

@ -661,7 +661,7 @@ def run_ui_tests(context, app, headless=False, parallel=True, ci_build_id=None):
frappe.commands.popen("yarn add cypress@^6 cypress-file-upload@^5 --no-lockfile")
# run for headless mode
run_or_open = 'run --browser firefox --record --key 4a48f41c-11b3-425b-aa88-c58048fa69eb' if headless else 'open'
run_or_open = 'run --browser firefox --record' if headless else 'open'
command = '{site_env} {password_env} {cypress} {run_or_open}'
formatted_command = command.format(site_env=site_env, password_env=password_env, cypress=cypress_path, run_or_open=run_or_open)
@ -770,19 +770,23 @@ def set_config(context, key, value, global_=False, parse=False, as_dict=False):
@click.command('version')
def get_version():
"Show the versions of all the installed apps"
from git import Repo
from frappe.utils.change_log import get_app_branch
frappe.init('')
for m in sorted(frappe.get_all_apps()):
branch_name = get_app_branch(m)
module = frappe.get_module(m)
app_hooks = frappe.get_module(m + ".hooks")
for app in sorted(frappe.get_all_apps()):
branch_name = get_app_branch(app)
module = frappe.get_module(app)
app_hooks = frappe.get_module(app + ".hooks")
repo = Repo(frappe.get_app_path(app, ".."))
branch = repo.head.ref.name
commit = repo.head.ref.commit.hexsha[:7]
if hasattr(app_hooks, '{0}_version'.format(branch_name)):
print("{0} {1}".format(m, getattr(app_hooks, '{0}_version'.format(branch_name))))
click.echo("{0} {1} {2} ({3})".format(app, getattr(app_hooks, '{0}_version'.format(branch_name)), branch, commit))
elif hasattr(module, "__version__"):
print("{0} {1}".format(m, module.__version__))
click.echo("{0} {1} {2} ({3})".format(app, module.__version__, branch, commit))
@click.command('rebuild-global-search')

View file

@ -85,8 +85,6 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
if attachments:
add_attachments(comm.name, attachments)
frappe.db.commit()
if cint(send_email):
if not comm.get_outgoing_email_account():
frappe.throw(msg=OUTGOING_EMAIL_ACCOUNT_MISSING, exc=frappe.OutgoingEmailError)

View file

@ -368,6 +368,7 @@ def get_desktop_page(page):
'allow_customization': not wspace.doc.disable_user_customization
}
except DoesNotExistError:
frappe.log_error(frappe.get_traceback())
return {}
@frappe.whitelist()

View file

@ -43,19 +43,19 @@ class Workspace(Document):
def get_link_groups(self):
cards = []
current_card = {
current_card = frappe._dict({
"label": "Link",
"type": "Card Break",
"icon": None,
"hidden": False,
}
})
card_links = []
for link in self.links:
link = link.as_dict()
if link.type == "Card Break":
if card_links and (not current_card.only_for or current_card.only_for == frappe.get_system_settings('country')):
if card_links and (not current_card.only_for or current_card.only_for == frappe.get_system_settings('country')):
current_card['links'] = card_links
cards.append(current_card)

View file

@ -83,11 +83,15 @@ class BaseDocument(object):
@property
def meta(self):
if not hasattr(self, "_meta"):
if not getattr(self, "_meta", None):
self._meta = frappe.get_meta(self.doctype)
return self._meta
def __getstate__(self):
self._meta = None
return self.__dict__
def update(self, d):
""" Update multiple fields of a doctype using a dictionary of key-value pairs.

View file

@ -11,7 +11,7 @@ frappe.ui.form.Attachments = class Attachments {
this.parent.find(".add-attachment-btn").click(function() {
me.new_attachment();
});
this.add_attachment_wrapper = this.parent.find(".add_attachment").parent();
this.add_attachment_wrapper = this.parent.find(".add-attachment-btn");
this.attachments_label = this.parent.find(".attachments-label");
}
max_reached(raise_exception=false) {
@ -39,7 +39,7 @@ frappe.ui.form.Attachments = class Attachments {
this.parent.find(".attachment-row").remove();
var max_reached = this.max_reached();
this.add_attachment_wrapper.toggleClass("hide", !max_reached);
this.add_attachment_wrapper.toggle(!max_reached);
// add attachment objects
var attachments = this.get_attachments();

View file

@ -5,7 +5,7 @@
{% } %}
<div class="col-md-4">
<div class="form-link-title">
<span>{{ transactions[i].label }}<span>
<span>{{ __(transactions[i].label) }}<span>
</div>
{% for (let j=0; j < transactions[i].items.length; j++) { %}
{% let doctype = transactions[i].items[j]; %}

View file

@ -5,7 +5,7 @@
{% } %}
<div class="col-md-4">
<div class="form-link-title">
<span>{{ reports[i].label }}</span>
<span>{{ __(reports[i].label) }}</span>
</div>
{% for (let j=0; j < reports[i].items.length; j++) { %}
{% let report = reports[i].items[j]; %}

View file

@ -728,7 +728,7 @@ frappe.views.CommunicationComposer = class {
const SALUTATION_END_COMMENT = "<!-- salutation-ends -->";
if (this.real_name && !message.includes(SALUTATION_END_COMMENT)) {
this.message = `
<p>${__('Dear')} ${this.real_name},</p>
<p>${__('Dear {0},', [this.real_name], 'Salutation in new email')},</p>
${SALUTATION_END_COMMENT}<br>
${message}
`;

View file

@ -64,6 +64,7 @@ export default class LinksWidget extends Widget {
const opts = {
name: item.link_to,
type: item.link_type,
doctype: item.doctype,
is_query_report: item.is_query_report
};

View file

@ -291,10 +291,18 @@ var verify_token = function (event) {
}
var request_otp = function (r) {
const otp_form_template = '{{ _("Verification") }}<input type="text" id="login_token" autocomplete="off" class="form-control" placeholder={{ _("Verification Code") }} required="" autofocus="">{{ _("Verify") }}';
$('.login-content').empty();
$('.login-content:visible').append(
$('<div>').attr({ 'id': 'twofactor_div' }).html(otp_form_template)
`<div id="twofactor_div">
<form class="form-verify">
<div class="page-card-head">
<span class="indicator blue" data-text="Verification">{{ _("Verification") }}</span>
</div>
<div id="otp_div"></div>
<input type="text" id="login_token" autocomplete="off" class="form-control" placeholder={{ _("Verification Code") }} required="" autofocus="">
<button class="btn btn-sm btn-primary btn-block mt-3" id="verify_token">{{ _("Verify") }}</button>
</form>
</div>`
);
// add event handler for submit button
verify_token();

View file

@ -1,20 +1,9 @@
<!-- base template for testing -->
<html>
<head>
{%- block style %}
{% if colocated_css -%}
<style>{{ colocated_css }}</style>
{%- endif %}
{%- endblock -%}
</head>
<body>
{% include "templates/includes/breadcrumbs.html" %}
<h1>This is for testing</h1>
{% block content %}{% endblock %}
{%- block script %}
{% if colocated_js -%}
<script>{{ colocated_js }}</script>
{%- endif %}
{%- endblock %}
</body>
</html>

View file

@ -0,0 +1,20 @@
<!-- base template for testing -->
<html>
<head>
{%- block style %}
{% if colocated_css -%}
<style>{{ colocated_css }}</style>
{%- endif %}
{%- endblock -%}
</head>
<body>
{% include "templates/includes/breadcrumbs.html" %}
<h1>This is for testing</h1>
{% block content %}{% endblock %}
{%- block script %}
{% if colocated_js -%}
<script>{{ colocated_js }}</script>
{%- endif %}
{%- endblock %}
</body>
</html>

View file

@ -244,14 +244,22 @@ class TestWebsite(unittest.TestCase):
self.assertIn("<script>console.log('test data');</script>", content)
self.assertIn("background-color: var(--bg-color);", content)
def test_raw_assets_are_loaded(self):
content = get_response_content('/_test/assets/js_asset.min.js')
# minified js files should not be passed through jinja renderer
self.assertEqual("//{% if title %} {{title}} {% endif %}\nconsole.log('in');", content)
content = get_response_content('/_test/assets/css_asset.css')
self.assertEqual("""body{color:red}""", content)
def test_breadcrumbs(self):
content = get_response_content('/_test/_test_folder/_test_page')
self.assertIn('<span itemprop="name">Test TOC</span>', content)
self.assertIn('<span itemprop="name">Test Folder</span>', content)
self.assertIn('<span itemprop="name"> Test Page</span>', content)
content = get_response_content('/_test/_test_folder/index')
self.assertIn('<span itemprop="name"> Test</span>', content)
self.assertIn('<span itemprop="name">Test TOC</span>', content)
self.assertIn('<span itemprop="name">Test Folder</span>', content)
def test_get_context_without_context_object(self):
content = get_response_content('/_test/_test_no_context')

View file

@ -70,7 +70,7 @@ class TemplatePage(BaseTemplatePage):
self.set_pymodule()
self.update_context()
self.setup_template()
self.setup_template_source()
self.load_colocated_files()
self.set_properties_from_source()
self.post_process_context()
@ -118,7 +118,7 @@ class TemplatePage(BaseTemplatePage):
if os.path.exists(os.path.join(self.app_path, self.pymodule_path)):
self.pymodule_name = self.app + "." + self.pymodule_path.replace(os.path.sep, ".")[:-3]
def setup_template(self):
def setup_template_source(self):
'''Setup template source, frontmatter and markdown conversion'''
self.source = self.get_raw_template()
self.extract_frontmatter()
@ -126,7 +126,6 @@ class TemplatePage(BaseTemplatePage):
def update_context(self):
self.set_page_properties()
self.set_properties_from_source()
self.context.build_version = frappe.utils.get_build_version()
if self.pymodule_name:
@ -150,8 +149,7 @@ class TemplatePage(BaseTemplatePage):
def set_page_properties(self):
self.context.base_template = self.context.base_template \
or get_base_template(self.path) \
or 'templates/web.html'
or get_base_template(self.path)
self.context.basepath = self.basepath
self.context.basename = self.basename
self.context.name = self.name
@ -203,13 +201,10 @@ class TemplatePage(BaseTemplatePage):
frappe.errprint(frappe.utils.get_traceback())
def render_template(self):
if self.source:
if self.template_path.endswith('min.js'):
html = self.source # static
else:
html = frappe.render_template(self.source, self.context)
elif self.template_path:
if self.path.endswith('min.js'):
html = self.get_raw_template() # static
else:
html = frappe.get_template(self.template_path).render(self.context)
return html

View file

@ -270,7 +270,7 @@ def get_doctypes_with_web_view():
doctypes_with_web_view = frappe.get_all('DocType', fields=['name', 'module'],
filters=dict(has_web_view=1))
module_app_map = frappe.local.module_app
doctypes += [d.name for d in doctypes_with_web_view if module_app_map[frappe.scrub(d.module)] in installed_apps]
doctypes += [d.name for d in doctypes_with_web_view if module_app_map.get(frappe.scrub(d.module)) in installed_apps]
return doctypes
return frappe.cache().get_value('doctypes_with_web_view', _get)

View file

@ -1,3 +1,4 @@
{% extends base_template_path %}
{% block content %}
{% include "templates/includes/web_sidebar.html" %}
<p>Test content</p>

View file

@ -1,3 +1,3 @@
def get_context(context):
context.base_template_path = 'frappe/templates/test/_test_base.html'
context.base_template_path = 'frappe/templates/test/_test_base_breadcrumbs.html'
context.add_breadcrumbs = 1

View file

@ -1,9 +1,9 @@
---
title: Test TOC
title: Test Folder
add_breadcrumbs: 1
show_sidebar: 1
base_template: templates/web.html
---
# Index
{index}

View file

View file

@ -0,0 +1 @@
body{color:red}

View file

@ -0,0 +1,2 @@
//{% if title %} {{title}} {% endif %}
console.log('in');

View file

@ -1381,12 +1381,12 @@ component-bind@1.0.0:
resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1"
integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=
component-emitter@1.2.1, component-emitter@^1.2.0:
component-emitter@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=
component-emitter@~1.3.0:
component-emitter@^1.2.0, component-emitter@~1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
@ -1713,28 +1713,14 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
debug@^3.0.1:
debug@^3.0.1, debug@^3.1.0, debug@^3.2.6:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
debug@^3.1.0, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
dependencies:
ms "^2.1.1"
debug@^4.1.1, debug@~4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
debug@^4.2.0, debug@^4.3.1:
debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@ -1748,6 +1734,13 @@ debug@~3.1.0:
dependencies:
ms "2.0.0"
debug@~4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
decamelize@^1.0.0, decamelize@^1.1.2, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@ -6484,11 +6477,11 @@ socket.io-client@2.4.0:
to-array "0.1.4"
socket.io-parser@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f"
integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==
version "3.3.2"
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6"
integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==
dependencies:
component-emitter "1.2.1"
component-emitter "~1.3.0"
debug "~3.1.0"
isarray "2.0.1"