Merge branch 'develop' into clear-all-filters

This commit is contained in:
Shariq Ansari 2023-04-17 14:39:02 +05:30 committed by Shariq Ansari
commit 3140cd2fb5
22 changed files with 116 additions and 40 deletions

View file

@ -8,6 +8,7 @@ context("Folder Navigation", () => {
it("Adding Folders", () => {
//Adding filter to go into the home folder
cy.get(".filter-x-button").click();
cy.click_filter_button();
cy.get(".filter-action-buttons > .text-muted").findByText("+ Add a Filter").click();
cy.get(".fieldname-select-area > .awesomplete > .form-control:last").type("Fol{enter}");
cy.get(
@ -46,9 +47,13 @@ context("Folder Navigation", () => {
//Adding a file inside the Test Folder
cy.findByRole("button", { name: "Add File" }).eq(0).click({ force: true });
cy.get(".file-uploader").findByText("Link").click();
cy.get(".input-group > .form-control").type(
"https://wallpaperplay.com/walls/full/8/2/b/72402.jpg"
);
cy.get(".input-group > input.form-control:visible").as("upload_input");
cy.get("@upload_input").type("https://wallpaperplay.com/walls/full/8/2/b/72402.jpg", {
waitForAnimations: false,
parseSpecialCharSequences: false,
force: true,
delay: 100,
});
cy.click_modal_primary_button("Upload");
//To check if the added file is present in the Test Folder

View file

@ -12,7 +12,7 @@ context("List Paging", () => {
it("test load more with count selection buttons", () => {
cy.visit("/app/todo/view/report");
cy.clear_filters();
cy.get(".filter-x-button").click();
cy.get(".list-paging-area .list-count").should("contain.text", "20 of");
cy.get(".list-paging-area .btn-more").click();

View file

@ -5,6 +5,7 @@ context("List View", () => {
});
it("List view check rows on drag", () => {
cy.get(".filter-x-button").click();
cy.get(".list-row-checkbox").then(($checkbox) => {
cy.wrap($checkbox).first().trigger("mousedown");
cy.get(".level.list-row").each(($ele) => {

View file

@ -182,9 +182,9 @@ if TYPE_CHECKING:
# end: static analysis hack
def init(site: str, sites_path: str = ".", new_site: bool = False) -> None:
def init(site: str, sites_path: str = ".", new_site: bool = False, force=False) -> None:
"""Initialize frappe for the current site. Reset thread locals `frappe.local`"""
if getattr(local, "initialised", None):
if getattr(local, "initialised", None) and not force:
return
local.error_log = []

View file

@ -74,12 +74,18 @@ def application(request: Request):
rollback = sync_database(rollback)
finally:
# Important note:
# this function *must* always return a response, hence any exception thrown outside of
# try..catch block like this finally block needs to be handled appropriately.
if request.method in UNSAFE_HTTP_METHODS and frappe.db and rollback:
frappe.db.rollback()
if getattr(frappe.local, "initialised", False):
for after_request_task in frappe.get_hooks("after_request"):
frappe.call(after_request_task, response=response, request=request)
try:
run_after_request_hooks(request, response)
except Exception as e:
# We can not handle exceptions safely here.
frappe.logger().error("Failed to run after request hook", exc_info=True)
log_request(request, response)
process_response(response)
@ -89,12 +95,20 @@ def application(request: Request):
return response
def run_after_request_hooks(request, response):
if not getattr(frappe.local, "initialised", False):
return
for after_request_task in frappe.get_hooks("after_request"):
frappe.call(after_request_task, response=response, request=request)
def init_request(request):
frappe.local.request = request
frappe.local.is_ajax = frappe.get_request_header("X-Requested-With") == "XMLHttpRequest"
site = _site or request.headers.get("X-Frappe-Site-Name") or get_site_name(request.host)
frappe.init(site=site, sites_path=_sites_path)
frappe.init(site=site, sites_path=_sites_path, force=True)
if not (frappe.local.conf and frappe.local.conf.db_name):
# site does not exist

View file

@ -205,9 +205,11 @@ class Exporter:
for df in self.fields:
is_parent = not df.is_child_table_field
if is_parent:
label = _(df.label)
label = _(df.label or df.fieldname)
else:
label = f"{_(df.label)} ({_(df.child_table_df.label)})"
label = (
f"{_(df.label or df.fieldname)} ({_(df.child_table_df.label or df.child_table_df.fieldname)})"
)
if label in header:
# this label is already in the header,

View file

@ -345,6 +345,7 @@ class DocType(Document):
"name",
"parent",
"creation",
"owner",
"modified",
"modified_by",
"parentfield",

View file

@ -51,7 +51,7 @@
"icon": "fa fa-globe",
"in_create": 1,
"links": [],
"modified": "2022-08-14 18:54:03.490836",
"modified": "2023-04-13 13:48:38.127995",
"modified_by": "Administrator",
"module": "Core",
"name": "Language",
@ -66,13 +66,8 @@
"write": 1
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Guest",
"share": 1
"role": "All",
"read": 1
}
],
"search_fields": "language_name",

View file

@ -148,11 +148,13 @@
{
"collapsible": 1,
"collapsible_depends_on": "filters",
"depends_on": "eval:doc.report_type != \"Custom Report\"",
"fieldname": "filters_section",
"fieldtype": "Section Break",
"label": "Filters"
},
{
"depends_on": "eval:doc.report_type != \"Custom Report\"",
"fieldname": "filters",
"fieldtype": "Table",
"label": "Filters",
@ -161,11 +163,13 @@
{
"collapsible": 1,
"collapsible_depends_on": "columns",
"depends_on": "eval:doc.report_type != \"Custom Report\"",
"fieldname": "columns_section",
"fieldtype": "Section Break",
"label": "Columns"
},
{
"depends_on": "eval:doc.report_type != \"Custom Report\"",
"fieldname": "columns",
"fieldtype": "Table",
"label": "Columns",
@ -182,7 +186,7 @@
"idx": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2022-11-20 14:56:36.578412",
"modified": "2023-04-07 18:18:11.782178",
"modified_by": "Administrator",
"module": "Core",
"name": "Report",

View file

@ -169,7 +169,7 @@ class Report(Document):
return columns, result
def run_query_report(self, filters, user, ignore_prepared_report=False):
def run_query_report(self, filters=None, user=None, ignore_prepared_report=False):
columns, result = [], []
data = frappe.desk.query_report.run(
self.name, filters=filters, user=user, ignore_prepared_report=ignore_prepared_report

View file

@ -118,11 +118,10 @@ class TestReport(FrappeTestCase):
}
]
),
json.dumps({"user": "Administrator", "doctype": "User"}),
)
custom_report = frappe.get_doc("Report", custom_report_name)
columns, result = custom_report.run_query_report(
filters={"user": "Administrator", "doctype": "User"}, user=frappe.session.user
)
columns, result = custom_report.run_query_report(user=frappe.session.user)
self.assertListEqual(["email"], [column.get("fieldname") for column in columns])
admin_dict = frappe.core.utils.find(result, lambda d: d["name"] == "Administrator")

View file

@ -15,12 +15,13 @@ from frappe.model.utils import render_include
from frappe.modules import get_module_path, scrub
from frappe.monitor import add_data_to_monitor
from frappe.permissions import get_role_permissions
from frappe.utils import cint, cstr, flt, format_duration, get_html_format
from frappe.utils import cint, cstr, flt, format_duration, get_html_format, sbool
def get_report_doc(report_name):
doc = frappe.get_doc("Report", report_name)
doc.custom_columns = []
doc.custom_filters = []
if doc.report_type == "Custom Report":
custom_report_doc = doc
@ -30,7 +31,8 @@ def get_report_doc(report_name):
if custom_report_doc.json:
data = json.loads(custom_report_doc.json)
if data:
doc.custom_columns = data["columns"]
doc.custom_columns = data.get("columns")
doc.custom_filters = data.get("filters")
doc.is_custom_report = True
if not doc.is_permitted():
@ -182,6 +184,7 @@ def run(
custom_columns=None,
is_tree=False,
parent_field=None,
are_default_filters=True,
):
report = get_report_doc(report_name)
if not user:
@ -194,6 +197,9 @@ def run(
result = None
if sbool(are_default_filters) and report.custom_filters:
filters = report.custom_filters
if report.prepared_report and not ignore_prepared_report and not custom_columns:
if filters:
if isinstance(filters, str):
@ -209,6 +215,9 @@ def run(
result["add_total_row"] = report.add_total_row and not result.get("skip_total_row", False)
if sbool(are_default_filters) and report.custom_filters:
result["custom_filters"] = report.custom_filters
return result
@ -463,7 +472,7 @@ def get_data_for_custom_report(columns):
@frappe.whitelist()
def save_report(reference_report, report_name, columns):
def save_report(reference_report, report_name, columns, filters):
report_doc = get_report_doc(reference_report)
docname = frappe.db.exists(
@ -479,6 +488,7 @@ def save_report(reference_report, report_name, columns):
report = frappe.get_doc("Report", docname)
existing_jd = json.loads(report.json)
existing_jd["columns"] = json.loads(columns)
existing_jd["filters"] = json.loads(filters)
report.update({"json": json.dumps(existing_jd, separators=(",", ":"))})
report.save()
frappe.msgprint(_("Report updated successfully"))
@ -489,7 +499,7 @@ def save_report(reference_report, report_name, columns):
{
"doctype": "Report",
"report_name": report_name,
"json": f'{{"columns":{columns}}}',
"json": f'{{"columns":{columns},"filters":{filters}}}',
"ref_doctype": report_doc.ref_doctype,
"is_standard": "No",
"report_type": "Custom Report",

View file

@ -168,7 +168,6 @@ execute:frappe.db.set_default('desktop:home_page', 'space')
execute:frappe.delete_doc_if_exists('Page', 'workspace')
execute:frappe.delete_doc_if_exists('Page', 'dashboard', force=1)
frappe.core.doctype.page.patches.drop_unused_pages
execute:frappe.get_doc('Role', 'Guest').save() # remove desk access
frappe.patches.v13_0.remove_chat
frappe.patches.v13_0.rename_desk_page_to_workspace # 02.02.2021
frappe.patches.v13_0.delete_package_publish_tool
@ -199,6 +198,7 @@ frappe.patches.v15_0.remove_event_streaming
frappe.patches.v15_0.copy_disable_prepared_report_to_prepared_report
[post_model_sync]
execute:frappe.get_doc('Role', 'Guest').save() # remove desk access
frappe.core.doctype.role.patches.v13_set_default_desk_properties
frappe.patches.v14_0.drop_data_import_legacy
frappe.patches.v14_0.copy_mail_data #08.03.21
@ -223,3 +223,4 @@ frappe.patches.v14_0.disable_email_accounts_with_oauth
execute:frappe.delete_doc("Page", "translation-tool", force=1)
frappe.patches.v15_0.remove_prepared_report_settings_from_system_settings
frappe.patches.v14_0.remove_manage_subscriptions_from_navbar
frappe.patches.v15_0.remove_background_jobs_from_dropdown

View file

@ -0,0 +1,9 @@
import frappe
def execute():
item = frappe.db.exists("Navbar Item", {"item_label": "Background Jobs"})
if not item:
return
frappe.delete_doc("Navbar Item", item)

View file

@ -1296,7 +1296,7 @@ export default class GridRow {
.find(".grid-delete-row")
.toggle(!(this.grid.df && this.grid.df.cannot_delete_rows));
frappe.dom.freeze("", "dark");
frappe.dom.freeze("", "dark grid-form");
if (cur_frm) cur_frm.cur_grid = this;
this.wrapper.addClass("grid-row-open");
if (

View file

@ -34,9 +34,7 @@ $.extend(frappe.perm, {
doctype_perm: {},
has_perm: (doctype, permlevel, ptype, doc) => {
if (!permlevel) permlevel = 0;
has_perm: (doctype, permlevel = 0, ptype = "read", doc) => {
const perms = frappe.perm.get_perm(doctype, doc);
return !!perms?.[permlevel]?.[ptype];
},

View file

@ -13,6 +13,9 @@ frappe.ui.toolbar.Toolbar = class {
})
);
$(".dropdown-toggle").dropdown();
$("#toolbar-user a[href]").click(function () {
$(this).closest(".dropdown-menu").prev().dropdown("toggle");
});
this.setup_awesomebar();
this.setup_notifications();
@ -133,6 +136,12 @@ frappe.ui.toolbar.Toolbar = class {
frappe.utils.generate_tracking_url,
__("Generate Tracking URL")
);
if (frappe.perm.has_perm("RQ Job")) {
frappe.search.utils.make_function_searchable(function () {
frappe.set_route("List", "RQ Job");
}, __("Background Jobs"));
}
}
}

View file

@ -542,7 +542,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
if (this.prepared_report) {
this.reset_report_view();
} else if (!this._no_refresh) {
this.refresh();
this.refresh(true);
}
}
};
@ -598,10 +598,25 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
this.page.clear_fields();
}
refresh() {
refresh(have_filters_changed) {
this.toggle_message(true);
this.toggle_report(false);
let filters = this.get_filter_values(true);
// for custom reports,
// are_default_filters is true if the filters haven't been modified and for all filters,
// the filter value is the default value or there's no default value for the filter and the current value is empty.
// are_default_filters is false otherwise.
let are_default_filters = this.filters
.map((filter) => {
return (
!have_filters_changed &&
(filter.default === filter.value || (!filter.default && !filter.value))
);
})
.every((res) => res === true);
this.show_loading_screen();
// only one refresh at a time
@ -624,6 +639,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
filters: filters,
is_tree: this.report_settings.tree,
parent_field: this.report_settings.parent_field,
are_default_filters: are_default_filters,
},
callback: resolve,
always: () => this.page.btn_secondary.prop("disabled", false),
@ -636,6 +652,11 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
this.execution_time = data.execution_time || 0.1;
if (data.custom_filters) {
this.set_filters(data.custom_filters);
this.previous_filters = data.custom_filters;
}
if (data.prepared_report) {
this.prepared_report = true;
this.prepared_report_document = data.doc;
@ -1715,6 +1736,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
reference_report: this.report_name,
report_name: values.report_name,
columns: this.get_visible_columns(),
filters: this.get_filter_values(),
},
callback: function (r) {
this.show_save = false;

View file

@ -321,7 +321,7 @@
overflow: hidden;
height: 0;
opacity: 0;
z-index: 1051;
z-index: 1021;
border-radius: var(--border-radius-md);
@include base-grid();
@ -362,6 +362,10 @@
}
}
#freeze.grid-form {
z-index: 1020;
}
.recorder-form-in-grid {
z-index: 0;
@include base-grid();

View file

@ -433,7 +433,7 @@ kbd {
// freeze backdrop text
#freeze {
z-index: 1050;
z-index: 1055;
bottom: 0;
opacity: 0;
background-color: var(--bg-color);

View file

@ -236,6 +236,7 @@ class TestWebsite(FrappeTestCase):
def test_printview_page(self):
frappe.db.value_cache[("DocType", "Language", "name")] = (("Language",),)
frappe.set_user("Administrator")
content = get_response_content("/Language/ru")
self.assertIn('<div class="print-format">', content)
self.assertIn("<div>Language</div>", content)

View file

@ -1,6 +1,7 @@
{
"actions": [],
"autoname": "field:workflow_action_name",
"allow_rename": 1,
"creation": "2012-12-28 10:49:56",
"description": "Workflow Action Master",
"doctype": "DocType",
@ -21,7 +22,7 @@
"icon": "fa fa-flag",
"idx": 1,
"links": [],
"modified": "2022-08-03 12:20:52.449982",
"modified": "2023-04-14 12:20:52.449982",
"modified_by": "Administrator",
"module": "Workflow",
"name": "Workflow Action Master",
@ -43,4 +44,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}