Skip to content

Commit

Permalink
Merge pull request #25453 from RitvikSardana/develop-ritvik-filter-ev…
Browse files Browse the repository at this point in the history
…al-support

feat: add eval support for link field filters
  • Loading branch information
ankush committed Mar 27, 2024
2 parents 12f1932 + d398110 commit f11313d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 46 deletions.
12 changes: 2 additions & 10 deletions frappe/public/js/form_builder/components/Field.vue
Expand Up @@ -92,11 +92,12 @@ function make_dialog(frm) {
filter.pop();
// filter_group component requires options and frm.set_query requires fieldname so storing both
filter[0] = { fieldname, field_option };
filter[0] = field_option;
return filter;
});
props.field.df.link_filters = JSON.stringify(filters);
store.form.selected_field = props.field.df;
frm.dialog.hide();
},
primary_action_label: __("Apply"),
Expand Down Expand Up @@ -133,11 +134,6 @@ function make_dialog(frm) {
}
});
}
// Setting selected field in store because when we click on the dialog the selected field is set to null
frm.dialog.$wrapper.on("click", () => {
store.form.selected_field = props.field.df;
});
}
function make_filter_area(frm, doctype) {
Expand All @@ -151,10 +147,6 @@ function make_filter_area(frm, doctype) {
function add_existing_filter(frm, df) {
if (df.link_filters) {
let filters = JSON.parse(df.link_filters);
filters.map((filter) => {
// filter_group component requires options and frm.set_query requires fieldname
filter[0] = filter[0].field_option;
});
if (filters) {
frm.filter_group.add_filters_to_filter_group(filters);
}
Expand Down
38 changes: 38 additions & 0 deletions frappe/public/js/frappe/form/controls/link.js
Expand Up @@ -509,6 +509,12 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
});
return obj;
};

// apply link field filters
if (this.df.link_filters && !!this.df.link_filters.length) {
this.apply_link_field_filters();
}

if (this.get_query || this.df.get_query) {
var get_query = this.get_query || this.df.get_query;
if ($.isPlainObject(get_query)) {
Expand Down Expand Up @@ -571,6 +577,38 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat
$.extend(args.filters, this.df.filters);
}
}

apply_link_field_filters() {
let link_filters = JSON.parse(this.df.link_filters);
let filters = this.parse_filters(link_filters);
// take filters from the link field and add to the query
this.get_query = function () {
return {
filters,
};
};
}

parse_filters(link_filters) {
let filters = {};
link_filters.forEach((filter) => {
let [_, fieldname, operator, value] = filter;
value = String(value).replace(/%/g, "");
if (value.startsWith("eval:")) {
// get the value to calculate
value = value.split("eval:")[1];
let context = {
doc: this.doc,
parent: this.doc.parenttype ? this.frm.doc : null,
frappe,
};
value = frappe.utils.eval(value, context);
}
filters[fieldname] = [operator, value];
});
return filters;
}

validate(value) {
// validate the value just entered
if (this._validated || this.df.options == "[Select]" || this.df.ignore_link_validation) {
Expand Down
36 changes: 0 additions & 36 deletions frappe/public/js/frappe/form/form.js
Expand Up @@ -107,7 +107,6 @@ frappe.ui.form.Form = class FrappeForm {

// 2 column layout
this.setup_std_layout();
this.setup_filters();

// client script must be called after "setup" - there are no fields_dict attached to the frm otherwise
this.script_manager = new frappe.ui.form.ScriptManager({
Expand Down Expand Up @@ -273,41 +272,6 @@ frappe.ui.form.Form = class FrappeForm {
});
}

setup_filters() {
let fields_with_filters = frappe
.get_meta(this.doctype)
.fields.filter((field) => field.link_filters)
.map((field) => JSON.parse(field.link_filters));
if (fields_with_filters.length === 0) return;
fields_with_filters = this.parse_filters(fields_with_filters);
for (let link_field in fields_with_filters) {
const filters = fields_with_filters[link_field];
this.set_query(link_field, () => filters);
}
}

parse_filters(data) {
const parsed_data = {};

for (const d of data) {
for (const condition of d) {
let [doctype, field, operator, value] = condition;
doctype = doctype.fieldname;
if (!parsed_data[doctype]) {
parsed_data[doctype] = {
filters: {},
};
}

if (!parsed_data[doctype].filters[field]) {
parsed_data[doctype].filters[field] = [operator, value];
}
}
}

return parsed_data;
}

watch_model_updates() {
// watch model updates
var me = this;
Expand Down

0 comments on commit f11313d

Please sign in to comment.