Merge branch 'develop' into add_pdf_backend_hook
This commit is contained in:
commit
8ff33c1ea4
63 changed files with 10273 additions and 9440 deletions
2
.github/workflows/server-tests.yml
vendored
2
.github/workflows/server-tests.yml
vendored
|
|
@ -70,7 +70,7 @@ jobs:
|
|||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
uses: actions/download-artifact@v4.1.9
|
||||
- name: Upload coverage data
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/ui-tests.yml
vendored
2
.github/workflows/ui-tests.yml
vendored
|
|
@ -57,7 +57,7 @@ jobs:
|
|||
- name: Clone
|
||||
uses: actions/checkout@v4
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4.1.8
|
||||
uses: actions/download-artifact@v4.1.9
|
||||
- name: Upload python coverage data
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ describe(
|
|||
before(() => {
|
||||
cy.login();
|
||||
cy.visit(`/app/note/new`);
|
||||
// close the sidebar cause default is expanded
|
||||
cy.get(".body-sidebar .collapse-sidebar-link").click();
|
||||
});
|
||||
|
||||
test_button_names.forEach((button_name) => {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from frappe.desk.doctype.form_tour.form_tour import get_onboarding_ui_tours
|
|||
from frappe.desk.doctype.route_history.route_history import frequently_visited_links
|
||||
from frappe.desk.form.load import get_meta_bundle
|
||||
from frappe.email.inbox import get_email_accounts
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site
|
||||
from frappe.model.base_document import get_controller
|
||||
from frappe.permissions import has_permission
|
||||
from frappe.query_builder import DocType
|
||||
|
|
@ -111,6 +112,7 @@ def get_bootinfo():
|
|||
bootinfo.translated_doctypes = get_translated_doctypes()
|
||||
bootinfo.subscription_conf = add_subscription_conf()
|
||||
bootinfo.marketplace_apps = get_marketplace_apps()
|
||||
bootinfo.is_fc_site = is_fc_site()
|
||||
bootinfo.changelog_feed = get_changelog_feed_items()
|
||||
bootinfo.enable_address_autocompletion = frappe.db.get_single_value(
|
||||
"Geolocation Settings", "enable_address_autocompletion"
|
||||
|
|
@ -139,7 +141,7 @@ def load_conf_settings(bootinfo):
|
|||
from frappe.core.api.file import get_max_file_size
|
||||
|
||||
bootinfo.max_file_size = get_max_file_size()
|
||||
for key in ("developer_mode", "socketio_port", "file_watcher_port", "fc_communication_secret"):
|
||||
for key in ("developer_mode", "socketio_port", "file_watcher_port"):
|
||||
if key in frappe.conf:
|
||||
bootinfo[key] = frappe.conf.get(key)
|
||||
|
||||
|
|
|
|||
|
|
@ -494,7 +494,7 @@ def delete_doc(doctype, name):
|
|||
for row in parent.get(parentfield):
|
||||
if row.name == name:
|
||||
parent.remove(row)
|
||||
parent.save(ignore_permissions=True)
|
||||
parent.save()
|
||||
break
|
||||
else:
|
||||
frappe.delete_doc(doctype, name, ignore_missing=False)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ frappe.ui.form.on("DocType", {
|
|||
if (doc.custom && frappe.session.user != "Administrator") {
|
||||
return {
|
||||
query: "frappe.core.doctype.role.role.role_query",
|
||||
filters: [["Role", "name", "!=", "All"]],
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -171,12 +171,14 @@ class Report(Document):
|
|||
prepared_report_watcher.start()
|
||||
|
||||
# The JOB
|
||||
if self.is_standard == "Yes":
|
||||
res = self.execute_module(filters)
|
||||
else:
|
||||
res = self.execute_script(filters)
|
||||
try:
|
||||
if self.is_standard == "Yes":
|
||||
res = self.execute_module(filters)
|
||||
else:
|
||||
res = self.execute_script(filters)
|
||||
finally:
|
||||
prepared_report_watcher and prepared_report_watcher.cancel()
|
||||
|
||||
prepared_report_watcher and prepared_report_watcher.cancel()
|
||||
execution_time = (datetime.datetime.now() - start_time).total_seconds()
|
||||
|
||||
frappe.cache.hset("report_execution_time", self.name, execution_time)
|
||||
|
|
|
|||
|
|
@ -121,10 +121,14 @@ def get_users(role):
|
|||
@frappe.whitelist()
|
||||
@frappe.validate_and_sanitize_search_inputs
|
||||
def role_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
report_filters = [["Role", "name", "like", f"%{txt}%"], ["Role", "is_custom", "=", 0]]
|
||||
if filters and isinstance(filters, list):
|
||||
report_filters.extend(filters)
|
||||
|
||||
return frappe.get_all(
|
||||
"Role", limit_start=start, limit_page_length=page_len, filters=report_filters, as_list=1
|
||||
"Role",
|
||||
limit_start=start,
|
||||
limit_page_length=page_len,
|
||||
filters=[
|
||||
["Role", "name", "like", f"%{txt}%"],
|
||||
["Role", "is_custom", "=", 0],
|
||||
["Role", "name", "!=", "All"],
|
||||
],
|
||||
as_list=True,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -891,6 +891,8 @@ def update_password(
|
|||
|
||||
user_doc, redirect_url = reset_user_data(user)
|
||||
|
||||
user_doc.validate_reset_password()
|
||||
|
||||
# get redirect url from cache
|
||||
redirect_to = frappe.cache.hget("redirect_after_login", user)
|
||||
if redirect_to:
|
||||
|
|
|
|||
0
frappe/core/report/prepared_report_analytics/__init__.py
Normal file
0
frappe/core/report/prepared_report_analytics/__init__.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2024, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Prepared Report Analytics"] = {
|
||||
filters: [
|
||||
{
|
||||
fieldname: "report",
|
||||
label: __("Report"),
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
fieldname: "top_10",
|
||||
label: __("Top 10"),
|
||||
fieldtype: "Check",
|
||||
default: 0,
|
||||
},
|
||||
{
|
||||
fieldname: "in_minutes",
|
||||
label: __("In Minutes"),
|
||||
fieldtype: "Check",
|
||||
default: 0,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"add_total_row": 0,
|
||||
"columns": [],
|
||||
"creation": "2024-12-18 11:58:00.693755",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"filters": [],
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letterhead": null,
|
||||
"modified": "2025-02-07 17:27:53.441631",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Prepared Report Analytics",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"ref_doctype": "Prepared Report",
|
||||
"report_name": "Prepared Report Analytics",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "System Manager"
|
||||
}
|
||||
],
|
||||
"timeout": 0
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# Copyright (c) 2024, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from pypika import Order
|
||||
|
||||
import frappe
|
||||
from frappe import _, qb
|
||||
from frappe.query_builder import Criterion
|
||||
from frappe.utils import add_months, nowdate
|
||||
|
||||
|
||||
def execute(filters: dict | None = None):
|
||||
"""Return columns and data for the report.
|
||||
|
||||
This is the main entry point for the report. It accepts the filters as a
|
||||
dictionary and should return columns and data. It is called by the framework
|
||||
every time the report is refreshed or a filter is updated.
|
||||
"""
|
||||
columns = get_columns(filters)
|
||||
data = get_data(filters=filters)
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_columns(filters) -> list[dict]:
|
||||
"""Return columns for the report.
|
||||
|
||||
One field definition per column, just like a DocType field definition.
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"label": _("Prepared Report"),
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Link",
|
||||
"options": "Prepared Report",
|
||||
"width": 250,
|
||||
},
|
||||
{
|
||||
"label": _("Report Name"),
|
||||
"fieldname": "report_name",
|
||||
"fieldtype": "Data",
|
||||
"width": 250,
|
||||
},
|
||||
{
|
||||
"label": _("Start"),
|
||||
"fieldname": "creation",
|
||||
"fieldtype": "DateTime",
|
||||
"width": 250,
|
||||
},
|
||||
{
|
||||
"label": _("End"),
|
||||
"fieldname": "report_end_time",
|
||||
"fieldtype": "DateTime",
|
||||
"width": 250,
|
||||
},
|
||||
{
|
||||
"label": _("Runtime in Minutes") if filters.in_minutes else _("Runtime in Seconds"),
|
||||
"fieldname": "runtime",
|
||||
"fieldtype": "float",
|
||||
"width": 250,
|
||||
},
|
||||
{
|
||||
"label": _("Memory Usage in MB"),
|
||||
"fieldname": "peak_memory_usage",
|
||||
"fieldtype": "float",
|
||||
"width": 250,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def get_data(filters) -> list[list]:
|
||||
"""Return data for the report.
|
||||
|
||||
The report data is a list of rows, with each row being a list of cell values.
|
||||
"""
|
||||
|
||||
pr = qb.DocType("Prepared Report")
|
||||
|
||||
conditions = [pr.status.eq("Completed"), pr.creation.gte(add_months(nowdate(), -2))]
|
||||
|
||||
if filters.report:
|
||||
conditions.append(pr.report_name.like(f"%{filters.report}%"))
|
||||
|
||||
divisor = 1
|
||||
if filters.in_minutes:
|
||||
divisor = 60
|
||||
|
||||
query = (
|
||||
qb.from_(pr)
|
||||
.select(
|
||||
pr.name,
|
||||
pr.report_name,
|
||||
pr.creation,
|
||||
pr.report_end_time,
|
||||
(pr.peak_memory_usage / 1024).as_("peak_memory_usage"),
|
||||
)
|
||||
.select(((pr.report_end_time - pr.creation) / divisor).as_("runtime"))
|
||||
.where(Criterion.all(conditions))
|
||||
.orderby(qb.Field("runtime"), order=Order.desc)
|
||||
)
|
||||
if filters.top_10:
|
||||
query = query.limit(10)
|
||||
|
||||
res = query.run(as_dict=True)
|
||||
|
||||
return res
|
||||
|
|
@ -67,8 +67,8 @@ frappe.ui.form.on("System Health Report", {
|
|||
const style = document.createElement("style");
|
||||
style.innerText = `.health-check-failed {
|
||||
font-weight: bold;
|
||||
color: var(--text-colour);
|
||||
background-color: var(--bg-red);
|
||||
color: var(--text-colour) !important;
|
||||
background-color: var(--bg-red) !important;
|
||||
}`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ def savedocs(doc, action):
|
|||
# action
|
||||
doc.docstatus = {
|
||||
"Save": DocStatus.DRAFT,
|
||||
"Submit": DocStatus.SUMBITTED,
|
||||
"Update": DocStatus.SUMBITTED,
|
||||
"Submit": DocStatus.SUBMITTED,
|
||||
"Update": DocStatus.SUBMITTED,
|
||||
"Cancel": DocStatus.CANCELLED,
|
||||
}[action]
|
||||
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ def get_doc_count(doctype, filters):
|
|||
limit=100,
|
||||
distinct=True,
|
||||
ignore_ifnull=True,
|
||||
order_by=None,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ def generate_report_result(
|
|||
if cint(report.add_total_row) and result and not skip_total_row:
|
||||
result = add_total_row(result, columns, is_tree=is_tree, parent_field=parent_field)
|
||||
|
||||
if isinstance(filters, dict) and filters.get("translate_data"):
|
||||
total_row = cint(report.add_total_row) and result and not skip_total_row
|
||||
result = translate_report_data(result, total_row)
|
||||
|
||||
return {
|
||||
"result": result,
|
||||
"columns": columns,
|
||||
|
|
@ -809,3 +813,11 @@ def validate_filters_permissions(report_name, filters=None, user=None):
|
|||
linked_doctype, filters[field.fieldname]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def translate_report_data(data, total_row):
|
||||
for d in data[:-1] if total_row else data:
|
||||
for field, value in d.items():
|
||||
if isinstance(value, str):
|
||||
d[field] = _(value)
|
||||
return data
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ def export_query():
|
|||
_(value) if translatable_fields[idx] else value for idx, value in enumerate(row)
|
||||
]
|
||||
processed_data.append(processed_row)
|
||||
data.extend(processed_data)
|
||||
data.extend(processed_data)
|
||||
|
||||
data = handle_duration_fieldtype_values(doctype, data, db_query.fields)
|
||||
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ class EmailAccount(Document):
|
|||
|
||||
if _raise_error:
|
||||
frappe.throw(
|
||||
_("Please setup default Email Account from Settings > Email Account"),
|
||||
_("Please setup default outgoing Email Account from Tools > Email Account"),
|
||||
frappe.OutgoingEmailError,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,10 @@ class SessionBootFailed(ValidationError):
|
|||
http_status_code = 500
|
||||
|
||||
|
||||
class QueueOverloaded(ValidationError):
|
||||
http_status_code = 503
|
||||
|
||||
|
||||
class PrintFormatError(ValidationError):
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"authorize_google_calendar_access",
|
||||
"sb_01",
|
||||
"pull_from_google_calendar",
|
||||
"sync_as_public",
|
||||
"cb_01",
|
||||
"push_to_google_calendar",
|
||||
"section_break_3",
|
||||
|
|
@ -98,6 +99,12 @@
|
|||
"fieldtype": "Check",
|
||||
"label": "Pull from Google Calendar"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "sync_as_public",
|
||||
"fieldtype": "Check",
|
||||
"label": "Sync events from Google as public"
|
||||
},
|
||||
{
|
||||
"fieldname": "cb_01",
|
||||
"fieldtype": "Column Break"
|
||||
|
|
@ -110,7 +117,7 @@
|
|||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2024-03-23 16:03:26.682486",
|
||||
"modified": "2025-01-27 13:06:00.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Google Calendar",
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ class GoogleCalendar(Document):
|
|||
google_calendar_id: DF.Data | None
|
||||
next_sync_token: DF.Password | None
|
||||
pull_from_google_calendar: DF.Check
|
||||
sync_as_public: DF.Check
|
||||
push_to_google_calendar: DF.Check
|
||||
refresh_token: DF.Password | None
|
||||
user: DF.Link
|
||||
|
|
@ -375,6 +376,8 @@ def insert_event_to_calendar(account, event, recurrence=None):
|
|||
"google_calendar_event_id": event.get("id"),
|
||||
"google_meet_link": event.get("hangoutLink"),
|
||||
"pulled_from_google_calendar": 1,
|
||||
"owner": account.owner,
|
||||
"event_type": "Public" if account.sync_as_public else "Private",
|
||||
}
|
||||
calendar_event.update(
|
||||
google_calendar_to_repeat_on(recurrence=recurrence, start=event.get("start"), end=event.get("end"))
|
||||
|
|
|
|||
|
|
@ -6,11 +6,15 @@ from frappe import _
|
|||
|
||||
def get_base_url():
|
||||
url = "https://frappecloud.com"
|
||||
if frappe.conf.developer_mode and frappe.conf.get("saas_billing_base_url"):
|
||||
url = frappe.conf.get("saas_billing_base_url")
|
||||
if frappe.conf.developer_mode and frappe.conf.get("fc_base_url"):
|
||||
url = frappe.conf.get("fc_base_url")
|
||||
return url
|
||||
|
||||
|
||||
def get_site_login_url():
|
||||
return f"{get_base_url()}/dashboard/site-login"
|
||||
|
||||
|
||||
def get_site_name():
|
||||
site_name = frappe.local.site
|
||||
if frappe.conf.developer_mode and frappe.conf.get("saas_billing_site_name"):
|
||||
|
|
@ -29,15 +33,28 @@ def get_headers():
|
|||
|
||||
return {
|
||||
"X-Site-Token": frappe.conf.get("fc_communication_secret"),
|
||||
"X-Site-User": frappe.session.user,
|
||||
"X-Site": get_site_name(),
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def current_site_info():
|
||||
from frappe.utils import cint
|
||||
|
||||
request = requests.post(f"{get_base_url()}/api/method/press.saas.api.site.info", headers=get_headers())
|
||||
if request.status_code == 200:
|
||||
return request.json().get("message")
|
||||
res = request.json().get("message")
|
||||
if not res:
|
||||
return None
|
||||
|
||||
return {
|
||||
**res,
|
||||
"site_name": get_site_name(),
|
||||
"base_url": get_base_url(),
|
||||
"setup_complete": cint(frappe.get_system_settings("setup_complete")),
|
||||
}
|
||||
|
||||
else:
|
||||
frappe.throw(_("Failed to get site info"))
|
||||
|
||||
|
|
@ -58,19 +75,19 @@ def api(method, data=None):
|
|||
|
||||
|
||||
@frappe.whitelist()
|
||||
def is_fc_site():
|
||||
def is_fc_site() -> bool:
|
||||
is_system_manager = frappe.get_roles(frappe.session.user).count("System Manager")
|
||||
setup_completed = frappe.get_system_settings("setup_complete")
|
||||
return is_system_manager and setup_completed and frappe.conf.get("fc_communication_secret")
|
||||
return bool(is_system_manager and setup_completed and frappe.conf.get("fc_communication_secret"))
|
||||
|
||||
|
||||
# login to frappe cloud dashboard
|
||||
@frappe.whitelist()
|
||||
def send_verification_code(route: str):
|
||||
def send_verification_code():
|
||||
request = requests.post(
|
||||
f"{get_base_url()}/api/method/press.api.developer.saas.send_verification_code",
|
||||
headers=get_headers(),
|
||||
json={"domain": get_site_name(), "route": route},
|
||||
json={"domain": get_site_name()},
|
||||
)
|
||||
if request.status_code == 200:
|
||||
return request.json().get("message")
|
||||
|
|
|
|||
1138
frappe/locale/ar.po
1138
frappe/locale/ar.po
File diff suppressed because it is too large
Load diff
4174
frappe/locale/bs.po
4174
frappe/locale/bs.po
File diff suppressed because it is too large
Load diff
1138
frappe/locale/de.po
1138
frappe/locale/de.po
File diff suppressed because it is too large
Load diff
1138
frappe/locale/eo.po
1138
frappe/locale/eo.po
File diff suppressed because it is too large
Load diff
1168
frappe/locale/es.po
1168
frappe/locale/es.po
File diff suppressed because it is too large
Load diff
1876
frappe/locale/fa.po
1876
frappe/locale/fa.po
File diff suppressed because it is too large
Load diff
1146
frappe/locale/fr.po
1146
frappe/locale/fr.po
File diff suppressed because it is too large
Load diff
1138
frappe/locale/hu.po
1138
frappe/locale/hu.po
File diff suppressed because it is too large
Load diff
|
|
@ -7,8 +7,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Framework VERSION\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2025-02-23 09:33+0000\n"
|
||||
"PO-Revision-Date: 2025-02-23 09:33+0000\n"
|
||||
"POT-Creation-Date: 2025-03-02 09:33+0000\n"
|
||||
"PO-Revision-Date: 2025-03-02 09:33+0000\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: developers@frappe.io\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -135,7 +135,7 @@ msgstr ""
|
|||
msgid "1 Day"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:359
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:360
|
||||
msgid "1 Google Calendar Event synced."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -885,7 +885,7 @@ msgstr ""
|
|||
msgid "Action Complete"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1860
|
||||
#: frappe/model/document.py:1859
|
||||
msgid "Action Failed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1296,7 +1296,7 @@ msgstr ""
|
|||
msgid "Added default log doctypes: {}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:736
|
||||
#: frappe/core/doctype/file/file.py:738
|
||||
msgid "Added {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1414,11 +1414,11 @@ msgstr ""
|
|||
msgid "Administrator"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1214
|
||||
#: frappe/core/doctype/user/user.py:1216
|
||||
msgid "Administrator Logged In"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1208
|
||||
#: frappe/core/doctype/user/user.py:1210
|
||||
msgid "Administrator accessed {0} on {1} via IP Address {2}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1662,8 +1662,8 @@ msgstr ""
|
|||
msgid "Allow Dropbox Access"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:101
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:115
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:102
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:116
|
||||
msgid "Allow Google Calendar Access"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -1926,7 +1926,7 @@ msgstr ""
|
|||
msgid "Allowing DocType, DocType. Be careful!"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1024
|
||||
#: frappe/core/doctype/user/user.py:1026
|
||||
msgid "Already Registered"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2017,7 +2017,7 @@ msgstr ""
|
|||
msgid "Amendment Naming Override"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:522
|
||||
#: frappe/model/document.py:544
|
||||
msgid "Amendment Not Allowed"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2025,7 +2025,7 @@ msgstr ""
|
|||
msgid "Amendment naming rules updated."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:322
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:323
|
||||
msgid "An error occurred while setting Session Defaults"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -2985,7 +2985,7 @@ msgstr ""
|
|||
#. Option for the 'Function' (Select) field in DocType 'Number Card'
|
||||
#: frappe/desk/doctype/dashboard_chart/dashboard_chart.json
|
||||
#: frappe/desk/doctype/number_card/number_card.json
|
||||
#: frappe/public/js/frappe/form/controls/password.js:89
|
||||
#: frappe/public/js/frappe/form/controls/password.js:88
|
||||
#: frappe/public/js/frappe/ui/group_by/group_by.js:21
|
||||
msgid "Average"
|
||||
msgstr ""
|
||||
|
|
@ -3132,7 +3132,7 @@ msgstr ""
|
|||
#. 'System Health Report'
|
||||
#: frappe/core/workspace/build/build.json
|
||||
#: frappe/desk/doctype/system_health_report/system_health_report.json
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:178
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:179
|
||||
msgid "Background Jobs"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4061,11 +4061,11 @@ msgstr ""
|
|||
msgid "Cannot Remove"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:1100
|
||||
#: frappe/model/base_document.py:1143
|
||||
msgid "Cannot Update After Submit"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:591
|
||||
#: frappe/core/doctype/file/file.py:589
|
||||
msgid "Cannot access file path {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4081,11 +4081,11 @@ msgstr ""
|
|||
msgid "Cannot cancel {0}."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:986
|
||||
#: frappe/model/document.py:1006
|
||||
msgid "Cannot change docstatus from 0 (Draft) to 2 (Cancelled)"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1000
|
||||
#: frappe/model/document.py:1020
|
||||
msgid "Cannot change docstatus from 1 (Submitted) to 0 (Draft)"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4168,7 +4168,7 @@ msgstr ""
|
|||
msgid "Cannot edit a standard report. Please duplicate and create a new report"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1006
|
||||
#: frappe/model/document.py:1026
|
||||
msgid "Cannot edit cancelled document"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4193,7 +4193,7 @@ msgstr ""
|
|||
msgid "Cannot find file {} on disk"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:531
|
||||
#: frappe/core/doctype/file/file.py:529
|
||||
msgid "Cannot get file contents of a Folder"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4201,7 +4201,7 @@ msgstr ""
|
|||
msgid "Cannot have multiple printers mapped to a single print format."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1074
|
||||
#: frappe/model/document.py:1094
|
||||
msgid "Cannot link cancelled document: {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -4675,7 +4675,7 @@ msgstr ""
|
|||
msgid "Click on the link below to verify your request"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:102
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:103
|
||||
#: frappe/integrations/doctype/google_contacts/google_contacts.py:41
|
||||
#: frappe/integrations/doctype/google_drive/google_drive.py:53
|
||||
#: frappe/website/doctype/website_settings/website_settings.py:161
|
||||
|
|
@ -5594,7 +5594,7 @@ msgstr ""
|
|||
msgid "Could not connect to outgoing email server"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1070
|
||||
#: frappe/model/document.py:1090
|
||||
msgid "Could not find {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -7745,7 +7745,7 @@ msgstr ""
|
|||
msgid "Document Naming Settings"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1718
|
||||
#: frappe/model/document.py:469
|
||||
msgid "Document Queued"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -7902,7 +7902,7 @@ msgid "Document Types and Permissions"
|
|||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/submission_queue/submission_queue.py:163
|
||||
#: frappe/model/document.py:1924
|
||||
#: frappe/model/document.py:1923
|
||||
msgid "Document Unlocked"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -8060,7 +8060,7 @@ msgstr ""
|
|||
msgid "Double click to edit label"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:10
|
||||
#: frappe/core/doctype/file/file.js:15
|
||||
#: frappe/email/doctype/auto_email_report/auto_email_report.js:8
|
||||
#: frappe/public/js/frappe/form/grid.js:66
|
||||
msgid "Download"
|
||||
|
|
@ -8208,7 +8208,7 @@ msgstr ""
|
|||
msgid "Duplicate Filter Name"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:611 frappe/model/rename_doc.py:111
|
||||
#: frappe/model/base_document.py:654 frappe/model/rename_doc.py:111
|
||||
msgid "Duplicate Name"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -8874,7 +8874,7 @@ msgstr ""
|
|||
msgid "Enable Email Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:90
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:91
|
||||
#: frappe/integrations/doctype/google_contacts/google_contacts.py:36
|
||||
#: frappe/website/doctype/website_settings/website_settings.py:129
|
||||
msgid "Enable Google API in Google Settings."
|
||||
|
|
@ -9182,7 +9182,7 @@ msgstr ""
|
|||
msgid "Ensure the user and group search paths are correct."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:93
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:94
|
||||
msgid "Enter Client Id and Client Secret in Google Settings."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9339,15 +9339,15 @@ msgstr ""
|
|||
msgid "Error while evaluating Notification {0}. Please fix your template."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:751
|
||||
#: frappe/model/base_document.py:794
|
||||
msgid "Error: Data missing in table {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:761
|
||||
#: frappe/model/base_document.py:804
|
||||
msgid "Error: Value missing for {0}: {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:755
|
||||
#: frappe/model/base_document.py:798
|
||||
msgid "Error: {0} Row #{1}: Value missing for: {2}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9388,8 +9388,8 @@ msgstr ""
|
|||
msgid "Event Reminders"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:452
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:536
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:455
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:539
|
||||
msgid "Event Synced with Google Calendar."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -9463,7 +9463,7 @@ msgstr ""
|
|||
msgid "Excel"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/form/controls/password.js:91
|
||||
#: frappe/public/js/frappe/form/controls/password.js:90
|
||||
msgid "Excellent"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10024,7 +10024,7 @@ msgstr ""
|
|||
msgid "Field {0} does not exist on {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/desk/form/meta.py:205
|
||||
#: frappe/desk/form/meta.py:208
|
||||
msgid "Field {0} is referring to non-existing doctype {1}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10123,7 +10123,7 @@ msgstr ""
|
|||
msgid "Fields Multicheck"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:410
|
||||
#: frappe/core/doctype/file/file.py:408
|
||||
msgid "Fields `file_name` or `file_url` must be set for File"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10228,7 +10228,7 @@ msgstr ""
|
|||
msgid "File backup is ready"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:594
|
||||
#: frappe/core/doctype/file/file.py:592
|
||||
msgid "File name cannot have {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10236,7 +10236,7 @@ msgstr ""
|
|||
msgid "File not attached"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:700 frappe/public/js/frappe/request.js:199
|
||||
#: frappe/core/doctype/file/file.py:702 frappe/public/js/frappe/request.js:199
|
||||
#: frappe/utils/file_manager.py:221
|
||||
msgid "File size exceeded the maximum allowed size of {0} MB"
|
||||
msgstr ""
|
||||
|
|
@ -10249,7 +10249,7 @@ msgstr ""
|
|||
msgid "File type of {0} is not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:361 frappe/core/doctype/file/file.py:426
|
||||
#: frappe/core/doctype/file/file.py:361 frappe/core/doctype/file/file.py:424
|
||||
msgid "File {0} does not exist"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -10504,7 +10504,7 @@ msgstr ""
|
|||
msgid "Folder name should not include '/' (slash)"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:472
|
||||
#: frappe/core/doctype/file/file.py:470
|
||||
msgid "Folder {0} is not empty"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -11131,7 +11131,7 @@ msgstr ""
|
|||
msgid "Generate Random Password"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:172
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:173
|
||||
#: frappe/public/js/frappe/utils/utils.js:1790
|
||||
msgid "Generate Tracking URL"
|
||||
msgstr ""
|
||||
|
|
@ -11345,19 +11345,19 @@ msgstr ""
|
|||
msgid "Google Calendar"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:776
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:779
|
||||
msgid "Google Calendar - Contact / email not found. Did not add attendee for -<br>{0}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:252
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:253
|
||||
msgid "Google Calendar - Could not create Calendar for {0}, error code {1}."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:572
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:575
|
||||
msgid "Google Calendar - Could not delete Event {0} from Google Calendar, error code {1}."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:289
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:290
|
||||
msgid "Google Calendar - Could not fetch event from Google Calendar, error code {0}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -11365,11 +11365,11 @@ msgstr ""
|
|||
msgid "Google Calendar - Could not insert contact in Google Contacts {0}, error code {1}."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:455
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:458
|
||||
msgid "Google Calendar - Could not insert event in Google Calendar {0}, error code {1}."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:539
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:542
|
||||
msgid "Google Calendar - Could not update Event {0} in Google Calendar, error code {1}."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -11385,7 +11385,7 @@ msgstr ""
|
|||
msgid "Google Calendar ID"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:167
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:168
|
||||
msgid "Google Calendar has been configured."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12552,7 +12552,7 @@ msgstr ""
|
|||
msgid "Image link '{0}' is not valid"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:105
|
||||
#: frappe/core/doctype/file/file.js:107
|
||||
msgid "Image optimized"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12832,7 +12832,7 @@ msgstr ""
|
|||
msgid "Include indentation"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/form/controls/password.js:107
|
||||
#: frappe/public/js/frappe/form/controls/password.js:106
|
||||
msgid "Include symbols, numbers and capital letters in the password"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12895,11 +12895,11 @@ msgstr ""
|
|||
msgid "Incorrect Verification code"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1515
|
||||
#: frappe/model/document.py:1535
|
||||
msgid "Incorrect value in row {0}:"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1517
|
||||
#: frappe/model/document.py:1537
|
||||
msgid "Incorrect value:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -12920,7 +12920,7 @@ msgstr ""
|
|||
msgid "Index Web Pages for Search"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/recorder/recorder.py:140
|
||||
#: frappe/core/doctype/recorder/recorder.py:132
|
||||
msgid "Index created successfully on column {0} of doctype {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13279,7 +13279,7 @@ msgstr ""
|
|||
msgid "Invalid Output Format"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:102
|
||||
#: frappe/model/base_document.py:115
|
||||
msgid "Invalid Override"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13287,7 +13287,7 @@ msgstr ""
|
|||
msgid "Invalid Parameters."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1229 frappe/www/update-password.html:123
|
||||
#: frappe/core/doctype/user/user.py:1231 frappe/www/update-password.html:123
|
||||
#: frappe/www/update-password.html:144 frappe/www/update-password.html:146
|
||||
#: frappe/www/update-password.html:247
|
||||
msgid "Invalid Password"
|
||||
|
|
@ -13341,7 +13341,7 @@ msgstr ""
|
|||
msgid "Invalid column"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:989 frappe/model/document.py:1003
|
||||
#: frappe/model/document.py:1009 frappe/model/document.py:1023
|
||||
msgid "Invalid docstatus"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -15757,7 +15757,7 @@ msgstr ""
|
|||
msgid "Miss"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/desk/form/meta.py:215
|
||||
#: frappe/desk/form/meta.py:218
|
||||
msgid "Missing DocType"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16169,7 +16169,7 @@ msgstr ""
|
|||
msgid "My Device"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:62
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:57
|
||||
msgid "My Workspaces"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16326,7 +16326,7 @@ msgstr ""
|
|||
msgid "Need Workspace Manager role to edit private workspace of other users"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:764
|
||||
#: frappe/model/document.py:787
|
||||
msgid "Negative Value"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16753,7 +16753,7 @@ msgstr ""
|
|||
msgid "No Filters Set"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:357
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:358
|
||||
msgid "No Google Calendar Event to sync."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16844,7 +16844,7 @@ msgstr ""
|
|||
msgid "No Select Field Found"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/recorder/recorder.py:187
|
||||
#: frappe/core/doctype/recorder/recorder.py:179
|
||||
msgid "No Suggestions"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -16868,7 +16868,7 @@ msgstr ""
|
|||
msgid "No alerts for today"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/recorder/recorder.py:186
|
||||
#: frappe/core/doctype/recorder/recorder.py:178
|
||||
msgid "No automatic optimization suggestions available."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -17104,7 +17104,7 @@ msgstr ""
|
|||
msgid "Normalized Query"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1019
|
||||
#: frappe/core/doctype/user/user.py:1021
|
||||
#: frappe/templates/includes/login/login.js:257 frappe/utils/oauth.py:270
|
||||
msgid "Not Allowed"
|
||||
msgstr ""
|
||||
|
|
@ -17856,7 +17856,7 @@ msgstr ""
|
|||
msgid "Only change this if you want to use other S3 compatible object storage backends."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1208
|
||||
#: frappe/model/document.py:1228
|
||||
msgid "Only draft documents can be discarded"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18031,13 +18031,13 @@ msgstr ""
|
|||
msgid "Operator must be one of {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:29
|
||||
#: frappe/core/doctype/file/file.js:34
|
||||
#: frappe/core/report/database_storage_usage_by_tables/database_storage_usage_by_tables.js:8
|
||||
#: frappe/public/js/frappe/file_uploader/FilePreview.vue:27
|
||||
msgid "Optimize"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:103
|
||||
#: frappe/core/doctype/file/file.js:105
|
||||
msgid "Optimizing image..."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18110,7 +18110,7 @@ msgstr ""
|
|||
msgid "Options is required for field {0} of type {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:810
|
||||
#: frappe/model/base_document.py:853
|
||||
msgid "Options not set for link field {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18574,7 +18574,7 @@ msgstr ""
|
|||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1082
|
||||
#: frappe/core/doctype/user/user.py:1084
|
||||
msgid "Password Email Sent"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -18612,7 +18612,7 @@ msgstr ""
|
|||
msgid "Password not found for {0} {1} {2}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1081
|
||||
#: frappe/core/doctype/user/user.py:1083
|
||||
msgid "Password reset instructions have been sent to {}'s email"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19013,7 +19013,7 @@ msgstr ""
|
|||
msgid "Please add a valid comment."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1064
|
||||
#: frappe/core/doctype/user/user.py:1066
|
||||
msgid "Please ask your administrator to verify your sign-up"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19041,11 +19041,11 @@ msgstr ""
|
|||
msgid "Please check the filter values set for Dashboard Chart: {}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:890
|
||||
#: frappe/model/base_document.py:933
|
||||
msgid "Please check the value of \"Fetch From\" set for field {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1062
|
||||
#: frappe/core/doctype/user/user.py:1064
|
||||
msgid "Please check your email for verification"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19093,7 +19093,7 @@ msgstr ""
|
|||
msgid "Please create chart first"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/desk/form/meta.py:211
|
||||
#: frappe/desk/form/meta.py:214
|
||||
msgid "Please delete the field from {0} or add the required doctype."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -19200,7 +19200,7 @@ msgstr ""
|
|||
msgid "Please make sure the Reference Communication Docs are not circularly linked."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:958
|
||||
#: frappe/model/document.py:981
|
||||
msgid "Please refresh to get the latest document."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -20239,7 +20239,7 @@ msgstr ""
|
|||
msgid "Query Report"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/recorder/recorder.py:196
|
||||
#: frappe/core/doctype/recorder/recorder.py:188
|
||||
msgid "Query analysis complete. Check suggested indexes."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -20979,7 +20979,7 @@ msgstr ""
|
|||
msgid "Refreshing..."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1026
|
||||
#: frappe/core/doctype/user/user.py:1028
|
||||
msgid "Registered but disabled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22071,7 +22071,7 @@ msgstr ""
|
|||
msgid "Route: Example \"/app\""
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:796 frappe/model/document.py:749
|
||||
#: frappe/model/base_document.py:839 frappe/model/document.py:772
|
||||
msgid "Row"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22084,7 +22084,7 @@ msgstr ""
|
|||
msgid "Row # {0}: Non administrator user can not set the role {1} to the custom doctype"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:921
|
||||
#: frappe/model/base_document.py:964
|
||||
msgid "Row #{0}:"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -22363,7 +22363,7 @@ msgstr ""
|
|||
#: frappe/public/js/frappe/list/list_settings.js:36
|
||||
#: frappe/public/js/frappe/list/list_settings.js:247
|
||||
#: frappe/public/js/frappe/list/list_sidebar_group_by.js:25
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:332
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:333
|
||||
#: frappe/public/js/frappe/utils/common.js:443
|
||||
#: frappe/public/js/frappe/views/kanban/kanban_settings.js:45
|
||||
#: frappe/public/js/frappe/views/kanban/kanban_settings.js:189
|
||||
|
|
@ -22561,7 +22561,7 @@ msgstr ""
|
|||
msgid "Scheduler Status"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/utils/scheduler.py:248
|
||||
#: frappe/utils/scheduler.py:256
|
||||
msgid "Scheduler can not be re-enabled when maintenance mode is active."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23528,11 +23528,11 @@ msgstr ""
|
|||
#. Label of the session_defaults (Table) field in DocType 'Session Default
|
||||
#. Settings'
|
||||
#: frappe/core/doctype/session_default_settings/session_default_settings.json
|
||||
#: frappe/hooks.py frappe/public/js/frappe/ui/toolbar/toolbar.js:331
|
||||
#: frappe/hooks.py frappe/public/js/frappe/ui/toolbar/toolbar.js:332
|
||||
msgid "Session Defaults"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:316
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:317
|
||||
msgid "Session Defaults Saved"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -23768,8 +23768,8 @@ msgstr ""
|
|||
#: frappe/core/doctype/doctype/doctype.json frappe/core/doctype/user/user.json
|
||||
#: frappe/integrations/workspace/integrations/integrations.json
|
||||
#: frappe/public/js/frappe/form/templates/print_layout.html:25
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:127
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:289
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:122
|
||||
#: frappe/public/js/frappe/ui/toolbar/toolbar.js:290
|
||||
#: frappe/public/js/frappe/views/workspace/workspace.js:362
|
||||
#: frappe/website/doctype/web_form/web_form.json
|
||||
#: frappe/website/doctype/web_page/web_page.json
|
||||
|
|
@ -24226,7 +24226,7 @@ msgstr ""
|
|||
msgid "Sign Up and Confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1019
|
||||
#: frappe/core/doctype/user/user.py:1021
|
||||
msgid "Sign Up is disabled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -24499,7 +24499,7 @@ msgstr ""
|
|||
msgid "Something went wrong"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:117
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:118
|
||||
msgid "Something went wrong during the token generation. Click on {0} to generate a new one."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -24970,7 +24970,7 @@ msgstr ""
|
|||
msgid "Strip EXIF tags from uploaded images"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/form/controls/password.js:90
|
||||
#: frappe/public/js/frappe/form/controls/password.js:89
|
||||
msgid "Strong"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -25366,11 +25366,16 @@ msgstr ""
|
|||
msgid "Sync Contacts"
|
||||
msgstr ""
|
||||
|
||||
#. Label of the sync_as_public (Check) field in DocType 'Google Calendar'
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.json
|
||||
msgid "Sync events from Google as public"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/custom/doctype/customize_form/customize_form.js:256
|
||||
msgid "Sync on Migrate"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:296
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:297
|
||||
msgid "Sync token was invalid and has been reset, Retry syncing."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -25719,7 +25724,7 @@ msgstr ""
|
|||
msgid "Table updated"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1538
|
||||
#: frappe/model/document.py:1558
|
||||
msgid "Table {0} cannot be empty"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -25836,7 +25841,7 @@ msgstr ""
|
|||
msgid "Templates"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1030
|
||||
#: frappe/core/doctype/user/user.py:1032
|
||||
msgid "Temporarily Disabled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26115,11 +26120,11 @@ msgid ""
|
|||
"</a>"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:990
|
||||
#: frappe/core/doctype/user/user.py:992
|
||||
msgid "The reset password link has been expired"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:992
|
||||
#: frappe/core/doctype/user/user.py:994
|
||||
msgid "The reset password link has either been used before or is invalid"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26227,7 +26232,7 @@ msgstr ""
|
|||
msgid "There is nothing new to show you right now."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:588 frappe/utils/file_manager.py:372
|
||||
#: frappe/core/doctype/file/file.py:586 frappe/utils/file_manager.py:372
|
||||
msgid "There is some problem with the file url: {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26361,7 +26366,7 @@ msgstr ""
|
|||
msgid "This document is already amended, you cannot ammend it again"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1715
|
||||
#: frappe/model/document.py:466
|
||||
msgid "This document is currently locked and queued for execution. Please try again after some time."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26389,7 +26394,7 @@ msgid ""
|
|||
"eval:doc.age>18"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:15
|
||||
#: frappe/core/doctype/file/file.js:20
|
||||
msgid "This file is public. It can be accessed without authentication."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -26548,7 +26553,7 @@ msgstr ""
|
|||
msgid "This will terminate the job immediately and might be dangerous, are you sure? "
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1243
|
||||
#: frappe/core/doctype/user/user.py:1245
|
||||
msgid "Throttled"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -27020,7 +27025,7 @@ msgstr ""
|
|||
msgid "Too many changes to database in single action."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1031
|
||||
#: frappe/core/doctype/user/user.py:1033
|
||||
msgid "Too many users signed up recently, so the registration is disabled. Please try back in an hour"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -27508,7 +27513,7 @@ msgstr ""
|
|||
#. Option for the 'Type' (Select) field in DocType 'Workspace Shortcut'
|
||||
#. Label of the url (Data) field in DocType 'Workspace Shortcut'
|
||||
#. Label of the url (Small Text) field in DocType 'Integration Request'
|
||||
#. Label of the url (Data) field in DocType 'Webhook Request Log'
|
||||
#. Label of the url (Text) field in DocType 'Webhook Request Log'
|
||||
#. Label of the url (Data) field in DocType 'Top Bar Item'
|
||||
#. Label of the url (Data) field in DocType 'Website Slideshow Item'
|
||||
#: frappe/desk/doctype/workspace/workspace.json
|
||||
|
|
@ -27597,7 +27602,7 @@ msgstr ""
|
|||
msgid "Unable to update event"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:464
|
||||
#: frappe/core/doctype/file/file.py:462
|
||||
msgid "Unable to write file format for {0}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -27728,7 +27733,7 @@ msgstr ""
|
|||
msgid "Untitled Column"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:33
|
||||
#: frappe/core/doctype/file/file.js:38
|
||||
msgid "Unzip"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28384,7 +28389,7 @@ msgstr ""
|
|||
msgid "User {0} has requested for data deletion"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1372
|
||||
#: frappe/core/doctype/user/user.py:1374
|
||||
msgid "User {0} impersonated as {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28553,15 +28558,15 @@ msgstr ""
|
|||
msgid "Value To Be Set"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:993 frappe/model/document.py:805
|
||||
#: frappe/model/base_document.py:1036 frappe/model/document.py:828
|
||||
msgid "Value cannot be changed for {0}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:751
|
||||
#: frappe/model/document.py:774
|
||||
msgid "Value cannot be negative for"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:755
|
||||
#: frappe/model/document.py:778
|
||||
msgid "Value cannot be negative for {0}: {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28573,7 +28578,7 @@ msgstr ""
|
|||
msgid "Value for field {0} is too long in {1}. Length should be lesser than {2} characters"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:402
|
||||
#: frappe/model/base_document.py:427
|
||||
msgid "Value for {0} cannot be a list"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28592,7 +28597,7 @@ msgstr ""
|
|||
msgid "Value to Validate"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:1063
|
||||
#: frappe/model/base_document.py:1106
|
||||
msgid "Value too big"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28704,7 +28709,7 @@ msgstr ""
|
|||
msgid "View Doctype Permissions"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:3
|
||||
#: frappe/core/doctype/file/file.js:4
|
||||
msgid "View File"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -28765,10 +28770,6 @@ msgstr ""
|
|||
msgid "View document"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:36
|
||||
msgid "View file"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/templates/emails/auto_email_report.html:60
|
||||
msgid "View report in your browser"
|
||||
msgstr ""
|
||||
|
|
@ -28896,7 +28897,7 @@ msgstr ""
|
|||
msgid "We've received your query!"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/form/controls/password.js:88
|
||||
#: frappe/public/js/frappe/form/controls/password.js:87
|
||||
msgid "Weak"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -29038,7 +29039,7 @@ msgstr ""
|
|||
#. Name of a Workspace
|
||||
#: frappe/core/doctype/module_def/module_def.json
|
||||
#: frappe/email/doctype/newsletter/newsletter.py:458
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:115
|
||||
#: frappe/public/js/frappe/ui/apps_switcher.js:110
|
||||
#: frappe/public/js/frappe/ui/toolbar/about.js:8
|
||||
#: frappe/website/workspace/website/website.json
|
||||
msgid "Website"
|
||||
|
|
@ -29345,7 +29346,7 @@ msgstr ""
|
|||
#. Description of the 'Run Jobs only Daily if Inactive For (Days)' (Int) field
|
||||
#. in DocType 'System Settings'
|
||||
#: frappe/core/doctype/system_settings/system_settings.json
|
||||
msgid "Will run scheduled jobs only once a day for inactive sites. Default 4 days if set to 0."
|
||||
msgid "Will run scheduled jobs only once a day for inactive sites. Set it to 0 to avoid automatically disabling the scheduler."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/public/js/frappe/form/print_utils.js:15
|
||||
|
|
@ -29579,7 +29580,7 @@ msgstr ""
|
|||
msgid "Write"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:893
|
||||
#: frappe/model/base_document.py:936
|
||||
msgid "Wrong Fetch From value"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -29817,7 +29818,7 @@ msgstr ""
|
|||
msgid "You can disable this {0} instead of deleting it."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:702
|
||||
#: frappe/core/doctype/file/file.py:704
|
||||
msgid "You can increase the limit from System Settings."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -30189,11 +30190,11 @@ msgstr ""
|
|||
msgid "Your assignment on {0} {1} has been removed by {2}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:71
|
||||
#: frappe/core/doctype/file/file.js:73
|
||||
msgid "Your browser does not support the audio element."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.js:53
|
||||
#: frappe/core/doctype/file/file.js:55
|
||||
msgid "Your browser does not support the video element."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31029,7 +31030,7 @@ msgstr ""
|
|||
msgid "{0} Fields"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:361
|
||||
#: frappe/integrations/doctype/google_calendar/google_calendar.py:362
|
||||
msgid "{0} Google Calendar Events synced."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31060,7 +31061,7 @@ msgstr ""
|
|||
msgid "{0} Name"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:1093
|
||||
#: frappe/model/base_document.py:1136
|
||||
msgid "{0} Not allowed to change {1} after submission from {2} to {3}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31175,7 +31176,7 @@ msgctxt "Form timeline"
|
|||
msgid "{0} cancelled this document {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:519
|
||||
#: frappe/model/document.py:541
|
||||
msgid "{0} cannot be amended because it is not cancelled. Please cancel the document before creating an amendment."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31325,7 +31326,7 @@ msgstr ""
|
|||
msgid "{0} is a mandatory field"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:514
|
||||
#: frappe/core/doctype/file/file.py:512
|
||||
msgid "{0} is a not a valid zip file"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31427,7 +31428,7 @@ msgstr ""
|
|||
msgid "{0} is not a valid report format. Report format should one of the following {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/file/file.py:494
|
||||
#: frappe/core/doctype/file/file.py:492
|
||||
msgid "{0} is not a zip file"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31474,7 +31475,7 @@ msgstr ""
|
|||
msgid "{0} items selected"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1381
|
||||
#: frappe/core/doctype/user/user.py:1383
|
||||
msgid "{0} just impersonated as you. They gave this reason: {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31507,35 +31508,35 @@ msgstr ""
|
|||
msgid "{0} months ago"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1780
|
||||
#: frappe/model/document.py:1779
|
||||
msgid "{0} must be after {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1524
|
||||
#: frappe/model/document.py:1544
|
||||
msgid "{0} must be beginning with '{1}'"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1526
|
||||
#: frappe/model/document.py:1546
|
||||
msgid "{0} must be equal to '{1}'"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1522
|
||||
#: frappe/model/document.py:1542
|
||||
msgid "{0} must be none of {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1520 frappe/utils/csvutils.py:161
|
||||
#: frappe/model/document.py:1540 frappe/utils/csvutils.py:161
|
||||
msgid "{0} must be one of {1}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:814
|
||||
#: frappe/model/base_document.py:857
|
||||
msgid "{0} must be set first"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:677
|
||||
#: frappe/model/base_document.py:720
|
||||
msgid "{0} must be unique"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1528
|
||||
#: frappe/model/document.py:1548
|
||||
msgid "{0} must be {1} {2}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31625,7 +31626,7 @@ msgstr ""
|
|||
msgid "{0} role does not have permission on any doctype"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/document.py:1773
|
||||
#: frappe/model/document.py:1772
|
||||
msgid "{0} row #{1}: "
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31721,11 +31722,11 @@ msgstr ""
|
|||
msgid "{0} {1} added to Dashboard {2}"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:610 frappe/model/rename_doc.py:110
|
||||
#: frappe/model/base_document.py:653 frappe/model/rename_doc.py:110
|
||||
msgid "{0} {1} already exists"
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:926
|
||||
#: frappe/model/base_document.py:969
|
||||
msgid "{0} {1} cannot be \"{2}\". It should be one of \"{3}\""
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31749,7 +31750,7 @@ msgstr ""
|
|||
msgid "{0} {1}: Submitted Record cannot be deleted. You must {2} Cancel {3} it first."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:1054
|
||||
#: frappe/model/base_document.py:1097
|
||||
msgid "{0}, Row {1}"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -31757,7 +31758,7 @@ msgstr ""
|
|||
msgid "{0}/{1} complete | Please leave this tab open until completion."
|
||||
msgstr ""
|
||||
|
||||
#: frappe/model/base_document.py:1059
|
||||
#: frappe/model/base_document.py:1102
|
||||
msgid "{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
1138
frappe/locale/pl.po
1138
frappe/locale/pl.po
File diff suppressed because it is too large
Load diff
1138
frappe/locale/ru.po
1138
frappe/locale/ru.po
File diff suppressed because it is too large
Load diff
1162
frappe/locale/sv.po
1162
frappe/locale/sv.po
File diff suppressed because it is too large
Load diff
1140
frappe/locale/tr.po
1140
frappe/locale/tr.po
File diff suppressed because it is too large
Load diff
1140
frappe/locale/zh.po
1140
frappe/locale/zh.po
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,7 @@ class DocStatus(int):
|
|||
return self == DocStatus.DRAFT
|
||||
|
||||
def is_submitted(self):
|
||||
return self == DocStatus.SUMBITTED
|
||||
return self == DocStatus.SUBMITTED
|
||||
|
||||
def is_cancelled(self):
|
||||
return self == DocStatus.CANCELLED
|
||||
|
|
@ -20,7 +20,7 @@ class DocStatus(int):
|
|||
|
||||
@staticmethod
|
||||
def submitted():
|
||||
return DocStatus.SUMBITTED
|
||||
return DocStatus.SUBMITTED
|
||||
|
||||
@staticmethod
|
||||
def cancelled():
|
||||
|
|
@ -28,5 +28,5 @@ class DocStatus(int):
|
|||
|
||||
|
||||
DocStatus.DRAFT = DocStatus(0)
|
||||
DocStatus.SUMBITTED = DocStatus(1)
|
||||
DocStatus.SUBMITTED = DocStatus(1)
|
||||
DocStatus.CANCELLED = DocStatus(2)
|
||||
|
|
|
|||
|
|
@ -1008,7 +1008,7 @@ class Document(BaseDocument, DocRef):
|
|||
else:
|
||||
raise frappe.ValidationError(_("Invalid docstatus"), self.docstatus)
|
||||
|
||||
elif to_docstatus == DocStatus.SUMBITTED:
|
||||
elif to_docstatus == DocStatus.SUBMITTED:
|
||||
if self.docstatus.is_submitted():
|
||||
self._action = "update_after_submit"
|
||||
self.check_permission("submit")
|
||||
|
|
@ -1188,7 +1188,7 @@ class Document(BaseDocument, DocRef):
|
|||
|
||||
def _submit(self):
|
||||
"""Submit the document. Sets `docstatus` = 1, then saves."""
|
||||
self.docstatus = DocStatus.SUMBITTED
|
||||
self.docstatus = DocStatus.SUBMITTED
|
||||
return self.save()
|
||||
|
||||
def _cancel(self):
|
||||
|
|
|
|||
|
|
@ -417,8 +417,7 @@ Tip: use lucide.svg in /icons for all downloaded icons
|
|||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-users">
|
||||
<path d="M17.727 18.728H20a1 1 0 0 0 1-1v-2.537a.818.818 0 0 0-.515-.76l-3.061-1.226a.819.819 0 0 1-.515-.758v-.718a3.258 3.258 0 0 0 1.636-2.82V7.274a3.272 3.272 0 0 0-4.909-2.835m.304 10.811l-3.062-1.227a.818.818 0 0 1-.514-.758v-.369c2.675-.357 3.272-1.532 3.272-1.532S12 9.728 12 8.092a3.273 3.273 0 1 0-6.545 0c0 1.636-1.637 3.272-1.637 3.272s.597 1.175 3.273 1.532v.37a.818.818 0 0 1-.515.758l-3.061 1.228a.819.819 0 0 0-.515.757v1.72a1 1 0 0 0 1 1h9.454a1 1 0 0 0 1-1v-1.72a.818.818 0 0 0-.514-.759z"
|
||||
stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M18 21a8 8 0 0 0-16 0" /> <circle cx="10" cy="8" r="5" /> <path d="M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-tool">
|
||||
|
|
@ -545,8 +544,7 @@ Tip: use lucide.svg in /icons for all downloaded icons
|
|||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-integration">
|
||||
<path d="M2.5 20.503l2.218-2.218m1.35-7.717l-1.35 1.35a4.5 4.5 0 1 0 6.364 6.365l1.35-1.35-6.364-6.365zM20.5 2.5l-2.218 2.218m-1.35 7.712l1.35-1.35a4.5 4.5 0 0 0-6.365-6.365l-1.35 1.35 6.365 6.365zM9.7 10.604l-1.8 1.8m4.5.898l-1.8 1.8"
|
||||
stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="m19 5 3-3" /> <path d="m2 22 3-3" /> <path d="M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z" /> <path d="M7.5 13.5 10 11" /> <path d="M10.5 16.5 13 14" /> <path d="m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z" />
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-hr">
|
||||
|
|
@ -876,7 +874,6 @@ Tip: use lucide.svg in /icons for all downloaded icons
|
|||
<symbol viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" id="icon-hammer" stroke-linejoin="round">
|
||||
<path d="m15 12-8.373 8.373a1 1 0 1 1-3-3L12 9"/><path d="m18 15 4-4"/><path d="m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172V7l-2.26-2.26a6 6 0 0 0-4.202-1.756L9 2.96l.92.82A6.18 6.18 0 0 1 12 8.4V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5"/>
|
||||
</symbol>
|
||||
|
||||
<symbol viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" id="icon-help">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M8.208 8.115v-.099a2.021 2.021 0 0 1 1.114-1.809l.057-.028a1.85 1.85 0 0 1 1.278-.142l.121.03c.623.156 1.1.659 1.223 1.289v0c.04.208.04.421 0 .63l-.029.153a1.805 1.805 0 0 1-.97 1.276l-.2.1a1.446 1.446 0 0 0-.804 1.297v0L10 11.5"/>
|
||||
<path fill="#20272E" d="M10.307 13.804a.304.304 0 1 1-.607 0 .304.304 0 0 1 .607 0Z"/>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
|
|
@ -1,8 +1,9 @@
|
|||
const frappeCloudBaseEndpoint = "https://frappecloud.com";
|
||||
let frappeCloudBaseEndpoint = "https://frappecloud.com";
|
||||
let isFCUser = false;
|
||||
|
||||
$(document).ready(function () {
|
||||
if (
|
||||
frappe.boot.fc_communication_secret &&
|
||||
frappe.boot.is_fc_site &&
|
||||
frappe.boot.setup_complete === 1 &&
|
||||
!frappe.is_mobile() &&
|
||||
frappe.user.has_role("System Manager")
|
||||
|
|
@ -10,147 +11,40 @@ $(document).ready(function () {
|
|||
frappe.call({
|
||||
method: "frappe.integrations.frappe_providers.frappecloud_billing.current_site_info",
|
||||
callback: (r) => {
|
||||
if (!r?.message) return;
|
||||
|
||||
const response = r.message;
|
||||
if (response.trial_end_date) {
|
||||
const trial_end_date = new Date(response.trial_end_date);
|
||||
frappeCloudBaseEndpoint = response.base_url;
|
||||
isFCUser = response.is_fc_user;
|
||||
|
||||
if (response.trial_end_date && trial_end_date > new Date()) {
|
||||
$(".layout-main-section").before(
|
||||
generateTrialSubscriptionBanner(response.trial_end_date)
|
||||
);
|
||||
|
||||
addLoginToFCDropdownItem();
|
||||
|
||||
$(".login-to-fc").on("click", function () {
|
||||
window.route = "dashboard";
|
||||
initiateRequestForLoginToFrappeCloud();
|
||||
});
|
||||
|
||||
$(".upgrade-plan-button").on("click", function () {
|
||||
window.route = "site-dashboard";
|
||||
initiateRequestForLoginToFrappeCloud();
|
||||
});
|
||||
}
|
||||
addManageBillingDropdown();
|
||||
|
||||
$(".login-to-fc, .upgrade-plan-button").on("click", function () {
|
||||
openFrappeCloudDashboard();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function initiateRequestForLoginToFrappeCloud() {
|
||||
frappe.confirm(__("Are you sure you want to login to Frappe Cloud dashboard?"), () => {
|
||||
requestLoginToFC();
|
||||
});
|
||||
}
|
||||
|
||||
function requestLoginToFC(freezing_msg = "Initiating login to Frappe Cloud...") {
|
||||
frappe.call({
|
||||
method: "frappe.integrations.frappe_providers.frappecloud_billing.send_verification_code",
|
||||
args: {
|
||||
route: window.route,
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __(freezing_msg),
|
||||
callback: function (r) {
|
||||
if (r.message.is_user_logged_in) {
|
||||
window.open(`${frappeCloudBaseEndpoint}${r.message.redirect_to}`, "_blank");
|
||||
return;
|
||||
} else {
|
||||
showFCLoginDialog(r.message.email);
|
||||
setErrorMessage("");
|
||||
}
|
||||
},
|
||||
error: function (r) {
|
||||
frappe.throw(__("Failed to login to Frappe Cloud. Please try again"));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function setErrorMessage(message) {
|
||||
$("#fc-login-error").text(message);
|
||||
}
|
||||
|
||||
function showFCLoginDialog(email) {
|
||||
if (!window.fc_login_dialog) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Login to Frappe Cloud"),
|
||||
primary_action_label: __("Verify", null, "Submit verification code"),
|
||||
primary_action: verifyCode,
|
||||
});
|
||||
|
||||
$(d.body).html(
|
||||
repl(
|
||||
`<div>
|
||||
<p>We have sent the verification code to your email id <strong>${email}</strong></p>
|
||||
<div class="form-group mt-2">
|
||||
<div class="clearfix">
|
||||
<label class="control-label" style="padding-right: 0px;">Verification Code</label>
|
||||
</div>
|
||||
<div class="control-input-wrapper">
|
||||
<div class="control-input"><input type="text" class="input-with-feedback form-control" id="fc-login-verification-code"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-danger" id="fc-login-error"></p>
|
||||
</div>`,
|
||||
frappe.app
|
||||
)
|
||||
);
|
||||
|
||||
d.add_custom_action("Didn't receive code? Resend", () => {
|
||||
d.hide();
|
||||
requestLoginToFC("Resending Verification Code...");
|
||||
});
|
||||
|
||||
window.fc_login_dialog = d;
|
||||
}
|
||||
|
||||
function verifyCode() {
|
||||
let otp = $("#fc-login-verification-code").val();
|
||||
if (!otp) {
|
||||
return;
|
||||
}
|
||||
frappe.call({
|
||||
method: "frappe.integrations.frappe_providers.frappecloud_billing.verify_verification_code",
|
||||
args: {
|
||||
verification_code: otp,
|
||||
route: window.route,
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __("Verifying verification code..."),
|
||||
callback: function (r) {
|
||||
const message = r.message;
|
||||
if (message.login_token) {
|
||||
window.fc_login_dialog.hide();
|
||||
window.open(
|
||||
`${frappeCloudBaseEndpoint}/api/method/press.api.developer.saas.login_to_fc?token=${message.login_token}`,
|
||||
"_blank"
|
||||
);
|
||||
frappe.msgprint({
|
||||
title: __("Frappe Cloud Login Successful"),
|
||||
indicator: "green",
|
||||
message: `<p>${__(
|
||||
"You will be redirected to Frappe Cloud soon."
|
||||
)}</p><p>${__(
|
||||
"If you haven't been redirected,"
|
||||
)} <a href="${frappeCloudBaseEndpoint}/api/method/press.api.developer.saas.login_to_fc?token=${
|
||||
message.login_token
|
||||
}" target="_blank">${__("Click here to login")}</a></p>`,
|
||||
});
|
||||
} else {
|
||||
setErrorMessage("Login failed. Please try again");
|
||||
}
|
||||
},
|
||||
error: function (r) {
|
||||
if (r.exc) {
|
||||
setErrorMessage(JSON.parse(JSON.parse(r._server_messages)[0])["message"]);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
window.fc_login_dialog.show();
|
||||
function addManageBillingDropdown() {
|
||||
$(".dropdown-navbar-user .dropdown-menu .dropdown-divider").before(
|
||||
`<div class="dropdown-item login-to-fc" target="_blank">Manage Billing</div>`
|
||||
);
|
||||
}
|
||||
|
||||
function addLoginToFCDropdownItem() {
|
||||
$(".dropdown-navbar-user .dropdown-menu .dropdown-item:last()").before(
|
||||
`<div class="dropdown-item login-to-fc" target="_blank">Login to Frappe Cloud</div>`
|
||||
);
|
||||
function openFrappeCloudDashboard() {
|
||||
window.open(`${frappeCloudBaseEndpoint}/dashboard/sites/${frappe.boot.sitename}`, "_blank");
|
||||
}
|
||||
|
||||
function generateTrialSubscriptionBanner(trialEndDate) {
|
||||
|
|
@ -169,14 +63,13 @@ function generateTrialSubscriptionBanner(trialEndDate) {
|
|||
align-items: center;
|
||||
background-color: var(--subtle-accent);
|
||||
border-radius: var(--border-radius-md);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.trial-banner > div {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.trial-banner .info-icon {
|
||||
margin: 4px 0;
|
||||
margin: auto 0;
|
||||
}
|
||||
.trial-banner > div > div {
|
||||
display: flex;
|
||||
|
|
@ -202,7 +95,7 @@ function generateTrialSubscriptionBanner(trialEndDate) {
|
|||
border-color: var(--gray-400);
|
||||
}
|
||||
</style>
|
||||
<div class="trial-banner px-3 py-2 m-2">
|
||||
<div class="trial-banner px-3 py-2 m-2 mt-4">
|
||||
<div>
|
||||
<svg class="info-icon" width="18" height="18" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_3360_13841)">
|
||||
|
|
@ -219,18 +112,26 @@ function generateTrialSubscriptionBanner(trialEndDate) {
|
|||
Your trial ends in ${trial_end_string}.
|
||||
</span>
|
||||
<span class="description">
|
||||
Please upgrade for uninterrupted services
|
||||
${
|
||||
isFCUser
|
||||
? "Please upgrade for uninterrupted services"
|
||||
: "Please contact your system administrator to upgrade your plan."
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button"
|
||||
${
|
||||
isFCUser
|
||||
? `<button type="button"
|
||||
class="upgrade-plan-button px-2 py-1"
|
||||
>
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.2641 1C5.5758 1 4.97583 1.46845 4.80889 2.1362L3.57555 7.06953C3.33887 8.01625 4.05491 8.93333 5.03077 8.93333H7.50682L6.72168 14.4293C6.68838 14.6624 6.82229 14.8872 7.04319 14.9689C7.26408 15.0507 7.51204 14.9671 7.63849 14.7684L13.2161 6.00354C13.6398 5.33782 13.1616 4.46667 12.3725 4.46667H9.59038L10.3017 1.62127C10.3391 1.4719 10.3055 1.31365 10.2108 1.19229C10.116 1.07094 9.97063 1 9.81666 1H6.2641ZM5.77903 2.37873C5.83468 2.15615 6.03467 2 6.2641 2H9.17627L8.46492 4.8454C8.42758 4.99477 8.46114 5.15302 8.55589 5.27437C8.65064 5.39573 8.79602 5.46667 8.94999 5.46667H12.3725L8.0395 12.2757L8.5783 8.50404C8.5988 8.36056 8.55602 8.21523 8.46105 8.10573C8.36608 7.99623 8.22827 7.93333 8.08332 7.93333H5.03077C4.70548 7.93333 4.4668 7.62764 4.5457 7.31207L5.77903 2.37873Z" fill="currentColor"/>
|
||||
</svg>
|
||||
${__("Upgrade plan")}
|
||||
</button>
|
||||
</button>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ frappe.data_import.ImportPreview = class ImportPreview {
|
|||
if (cell == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (typeof cell === "string") {
|
||||
cell = frappe.utils.xss_sanitise(cell);
|
||||
}
|
||||
return cell;
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -107,13 +107,15 @@ frappe.ui.form.ControlAttach = class ControlAttach extends frappe.ui.form.Contro
|
|||
this.$value
|
||||
.toggle(true)
|
||||
.find(".attached-file-link")
|
||||
.html(filename || this.value)
|
||||
.html(frappe.utils.xss_sanitise(filename || this.value))
|
||||
.attr("href", dataurl || this.value);
|
||||
} else {
|
||||
this.$wrapper.html(`
|
||||
<div class="attached-file flex justify-between align-center">
|
||||
<div class="ellipsis">
|
||||
<a href="${dataurl || this.value}" target="_blank">${filename || this.value}</a>
|
||||
<a href="${dataurl || this.value}" target="_blank">${frappe.utils.xss_sanitise(
|
||||
filename || this.value
|
||||
)}</a>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -428,7 +428,11 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
this.read_only = frappe.workflow.is_read_only(this.doctype, this.docname);
|
||||
if (this.read_only) {
|
||||
this.set_read_only();
|
||||
frappe.show_alert(__("This form is not editable due to a Workflow."));
|
||||
this.dashboard.set_headline(
|
||||
__("This form is not editable due to a Workflow."),
|
||||
"blue",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// check if doctype is already open
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ frappe.ui.form.Layout = class Layout {
|
|||
this.parent = this.body;
|
||||
}
|
||||
this.wrapper = $('<div class="form-layout">').appendTo(this.parent);
|
||||
this.message = $('<div class="form-message hidden"></div>').appendTo(this.wrapper);
|
||||
this.message = $('<div class="form-message-container hidden"></div>').appendTo(
|
||||
this.wrapper
|
||||
);
|
||||
this.page = $('<div class="form-page"></div>').appendTo(this.wrapper);
|
||||
|
||||
if (!this.fields) {
|
||||
|
|
@ -97,28 +99,41 @@ frappe.ui.form.Layout = class Layout {
|
|||
return fields;
|
||||
}
|
||||
|
||||
/**Render a message block with its own color and close button
|
||||
* @param {String} html - message or HTML to be displayed
|
||||
* @param {String} color - color of the block. One of "yellow", "blue", "red", "green" or "orange". Defaults to "blue".
|
||||
* @param {Boolean} permanent - if true, the block will not have a close button
|
||||
*/
|
||||
show_message(html, color, permanent = false) {
|
||||
if (this.message_color) {
|
||||
// remove previous color
|
||||
this.message.removeClass(this.message_color);
|
||||
}
|
||||
let close_message = $(`<div class="close-message">${frappe.utils.icon("close")}</div>`);
|
||||
this.message_color =
|
||||
color && ["yellow", "blue", "red", "green", "orange"].includes(color) ? color : "blue";
|
||||
if (html) {
|
||||
if (html.substr(0, 1) !== "<") {
|
||||
// wrap in a block
|
||||
html = "<div>" + html + "</div>";
|
||||
}
|
||||
this.message.removeClass("hidden").addClass(this.message_color);
|
||||
$(html).appendTo(this.message);
|
||||
if (!permanent) {
|
||||
close_message.appendTo(this.message);
|
||||
close_message.on("click", () => this.message.empty().addClass("hidden"));
|
||||
}
|
||||
} else {
|
||||
if (!html) {
|
||||
this.message.empty().addClass("hidden");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare Block
|
||||
let $html;
|
||||
if (html.substring(0, 1) !== "<") {
|
||||
// wrap in a block if `html` does not contain html tags
|
||||
$html = $("<div class='form-message border-bottom'></div>").text(html);
|
||||
} else {
|
||||
$html = $(html);
|
||||
$html.addClass("form-message border-bottom");
|
||||
}
|
||||
|
||||
// Add close button to block if not permanent
|
||||
const close_message = $(`<div class="close-message">${frappe.utils.icon("close")}</div>`);
|
||||
if (!permanent) {
|
||||
close_message.appendTo($html);
|
||||
close_message.on("click", () => $html.remove());
|
||||
}
|
||||
|
||||
// Add block color and append to parent container `form-message-container`
|
||||
const block_color =
|
||||
color && ["yellow", "blue", "red", "green", "orange"].includes(color) ? color : "blue";
|
||||
$html.addClass(block_color).appendTo(this.message);
|
||||
|
||||
// Show parent container if hidden
|
||||
this.message.removeClass("hidden");
|
||||
}
|
||||
|
||||
render(new_fields) {
|
||||
|
|
|
|||
|
|
@ -215,7 +215,8 @@ frappe.ui.form.QuickEntryForm = class QuickEntryForm extends frappe.ui.Dialog {
|
|||
},
|
||||
callback: function (r) {
|
||||
if (
|
||||
frappe.model.is_submittable(me.doctype) &&
|
||||
r?.message?.docstatus === 0 &&
|
||||
frappe.model.can_submit(me.doctype) &&
|
||||
!frappe.model.has_workflow(me.doctype)
|
||||
) {
|
||||
frappe.run_serially([
|
||||
|
|
|
|||
|
|
@ -3,22 +3,17 @@ frappe.ui.AppsSwitcher = class AppsSwitcher {
|
|||
this.drop_down_state = false;
|
||||
this.sidebar_wrapper = sidebar.wrapper;
|
||||
this.sidebar = sidebar;
|
||||
this.app_switcher = $(sidebar.app_switcher_dropdown[0]);
|
||||
this.setup_app_switcher();
|
||||
this.set_hover();
|
||||
}
|
||||
|
||||
setup_app_switcher() {
|
||||
this.app_switcher_menu = $(".app-switcher-menu");
|
||||
$(".app-switcher-dropdown").on("click", () => {
|
||||
this.set_active();
|
||||
this.app_switcher_menu.toggleClass("hidden");
|
||||
});
|
||||
|
||||
// hover out of the sidebar move this to sidebar.js
|
||||
this.sidebar_wrapper.find(".body-sidebar").on("mouseleave", () => {
|
||||
this.app_switcher_menu.addClass("hidden");
|
||||
|
||||
// hide any expanded menus as they leave a blank space in the sidebar
|
||||
this.sidebar_wrapper.find(".drop-icon[data-state='opened'").click();
|
||||
});
|
||||
}
|
||||
create_app_data_map() {
|
||||
frappe.boot.app_data_map = {};
|
||||
|
|
@ -152,4 +147,23 @@ frappe.ui.AppsSwitcher = class AppsSwitcher {
|
|||
// re-render the sidebar
|
||||
frappe.app.sidebar.make_sidebar();
|
||||
}
|
||||
set_hover() {
|
||||
this.app_switcher.on("mouseover", function (event) {
|
||||
if ($(this).hasClass("active-sidebar")) return;
|
||||
$(this).addClass("hover");
|
||||
if (!this.sidebar.sidebar_expanded) {
|
||||
$(this).removeClass("hover");
|
||||
}
|
||||
});
|
||||
|
||||
this.app_switcher.on("mouseleave", function () {
|
||||
$(this).removeClass("hover");
|
||||
});
|
||||
}
|
||||
set_active() {
|
||||
this.app_switcher.toggleClass("active-sidebar");
|
||||
if (!this.sidebar.sidebar_expanded) {
|
||||
this.app_switcher.removeClass("active-sidebar");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
frappe.ui.Sidebar = class Sidebar {
|
||||
constructor() {
|
||||
this.items = {};
|
||||
this.child_items = [];
|
||||
this.sidebar_expanded = false;
|
||||
|
||||
if (!frappe.boot.setup_complete) {
|
||||
|
|
@ -79,16 +80,64 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
}
|
||||
|
||||
set_active_workspace_item() {
|
||||
if (this.is_route_in_sidebar(decodeURIComponent(window.location.pathname))) {
|
||||
if (!frappe.get_route()) return;
|
||||
let current_route = frappe.get_route();
|
||||
let current_route_str = frappe.get_route_str();
|
||||
let current_item;
|
||||
if (current_route[0] == "Workspaces") {
|
||||
current_item = current_route[1];
|
||||
} else if (frappe.breadcrumbs) {
|
||||
if (Object.keys(frappe.breadcrumbs.all).length == 0) return;
|
||||
if (frappe.breadcrumbs.all[current_route_str]) {
|
||||
current_item =
|
||||
frappe.breadcrumbs.all[current_route_str].workspace ||
|
||||
frappe.breadcrumbs.all[current_route_str].module;
|
||||
}
|
||||
}
|
||||
if (this.is_route_in_sidebar(current_item)) {
|
||||
this.active_item.addClass("active-sidebar");
|
||||
}
|
||||
if (this.active_item) {
|
||||
if (this.is_nested_item(this.active_item.parent())) {
|
||||
let current_item = this.active_item.parent();
|
||||
this.expand_parent_item(current_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
expand_parent_item(item) {
|
||||
let parent_title = item.attr("item-parent");
|
||||
if (!parent_title) return;
|
||||
|
||||
let parent = this.get_sidebar_item(parent_title);
|
||||
$($(parent).children()[1]).removeClass("hidden");
|
||||
if (parent) {
|
||||
if (this.is_nested_item($(parent))) {
|
||||
this.expand_parent_item($(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
is_nested_item(item) {
|
||||
if (item.attr("item-parent")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
is_route_in_sidebar(route_name) {
|
||||
get_sidebar_item(name) {
|
||||
let sidebar_item = "";
|
||||
$(".sidebar-item-container").each(function () {
|
||||
if ($(this).attr("item-name") == name) {
|
||||
sidebar_item = this;
|
||||
}
|
||||
});
|
||||
return sidebar_item;
|
||||
}
|
||||
is_route_in_sidebar(active_module) {
|
||||
let match = false;
|
||||
const that = this;
|
||||
$(".item-anchor").each(function () {
|
||||
if ($(this).attr("href") == route_name) {
|
||||
if ($(this).attr("title") == active_module) {
|
||||
match = true;
|
||||
if (that.active_item) that.active_item.removeClass("active-sidebar");
|
||||
that.active_item = $(this).parent();
|
||||
|
|
@ -126,12 +175,19 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
this.make_sidebar();
|
||||
}
|
||||
this.set_hover();
|
||||
this.set_sidebar_state();
|
||||
if (!this.sidebar_expanded) this.close_children_item();
|
||||
}
|
||||
set_sidebar_state() {
|
||||
this.sidebar_expanded = true;
|
||||
if (localStorage.getItem("sidebar-expanded") !== null) {
|
||||
this.sidebar_expanded = JSON.parse(localStorage.getItem("sidebar-expanded"));
|
||||
this.expand_sidebar();
|
||||
}
|
||||
if (frappe.is_mobile()) {
|
||||
this.sidebar_expanded = false;
|
||||
}
|
||||
this.expand_sidebar();
|
||||
}
|
||||
|
||||
make_sidebar() {
|
||||
if (this.wrapper.find(".standard-sidebar-section")[0]) {
|
||||
this.wrapper.find(".standard-sidebar-section").remove();
|
||||
|
|
@ -173,6 +229,9 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
$(".list-sidebar.hidden-xs.hidden-sm").removeClass("opened");
|
||||
// $(".close-sidebar").css("display", "none");
|
||||
$("body").css("overflow", "auto");
|
||||
if (frappe.is_mobile()) {
|
||||
this.close_sidebar();
|
||||
}
|
||||
});
|
||||
|
||||
if (
|
||||
|
|
@ -242,6 +301,7 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
let child_container = $item_container.find(".sidebar-child-item");
|
||||
child_container.addClass("hidden");
|
||||
this.prepare_sidebar(child_items, child_container, $item_container);
|
||||
this.child_items.push(child_container);
|
||||
}
|
||||
|
||||
$item_container.appendTo(container);
|
||||
|
|
@ -394,10 +454,18 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
close_sidebar() {
|
||||
this.sidebar_expanded = false;
|
||||
this.expand_sidebar();
|
||||
this.close_children_item();
|
||||
}
|
||||
open_sidebar() {
|
||||
this.sidebar_expanded = true;
|
||||
this.expand_sidebar();
|
||||
this.set_active_workspace_item();
|
||||
}
|
||||
|
||||
close_children_item() {
|
||||
this.child_items.forEach((i) => {
|
||||
i.addClass("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
reload() {
|
||||
|
|
@ -406,4 +474,9 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
this.setup_pages();
|
||||
});
|
||||
}
|
||||
set_height() {
|
||||
$(".body-sidebar").css("height", window.innerHeight + "px");
|
||||
$(".overlay").css("height", window.innerHeight + "px");
|
||||
document.body.style.overflow = "hidden";
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -324,7 +324,10 @@ frappe.search.AwesomeBar = class AwesomeBar {
|
|||
var options = {};
|
||||
options[search_field] = ["like", "%" + txt + "%"];
|
||||
this.options.push({
|
||||
label: __("Find {0} in {1}", [txt.bold(), __(route[1]).bold()]),
|
||||
label: __("Find {0} in {1}", [
|
||||
frappe.utils.xss_sanitise(txt).bold(),
|
||||
__(route[1]).bold(),
|
||||
]),
|
||||
value: __("Find {0} in {1}", [txt, __(route[1])]),
|
||||
route_options: options,
|
||||
onclick: function () {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ frappe.ui.toolbar.Toolbar = class {
|
|||
this.bind_events();
|
||||
$(document).trigger("toolbar_setup");
|
||||
$(".navbar-brand .app-logo").on("click", () => {
|
||||
frappe.app.sidebar.set_height();
|
||||
frappe.app.sidebar.toggle_sidebar();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ frappe.breadcrumbs = {
|
|||
}
|
||||
this.all[frappe.breadcrumbs.current_page()] = obj;
|
||||
this.update();
|
||||
frappe.app.sidebar.set_active_workspace_item();
|
||||
},
|
||||
|
||||
current_page() {
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
frappe.run_serially([
|
||||
() => this.get_report_doc(),
|
||||
() => this.get_report_settings(),
|
||||
() => this.add_translate_data_checkbox(),
|
||||
() => this.setup_progress_bar(),
|
||||
() => this.setup_page_head(),
|
||||
() => this.refresh_report(route_options),
|
||||
|
|
@ -529,7 +530,6 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
const { filters = [] } = this.report_settings;
|
||||
|
||||
let filter_area = this.page.page_form;
|
||||
|
||||
this.filters = filters
|
||||
.map((df) => {
|
||||
if (df.fieldtype === "Break") return;
|
||||
|
|
@ -554,7 +554,6 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
// filter values have not changed
|
||||
return;
|
||||
}
|
||||
|
||||
// clear previous_filters after 10 seconds, to allow refresh for new data
|
||||
this.previous_filters = current_filters;
|
||||
setTimeout(() => (this.previous_filters = null), 10000);
|
||||
|
|
@ -1249,7 +1248,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
if (column.colIndex === index && !value) {
|
||||
value = "Total";
|
||||
value = __("Total");
|
||||
column = { fieldtype: "Data" }; // avoid type issues for value if Date column
|
||||
} else if (["Currency", "Float"].includes(column.fieldtype)) {
|
||||
// proxy for currency and float
|
||||
|
|
@ -2113,4 +2112,14 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
get get_values() {
|
||||
return this.get_filter_values;
|
||||
}
|
||||
|
||||
add_translate_data_checkbox() {
|
||||
if (frappe.boot.lang == "en") return;
|
||||
let filter_config = {
|
||||
fieldname: "translate_data",
|
||||
fieldtype: "Check",
|
||||
label: __("Translate Data"),
|
||||
};
|
||||
this.report_settings.filters.push(filter_config);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -30,7 +30,11 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
this.report_doc = doc;
|
||||
this.report_doc.json = JSON.parse(this.report_doc.json);
|
||||
|
||||
this.filters = this.report_doc.json.filters;
|
||||
this.filters = [
|
||||
...this.report_doc.json.filters,
|
||||
...this.parse_filters_from_route_options(),
|
||||
];
|
||||
|
||||
this.order_by = this.report_doc.json.order_by;
|
||||
this.add_totals_row = this.report_doc.json.add_totals_row;
|
||||
this.page_title = __(this.report_name);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
background-position: 50% 50%;
|
||||
fill: var(--icon-fill);
|
||||
stroke: var(--icon-stroke);
|
||||
stroke-width: 1.25px;
|
||||
stroke-width: 1.5px;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
}
|
||||
|
||||
.es-icon {
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@
|
|||
min-height: 100px;
|
||||
scrollbar-width: thin;
|
||||
border-top: 0 !important;
|
||||
.dt-cell {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.dt-tree-node__toggle + a {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
--surface-modal: rgba(255, 255, 255, 1);
|
||||
--divider-color: rgba(237, 237, 237, 1);
|
||||
--sidebar-width: 220px;
|
||||
--left-sidebar-width: 240px;
|
||||
}
|
||||
[data-theme="dark"] {
|
||||
--sidebar-hover-color: rgba(43, 43, 43, 1);
|
||||
|
|
@ -122,7 +123,7 @@ body {
|
|||
}
|
||||
|
||||
.sidebar-items {
|
||||
width: 204px;
|
||||
width: 224px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
width: 100%;
|
||||
|
|
@ -172,7 +173,7 @@ body {
|
|||
}
|
||||
|
||||
svg {
|
||||
margin: -1px;
|
||||
margin: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,17 +249,17 @@ body {
|
|||
.body-sidebar {
|
||||
// make it an overlay on hover
|
||||
position: absolute;
|
||||
width: var(--sidebar-width);
|
||||
width: var(--left-sidebar-width);
|
||||
.app-switcher-dropdown {
|
||||
width: 204px;
|
||||
width: 224px;
|
||||
left: 0px;
|
||||
padding: 2px 0px 2px 3px;
|
||||
padding: 3px;
|
||||
}
|
||||
.body-sidebar-top {
|
||||
width: 204px;
|
||||
width: 224px;
|
||||
overflow-y: hidden;
|
||||
.app-switcher-dropdown {
|
||||
width: 204px;
|
||||
width: 224px;
|
||||
}
|
||||
}
|
||||
.sidebar-item-container {
|
||||
|
|
@ -279,7 +280,7 @@ body {
|
|||
visibility: visible;
|
||||
}
|
||||
.body-sidebar-bottom {
|
||||
width: var(--sidebar-width);
|
||||
width: 224px;
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
|
|
@ -287,7 +288,7 @@ body {
|
|||
// show placeholder so that main section remains static
|
||||
.body-sidebar-placeholder {
|
||||
display: flex;
|
||||
width: var(--sidebar-width);
|
||||
width: var(--left-sidebar-width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +311,7 @@ body {
|
|||
position: relative;
|
||||
.body-sidebar {
|
||||
padding: 8px 8px 10px 8px;
|
||||
width: var(--sidebar-width);
|
||||
width: var(--left-sidebar-width);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
|
@ -319,10 +320,10 @@ body {
|
|||
.overlay {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100vw;
|
||||
width: calc(100vw - 240px);
|
||||
height: 100%;
|
||||
z-index: 1021;
|
||||
left: var(--sidebar-width);
|
||||
left: var(--left-sidebar-width);
|
||||
overflow: auto;
|
||||
background-color: rgba(128, 128, 128, 0.5);
|
||||
}
|
||||
|
|
@ -347,15 +348,15 @@ body {
|
|||
text-decoration: none;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
left: -2px;
|
||||
padding: 3px;
|
||||
margin-left: -2px;
|
||||
.standard-sidebar-item {
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
.d-flex {
|
||||
width: 161px;
|
||||
}
|
||||
gap: 8px;
|
||||
gap: 30px;
|
||||
}
|
||||
.sidebar-item-control {
|
||||
margin: 2px;
|
||||
|
|
@ -365,15 +366,13 @@ body {
|
|||
|
||||
.app-switcher-menu {
|
||||
position: absolute;
|
||||
top: 44px;
|
||||
left: 7px;
|
||||
width: 205px;
|
||||
top: 50px;
|
||||
left: 9px;
|
||||
width: 220px;
|
||||
padding: 6px;
|
||||
border-radius: var(--border-radius-lg);
|
||||
background: var(--surface-modal);
|
||||
box-shadow: 0px 10px 24px -3px rgba(0, 0, 0, 0.1);
|
||||
// box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.05);
|
||||
// box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: var(--shadow-xl);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
|
@ -421,7 +420,7 @@ body {
|
|||
|
||||
.active-sidebar {
|
||||
background: var(--sidebar-active-color);
|
||||
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: var(--shadow-sm);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.overlay {
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ class TestDocStatus(IntegrationTestCase):
|
|||
self.assertFalse(DocStatus.DRAFT.is_submitted())
|
||||
|
||||
def test_submitted(self):
|
||||
self.assertEqual(DocStatus(1), DocStatus.SUMBITTED)
|
||||
self.assertEqual(DocStatus(1), DocStatus.SUBMITTED)
|
||||
|
||||
self.assertFalse(DocStatus.SUMBITTED.is_draft())
|
||||
self.assertTrue(DocStatus.SUMBITTED.is_submitted())
|
||||
self.assertFalse(DocStatus.SUMBITTED.is_cancelled())
|
||||
self.assertFalse(DocStatus.SUBMITTED.is_draft())
|
||||
self.assertTrue(DocStatus.SUBMITTED.is_submitted())
|
||||
self.assertFalse(DocStatus.SUBMITTED.is_cancelled())
|
||||
|
||||
def test_cancelled(self):
|
||||
self.assertEqual(DocStatus(2), DocStatus.CANCELLED)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fi
|
|||
import frappe
|
||||
import frappe.monitor
|
||||
from frappe import _
|
||||
from frappe.utils import CallbackManager, cint, get_bench_id
|
||||
from frappe.utils import CallbackManager, cint, get_bench_id, get_sites
|
||||
from frappe.utils.caching import site_cache
|
||||
from frappe.utils.commands import log
|
||||
from frappe.utils.data import sbool
|
||||
from frappe.utils.redis_queue import RedisQueue
|
||||
|
|
@ -40,6 +41,8 @@ RQ_RESULTS_TTL = 10 * 60
|
|||
RQ_MAX_JOBS = 5000 # Restart NOFORK workers after every N number of jobs
|
||||
RQ_MAX_JOBS_JITTER = 50 # Random difference in max jobs to avoid restarting at same time
|
||||
|
||||
MAX_QUEUED_JOBS = 500 # frappe.enqueue will start failing when these many jobs exist in queue.
|
||||
|
||||
|
||||
_redis_queue_conn = None
|
||||
|
||||
|
|
@ -154,6 +157,8 @@ def enqueue(
|
|||
|
||||
raise
|
||||
|
||||
_check_queue_size(q)
|
||||
|
||||
if not timeout:
|
||||
timeout = get_queues_timeout().get(queue) or 300
|
||||
|
||||
|
|
@ -723,6 +728,31 @@ def flush_telemetry():
|
|||
ph and ph.flush()
|
||||
|
||||
|
||||
def _check_queue_size(q: Queue):
|
||||
max_jobs = cint(frappe.conf.max_queued_jobs) or MAX_QUEUED_JOBS
|
||||
# Workaround for arbitrarily sized benches,
|
||||
# TODO: Some concept of site-based fairness on consumption of queue
|
||||
max_jobs += _site_count() * 50
|
||||
|
||||
if cint(q.count) >= max_jobs:
|
||||
primary_action = {
|
||||
"label": "Monitor System Health",
|
||||
"client_action": "frappe.set_route",
|
||||
"args": ["Form", "System Health Report"],
|
||||
}
|
||||
frappe.throw(
|
||||
_("Too many queued background jobs ({0}). Please retry after some time.").format(max_jobs),
|
||||
title=_("Queue Overloaded"),
|
||||
exc=frappe.QueueOverloaded,
|
||||
primary_action=primary_action if frappe.has_permission("System Health Report") else None,
|
||||
)
|
||||
|
||||
|
||||
@site_cache(ttl=10 * 60)
|
||||
def _site_count() -> int:
|
||||
return len(get_sites())
|
||||
|
||||
|
||||
def _start_sentry():
|
||||
sentry_dsn = os.getenv("FRAPPE_SENTRY_DSN")
|
||||
if not sentry_dsn:
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ def get_home_page_via_hooks():
|
|||
|
||||
|
||||
def get_boot_data():
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site
|
||||
from frappe.locale import get_date_format, get_first_day_of_the_week, get_number_format, get_time_format
|
||||
|
||||
return {
|
||||
|
|
@ -187,6 +188,7 @@ def get_boot_data():
|
|||
},
|
||||
"assets_json": get_assets_json(),
|
||||
"sitename": frappe.local.site,
|
||||
"is_fc_site": is_fc_site(),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ no_cache = True
|
|||
|
||||
|
||||
def get_context(context):
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site
|
||||
|
||||
redirect_to = frappe.local.request.args.get("redirect-to")
|
||||
redirect_to = sanitize_redirect(redirect_to)
|
||||
|
||||
|
|
@ -37,6 +39,12 @@ def get_context(context):
|
|||
frappe.local.flags.redirect_location = redirect_to
|
||||
raise frappe.Redirect
|
||||
|
||||
if is_fc_site():
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import get_site_login_url
|
||||
|
||||
frappe.local.flags.redirect_location = get_site_login_url()
|
||||
raise frappe.Redirect
|
||||
|
||||
context.no_header = True
|
||||
context.for_test = "login.html"
|
||||
context["title"] = "Login"
|
||||
|
|
|
|||
|
|
@ -442,19 +442,20 @@ def get_print_format(doctype: str, print_format: "PrintFormat") -> str:
|
|||
module = print_format.module or frappe.db.get_value("DocType", doctype, "module")
|
||||
|
||||
is_custom_module = frappe.get_cached_value("Module Def", module, "custom")
|
||||
if is_custom_module:
|
||||
if print_format.raw_printing:
|
||||
return print_format.raw_commands
|
||||
if print_format.html:
|
||||
return print_format.html
|
||||
|
||||
path = os.path.join(
|
||||
get_module_path(module, "Print Format", print_format.name),
|
||||
frappe.scrub(print_format.name) + ".html",
|
||||
)
|
||||
if os.path.exists(path):
|
||||
with open(path) as pffile:
|
||||
return pffile.read()
|
||||
if not is_custom_module:
|
||||
path = os.path.join(
|
||||
get_module_path(module, "Print Format", print_format.name),
|
||||
frappe.scrub(print_format.name) + ".html",
|
||||
)
|
||||
if os.path.exists(path):
|
||||
with open(path) as pffile:
|
||||
return pffile.read()
|
||||
|
||||
if print_format.raw_printing:
|
||||
return print_format.raw_commands
|
||||
if print_format.html:
|
||||
return print_format.html
|
||||
|
||||
frappe.throw(_("No template found at path: {0}").format(path), frappe.TemplateNotFoundError)
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-glob": "^3.2.5",
|
||||
"frappe-charts": "2.0.0-rc22",
|
||||
"frappe-datatable": "1.17.16",
|
||||
"frappe-datatable": "1.18.0",
|
||||
"frappe-gantt": "^0.6.0",
|
||||
"highlight.js": "^10.4.1",
|
||||
"html5-qrcode": "^2.3.8",
|
||||
|
|
|
|||
|
|
@ -1490,10 +1490,10 @@ frappe-charts@2.0.0-rc22:
|
|||
resolved "https://registry.yarnpkg.com/frappe-charts/-/frappe-charts-2.0.0-rc22.tgz#9a5a747febdc381a1d4d7af96e89cf519dfba8c0"
|
||||
integrity sha512-N7f/8979wJCKjusOinaUYfMxB80YnfuVLrSkjpj4LtyqS0BGS6SuJxUnb7Jl4RWUFEIs7zEhideIKnyLeFZF4Q==
|
||||
|
||||
frappe-datatable@1.17.16:
|
||||
version "1.17.16"
|
||||
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.17.16.tgz#4e7bf3b50dad5bc048f95ccd7ca7da91e04844ab"
|
||||
integrity sha512-BJgWFX8msHZcS1mw2xbuaY1YdH1dBXUIuREVmqH5z1p78GusPaDV8sbWskTS5yVBUklMrMq2VfBTUsJXjvl+wg==
|
||||
frappe-datatable@1.18.0:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.18.0.tgz#d50be2ed3a4a34e22d7e64e05ee3d30f1ec9b617"
|
||||
integrity sha512-8tPCFB75eF1ITYXNQaNY8HZBb/HZB2ol3HjsEYeigYbnhq/v9gYDroQuVN8v9j1WbBeFdDPR02ca2wOuUIEsDA==
|
||||
dependencies:
|
||||
hyperlist "^1.0.0-beta"
|
||||
lodash "^4.17.5"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue