refactor: fetch mask field from cache instead of meta
This commit is contained in:
parent
af27ab36e4
commit
03ac6e2f75
7 changed files with 42 additions and 43 deletions
|
|
@ -45,19 +45,6 @@ def get_meta(doctype, cached=True) -> "FormMeta":
|
|||
# In prod don't use cached meta when explicitly requesting from DB.
|
||||
meta = FormMeta(doctype, cached=frappe.conf.developer_mode)
|
||||
|
||||
if meta.name not in meta.special_doctypes:
|
||||
meta = mask_protected_fields(meta)
|
||||
|
||||
return meta
|
||||
|
||||
|
||||
def mask_protected_fields(meta):
|
||||
for df in meta.fields:
|
||||
if df.get("mask") and not meta.has_permlevel_access_to(
|
||||
fieldname=df.fieldname, df=df, permission_type="mask"
|
||||
):
|
||||
# store orignal fieldtype and change fieldtype to Data
|
||||
df.mask_readonly = 1
|
||||
return meta
|
||||
|
||||
|
||||
|
|
@ -89,6 +76,9 @@ class FormMeta(Meta):
|
|||
for k in ASSET_KEYS:
|
||||
d[k] = __dict.get(k)
|
||||
|
||||
# add masked fields (per-user, per-meta)
|
||||
d["masked_fields"] = [df.fieldname for df in self.get_masked_fields()]
|
||||
|
||||
return d
|
||||
|
||||
def add_code(self):
|
||||
|
|
|
|||
|
|
@ -88,11 +88,6 @@ def get_meta(doctype: "str | DocType", cached: bool = True) -> "_Meta":
|
|||
|
||||
meta = Meta(doctype)
|
||||
|
||||
if meta.name not in meta.special_doctypes:
|
||||
from frappe.desk.form.meta import mask_protected_fields
|
||||
|
||||
meta = mask_protected_fields(meta)
|
||||
|
||||
key = f"doctype_meta::{meta.name}"
|
||||
frappe.client_cache.set_value(key, meta)
|
||||
return meta
|
||||
|
|
@ -200,7 +195,26 @@ class Meta(Document):
|
|||
return self._dynamic_link_fields
|
||||
|
||||
def get_masked_fields(self):
|
||||
return self.get("fields", {"mask_readonly": 1})
|
||||
import copy
|
||||
|
||||
if frappe.session.user == "Administrator":
|
||||
return []
|
||||
cache_key = f"masked_fields::{self.name}::{frappe.session.user}"
|
||||
masked_fields = frappe.cache.get_value(cache_key)
|
||||
|
||||
if masked_fields is None:
|
||||
masked_fields = []
|
||||
for df in self.fields:
|
||||
if df.get("mask") and not self.has_permlevel_access_to(
|
||||
fieldname=df.fieldname, df=df, permission_type="mask"
|
||||
):
|
||||
# work on a copy instead of original df
|
||||
df_copy = copy.deepcopy(df)
|
||||
df_copy.mask_readonly = 1
|
||||
masked_fields.append(df_copy)
|
||||
frappe.cache.set_value(cache_key, masked_fields)
|
||||
|
||||
return masked_fields
|
||||
|
||||
@cached_property
|
||||
def _dynamic_link_fields(self):
|
||||
|
|
|
|||
|
|
@ -1174,11 +1174,11 @@ frappe.ui.form.Form = class FrappeForm {
|
|||
}
|
||||
|
||||
mark_mask_fields_readonly() {
|
||||
this.fields.forEach((field) => {
|
||||
if (field.df.mask && field.df.mask_readonly) {
|
||||
this.set_df_property(field.df.fieldname, "disabled", "1");
|
||||
this.set_df_property(field.df.fieldname, "fieldtype", "Data");
|
||||
}
|
||||
const masked_fields = this.meta.masked_fields || [];
|
||||
|
||||
masked_fields.forEach((fieldname) => {
|
||||
this.set_df_property(fieldname, "read_only", 1);
|
||||
this.set_df_property(fieldname, "fieldtype", "Data");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -417,7 +417,13 @@ frappe.form.get_formatter = function (fieldtype) {
|
|||
};
|
||||
|
||||
frappe.format = function (value, df, options, doc) {
|
||||
if (!df || df?.mask_readonly) df = { fieldtype: "Data" };
|
||||
let mask_readonly = false;
|
||||
if (df.parent) {
|
||||
const mask_fields = frappe.get_meta(df.parent)?.masked_fields;
|
||||
mask_readonly = mask_fields?.includes(df.fieldname);
|
||||
}
|
||||
|
||||
if (!df || mask_readonly) df = { fieldtype: "Data" };
|
||||
if (df.fieldname == "_user_tags") df = { ...df, fieldtype: "Tag" };
|
||||
var fieldtype = df.fieldtype || "Data";
|
||||
|
||||
|
|
|
|||
|
|
@ -245,12 +245,6 @@ frappe.ui.form.Layout = class Layout {
|
|||
}
|
||||
|
||||
init_field(df, parent, render = false) {
|
||||
if (df.mask && df.mask_readonly) {
|
||||
if (df.fieldtype !== "Data") {
|
||||
df.read_only = 1;
|
||||
df.fieldtype = "Data";
|
||||
}
|
||||
}
|
||||
const fieldobj = frappe.ui.form.make_control({
|
||||
df: df,
|
||||
doctype: this.doctype,
|
||||
|
|
|
|||
|
|
@ -922,7 +922,10 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
_value = _value * out_of_ratings;
|
||||
}
|
||||
|
||||
let filterable = df?.mask_readonly ? "no-underline" : " filterable";
|
||||
let masked_fields = frappe.get_meta(this.doctype).masked_fields || [];
|
||||
let is_masked = masked_fields.includes(df.fieldname);
|
||||
|
||||
let filterable = is_masked ? "no-underline" : " filterable";
|
||||
|
||||
if (df.fieldtype === "Image") {
|
||||
html = df.options
|
||||
|
|
|
|||
|
|
@ -1090,22 +1090,14 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
update_masked_fields_in_columns(columns) {
|
||||
const meta_fields = frappe.get_meta(this.report_doc?.ref_doctype).fields;
|
||||
const masked_fields = frappe.get_meta(this.report_doc?.ref_doctype).masked_fields;
|
||||
|
||||
const masked_field_map = Object.fromEntries(
|
||||
meta_fields
|
||||
.filter((field) => field.mask && field.mask_readonly)
|
||||
.map((field) => [field.fieldname, field])
|
||||
);
|
||||
|
||||
// return updated columns with masked field metadata applied
|
||||
return columns.map((col) => {
|
||||
const masked_field = masked_field_map[col.fieldname];
|
||||
if (masked_field) {
|
||||
if (masked_fields.includes(col.fieldname)) {
|
||||
return {
|
||||
...col,
|
||||
fieldtype: "Data",
|
||||
options: masked_field.options,
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
return col;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue