Merge pull request #81 from shariquerik/fields-display-rules
feat: Permissions & Field Visibility
This commit is contained in:
commit
9b018c29ea
@ -244,7 +244,7 @@ def get_list_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_doctype_fields(doctype):
|
def get_doctype_fields(doctype, name):
|
||||||
not_allowed_fieldtypes = [
|
not_allowed_fieldtypes = [
|
||||||
"Section Break",
|
"Section Break",
|
||||||
"Column Break",
|
"Column Break",
|
||||||
@ -256,6 +256,12 @@ def get_doctype_fields(doctype):
|
|||||||
sections = {}
|
sections = {}
|
||||||
section_fields = []
|
section_fields = []
|
||||||
last_section = None
|
last_section = None
|
||||||
|
doc = frappe.get_cached_doc(doctype, name)
|
||||||
|
|
||||||
|
has_high_permlevel_fields = any(df.permlevel > 0 for df in fields)
|
||||||
|
if has_high_permlevel_fields:
|
||||||
|
has_read_access_to_permlevels = doc.get_permlevel_access("read")
|
||||||
|
has_write_access_to_permlevels = doc.get_permlevel_access("write")
|
||||||
|
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if field.fieldtype == "Tab Break" and last_section:
|
if field.fieldtype == "Tab Break" and last_section:
|
||||||
@ -277,6 +283,13 @@ def get_doctype_fields(doctype):
|
|||||||
"fields": [],
|
"fields": [],
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
|
if field.permlevel > 0:
|
||||||
|
field_has_write_access = field.permlevel in has_write_access_to_permlevels
|
||||||
|
field_has_read_access = field.permlevel in has_read_access_to_permlevels
|
||||||
|
if not field_has_write_access and field_has_read_access:
|
||||||
|
field.read_only = 1
|
||||||
|
if not field_has_read_access and not field_has_write_access:
|
||||||
|
field.hidden = 1
|
||||||
section_fields.append(get_field_obj(field))
|
section_fields.append(get_field_obj(field))
|
||||||
|
|
||||||
section_fields = []
|
section_fields = []
|
||||||
@ -299,6 +312,7 @@ def get_field_obj(field):
|
|||||||
"hidden": field.hidden,
|
"hidden": field.hidden,
|
||||||
"reqd": field.reqd,
|
"reqd": field.reqd,
|
||||||
"read_only": field.read_only,
|
"read_only": field.read_only,
|
||||||
|
"all_properties": field,
|
||||||
}
|
}
|
||||||
|
|
||||||
obj["placeholder"] = "Add " + field.label + "..."
|
obj["placeholder"] = "Add " + field.label + "..."
|
||||||
|
|||||||
@ -27,7 +27,7 @@ def get_deal(name):
|
|||||||
fields=["contact", "is_primary"],
|
fields=["contact", "is_primary"],
|
||||||
)
|
)
|
||||||
|
|
||||||
deal["doctype_fields"], deal["all_fields"] = get_doctype_fields("CRM Deal")
|
deal["doctype_fields"], deal["all_fields"] = get_doctype_fields("CRM Deal", name)
|
||||||
deal["doctype"] = "CRM Deal"
|
deal["doctype"] = "CRM Deal"
|
||||||
deal["_form_script"] = get_form_script('CRM Deal')
|
deal["_form_script"] = get_form_script('CRM Deal')
|
||||||
deal["_assign"] = get_assigned_users("CRM Deal", deal.name)
|
deal["_assign"] = get_assigned_users("CRM Deal", deal.name)
|
||||||
|
|||||||
@ -15,7 +15,7 @@ def get_lead(name):
|
|||||||
frappe.throw(_("Lead not found"), frappe.DoesNotExistError)
|
frappe.throw(_("Lead not found"), frappe.DoesNotExistError)
|
||||||
lead = lead.pop()
|
lead = lead.pop()
|
||||||
|
|
||||||
lead["doctype_fields"], lead["all_fields"] = get_doctype_fields("CRM Lead")
|
lead["doctype_fields"], lead["all_fields"] = get_doctype_fields("CRM Lead", name)
|
||||||
lead["doctype"] = "CRM Lead"
|
lead["doctype"] = "CRM Lead"
|
||||||
lead["_form_script"] = get_form_script('CRM Lead')
|
lead["_form_script"] = get_form_script('CRM Lead')
|
||||||
lead["_assign"] = get_assigned_users("CRM Lead", lead.name)
|
lead["_assign"] = get_assigned_users("CRM Lead", lead.name)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex max-h-[300px] flex-col gap-1.5 overflow-y-auto">
|
<div class="flex max-h-[300px] flex-col gap-1.5 overflow-y-auto">
|
||||||
<div
|
<div
|
||||||
v-for="field in fields"
|
v-for="field in _fields"
|
||||||
:key="field.label"
|
:key="field.label"
|
||||||
:class="[field.hidden && 'hidden']"
|
:class="[field.hidden && 'hidden']"
|
||||||
class="flex items-center gap-2 px-3 leading-5 first:mt-3"
|
class="flex items-center gap-2 px-3 leading-5 first:mt-3"
|
||||||
@ -109,7 +109,7 @@ import Link from '@/components/Controls/Link.vue'
|
|||||||
import UserAvatar from '@/components/UserAvatar.vue'
|
import UserAvatar from '@/components/UserAvatar.vue'
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import { Tooltip } from 'frappe-ui'
|
import { Tooltip } from 'frappe-ui'
|
||||||
import { defineModel } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
fields: {
|
fields: {
|
||||||
@ -123,6 +123,43 @@ const { getUser } = usersStore()
|
|||||||
const emit = defineEmits(['update'])
|
const emit = defineEmits(['update'])
|
||||||
|
|
||||||
const data = defineModel()
|
const data = defineModel()
|
||||||
|
|
||||||
|
const _fields = computed(() => {
|
||||||
|
let all_fields = []
|
||||||
|
props.fields?.forEach((field) => {
|
||||||
|
let df = field.all_properties
|
||||||
|
if (df.depends_on) evaluate_depends_on(df.depends_on, field)
|
||||||
|
all_fields.push(field)
|
||||||
|
})
|
||||||
|
return all_fields
|
||||||
|
})
|
||||||
|
|
||||||
|
function evaluate_depends_on(expression, field) {
|
||||||
|
if (expression.substr(0, 5) == 'eval:') {
|
||||||
|
try {
|
||||||
|
let out = evaluate(expression.substr(5), { doc: data.value })
|
||||||
|
if (!out) {
|
||||||
|
field.hidden = true
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function evaluate(code, context = {}) {
|
||||||
|
let variable_names = Object.keys(context)
|
||||||
|
let variables = Object.values(context)
|
||||||
|
code = `let out = ${code}; return out`
|
||||||
|
try {
|
||||||
|
let expression_function = new Function(...variable_names, code)
|
||||||
|
return expression_function(...variables)
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Error evaluating the following expression:')
|
||||||
|
console.error(code)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user