Merge branch 'develop' into 27880-child-table-titles-not-translating-in-notifications-with-custom-print-templates
This commit is contained in:
commit
e32d5e0e3f
63 changed files with 627 additions and 275 deletions
|
|
@ -27,7 +27,9 @@ context("Web Form", () => {
|
|||
|
||||
cy.wait("@save_form");
|
||||
|
||||
cy.get('.frappe-control[data-fieldname="route"]').scrollIntoView();
|
||||
cy.get_field("route").should("have.value", "note");
|
||||
|
||||
cy.get(".title-area .indicator-pill")
|
||||
.should("contain.text", "Published")
|
||||
.should("have.class", "green");
|
||||
|
|
|
|||
|
|
@ -211,8 +211,7 @@ frappe.ui.form.on("Communication", {
|
|||
],
|
||||
primary_action_label: __("Move"),
|
||||
primary_action(values) {
|
||||
d.hide();
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: "frappe.email.inbox.move_email",
|
||||
args: {
|
||||
communication: frm.doc.name,
|
||||
|
|
@ -220,6 +219,7 @@ frappe.ui.form.on("Communication", {
|
|||
},
|
||||
freeze: true,
|
||||
callback: function () {
|
||||
d.hide();
|
||||
window.history.back();
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ frappe.listview_settings["DocType"] = {
|
|||
primary_action_label: __("Create & Continue"),
|
||||
primary_action(values) {
|
||||
if (!values.istable) values.editable_grid = 0;
|
||||
frappe.db
|
||||
return frappe.db
|
||||
.insert({
|
||||
doctype: "DocType",
|
||||
...values,
|
||||
|
|
|
|||
|
|
@ -890,6 +890,14 @@ def has_permission(doc, ptype=None, user=None, debug=False):
|
|||
|
||||
if user != "Guest" and doc.owner == user:
|
||||
return True
|
||||
if (
|
||||
user != "Guest"
|
||||
and ptype in ["read", "write", "share", "submit"]
|
||||
and frappe.share.get_shared(
|
||||
"File", filters=[["share_name", "=", doc.name]], rights=[ptype], user=user
|
||||
)
|
||||
):
|
||||
return True
|
||||
|
||||
if doc.attached_to_doctype and doc.attached_to_name:
|
||||
attached_to_doctype = doc.attached_to_doctype
|
||||
|
|
|
|||
|
|
@ -427,6 +427,29 @@ def relink_mismatched_files(doc: "Document") -> None:
|
|||
for df in attach_fields:
|
||||
if doc.get(df.fieldname):
|
||||
relink_files(doc, df.fieldname, doc.__temporary_name)
|
||||
|
||||
# Relink files in child table Attach fields
|
||||
table_fields = doc.meta.get("fields", {"fieldtype": "Table"})
|
||||
for table_df in table_fields:
|
||||
child_rows = doc.get(table_df.fieldname) or []
|
||||
if not child_rows:
|
||||
continue
|
||||
|
||||
child_meta = frappe.get_meta(table_df.options)
|
||||
child_attach_fields = child_meta.get("fields", {"fieldtype": ["in", ["Attach", "Attach Image"]]})
|
||||
|
||||
if not child_attach_fields:
|
||||
continue
|
||||
|
||||
for child_row in child_rows:
|
||||
for child_df in child_attach_fields:
|
||||
file_url = child_row.get(child_df.fieldname)
|
||||
if file_url:
|
||||
frappe.db.set_value(
|
||||
"File",
|
||||
{"file_url": file_url, "attached_to_name": doc.__temporary_name},
|
||||
{"attached_to_name": doc.name},
|
||||
)
|
||||
# delete temporary name after relinking is done
|
||||
doc.delete_key("__temporary_name")
|
||||
|
||||
|
|
|
|||
|
|
@ -201,18 +201,19 @@ frappe.ui.form.on("User", {
|
|||
},
|
||||
],
|
||||
primary_action: (values) => {
|
||||
d.hide();
|
||||
if (values.new_password !== values.confirm_password) {
|
||||
frappe.throw(__("Passwords do not match!"));
|
||||
}
|
||||
frappe.call(
|
||||
"frappe.integrations.doctype.ldap_settings.ldap_settings.reset_password",
|
||||
{
|
||||
user: frm.doc.email,
|
||||
password: values.new_password,
|
||||
logout: values.logout_sessions,
|
||||
}
|
||||
);
|
||||
return frappe
|
||||
.call(
|
||||
"frappe.integrations.doctype.ldap_settings.ldap_settings.reset_password",
|
||||
{
|
||||
user: frm.doc.email,
|
||||
password: values.new_password,
|
||||
logout: values.logout_sessions,
|
||||
}
|
||||
)
|
||||
.then(() => d.hide());
|
||||
},
|
||||
});
|
||||
d.show();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ frappe.query_reports["Database Storage Usage By Tables"] = {
|
|||
size: "small",
|
||||
primary_action_label: "Optimize",
|
||||
primary_action(values) {
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: "frappe.core.report.database_storage_usage_by_tables.database_storage_usage_by_tables.optimize_doctype",
|
||||
args: {
|
||||
doctype_name: values.doctype_name,
|
||||
|
|
@ -38,9 +38,9 @@ frappe.query_reports["Database Storage Usage By Tables"] = {
|
|||
)
|
||||
);
|
||||
}
|
||||
d.hide();
|
||||
},
|
||||
});
|
||||
d.hide();
|
||||
},
|
||||
});
|
||||
d.show();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ def execute(filters=None):
|
|||
round((data_length / 1024 / 1024), 2) as data_size,
|
||||
round((index_length / 1024 / 1024), 2) as index_size
|
||||
FROM information_schema.TABLES
|
||||
WHERE table_schema = DATABASE()
|
||||
ORDER BY (data_length + index_length) DESC;
|
||||
""",
|
||||
"postgres": """
|
||||
|
|
|
|||
|
|
@ -488,7 +488,13 @@ frappe.ui.form.on("Dashboard Chart", {
|
|||
});
|
||||
|
||||
dialog.show();
|
||||
dialog.set_values(frm.dynamic_filters);
|
||||
if (frm.dynamic_filters) {
|
||||
let filter_values = {};
|
||||
frm.dynamic_filters.forEach((f) => {
|
||||
filter_values[f[0] + ":" + f[1]] = f[3];
|
||||
});
|
||||
dialog.set_values(filter_values);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -124,11 +124,6 @@ frappe.ui.form.on("Number Card", {
|
|||
frappe.model.with_doctype(doctype, () => {
|
||||
frappe.get_meta(doctype).fields.map((df) => {
|
||||
if (frappe.model.numeric_fieldtypes.includes(df.fieldtype)) {
|
||||
if (df.fieldtype == "Currency") {
|
||||
if (!df.options || df.options !== "Company:company:default_currency") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
aggregate_based_on_fields.push({ label: df.label, value: df.fieldname });
|
||||
}
|
||||
});
|
||||
|
|
@ -405,7 +400,13 @@ frappe.ui.form.on("Number Card", {
|
|||
});
|
||||
|
||||
dialog.show();
|
||||
dialog.set_values(frm.dynamic_filters);
|
||||
if (frm.dynamic_filters) {
|
||||
let filter_values = {};
|
||||
frm.dynamic_filters.forEach((f) => {
|
||||
filter_values[f[0] + ":" + f[1]] = f[3];
|
||||
});
|
||||
dialog.set_values(filter_values);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -437,37 +437,19 @@ def get_linked_docs(doctype: str, name: str, linkinfo: dict | None = None) -> di
|
|||
is_target_doctype_table = frappe.get_meta(doctype).istable
|
||||
|
||||
for linked_doctype, link_context in linkinfo.items():
|
||||
# Don't try to fetch linked documents if the user can't read the doctype
|
||||
if not frappe.has_permission(linked_doctype):
|
||||
continue
|
||||
|
||||
linked_doctype_meta = frappe.get_meta(linked_doctype)
|
||||
|
||||
if linked_doctype_meta.issingle:
|
||||
continue
|
||||
|
||||
has_permission = frappe.has_permission(linked_doctype)
|
||||
filters = []
|
||||
or_filters = []
|
||||
ret = None
|
||||
parent_info = None
|
||||
|
||||
fields = [
|
||||
d.fieldname
|
||||
for d in linked_doctype_meta.get(
|
||||
"fields",
|
||||
{
|
||||
"in_list_view": 1,
|
||||
"fieldtype": ["not in", ("Image", "HTML", "Button", *frappe.model.table_fields)],
|
||||
},
|
||||
)
|
||||
] + ["name", "modified", "docstatus"]
|
||||
|
||||
if add_fields := link_context.get("add_fields"):
|
||||
fields += add_fields
|
||||
|
||||
fields = [sf.strip() for sf in fields if sf]
|
||||
|
||||
if filters_ctx := link_context.get("filters"):
|
||||
ret = frappe.get_list(doctype=linked_doctype, fields=fields, filters=filters_ctx, order_by=None)
|
||||
filters = filters_ctx
|
||||
|
||||
elif link_context.get("get_parent"):
|
||||
# check for child table
|
||||
|
|
@ -478,13 +460,10 @@ def get_linked_docs(doctype: str, name: str, linkinfo: dict | None = None) -> di
|
|||
doctype, name, ["parenttype", "parent"], as_dict=True, order_by=None
|
||||
)
|
||||
|
||||
if parent_info and parent_info.parenttype == linked_doctype:
|
||||
ret = frappe.get_list(
|
||||
doctype=linked_doctype,
|
||||
fields=fields,
|
||||
filters=[[linked_doctype, "name", "=", parent_info.parent]],
|
||||
order_by=None,
|
||||
)
|
||||
if not (parent_info and parent_info.parenttype == linked_doctype):
|
||||
continue
|
||||
|
||||
filters = [[linked_doctype, "name", "=", parent_info.parent]]
|
||||
|
||||
elif child_doctype := link_context.get("child_doctype"):
|
||||
or_filters = [
|
||||
|
|
@ -495,15 +474,6 @@ def get_linked_docs(doctype: str, name: str, linkinfo: dict | None = None) -> di
|
|||
if doctype_fieldname := link_context.get("doctype_fieldname"):
|
||||
filters.append([child_doctype, doctype_fieldname, "=", doctype])
|
||||
|
||||
ret = frappe.get_list(
|
||||
doctype=linked_doctype,
|
||||
fields=fields,
|
||||
filters=filters,
|
||||
or_filters=or_filters,
|
||||
distinct=True,
|
||||
order_by=None,
|
||||
)
|
||||
|
||||
elif link_fieldnames := link_context.get("fieldname"):
|
||||
if isinstance(link_fieldnames, str):
|
||||
link_fieldnames = [link_fieldnames]
|
||||
|
|
@ -518,12 +488,51 @@ def get_linked_docs(doctype: str, name: str, linkinfo: dict | None = None) -> di
|
|||
or frappe.db.exists(linked_doctype, {"parenttype": doctype, "parent": name})
|
||||
):
|
||||
continue
|
||||
|
||||
total_count = len(
|
||||
frappe.get_all(
|
||||
linked_doctype,
|
||||
filters=filters,
|
||||
or_filters=or_filters,
|
||||
fields=["name"],
|
||||
order_by=None,
|
||||
)
|
||||
)
|
||||
|
||||
if not total_count:
|
||||
continue
|
||||
|
||||
if has_permission:
|
||||
fields = [
|
||||
d.fieldname
|
||||
for d in linked_doctype_meta.get(
|
||||
"fields",
|
||||
{
|
||||
"in_list_view": 1,
|
||||
"fieldtype": ["not in", ("Image", "HTML", "Button", *frappe.model.table_fields)],
|
||||
},
|
||||
)
|
||||
] + ["name", "modified", "docstatus"]
|
||||
|
||||
if add_fields := link_context.get("add_fields"):
|
||||
fields += add_fields
|
||||
|
||||
fields = [sf.strip() for sf in fields if sf]
|
||||
|
||||
ret = frappe.get_list(
|
||||
doctype=linked_doctype, fields=fields, filters=filters, or_filters=or_filters, order_by=None
|
||||
doctype=linked_doctype,
|
||||
fields=fields,
|
||||
filters=filters,
|
||||
or_filters=or_filters,
|
||||
distinct=True,
|
||||
order_by=None,
|
||||
)
|
||||
|
||||
if ret:
|
||||
results[linked_doctype] = ret
|
||||
permitted_count = len(ret or [])
|
||||
results[linked_doctype] = {
|
||||
"docs": ret or [],
|
||||
"hidden_count": total_count - permitted_count,
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
|
|
|
|||
|
|
@ -87,12 +87,17 @@
|
|||
}
|
||||
}
|
||||
.modal
|
||||
.modal-body .icons-container,.folder-icon .icons-container {
|
||||
.modal-body .icons-container, .folder-icon .icons-container {
|
||||
padding:0px;
|
||||
margin: 0px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.folder-icon .icons-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icons{
|
||||
gap: 16px;
|
||||
display: grid;
|
||||
|
|
|
|||
|
|
@ -548,7 +548,6 @@ class DesktopPage {
|
|||
frappe.router.on("change", function () {
|
||||
if (frappe.get_route()[0] == "desktop" || frappe.get_route()[0] == "") {
|
||||
me.setup_navbar();
|
||||
me.setup_edit_button();
|
||||
} else {
|
||||
$(".navbar").show();
|
||||
frappe.desktop_utils.close_desktop_modal();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-25 23:15\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Bosnian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -2870,7 +2870,7 @@ msgstr "Dodjela je Završena"
|
|||
#. Label of the assignment_days (Table) field in DocType 'Assignment Rule'
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.json
|
||||
msgid "Assignment Days"
|
||||
msgstr "Dani Dodjeljivanja"
|
||||
msgstr "Dani Dodjele"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of the assignment_rule (Link) field in DocType 'ToDo'
|
||||
|
|
@ -2888,7 +2888,7 @@ msgstr "Dan Dodjele Pravila"
|
|||
#. Name of a DocType
|
||||
#: frappe/automation/doctype/assignment_rule_user/assignment_rule_user.json
|
||||
msgid "Assignment Rule User"
|
||||
msgstr "Korisnik Dodjele Pravila"
|
||||
msgstr "Korisnik Pravila Dodjele"
|
||||
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.py:55
|
||||
msgid "Assignment Rule is not allowed on document type {0}"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-25 23:14\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Persian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -6314,7 +6314,7 @@ msgstr "سفارشیسازی"
|
|||
|
||||
#: frappe/custom/doctype/customize_form/customize_form.js:89
|
||||
msgid "Customize Child Table"
|
||||
msgstr "سفارشی کردن جدول فرزند"
|
||||
msgstr "سفارشیسازی جدول فرزند"
|
||||
|
||||
#: frappe/public/js/frappe/views/dashboard/dashboard_view.js:38
|
||||
msgid "Customize Dashboard"
|
||||
|
|
@ -6339,7 +6339,7 @@ msgstr "سفارشیسازی فرم - {0}"
|
|||
#. Name of a DocType
|
||||
#: frappe/custom/doctype/customize_form_field/customize_form_field.json
|
||||
msgid "Customize Form Field"
|
||||
msgstr "سفارشی کردن فیلد فرم"
|
||||
msgstr "سفارشیسازی فیلد فرم"
|
||||
|
||||
#: frappe/public/js/frappe/list/list_view.js:1994
|
||||
msgctxt "Customize qucik filters of List View"
|
||||
|
|
@ -18808,7 +18808,7 @@ msgstr ""
|
|||
|
||||
#: frappe/core/doctype/doctype/doctype.py:1699
|
||||
msgid "Options for Rating field can range from 3 to 10"
|
||||
msgstr "گزینههای فیلد رتبه بندی میتواند از 3 تا 10 باشد"
|
||||
msgstr "گزینههای فیلد رتبهبندی میتواند از 3 تا 10 باشد"
|
||||
|
||||
#: frappe/custom/doctype/custom_field/custom_field.js:96
|
||||
msgid "Options for select. Each option on a new line."
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-25 23:14\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Croatian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -2870,7 +2870,7 @@ msgstr "Dodjela je Završena"
|
|||
#. Label of the assignment_days (Table) field in DocType 'Assignment Rule'
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.json
|
||||
msgid "Assignment Days"
|
||||
msgstr "Dani Dodjeljivanja"
|
||||
msgstr "Dani Dodjele"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of the assignment_rule (Link) field in DocType 'ToDo'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-26 23:27\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Serbian (Cyrillic)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -1357,7 +1357,7 @@ msgstr "Додај параметре упита"
|
|||
#. Label of the add_reply_to_header (Check) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Add Reply-To header"
|
||||
msgstr ""
|
||||
msgstr "Додај заглавље адресе за одговор"
|
||||
|
||||
#: frappe/core/doctype/user/user.py:860
|
||||
msgid "Add Roles"
|
||||
|
|
@ -1523,7 +1523,7 @@ msgstr "Додај на контролну таблу"
|
|||
|
||||
#: frappe/desk/doctype/workspace/workspace.js:49
|
||||
msgid "Add to Desktop"
|
||||
msgstr ""
|
||||
msgstr "Додај на радну површину"
|
||||
|
||||
#: frappe/public/js/frappe/form/sidebar/assign_to.js:110
|
||||
msgid "Add to ToDo"
|
||||
|
|
@ -1646,7 +1646,7 @@ msgstr "Адресе и контакти"
|
|||
#. Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Addresses added here will be used as the Reply-To header for outgoing emails sent from this account."
|
||||
msgstr ""
|
||||
msgstr "Адресе додате овде користиће се као адреса за одговор за излазне имејлове послате са овог налога."
|
||||
|
||||
#. Description of a DocType
|
||||
#: frappe/custom/doctype/client_script/client_script.json
|
||||
|
|
@ -3082,7 +3082,7 @@ msgstr "Историја измена"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/users.json
|
||||
msgid "Audits"
|
||||
msgstr ""
|
||||
msgstr "Ревизије"
|
||||
|
||||
#. Label of the auth_url_data (Code) field in DocType 'Social Login Key'
|
||||
#: frappe/integrations/doctype/social_login_key/social_login_key.json
|
||||
|
|
@ -3516,7 +3516,7 @@ msgstr "Слика позадине"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/system.json
|
||||
msgid "Background Job"
|
||||
msgstr ""
|
||||
msgstr "Позадински задатак"
|
||||
|
||||
#. Label of a Link in the Build Workspace
|
||||
#. Label of the background_jobs_section (Section Break) field in DocType
|
||||
|
|
@ -4934,7 +4934,7 @@ msgstr "Кликните да поставите филтере"
|
|||
|
||||
#: frappe/desk/page/desktop/desktop.js:1261
|
||||
msgid "Click to edit"
|
||||
msgstr ""
|
||||
msgstr "Кликните за уређивање"
|
||||
|
||||
#: frappe/public/js/frappe/list/list_view.js:754
|
||||
msgid "Click to sort by {0}"
|
||||
|
|
@ -6537,7 +6537,7 @@ msgstr "Цијан"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "DELAY"
|
||||
msgstr ""
|
||||
msgstr "ОДЛАГАЊЕ"
|
||||
|
||||
#. Option for the 'Method' (Select) field in DocType 'Recorder'
|
||||
#. Option for the 'Request Method' (Select) field in DocType 'Webhook'
|
||||
|
|
@ -7365,7 +7365,7 @@ msgstr "Статус"
|
|||
#. Label of the dsn_notify_type (Select) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Delivery Status Notification Type"
|
||||
msgstr ""
|
||||
msgstr "Врста обавештења о статусу испоруке"
|
||||
|
||||
#. Option for the 'Sign ups' (Select) field in DocType 'Social Login Key'
|
||||
#: frappe/integrations/doctype/social_login_key/social_login_key.json
|
||||
|
|
@ -9430,7 +9430,7 @@ msgstr "Планер омогућен"
|
|||
#. Label of the enabled (Check) field in DocType 'Notification Settings'
|
||||
#: frappe/desk/doctype/notification_settings/notification_settings.json
|
||||
msgid "Enabled System Notification"
|
||||
msgstr ""
|
||||
msgstr "Омогућено системско обавештење"
|
||||
|
||||
#: frappe/email/doctype/email_account/email_account.py:1101
|
||||
msgid "Enabled email inbox for user {0}"
|
||||
|
|
@ -10128,7 +10128,7 @@ msgstr "Додатни параметри"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "FAILURE"
|
||||
msgstr ""
|
||||
msgstr "НЕУСПЕХ"
|
||||
|
||||
#. Option for the 'Social Login Provider' (Select) field in DocType 'Social
|
||||
#. Login Key'
|
||||
|
|
@ -10272,7 +10272,7 @@ msgstr "Неуспешан покушај пријаве на Frappe Cloud"
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:232
|
||||
msgid "Failed to retrieve the list of IMAP folders from the server. Please ensure the mailbox is accessible and the account has permission to list folders."
|
||||
msgstr ""
|
||||
msgstr "Неуспешно преузимање листе IMAP директоријума са сервера. Проверите да ли је поштанско сандуче доступно и да ли налог има дозволу за приказ директоријума."
|
||||
|
||||
#: frappe/email/doctype/email_queue/email_queue.py:311
|
||||
msgid "Failed to send email with subject:"
|
||||
|
|
@ -11339,7 +11339,7 @@ msgstr "Јединица фракције"
|
|||
#. Label of a Desktop Icon
|
||||
#: frappe/desktop_icon/framework.json
|
||||
msgid "Framework"
|
||||
msgstr ""
|
||||
msgstr "Framework"
|
||||
|
||||
#. Option for the 'Social Login Provider' (Select) field in DocType 'Social
|
||||
#. Login Key'
|
||||
|
|
@ -12235,7 +12235,7 @@ msgstr "Наслов"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/system.json
|
||||
msgid "Health Report"
|
||||
msgstr ""
|
||||
msgstr "Извештај о стању система"
|
||||
|
||||
#. Option for the 'Type' (Select) field in DocType 'Dashboard Chart'
|
||||
#: frappe/desk/doctype/dashboard_chart/dashboard_chart.json
|
||||
|
|
@ -12654,7 +12654,7 @@ msgstr "IMAP датотека"
|
|||
#: frappe/email/doctype/email_account/email_account.py:235
|
||||
#: frappe/email/doctype/email_account/email_account.py:263
|
||||
msgid "IMAP Folder Not Found"
|
||||
msgstr ""
|
||||
msgstr "IMAP директоријум није пронађен"
|
||||
|
||||
#. Label of the ip_address (Data) field in DocType 'Activity Log'
|
||||
#. Label of the ip_address (Data) field in DocType 'Comment'
|
||||
|
|
@ -13414,7 +13414,7 @@ msgstr "Погрешан верификациони код"
|
|||
|
||||
#: frappe/public/js/frappe/views/gantt/gantt_view.js:88
|
||||
msgid "Incorrect configuration"
|
||||
msgstr ""
|
||||
msgstr "Неисправна конфигурација"
|
||||
|
||||
#: frappe/model/document.py:1733
|
||||
msgid "Incorrect value in row {0}:"
|
||||
|
|
@ -16979,7 +16979,7 @@ msgstr "MyISAM"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "NEVER"
|
||||
msgstr ""
|
||||
msgstr "НИКАДА"
|
||||
|
||||
#: frappe/workflow/doctype/workflow/workflow.js:19
|
||||
msgid "NOTE: If you add states or transitions in the table, it will be reflected in the Workflow Builder but you will have to position them manually. Also Workflow Builder is currently in <b>BETA</b>."
|
||||
|
|
@ -17750,7 +17750,7 @@ msgstr "Нема података за извоз"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/query_report.js:1543
|
||||
msgid "No data to perform this action"
|
||||
msgstr ""
|
||||
msgstr "Нема података за извршавање ове радње"
|
||||
|
||||
#: frappe/contacts/doctype/address/address.py:247
|
||||
msgid "No default Address Template found. Please create a new one from Setup > Printing and Branding > Address Template."
|
||||
|
|
@ -17795,7 +17795,7 @@ msgstr "Нема додатних записа"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/report_view.js:337
|
||||
msgid "No matching entries in the current results"
|
||||
msgstr ""
|
||||
msgstr "Нема подударних записа у тренутним резултатима"
|
||||
|
||||
#: frappe/templates/includes/search_template.html:49
|
||||
msgid "No matching records. Search something new"
|
||||
|
|
@ -18429,7 +18429,7 @@ msgstr "OAuth грешка"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/integrations.json
|
||||
msgid "OAuth Provider"
|
||||
msgstr ""
|
||||
msgstr "OAuth провајдер"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of a Link in the Integrations Workspace
|
||||
|
|
@ -18698,7 +18698,7 @@ msgstr "Дозволи уређивање само за"
|
|||
|
||||
#: frappe/core/doctype/module_def/module_def.py:95
|
||||
msgid "Only Custom Modules can be renamed."
|
||||
msgstr ""
|
||||
msgstr "Искључиво прилагођени модули могу бити преименовани."
|
||||
|
||||
#: frappe/core/doctype/doctype/doctype.py:1652
|
||||
msgid "Only Options allowed for Data field are:"
|
||||
|
|
@ -19969,7 +19969,7 @@ msgstr "Молимо Вас да додате валидан коментар."
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/query_report.js:1544
|
||||
msgid "Please adjust filters to include some data"
|
||||
msgstr ""
|
||||
msgstr "Прилагодите филтере како бисте укључили неке податке"
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1122
|
||||
msgid "Please ask your administrator to verify your sign-up"
|
||||
|
|
@ -20029,7 +20029,7 @@ msgstr "Молимо Вас да кликнете на следећи линк
|
|||
|
||||
#: frappe/public/js/frappe/views/gantt/gantt_view.js:89
|
||||
msgid "Please configure the start field for this Doctype in the controller file."
|
||||
msgstr ""
|
||||
msgstr "Молимо Вас да конфигуришете почетно поље за овај DocType у датотеци контролера."
|
||||
|
||||
#: frappe/www/confirm_workflow_action.html:4
|
||||
msgid "Please confirm your action to {0} this document."
|
||||
|
|
@ -21132,7 +21132,7 @@ msgstr "Љубичасто"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/integrations.json
|
||||
msgid "Push Notification"
|
||||
msgstr ""
|
||||
msgstr "Push обавештење"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of a Link in the Integrations Workspace
|
||||
|
|
@ -22225,16 +22225,16 @@ msgstr "Одговори свима"
|
|||
#. Name of a DocType
|
||||
#: frappe/email/doctype/reply_to_address/reply_to_address.json
|
||||
msgid "Reply To Address"
|
||||
msgstr ""
|
||||
msgstr "Адреса за одговор"
|
||||
|
||||
#: frappe/email/doctype/email_account/email_account.py:278
|
||||
msgid "Reply To email is required"
|
||||
msgstr ""
|
||||
msgstr "Адреса за одговор је обавезна"
|
||||
|
||||
#. Label of the reply_to_addresses (Table) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Reply-To Addresses"
|
||||
msgstr ""
|
||||
msgstr "Адреса за одговор"
|
||||
|
||||
#. Label of the report (Check) field in DocType 'Custom DocPerm'
|
||||
#. Label of the report (Link) field in DocType 'Custom Role'
|
||||
|
|
@ -23276,19 +23276,19 @@ msgstr "SSL/TLS режим"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS"
|
||||
msgstr ""
|
||||
msgstr "УСПЕХ"
|
||||
|
||||
#. Option for the 'Delivery Status Notification Type' (Select) field in DocType
|
||||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS,FAILURE"
|
||||
msgstr ""
|
||||
msgstr "УСПЕХ, НЕУСПЕХ"
|
||||
|
||||
#. Option for the 'Delivery Status Notification Type' (Select) field in DocType
|
||||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS,FAILURE,DELAY"
|
||||
msgstr ""
|
||||
msgstr "УСПЕХ, НЕУСПЕХ, ОДЛАГАЊЕ"
|
||||
|
||||
#: frappe/public/js/frappe/color_picker/color_picker.js:20
|
||||
msgid "SWATCHES"
|
||||
|
|
@ -24115,7 +24115,7 @@ msgstr "Изабери две верзије за приказ разлика."
|
|||
#. DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Select which delivery events should trigger a delivery status notification (DSN) from the SMTP server."
|
||||
msgstr ""
|
||||
msgstr "Изаберите који догађаји испоруке треба да покрену обавештење о статусу испоруке (DNS) са SMTP сервера."
|
||||
|
||||
#: frappe/public/js/frappe/form/link_selector.js:24
|
||||
#: frappe/public/js/frappe/form/multi_select_dialog.js:80
|
||||
|
|
@ -27098,7 +27098,7 @@ msgstr "Коментар не може бити празан"
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:290
|
||||
msgid "The configured SMTP server does not support DSN (Delivery Status Notification)."
|
||||
msgstr ""
|
||||
msgstr "Конфигурисани SMTP сервер не подржава DNS (обавештење о статусу испоруке)."
|
||||
|
||||
#: frappe/templates/emails/workflow_action.html:9
|
||||
msgid "The contents of this email are strictly confidential. Please do not forward this email to anyone."
|
||||
|
|
@ -27160,7 +27160,7 @@ msgstr "Следећа скрипта заглавља ће додати тре
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:257
|
||||
msgid "The following configured IMAP folder(s) were not found on the server:<br><ul>{0}</ul>Please verify the folder names exactly as they appear on the server (folder names are case-sensitive)."
|
||||
msgstr ""
|
||||
msgstr "Следећи конфигурисани IMAP директоријуми нису пронађени на серверу:<br><ul>{0}</ul>Молимо Вас да проверите називе директоријума тачно онако како су приказани на серверу (велика и мала слова су битна за називе датотека)."
|
||||
|
||||
#: frappe/core/doctype/data_import/importer.py:1092
|
||||
msgid "The following values are invalid: {0}. Values must be one of {1}"
|
||||
|
|
@ -27252,7 +27252,7 @@ msgstr "Изабрани документ {0} није {1}."
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:247
|
||||
msgid "The server did not return any IMAP folders for this account."
|
||||
msgstr ""
|
||||
msgstr "Сервер није вратио ниједан IMAP директоријум за овај налог."
|
||||
|
||||
#: frappe/utils/response.py:343
|
||||
msgid "The system is being updated. Please refresh again after a few moments."
|
||||
|
|
@ -29089,7 +29089,7 @@ msgstr "Отпреми"
|
|||
|
||||
#: frappe/public/js/frappe/file_uploader/FileUploader.vue:663
|
||||
msgid "Upload Failed"
|
||||
msgstr ""
|
||||
msgstr "Отпремање је неуспешно"
|
||||
|
||||
#: frappe/public/js/print_format_builder/LetterHeadEditor.vue:93
|
||||
msgid "Upload Image"
|
||||
|
|
@ -30783,7 +30783,7 @@ msgstr "Ставка бочне траке радног простора"
|
|||
|
||||
#: frappe/desk/doctype/workspace/workspace.js:58
|
||||
msgid "Workspace added to desktop"
|
||||
msgstr ""
|
||||
msgstr "Радни простор је додат на радну површину"
|
||||
|
||||
#: frappe/public/js/frappe/views/workspace/workspace.js:558
|
||||
msgid "Workspace {0} created"
|
||||
|
|
@ -31698,7 +31698,7 @@ msgstr "нпр. \"Подршка\", \"Продаја\", \"Петар Петро
|
|||
|
||||
#: frappe/public/js/frappe/ui/toolbar/awesome_bar.js:230
|
||||
msgid "e.g. (55 + 434) / 4"
|
||||
msgstr ""
|
||||
msgstr "на пример (55 + 434) / 4"
|
||||
|
||||
#. Description of the 'Incoming Server' (Data) field in DocType 'Email Account'
|
||||
#. Description of the 'Incoming Server' (Data) field in DocType 'Email Domain'
|
||||
|
|
@ -32860,7 +32860,7 @@ msgstr "{0} од {1} ({2} редова са зависним подацима)"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/report_view.js:456
|
||||
msgid "{0} of {1} records match (filtered on visible rows only)"
|
||||
msgstr ""
|
||||
msgstr "{0} од {1} записа одговара критеријуму (филтрирано само по видљивим редовима)"
|
||||
|
||||
#: frappe/utils/data.py:1571
|
||||
msgctxt "Money in words"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-26 23:27\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Serbian (Latin)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -1358,7 +1358,7 @@ msgstr "Dodaj parametre upita"
|
|||
#. Label of the add_reply_to_header (Check) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Add Reply-To header"
|
||||
msgstr ""
|
||||
msgstr "Dodaj zaglavlje adrese za odgovor"
|
||||
|
||||
#: frappe/core/doctype/user/user.py:860
|
||||
msgid "Add Roles"
|
||||
|
|
@ -1524,7 +1524,7 @@ msgstr "Dodaj na kontrolnu tablu"
|
|||
|
||||
#: frappe/desk/doctype/workspace/workspace.js:49
|
||||
msgid "Add to Desktop"
|
||||
msgstr ""
|
||||
msgstr "Dodaj na radnu površinu"
|
||||
|
||||
#: frappe/public/js/frappe/form/sidebar/assign_to.js:110
|
||||
msgid "Add to ToDo"
|
||||
|
|
@ -1647,7 +1647,7 @@ msgstr "Adrese i kontakti"
|
|||
#. Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Addresses added here will be used as the Reply-To header for outgoing emails sent from this account."
|
||||
msgstr ""
|
||||
msgstr "Adrese dodate ovde koristiće se kao adresa za odgovor za izlazne imejlove poslate sa ovog naloga."
|
||||
|
||||
#. Description of a DocType
|
||||
#: frappe/custom/doctype/client_script/client_script.json
|
||||
|
|
@ -3083,7 +3083,7 @@ msgstr "Istorija izmena"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/users.json
|
||||
msgid "Audits"
|
||||
msgstr ""
|
||||
msgstr "Revizije"
|
||||
|
||||
#. Label of the auth_url_data (Code) field in DocType 'Social Login Key'
|
||||
#: frappe/integrations/doctype/social_login_key/social_login_key.json
|
||||
|
|
@ -3517,7 +3517,7 @@ msgstr "Slika pozadine"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/system.json
|
||||
msgid "Background Job"
|
||||
msgstr ""
|
||||
msgstr "Pozadinski zadatak"
|
||||
|
||||
#. Label of a Link in the Build Workspace
|
||||
#. Label of the background_jobs_section (Section Break) field in DocType
|
||||
|
|
@ -4935,7 +4935,7 @@ msgstr "Kliknite da postavite filtere"
|
|||
|
||||
#: frappe/desk/page/desktop/desktop.js:1261
|
||||
msgid "Click to edit"
|
||||
msgstr ""
|
||||
msgstr "Kliknite za uređivanje"
|
||||
|
||||
#: frappe/public/js/frappe/list/list_view.js:754
|
||||
msgid "Click to sort by {0}"
|
||||
|
|
@ -6538,7 +6538,7 @@ msgstr "Cijan"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "DELAY"
|
||||
msgstr ""
|
||||
msgstr "ODLAGANJE"
|
||||
|
||||
#. Option for the 'Method' (Select) field in DocType 'Recorder'
|
||||
#. Option for the 'Request Method' (Select) field in DocType 'Webhook'
|
||||
|
|
@ -7366,7 +7366,7 @@ msgstr "Status"
|
|||
#. Label of the dsn_notify_type (Select) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Delivery Status Notification Type"
|
||||
msgstr ""
|
||||
msgstr "Vrsta obaveštenja o statusu isporuke"
|
||||
|
||||
#. Option for the 'Sign ups' (Select) field in DocType 'Social Login Key'
|
||||
#: frappe/integrations/doctype/social_login_key/social_login_key.json
|
||||
|
|
@ -9431,7 +9431,7 @@ msgstr "Planer omogućen"
|
|||
#. Label of the enabled (Check) field in DocType 'Notification Settings'
|
||||
#: frappe/desk/doctype/notification_settings/notification_settings.json
|
||||
msgid "Enabled System Notification"
|
||||
msgstr ""
|
||||
msgstr "Omogućeno sistemsko obaveštenje"
|
||||
|
||||
#: frappe/email/doctype/email_account/email_account.py:1101
|
||||
msgid "Enabled email inbox for user {0}"
|
||||
|
|
@ -10129,7 +10129,7 @@ msgstr "Dodatni parametri"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "FAILURE"
|
||||
msgstr ""
|
||||
msgstr "NEUSPEH"
|
||||
|
||||
#. Option for the 'Social Login Provider' (Select) field in DocType 'Social
|
||||
#. Login Key'
|
||||
|
|
@ -10273,7 +10273,7 @@ msgstr "Neuspešan pokušaj prijave na Frappe Cloud"
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:232
|
||||
msgid "Failed to retrieve the list of IMAP folders from the server. Please ensure the mailbox is accessible and the account has permission to list folders."
|
||||
msgstr ""
|
||||
msgstr "Neuspešno preuzimanje liste IMAP direktorijuma sa servera. Proverite da li je poštansko sanduče dostupno i da li nalog ima dozvolu za prikaz direktorijuma."
|
||||
|
||||
#: frappe/email/doctype/email_queue/email_queue.py:311
|
||||
msgid "Failed to send email with subject:"
|
||||
|
|
@ -11340,7 +11340,7 @@ msgstr "Jedinica frakcije"
|
|||
#. Label of a Desktop Icon
|
||||
#: frappe/desktop_icon/framework.json
|
||||
msgid "Framework"
|
||||
msgstr ""
|
||||
msgstr "Framework"
|
||||
|
||||
#. Option for the 'Social Login Provider' (Select) field in DocType 'Social
|
||||
#. Login Key'
|
||||
|
|
@ -12236,7 +12236,7 @@ msgstr "Naslov"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/system.json
|
||||
msgid "Health Report"
|
||||
msgstr ""
|
||||
msgstr "Izveštaj o stanju sistema"
|
||||
|
||||
#. Option for the 'Type' (Select) field in DocType 'Dashboard Chart'
|
||||
#: frappe/desk/doctype/dashboard_chart/dashboard_chart.json
|
||||
|
|
@ -12655,7 +12655,7 @@ msgstr "IMAP datoteka"
|
|||
#: frappe/email/doctype/email_account/email_account.py:235
|
||||
#: frappe/email/doctype/email_account/email_account.py:263
|
||||
msgid "IMAP Folder Not Found"
|
||||
msgstr ""
|
||||
msgstr "IMAP direktorijum nije pronađen"
|
||||
|
||||
#. Label of the ip_address (Data) field in DocType 'Activity Log'
|
||||
#. Label of the ip_address (Data) field in DocType 'Comment'
|
||||
|
|
@ -13415,7 +13415,7 @@ msgstr "Pogrešan verifikacioni kod"
|
|||
|
||||
#: frappe/public/js/frappe/views/gantt/gantt_view.js:88
|
||||
msgid "Incorrect configuration"
|
||||
msgstr ""
|
||||
msgstr "Neispravna konfiguracija"
|
||||
|
||||
#: frappe/model/document.py:1733
|
||||
msgid "Incorrect value in row {0}:"
|
||||
|
|
@ -16980,7 +16980,7 @@ msgstr "MyISAM"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "NEVER"
|
||||
msgstr ""
|
||||
msgstr "NIKADA"
|
||||
|
||||
#: frappe/workflow/doctype/workflow/workflow.js:19
|
||||
msgid "NOTE: If you add states or transitions in the table, it will be reflected in the Workflow Builder but you will have to position them manually. Also Workflow Builder is currently in <b>BETA</b>."
|
||||
|
|
@ -17751,7 +17751,7 @@ msgstr "Nema podataka za izvoz"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/query_report.js:1543
|
||||
msgid "No data to perform this action"
|
||||
msgstr ""
|
||||
msgstr "Nema podataka za izvršavanje ove radnje"
|
||||
|
||||
#: frappe/contacts/doctype/address/address.py:247
|
||||
msgid "No default Address Template found. Please create a new one from Setup > Printing and Branding > Address Template."
|
||||
|
|
@ -17796,7 +17796,7 @@ msgstr "Nema dodatnih zapisa"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/report_view.js:337
|
||||
msgid "No matching entries in the current results"
|
||||
msgstr ""
|
||||
msgstr "Nema podudarnih zapisa u trenutnim rezultatima"
|
||||
|
||||
#: frappe/templates/includes/search_template.html:49
|
||||
msgid "No matching records. Search something new"
|
||||
|
|
@ -18430,7 +18430,7 @@ msgstr "OAuth greška"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/integrations.json
|
||||
msgid "OAuth Provider"
|
||||
msgstr ""
|
||||
msgstr "OAuth provajder"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of a Link in the Integrations Workspace
|
||||
|
|
@ -18699,7 +18699,7 @@ msgstr "Dozvoli uređivanje samo za"
|
|||
|
||||
#: frappe/core/doctype/module_def/module_def.py:95
|
||||
msgid "Only Custom Modules can be renamed."
|
||||
msgstr ""
|
||||
msgstr "Isključivo prilagođeni moduli mogu biti preimenovani."
|
||||
|
||||
#: frappe/core/doctype/doctype/doctype.py:1652
|
||||
msgid "Only Options allowed for Data field are:"
|
||||
|
|
@ -19970,7 +19970,7 @@ msgstr "Molimo Vas da dodate validan komentar."
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/query_report.js:1544
|
||||
msgid "Please adjust filters to include some data"
|
||||
msgstr ""
|
||||
msgstr "Prilagodite filtere kako biste uključili neke podatke"
|
||||
|
||||
#: frappe/core/doctype/user/user.py:1122
|
||||
msgid "Please ask your administrator to verify your sign-up"
|
||||
|
|
@ -20030,7 +20030,7 @@ msgstr "Molimo Vas da kliknete na sledeći link da biste postavili novu lozinku"
|
|||
|
||||
#: frappe/public/js/frappe/views/gantt/gantt_view.js:89
|
||||
msgid "Please configure the start field for this Doctype in the controller file."
|
||||
msgstr ""
|
||||
msgstr "Molimo Vas da konfigurišete početno polje za ovaj DocType u datoteci kontrolera."
|
||||
|
||||
#: frappe/www/confirm_workflow_action.html:4
|
||||
msgid "Please confirm your action to {0} this document."
|
||||
|
|
@ -21133,7 +21133,7 @@ msgstr "Ljubičasto"
|
|||
#. Label of a Workspace Sidebar Item
|
||||
#: frappe/workspace_sidebar/integrations.json
|
||||
msgid "Push Notification"
|
||||
msgstr ""
|
||||
msgstr "Push obaveštenje"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of a Link in the Integrations Workspace
|
||||
|
|
@ -22226,16 +22226,16 @@ msgstr "Odgovori svima"
|
|||
#. Name of a DocType
|
||||
#: frappe/email/doctype/reply_to_address/reply_to_address.json
|
||||
msgid "Reply To Address"
|
||||
msgstr ""
|
||||
msgstr "Adresa za odgovor"
|
||||
|
||||
#: frappe/email/doctype/email_account/email_account.py:278
|
||||
msgid "Reply To email is required"
|
||||
msgstr ""
|
||||
msgstr "Adresa za odgovor je obavezna"
|
||||
|
||||
#. Label of the reply_to_addresses (Table) field in DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Reply-To Addresses"
|
||||
msgstr ""
|
||||
msgstr "Adrese za odgovor"
|
||||
|
||||
#. Label of the report (Check) field in DocType 'Custom DocPerm'
|
||||
#. Label of the report (Link) field in DocType 'Custom Role'
|
||||
|
|
@ -23277,19 +23277,19 @@ msgstr "SSL/TLS režim"
|
|||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS"
|
||||
msgstr ""
|
||||
msgstr "USPEH"
|
||||
|
||||
#. Option for the 'Delivery Status Notification Type' (Select) field in DocType
|
||||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS,FAILURE"
|
||||
msgstr ""
|
||||
msgstr "USPEH, NEUSPEH"
|
||||
|
||||
#. Option for the 'Delivery Status Notification Type' (Select) field in DocType
|
||||
#. 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "SUCCESS,FAILURE,DELAY"
|
||||
msgstr ""
|
||||
msgstr "USPEH, NEUSPEH, ODLAGANJE"
|
||||
|
||||
#: frappe/public/js/frappe/color_picker/color_picker.js:20
|
||||
msgid "SWATCHES"
|
||||
|
|
@ -24116,7 +24116,7 @@ msgstr "Izaberi dve verzije za prikaz razlika."
|
|||
#. DocType 'Email Account'
|
||||
#: frappe/email/doctype/email_account/email_account.json
|
||||
msgid "Select which delivery events should trigger a delivery status notification (DSN) from the SMTP server."
|
||||
msgstr ""
|
||||
msgstr "Izaberite koji događaji isporuke treba da pokrenu obaveštenje o statusu isporuke (DNS) sa SMTP servera."
|
||||
|
||||
#: frappe/public/js/frappe/form/link_selector.js:24
|
||||
#: frappe/public/js/frappe/form/multi_select_dialog.js:80
|
||||
|
|
@ -27099,7 +27099,7 @@ msgstr "Komentar ne može biti prazan"
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:290
|
||||
msgid "The configured SMTP server does not support DSN (Delivery Status Notification)."
|
||||
msgstr ""
|
||||
msgstr "Konfigurisani SMTP server ne podržava DSN (obaveštenje o statusu isporuke)."
|
||||
|
||||
#: frappe/templates/emails/workflow_action.html:9
|
||||
msgid "The contents of this email are strictly confidential. Please do not forward this email to anyone."
|
||||
|
|
@ -27161,7 +27161,7 @@ msgstr "Sledeća skripta zaglavlja će dodati trenutni datum u element klase 'he
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:257
|
||||
msgid "The following configured IMAP folder(s) were not found on the server:<br><ul>{0}</ul>Please verify the folder names exactly as they appear on the server (folder names are case-sensitive)."
|
||||
msgstr ""
|
||||
msgstr "Sledeći konfigurisani IMAP direktorijumi nisu pronađeni na serveru:<br><ul>{0}</ul>Molimo Vas da proverite nazive direktorijuma tačno onako kako su prikazani na serveru (velika i mala slova su bitna za nazive datoteka)."
|
||||
|
||||
#: frappe/core/doctype/data_import/importer.py:1092
|
||||
msgid "The following values are invalid: {0}. Values must be one of {1}"
|
||||
|
|
@ -27253,7 +27253,7 @@ msgstr "Izabrani dokument {0} nije {1}."
|
|||
|
||||
#: frappe/email/doctype/email_account/email_account.py:247
|
||||
msgid "The server did not return any IMAP folders for this account."
|
||||
msgstr ""
|
||||
msgstr "Server nije vratio nijedan IMAP direktorijum za ovaj nalog."
|
||||
|
||||
#: frappe/utils/response.py:343
|
||||
msgid "The system is being updated. Please refresh again after a few moments."
|
||||
|
|
@ -29089,7 +29089,7 @@ msgstr "Otpremi"
|
|||
|
||||
#: frappe/public/js/frappe/file_uploader/FileUploader.vue:663
|
||||
msgid "Upload Failed"
|
||||
msgstr ""
|
||||
msgstr "Otpremanje je neuspešno"
|
||||
|
||||
#: frappe/public/js/print_format_builder/LetterHeadEditor.vue:93
|
||||
msgid "Upload Image"
|
||||
|
|
@ -30783,7 +30783,7 @@ msgstr "Stavka bočne trake radnog prostora"
|
|||
|
||||
#: frappe/desk/doctype/workspace/workspace.js:58
|
||||
msgid "Workspace added to desktop"
|
||||
msgstr ""
|
||||
msgstr "Radni prostor je dodat na radnu površinu"
|
||||
|
||||
#: frappe/public/js/frappe/views/workspace/workspace.js:558
|
||||
msgid "Workspace {0} created"
|
||||
|
|
@ -31698,7 +31698,7 @@ msgstr "npr. \"Podrška\", \"Prodaja\", \"Petar Petrović\""
|
|||
|
||||
#: frappe/public/js/frappe/ui/toolbar/awesome_bar.js:230
|
||||
msgid "e.g. (55 + 434) / 4"
|
||||
msgstr ""
|
||||
msgstr "na primer (55 + 434) / 4"
|
||||
|
||||
#. Description of the 'Incoming Server' (Data) field in DocType 'Email Account'
|
||||
#. Description of the 'Incoming Server' (Data) field in DocType 'Email Domain'
|
||||
|
|
@ -32860,7 +32860,7 @@ msgstr "{0} od {1} ({2} redova sa zavisnim podacima)"
|
|||
|
||||
#: frappe/public/js/frappe/views/reports/report_view.js:456
|
||||
msgid "{0} of {1} records match (filtered on visible rows only)"
|
||||
msgstr ""
|
||||
msgstr "{0} od {1} zapisa odgovara kriterijumu (filtrirano samo po vidljivim redovima)"
|
||||
|
||||
#: frappe/utils/data.py:1571
|
||||
msgctxt "Money in words"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
"Project-Id-Version: frappe\n"
|
||||
"Report-Msgid-Bugs-To: developers@frappe.io\n"
|
||||
"POT-Creation-Date: 2026-02-22 09:42+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 22:07\n"
|
||||
"PO-Revision-Date: 2026-02-25 23:14\n"
|
||||
"Last-Translator: developers@frappe.io\n"
|
||||
"Language-Team: Swedish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -2868,7 +2868,7 @@ msgstr "Tilldelning Klar"
|
|||
#. Label of the assignment_days (Table) field in DocType 'Assignment Rule'
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.json
|
||||
msgid "Assignment Days"
|
||||
msgstr "Automation Dagar"
|
||||
msgstr "Tilldelning Dagar"
|
||||
|
||||
#. Name of a DocType
|
||||
#. Label of the assignment_rule (Link) field in DocType 'ToDo'
|
||||
|
|
@ -2876,7 +2876,7 @@ msgstr "Automation Dagar"
|
|||
#: frappe/automation/doctype/assignment_rule/assignment_rule.json
|
||||
#: frappe/desk/doctype/todo/todo.json frappe/workspace_sidebar/automation.json
|
||||
msgid "Assignment Rule"
|
||||
msgstr "Automation Regel"
|
||||
msgstr "Tilldelning Regel"
|
||||
|
||||
#. Name of a DocType
|
||||
#: frappe/automation/doctype/assignment_rule_day/assignment_rule_day.json
|
||||
|
|
@ -2890,13 +2890,13 @@ msgstr "Automation Regel Användare"
|
|||
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.py:55
|
||||
msgid "Assignment Rule is not allowed on document type {0}"
|
||||
msgstr "Automation Regel är ej tillåten på dokument typ {0}"
|
||||
msgstr "Tilldelning Regel är ej tillåten på dokument typ {0}"
|
||||
|
||||
#. Label of the assignment_rules_section (Section Break) field in DocType
|
||||
#. 'Assignment Rule'
|
||||
#: frappe/automation/doctype/assignment_rule/assignment_rule.json
|
||||
msgid "Assignment Rules"
|
||||
msgstr "Automation Regler"
|
||||
msgstr "Tilldelning Regler"
|
||||
|
||||
#: frappe/desk/doctype/notification_log/notification_log.py:153
|
||||
msgid "Assignment Update on {0}"
|
||||
|
|
|
|||
|
|
@ -894,6 +894,12 @@ def get_field_currency(df, doc=None):
|
|||
if frappe.get_meta(doc.parenttype).has_field(df.get("options")):
|
||||
# only get_value if parent has currency field
|
||||
currency = frappe.db.get_value(doc.parenttype, doc.parent, df.get("options"))
|
||||
if not currency:
|
||||
# Parent may not be in DB yet (new document being saved).
|
||||
# Use the in-memory parent document reference if available.
|
||||
parent = getattr(doc, "parent_doc", None)
|
||||
if parent:
|
||||
currency = parent.get(df.get("options"))
|
||||
|
||||
if currency:
|
||||
frappe.local.field_currency.setdefault((doc.doctype, ref_docname), frappe._dict()).setdefault(
|
||||
|
|
|
|||
|
|
@ -127,12 +127,12 @@
|
|||
{
|
||||
"fieldname": "image_height",
|
||||
"fieldtype": "Float",
|
||||
"label": "Image Height"
|
||||
"label": "Image Height (px)"
|
||||
},
|
||||
{
|
||||
"fieldname": "image_width",
|
||||
"fieldtype": "Float",
|
||||
"label": "Image Width"
|
||||
"label": "Image Width (px)"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.footer_source==='Image' && doc.letter_head_name",
|
||||
|
|
@ -148,12 +148,12 @@
|
|||
{
|
||||
"fieldname": "footer_image_height",
|
||||
"fieldtype": "Float",
|
||||
"label": "Image Height"
|
||||
"label": "Image Height (px)"
|
||||
},
|
||||
{
|
||||
"fieldname": "footer_image_width",
|
||||
"fieldtype": "Float",
|
||||
"label": "Image Width"
|
||||
"label": "Image Width (px)"
|
||||
},
|
||||
{
|
||||
"fieldname": "footer_align",
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
"links": [],
|
||||
"make_attachments_public": 1,
|
||||
"max_attachments": 3,
|
||||
"modified": "2026-02-24 20:53:14.297567",
|
||||
"modified": "2026-02-25 14:37:57.061516",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Printing",
|
||||
"name": "Letter Head",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ frappe.PrintFormatBuilder = class PrintFormatBuilder {
|
|||
this.show_start();
|
||||
} else {
|
||||
this.page.set_title(this.print_format.name);
|
||||
this.page.sidebar.toggle(true);
|
||||
this.setup_print_format();
|
||||
}
|
||||
}
|
||||
|
|
@ -65,6 +66,7 @@ frappe.PrintFormatBuilder = class PrintFormatBuilder {
|
|||
this.page.main.html(frappe.render_template("print_format_builder_start", {}));
|
||||
this.page.clear_actions();
|
||||
this.page.set_title(__("Print Format Builder"));
|
||||
this.page.sidebar.toggle(false);
|
||||
this.start_edit_print_format();
|
||||
this.start_new_print_format();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,14 @@ $(document).ready(function () {
|
|||
!frappe.is_mobile() &&
|
||||
frappe.user.has_role("System Manager");
|
||||
if (visiblity_condition && isFCUser) {
|
||||
addChatBubble();
|
||||
frappe.router.on("change", function () {
|
||||
if (frappe.get_route()[0] == "") {
|
||||
addChatBubble();
|
||||
toggleChatBubble(true);
|
||||
} else {
|
||||
toggleChatBubble(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (isFCUser) {
|
||||
$.extend(card_args, {
|
||||
|
|
@ -89,13 +96,18 @@ function openFrappeCloudDashboard() {
|
|||
}
|
||||
|
||||
function addChatBubble() {
|
||||
if (checkBusinessHours()) {
|
||||
const all_apps = frappe.utils.get_installed_apps();
|
||||
const desk_apps = ["erpnext", "hrms"];
|
||||
|
||||
const apps_allowed = frappe.utils.is_sub_array(all_apps, desk_apps);
|
||||
if (checkBusinessHours && apps_allowed) {
|
||||
let chat_banner = document.createElement("script");
|
||||
chat_banner.setAttribute("id", "chat_widget_trigger");
|
||||
chat_banner.innerHTML =
|
||||
'(function(d,t){var BASE_URL="https://chat.frappe.cloud";var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src=BASE_URL+"/packs/js/sdk.js";g.async=true;s.parentNode.insertBefore(g,s);g.onload=function(){window.chatwootSDK.run({websiteToken:"LdmfJzftdJGEcFjoTqk8CrSq",baseUrl:BASE_URL})}})(document,"script");';
|
||||
document.body.append(chat_banner);
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty("--s-700", "var(--gray-50)");
|
||||
root.style.setProperty("--s-700", "var(--gray-500)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,5 +115,15 @@ function checkBusinessHours() {
|
|||
let currentTime = new Date();
|
||||
const istTime = new Date(currentTime.toLocaleString("en-US", { timeZone: "Asia/Kolkata" }));
|
||||
|
||||
return istTime.getHours() >= 11 && istTime.getHours() <= 18;
|
||||
return istTime.getHours() >= 11 && istTime.getHours() < 18;
|
||||
}
|
||||
|
||||
function toggleChatBubble(toggle) {
|
||||
if (toggle) {
|
||||
$(".woot-widget-holder").show();
|
||||
$("#cw-bubble-holder").show();
|
||||
} else {
|
||||
$(".woot-widget-holder").hide();
|
||||
$("#cw-bubble-holder").hide();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,22 +514,7 @@ function check_restrictions(file) {
|
|||
return is_correct_type && valid_file_size;
|
||||
}
|
||||
|
||||
function set_loading_state(dialog, loading) {
|
||||
let $btn = dialog?.get_primary_btn();
|
||||
if (loading) {
|
||||
$btn?.css("width", $btn.outerWidth());
|
||||
$btn?.html(`<i class="fa fa-spinner fa-spin"></i>`);
|
||||
$btn?.prop("disabled", true);
|
||||
dialog?.get_secondary_btn().prop("disabled", true);
|
||||
} else {
|
||||
$btn?.css("width", "");
|
||||
$btn?.html(__("Upload"));
|
||||
$btn?.prop("disabled", false);
|
||||
dialog?.get_secondary_btn().prop("disabled", false);
|
||||
}
|
||||
}
|
||||
function upload_files(dialog) {
|
||||
set_loading_state(dialog, true);
|
||||
function upload_files() {
|
||||
if (show_file_browser.value) {
|
||||
promise = upload_via_file_browser();
|
||||
} else if (show_web_link.value) {
|
||||
|
|
@ -542,7 +527,7 @@ function upload_files(dialog) {
|
|||
} else {
|
||||
promise = frappe.run_serially(files.value.map((file, i) => () => upload_file(file, i)));
|
||||
}
|
||||
return promise.finally(() => set_loading_state(dialog, false));
|
||||
return promise;
|
||||
}
|
||||
function upload_via_file_browser() {
|
||||
let selected_file = file_browser.value.selected_node;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ class FileUploader {
|
|||
const dialog_opts = {
|
||||
title: title || __("Upload"),
|
||||
primary_action_label: __("Upload"),
|
||||
primary_action_loading_label: __("Uploading"),
|
||||
primary_action: () => this.upload_files(),
|
||||
on_page_show: () => {
|
||||
this.uploader.wrapper_ready = true;
|
||||
|
|
|
|||
|
|
@ -37,24 +37,35 @@ export default class Column {
|
|||
}
|
||||
|
||||
resize_all_columns() {
|
||||
// distribute all columns equally
|
||||
let columns = this.section.wrapper.find(".form-column").length;
|
||||
// distribute visible columns equally
|
||||
let all_columns = this.section.wrapper.find(".form-column");
|
||||
let visible_columns = all_columns.filter(":not(.hide-control)");
|
||||
let columns = visible_columns.length || all_columns.length;
|
||||
let colspan = cint(12 / columns);
|
||||
|
||||
if (columns == 5) {
|
||||
colspan = 20;
|
||||
}
|
||||
|
||||
this.section.wrapper
|
||||
.find(".form-column")
|
||||
.removeClass()
|
||||
.addClass("form-column")
|
||||
.addClass("col-sm-" + colspan);
|
||||
all_columns.each(function () {
|
||||
const $col = $(this);
|
||||
const is_hidden = $col.hasClass("hide-control");
|
||||
$col.removeClass()
|
||||
.addClass("form-column")
|
||||
.addClass("col-sm-" + colspan);
|
||||
if (is_hidden) {
|
||||
$col.addClass("hide-control");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
add_field() {}
|
||||
|
||||
refresh() {
|
||||
if (!this.df) return;
|
||||
const hide = this.df.hidden || this.df.hidden_due_to_dependency;
|
||||
this.wrapper.toggleClass("hide-control", !!hide);
|
||||
this.resize_all_columns();
|
||||
this.section.refresh();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Picker from "../../color_picker/color_picker";
|
|||
|
||||
frappe.ui.form.ControlColor = class ControlColor extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
this.df.placeholder = this.df.placeholder || __("Choose a color");
|
||||
this.df.placeholder = __(this.df.placeholder) || __("Choose a color");
|
||||
super.make_input();
|
||||
this.make_color_input();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlInp
|
|||
this.$input
|
||||
.attr("data-fieldtype", this.df.fieldtype)
|
||||
.attr("data-fieldname", this.df.fieldname)
|
||||
.attr("placeholder", this.df.placeholder || "");
|
||||
.attr("placeholder", __(this.df.placeholder || ""));
|
||||
if (this.doctype) {
|
||||
this.$input.attr("data-doctype", this.doctype);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import Picker from "../../icon_picker/icon_picker";
|
|||
|
||||
frappe.ui.form.ControlIcon = class ControlIcon extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
this.df.placeholder = this.df.placeholder || __("Choose an icon");
|
||||
this.df.placeholder = __(this.df.placeholder) || __("Choose an icon");
|
||||
super.make_input();
|
||||
this.get_all_icons();
|
||||
this.make_icon_input();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ frappe.ui.form.ControlSelect = class ControlSelect extends frappe.ui.form.Contro
|
|||
const placeholder_html = `<div class="placeholder ellipsis text-extra-muted ${
|
||||
is_xs_input ? "xs" : ""
|
||||
}">
|
||||
<span>${this.df.placeholder}</span>
|
||||
<span>${__(this.df.placeholder)}</span>
|
||||
</div>`;
|
||||
if (this.only_input) {
|
||||
this.$wrapper.append(placeholder_html);
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ frappe.ui.form.ControlTextEditor = class ControlTextEditor extends frappe.ui.for
|
|||
theme: this.df.theme || "snow",
|
||||
readOnly: this.disabled || this.df.read_only,
|
||||
bounds: this.quill_container[0],
|
||||
placeholder: this.df.placeholder || "",
|
||||
placeholder: __(this.df.placeholder || ""),
|
||||
};
|
||||
|
||||
// In a grid row where space is constrained, hide the toolbar.
|
||||
|
|
|
|||
|
|
@ -1574,15 +1574,10 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
var scroll_to = frappe.route_options.scroll_to;
|
||||
delete frappe.route_options.scroll_to;
|
||||
|
||||
var selector = [];
|
||||
for (var key in scroll_to) {
|
||||
var value = scroll_to[key];
|
||||
selector.push(repl('[data-%(key)s="%(value)s"]', { key: key, value: value }));
|
||||
}
|
||||
|
||||
selector = $(selector.join(" "));
|
||||
if (selector.length) {
|
||||
frappe.utils.scroll_to(selector);
|
||||
if (this.scroll_to_field(scroll_to)) {
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.delete("scroll_to");
|
||||
history.replaceState(null, null, url);
|
||||
}
|
||||
} else if (window.location.hash) {
|
||||
if ($(window.location.hash).length) {
|
||||
|
|
@ -2050,6 +2045,9 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
if (df.fieldname === fieldname && isLinkToParent) {
|
||||
new_doc[df.fieldname] = me.doc.name;
|
||||
}
|
||||
if (df.fieldtype === "Table" && df.options && df.reqd) {
|
||||
me.set_link_field(df.options, new_doc[df.fieldname][0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2103,7 +2101,7 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
}
|
||||
|
||||
// scroll to input
|
||||
frappe.utils.scroll_to($el, true, 15);
|
||||
frappe.utils.scroll_to($el, true, 15, $(".main-section"));
|
||||
|
||||
// focus if text field
|
||||
if (focus) {
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ export default class GridRow {
|
|||
let is_focused = false;
|
||||
|
||||
var $col = $(
|
||||
`<div class="col grid-static-col col-xs-${colsize} ${add_class}" style="${add_style}"></div>`
|
||||
`<div class="col grid-static-col flex col-xs-${colsize} ${add_class}" style="${add_style}"></div>`
|
||||
)
|
||||
.attr("data-fieldname", df.fieldname)
|
||||
.attr("data-fieldtype", df.fieldtype)
|
||||
|
|
@ -1095,7 +1095,9 @@ export default class GridRow {
|
|||
return out;
|
||||
});
|
||||
|
||||
$col.field_area = $('<div class="field-area"></div>').appendTo($col).toggle(false);
|
||||
$col.field_area = $('<div class="field-area flex flex-grow-1"></div>')
|
||||
.appendTo($col)
|
||||
.toggle(false);
|
||||
$col.static_area = $('<div class="static-area ellipsis"></div>').appendTo($col).html(txt);
|
||||
|
||||
// set title attribute to see full label for columns in the heading row
|
||||
|
|
|
|||
|
|
@ -745,7 +745,7 @@ frappe.ui.form.Layout = class Layout {
|
|||
|
||||
if (f.df.fieldtype === "Table") {
|
||||
for (const row of f.grid?.grid_rows || []) {
|
||||
row.refresh_dependency();
|
||||
row?.refresh_dependency();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ frappe.ui.form.LinkedWith = class LinkedWith {
|
|||
|
||||
make_dialog() {
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: __("Linked With"),
|
||||
title: __("Links"),
|
||||
minimizable: true,
|
||||
});
|
||||
|
||||
this.dialog.on_page_show = () => {
|
||||
|
|
@ -39,22 +40,40 @@ frappe.ui.form.LinkedWith = class LinkedWith {
|
|||
make_html() {
|
||||
let html = "";
|
||||
const linked_docs = this.frm.__linked_docs;
|
||||
const linked_doctypes = Object.keys(linked_docs);
|
||||
const linked_doctypes = Object.keys(linked_docs).filter((dt) => {
|
||||
const entry = linked_docs[dt];
|
||||
return (entry.docs && entry.docs.length) || entry.hidden_count > 0;
|
||||
});
|
||||
|
||||
if (linked_doctypes.length === 0) {
|
||||
html = __("Not Linked to any record");
|
||||
} else {
|
||||
html = linked_doctypes
|
||||
.map((doctype) => {
|
||||
const docs = linked_docs[doctype];
|
||||
return `
|
||||
<div class="list-item-table margin-bottom">
|
||||
${this.make_doc_head(doctype)}
|
||||
${docs.map((doc) => this.make_doc_row(doc, doctype)).join("")}
|
||||
html = `
|
||||
<div class="margin-bottom">
|
||||
${__("Following documents are linked with {0}", [
|
||||
frappe.utils
|
||||
.get_form_link(this.frm.doctype, this.frm.docname, true)
|
||||
.bold(),
|
||||
])}
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
${linked_doctypes
|
||||
.map((doctype) => {
|
||||
const { docs, hidden_count } = linked_docs[doctype];
|
||||
let rows = (docs || [])
|
||||
.map((doc) => this.make_doc_row(doc, doctype))
|
||||
.join("");
|
||||
if (hidden_count > 0) {
|
||||
rows += this.make_hidden_count_row(hidden_count);
|
||||
}
|
||||
return `
|
||||
<div class="list-item-table margin-bottom">
|
||||
${this.make_doc_head(doctype)}
|
||||
${rows}
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("")}
|
||||
`;
|
||||
}
|
||||
|
||||
$(this.dialog.body).html(html);
|
||||
|
|
@ -68,6 +87,16 @@ frappe.ui.form.LinkedWith = class LinkedWith {
|
|||
`;
|
||||
}
|
||||
|
||||
make_hidden_count_row(count) {
|
||||
return `<div class="list-row-container">
|
||||
<div class="level list-row small text-muted">
|
||||
<div class="level-left">
|
||||
${count == 1 ? __("{0} restricted document", [count]) : __("{0} restricted documents", [count])}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
make_doc_row(doc, doctype) {
|
||||
return `<div class="list-row-container">
|
||||
<div class="level list-row small">
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ export class ReminderManager {
|
|||
],
|
||||
primary_action_label: __("Create"),
|
||||
primary_action: () => {
|
||||
this.create_reminder();
|
||||
this.dialog.hide();
|
||||
return this.create_reminder().then(() => this.dialog.hide());
|
||||
},
|
||||
secondary_action_label: __("Cancel"),
|
||||
secondary_action: () => {
|
||||
|
|
@ -84,7 +83,7 @@ export class ReminderManager {
|
|||
}
|
||||
|
||||
create_reminder() {
|
||||
frappe
|
||||
return frappe
|
||||
.xcall("frappe.automation.doctype.reminder.reminder.create_new_reminder", {
|
||||
remind_at: this.dialog.get_value("remind_at"),
|
||||
description: this.dialog.get_value("description"),
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ frappe.ui.form.check_mandatory = function (frm) {
|
|||
}
|
||||
|
||||
function scroll_to(fieldname) {
|
||||
if (frm.scroll_to_field(fieldname)) {
|
||||
if (frm.scroll_to_field(fieldname, false)) {
|
||||
frm.scroll_set = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,9 +114,7 @@ frappe.ui.form.AssignToDialog = class AssignToDialog {
|
|||
let args = me.dialog.get_values();
|
||||
|
||||
if (args && args.assign_to) {
|
||||
me.dialog.set_message("Assigning...");
|
||||
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: me.method,
|
||||
args: $.extend(args, {
|
||||
doctype: me.doctype,
|
||||
|
|
@ -125,15 +123,12 @@ frappe.ui.form.AssignToDialog = class AssignToDialog {
|
|||
bulk_assign: me.bulk_assign || false,
|
||||
re_assign: me.re_assign || false,
|
||||
}),
|
||||
btn: me.dialog.get_primary_btn(),
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
if (me.callback) {
|
||||
me.callback(r);
|
||||
}
|
||||
me.dialog && me.dialog.hide();
|
||||
} else {
|
||||
me.dialog.clear_message();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -180,8 +180,18 @@ frappe.ui.form.Attachments = class Attachments {
|
|||
file_url = "/files/" + attachment.file_name;
|
||||
}
|
||||
}
|
||||
|
||||
const is_web_url = /^(https?:)?\/\//i.test(file_url);
|
||||
|
||||
file_url = encodeURI(file_url);
|
||||
|
||||
// hash is not escaped, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
|
||||
return encodeURI(file_url).replace(/#/g, "%23");
|
||||
// only encode hash if it's a local file path, not a web URL
|
||||
if (!is_web_url) {
|
||||
file_url = file_url.replace(/#/g, "%23");
|
||||
}
|
||||
|
||||
return file_url;
|
||||
}
|
||||
get_file_id_from_file_url(file_url) {
|
||||
var fid;
|
||||
|
|
|
|||
|
|
@ -452,9 +452,7 @@ export default class BulkOperations {
|
|||
primary_action: () => {
|
||||
let args = dialog.get_values();
|
||||
if (args && args.tags) {
|
||||
dialog.set_message("Adding Tags...");
|
||||
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: "frappe.desk.doctype.tag.tag.add_tags",
|
||||
args: {
|
||||
tags: args.tags,
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ export default class ListFilter {
|
|||
fields: fields,
|
||||
primary_action_label: __("Create"),
|
||||
primary_action: (values) => {
|
||||
this.bind_save_filter(dialog, values.filter_name, values?.is_global);
|
||||
return this.bind_save_filter(dialog, values.filter_name, values?.is_global);
|
||||
},
|
||||
});
|
||||
dialog.show();
|
||||
|
|
@ -138,7 +138,7 @@ export default class ListFilter {
|
|||
dialog.fields_dict.filter_name.set_description(__("Duplicate Filter Name"));
|
||||
return;
|
||||
}
|
||||
this.save_filter(value, is_global).then(() => {
|
||||
return this.save_filter(value, is_global).then(() => {
|
||||
this.refresh_list_filter();
|
||||
dialog.hide();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -332,7 +332,8 @@ $.extend(frappe.meta, {
|
|||
} else if (df && df.fieldtype === "Currency") {
|
||||
precision = cint(frappe.defaults.get_default("currency_precision"));
|
||||
if (!precision) {
|
||||
var number_format = get_number_format();
|
||||
var currency = frappe.meta.get_field_currency(df, doc);
|
||||
var number_format = get_number_format(currency);
|
||||
var number_format_info = get_number_format_info(number_format);
|
||||
precision = number_format_info.precision;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,6 @@ frappe.ui.AddressAutocompleteDialog = class AddressAutocompleteDialog {
|
|||
],
|
||||
primary_action_label: __("Create Address"),
|
||||
primary_action: () => {
|
||||
// Insert the address into the database
|
||||
dialog.hide();
|
||||
|
||||
const address = this.parse_selected_value();
|
||||
address["doctype"] = "Address";
|
||||
address["links"] = [
|
||||
|
|
@ -59,7 +56,8 @@ frappe.ui.AddressAutocompleteDialog = class AddressAutocompleteDialog {
|
|||
link_name: this.link_name,
|
||||
},
|
||||
];
|
||||
frappe.db.insert(address).then((doc) => {
|
||||
return frappe.db.insert(address).then((doc) => {
|
||||
dialog.hide();
|
||||
this.after_insert && this.after_insert(doc);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup {
|
|||
this.has_primary_action = true;
|
||||
var me = this;
|
||||
const primary_btn = this.get_primary_btn().removeClass("hide").html(label);
|
||||
const spinner = `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" style="width: 13px; height: 13px; animation: spin 1s linear infinite;"><circle opacity=".25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path opacity=".25" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/></svg>`;
|
||||
if (typeof click == "function") {
|
||||
primary_btn.off("click").on("click", function () {
|
||||
me.primary_action_fulfilled = true;
|
||||
|
|
@ -215,7 +216,35 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup {
|
|||
// if no values then return
|
||||
var values = me.get_values();
|
||||
if (!values) return;
|
||||
click && click.apply(me, [values]);
|
||||
const action = click.apply(me, [values]);
|
||||
if (action && typeof action.then === "function") {
|
||||
const loading_label = me.primary_action_loading_label;
|
||||
primary_btn
|
||||
.css({
|
||||
"min-width": primary_btn.outerWidth(),
|
||||
"min-height": primary_btn.outerHeight(),
|
||||
})
|
||||
.prop("disabled", true)
|
||||
.addClass("btn-primary-dark")
|
||||
.html(
|
||||
`<div class="d-flex align-items-center justify-content-center" style="gap: 0.45rem;">
|
||||
${spinner}
|
||||
${
|
||||
loading_label
|
||||
? `<span class="text-muted" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${loading_label}</span>`
|
||||
: ""
|
||||
}
|
||||
</div>`
|
||||
);
|
||||
|
||||
Promise.resolve(action).finally(() => {
|
||||
primary_btn
|
||||
.css({ "min-width": "", "min-height": "" })
|
||||
.prop("disabled", false)
|
||||
.removeClass("btn-primary-dark")
|
||||
.html(label);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return primary_btn;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,35 @@ frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout {
|
|||
}
|
||||
}
|
||||
|
||||
resolve_date_default_keywords(def_value, fieldtype) {
|
||||
if (!def_value || typeof def_value !== "string") return def_value;
|
||||
|
||||
def_value = def_value.toLowerCase();
|
||||
|
||||
if (def_value == "today" && fieldtype == "Date") {
|
||||
return frappe.datetime.get_today();
|
||||
}
|
||||
|
||||
if (def_value == "now") {
|
||||
if (fieldtype == "Datetime") {
|
||||
return frappe.datetime.now_datetime();
|
||||
}
|
||||
if (fieldtype == "Time") {
|
||||
return frappe.datetime.now_time();
|
||||
}
|
||||
}
|
||||
|
||||
return def_value;
|
||||
}
|
||||
|
||||
make() {
|
||||
let me = this;
|
||||
if (this.fields) {
|
||||
super.make();
|
||||
this.refresh();
|
||||
// set default
|
||||
|
||||
let defaults = {};
|
||||
|
||||
$.each(this.fields_list, function (i, field) {
|
||||
let def_value = field.df["default"];
|
||||
// loose equality check matches undefined also
|
||||
|
|
@ -33,12 +56,14 @@ frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout {
|
|||
)
|
||||
return;
|
||||
|
||||
if (def_value == "Today" && field.df["fieldtype"] == "Date") {
|
||||
def_value = frappe.datetime.get_today();
|
||||
if (["Date", "Datetime", "Time"].includes(field.df.fieldtype)) {
|
||||
def_value = me.resolve_date_default_keywords(def_value, field.df.fieldtype);
|
||||
}
|
||||
|
||||
field.set_input(def_value);
|
||||
// if default and has depends_on, render its fields.
|
||||
defaults[field.df.fieldname] = def_value;
|
||||
});
|
||||
|
||||
this.set_values(defaults).then(() => {
|
||||
me.refresh_dependency();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ frappe.msgprint = function (msg, title, is_minimizable, re_route) {
|
|||
typeof data.primary_action.server_action === "string"
|
||||
) {
|
||||
data.primary_action.action = () => {
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: data.primary_action.server_action,
|
||||
args: data.primary_action.args,
|
||||
callback() {
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ function markReset(step) {
|
|||
</div>
|
||||
<div v-else>
|
||||
<span
|
||||
class="text-base onb-step-text"
|
||||
class="text-base onb-step-text text-extra-muted"
|
||||
style="text-decoration-line: line-through"
|
||||
>
|
||||
{{ __(step.action_label) }}
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ frappe.dashboard_utils = {
|
|||
primary_action: (values) => {
|
||||
values.name = docname;
|
||||
values.set_standard = frappe.boot.developer_mode;
|
||||
frappe.xcall(method, { args: values }).then(() => {
|
||||
return frappe.xcall(method, { args: values }).then(() => {
|
||||
let dashboard_route_html = `<a href = "/desk/dashboard/${values.dashboard}">${values.dashboard}</a>`;
|
||||
let message = __("{0} {1} added to Dashboard {2}", [
|
||||
doctype,
|
||||
|
|
@ -273,9 +273,8 @@ frappe.dashboard_utils = {
|
|||
]);
|
||||
|
||||
frappe.msgprint(message);
|
||||
dialog.hide();
|
||||
});
|
||||
|
||||
dialog.hide();
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ Object.assign(frappe.utils, {
|
|||
scroll_top =
|
||||
typeof element == "number"
|
||||
? element - cint(additional_offset)
|
||||
: this.get_scroll_position(element, additional_offset);
|
||||
: this.get_scroll_position(element, additional_offset, element_to_be_scrolled);
|
||||
}
|
||||
|
||||
if (scroll_top < 0) {
|
||||
|
|
@ -366,10 +366,33 @@ Object.assign(frappe.utils, {
|
|||
element_to_be_scrolled.scrollTop(scroll_top);
|
||||
}
|
||||
},
|
||||
get_scroll_position: function (element, additional_offset) {
|
||||
let header_offset =
|
||||
$(".navbar").height() + $(".page-head:visible").height() || $(".navbar").height();
|
||||
return $(element).offset().top - header_offset - cint(additional_offset);
|
||||
get_scroll_position: function (element, additional_offset, element_to_be_scrolled) {
|
||||
const get_offset_relative_to_container = () => {
|
||||
let offset = 0;
|
||||
|
||||
let el = element instanceof HTMLElement ? element : element[0];
|
||||
const container = element_to_be_scrolled ? element_to_be_scrolled[0] : null;
|
||||
|
||||
while (el && el !== container && el.offsetParent) {
|
||||
offset += el.offsetTop;
|
||||
el = el.offsetParent;
|
||||
}
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
const get_header_offset = () => {
|
||||
const navbar_height = $(".navbar").height() || 0;
|
||||
const page_head_height = $(".page-head:visible").height() || 0;
|
||||
const tabs_container_height = $(".form-tabs-list:visible").height() || 0;
|
||||
|
||||
return navbar_height + page_head_height + tabs_container_height;
|
||||
};
|
||||
|
||||
const element_offset_top = get_offset_relative_to_container();
|
||||
const header_offset = get_header_offset();
|
||||
|
||||
return element_offset_top - header_offset - cint(additional_offset);
|
||||
},
|
||||
filter_dict: function (dict, filters) {
|
||||
var ret = [];
|
||||
|
|
@ -2229,4 +2252,16 @@ Object.assign(frappe.utils, {
|
|||
}
|
||||
return value;
|
||||
},
|
||||
get_installed_apps() {
|
||||
return frappe.boot.app_data.map((app) => {
|
||||
return app.app_name;
|
||||
});
|
||||
},
|
||||
is_sub_array(big, small) {
|
||||
let i = 0;
|
||||
for (let num of big) {
|
||||
if (num === small[i]) i++;
|
||||
}
|
||||
return i === small.length;
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ frappe.views.DashboardView = class DashboardView extends frappe.views.ListView {
|
|||
: chart.chart_type;
|
||||
chart.document_type = this.doctype;
|
||||
chart.filters_json = "[]";
|
||||
frappe
|
||||
return frappe
|
||||
.xcall(
|
||||
"frappe.desk.doctype.dashboard_chart.dashboard_chart.create_dashboard_chart",
|
||||
{ args: chart }
|
||||
|
|
@ -460,6 +460,7 @@ frappe.views.DashboardView = class DashboardView extends frappe.views.ListView {
|
|||
name: doc.chart_name,
|
||||
label: chart.label,
|
||||
});
|
||||
dialog.hide();
|
||||
});
|
||||
} else {
|
||||
this.chart_group.new_widget.on_create({
|
||||
|
|
@ -467,8 +468,8 @@ frappe.views.DashboardView = class DashboardView extends frappe.views.ListView {
|
|||
label: __(chart.chart),
|
||||
name: chart.chart,
|
||||
});
|
||||
dialog.hide();
|
||||
}
|
||||
dialog.hide();
|
||||
},
|
||||
});
|
||||
dialog.show();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ frappe.views.InteractionComposer = class InteractionComposer {
|
|||
fields: me.get_fields(),
|
||||
primary_action_label: __("Create"),
|
||||
primary_action: function () {
|
||||
me.create_action();
|
||||
return me.create_action();
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2109,7 +2109,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
},
|
||||
],
|
||||
primary_action: (values) => {
|
||||
frappe.call({
|
||||
return frappe.call({
|
||||
method: "frappe.desk.query_report.save_report",
|
||||
args: {
|
||||
reference_report: this.report_name,
|
||||
|
|
|
|||
|
|
@ -99,16 +99,6 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
});
|
||||
}
|
||||
|
||||
setup_paging_area() {
|
||||
super.setup_paging_area();
|
||||
const message = __(
|
||||
"For comparison, use >5, <10 or =324. For ranges, use 5:10 (for values between 5 & 10)."
|
||||
);
|
||||
this.$paging_area.before(
|
||||
`<span class="comparison-message text-extra-muted">${message}</span>`
|
||||
);
|
||||
}
|
||||
|
||||
setup_sort_selector() {
|
||||
this.sort_selector = new frappe.ui.SortSelector({
|
||||
parent: this.filter_area.$filter_list_wrapper,
|
||||
|
|
@ -430,6 +420,8 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
}
|
||||
|
||||
setup_inline_filter_observer() {
|
||||
this.setup_inline_filter_help_icons();
|
||||
|
||||
this.$datatable_wrapper.on(
|
||||
"keyup",
|
||||
".dt-filter",
|
||||
|
|
@ -439,6 +431,29 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
);
|
||||
}
|
||||
|
||||
setup_inline_filter_help_icons() {
|
||||
const message = __(
|
||||
"For comparison, use >5, <10 or =324.\nFor ranges, use 5:10 (for values between 5 & 10)."
|
||||
);
|
||||
|
||||
this.$datatable_wrapper.find(".dt-filter").each((_, input) => {
|
||||
const $input = $(input);
|
||||
|
||||
if ($input.siblings(".comparison-help-icon").length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const $icon = $(
|
||||
`<span class="comparison-help-icon text-muted" title="${message}">${frappe.utils.icon(
|
||||
"info",
|
||||
"xs"
|
||||
)}</span>`
|
||||
);
|
||||
|
||||
$input.after($icon);
|
||||
});
|
||||
}
|
||||
|
||||
update_count_for_inline_filter() {
|
||||
if (!this.datatable) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -570,8 +570,14 @@ export default class ChartWidget extends Widget {
|
|||
let setup_dashboard_chart = () => {
|
||||
const chart_args = this.get_chart_args();
|
||||
|
||||
const is_circular_chart = ["Pie", "Donut", "Percentage"].includes(this.chart_doc.type);
|
||||
|
||||
if (!this.dashboard_chart) {
|
||||
this.dashboard_chart = frappe.utils.make_chart(this.chart_wrapper[0], chart_args);
|
||||
} else if (is_circular_chart) {
|
||||
this.chart_wrapper.empty();
|
||||
delete this.dashboard_chart;
|
||||
this.dashboard_chart = frappe.utils.make_chart(this.chart_wrapper[0], chart_args);
|
||||
} else {
|
||||
this.dashboard_chart.update(this.data);
|
||||
}
|
||||
|
|
@ -619,6 +625,7 @@ export default class ChartWidget extends Widget {
|
|||
colors: colors,
|
||||
height: this.height,
|
||||
maxSlices: this.chart_doc.number_of_groups || max_slices,
|
||||
truncateLegends: 0,
|
||||
axisOptions: {
|
||||
xIsSeries: this.chart_doc.timeseries,
|
||||
shortenYAxisNumbers: 1,
|
||||
|
|
|
|||
|
|
@ -309,8 +309,8 @@
|
|||
border-radius: 0px;
|
||||
border: 0px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: calc(var(--padding-md) - 3px);
|
||||
height: auto;
|
||||
padding-bottom: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
|
|
@ -430,6 +430,7 @@
|
|||
.frappe-control {
|
||||
margin-bottom: 0px !important;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.col-sm-6 {
|
||||
|
|
@ -779,7 +780,7 @@
|
|||
.data-row.row {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.frappe-control[data-fieldtype="Table"].form-group:has(.column-limit-reached) {
|
||||
.frappe-control[data-fieldtype="Table"].form-group:has(.column-limit-reached):not(.highlight) {
|
||||
overflow-x: clip;
|
||||
}
|
||||
.column-limit-reached {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ h5.modal-title {
|
|||
margin: 0px !important;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
// Hack to fix incorrect padding applied by Bootstrap
|
||||
body.modal-open[style^="padding-right"] {
|
||||
padding-right: 12px !important;
|
||||
|
|
@ -103,6 +109,11 @@ body.modal-open[style^="padding-right"] {
|
|||
button:not(:last-child) {
|
||||
margin-right: var(--margin-xs);
|
||||
}
|
||||
|
||||
.btn-primary-dark {
|
||||
min-width: 80px;
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
& > * {
|
||||
|
|
|
|||
|
|
@ -371,6 +371,27 @@ input.list-header-checkbox {
|
|||
.list-item-table {
|
||||
border: 1px solid $border-color;
|
||||
border-radius: 3px;
|
||||
|
||||
.list-row-head {
|
||||
border-radius: unset;
|
||||
}
|
||||
|
||||
.list-row-container {
|
||||
border-bottom: 1px solid $border-color;
|
||||
border-radius: unset;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list-row-container:hover {
|
||||
border-radius: unset;
|
||||
}
|
||||
|
||||
.list-row-container .list-row {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list-item {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,37 @@
|
|||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.report-view {
|
||||
.layout-main-section {
|
||||
height: calc(100vh - var(--page-head-height));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.page-form {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.frappe-list {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.result,
|
||||
.no-result {
|
||||
flex-grow: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.comparison-message {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
.report-view {
|
||||
width: calc(100% - 220px);
|
||||
|
|
@ -129,6 +160,36 @@
|
|||
@include get_textstyle("base", "regular");
|
||||
}
|
||||
|
||||
.report-view {
|
||||
.datatable .dt-row-filter .dt-cell__content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.datatable .dt-row-filter .dt-filter.dt-input {
|
||||
padding-inline-end: 1.5rem;
|
||||
}
|
||||
|
||||
.datatable .dt-row-filter .comparison-help-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 10px;
|
||||
transform: translateY(-50%);
|
||||
display: inline-flex;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.15s ease;
|
||||
|
||||
.icon {
|
||||
stroke: currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
.datatable .dt-row-filter .dt-filter.dt-input:focus + .comparison-help-icon {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.list-count {
|
||||
margin-right: var(--margin-sm);
|
||||
@include get_textstyle("base", "regular");
|
||||
|
|
|
|||
|
|
@ -369,6 +369,12 @@ def prepare_header_footer(soup: BeautifulSoup):
|
|||
|
||||
# {"header-html": "/tmp/frappe-pdf-random.html"}
|
||||
options[html_id] = fname
|
||||
|
||||
if html_id == "header-html":
|
||||
options["margin-top"] = "25mm"
|
||||
elif html_id == "footer-html":
|
||||
options["margin-bottom"] = "25mm"
|
||||
|
||||
else:
|
||||
if html_id == "header-html":
|
||||
options["margin-top"] = "15mm"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ frappe.ui.form.on("Website Settings", {
|
|||
frm.add_custom_button(__("View Website"), () => {
|
||||
window.open("/", "_blank");
|
||||
});
|
||||
|
||||
// Check if templates have fields and show/hide edit button
|
||||
frm.events.check_template_has_fields(frm, "navbar_template");
|
||||
frm.events.check_template_has_fields(frm, "footer_template");
|
||||
},
|
||||
|
||||
set_banner_from_image: function (frm) {
|
||||
|
|
@ -100,11 +104,36 @@ frappe.ui.form.on("Website Settings", {
|
|||
frappe.show_alert(__("Please select {0}", [frm.get_docfield(template_field).label]));
|
||||
return;
|
||||
}
|
||||
|
||||
let values = JSON.parse(frm.doc[values_field] || "{}");
|
||||
open_web_template_values_editor(template, values).then((new_values) => {
|
||||
frm.set_value(values_field, JSON.stringify(new_values));
|
||||
});
|
||||
},
|
||||
|
||||
check_template_has_fields(frm, template_field) {
|
||||
let template = frm.doc[template_field];
|
||||
let button_field = "edit_" + template_field + "_values";
|
||||
|
||||
if (!template || template === "Standard Navbar" || template === "Standard Footer") {
|
||||
frm.toggle_display(button_field, false);
|
||||
return;
|
||||
}
|
||||
|
||||
frappe.model.with_doc("Web Template", template, () => {
|
||||
let doc = frappe.model.get_doc("Web Template", template);
|
||||
let has_fields = doc.fields && doc.fields.length > 0;
|
||||
frm.toggle_display(button_field, has_fields);
|
||||
});
|
||||
},
|
||||
|
||||
navbar_template(frm) {
|
||||
frm.events.check_template_has_fields(frm, "navbar_template");
|
||||
},
|
||||
|
||||
footer_template(frm) {
|
||||
frm.events.check_template_has_fields(frm, "footer_template");
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Top Bar Item", {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ frappe.ui.form.on("Website Slideshow", {
|
|||
],
|
||||
primary_action_label: __("Add to table"),
|
||||
primary_action: ({ reference_doctype, reference_name }) => {
|
||||
frappe.db
|
||||
return frappe.db
|
||||
.get_list("File", {
|
||||
fields: ["file_url"],
|
||||
filters: {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ dependencies = [
|
|||
# We depend on internal attributes,
|
||||
# do NOT add loose requirements on PyMySQL versions.
|
||||
"PyMySQL==1.1.2",
|
||||
"pypdf==6.7.1",
|
||||
"pypdf==6.7.3",
|
||||
"PyPika @ git+https://github.com/frappe/pypika@2c50e6142b2d61d2d243e466fdd5dc03b3d918f2",
|
||||
"mysqlclient==2.2.7",
|
||||
"PyQRCode~=1.2.1",
|
||||
|
|
|
|||
|
|
@ -2055,9 +2055,9 @@ mime@^1.4.1:
|
|||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
minimatch@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.3.tgz#6a5cba9b31f503887018f579c89f81f61162e624"
|
||||
integrity sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e"
|
||||
integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue