fix: use fieldname & fieldtype instead of name & type in side panel

This commit is contained in:
Shariq Ansari 2025-01-02 19:47:38 +05:30
parent 319d4ff5ac
commit b4e4273810
7 changed files with 144 additions and 112 deletions

View File

@ -614,29 +614,19 @@ def get_sidebar_fields(doctype, name):
def get_field_obj(field): def get_field_obj(field):
obj = { field = field.as_dict()
"label": field.label, field["placeholder"] = field.get("placeholder") or "Add " + field.label + "..."
"type": field.fieldtype,
"name": field.fieldname,
"hidden": field.hidden,
"reqd": field.reqd,
"read_only": field.read_only,
"options": field.options,
"all_properties": field,
}
obj["placeholder"] = field.get("placeholder") or "Add " + field.label + "..."
if field.fieldtype == "Link": if field.fieldtype == "Link":
obj["placeholder"] = field.get("placeholder") or "Select " + field.label + "..." field["placeholder"] = field.get("placeholder") or "Select " + field.label + "..."
elif field.fieldtype == "Select" and field.options: elif field.fieldtype == "Select" and field.options:
obj["placeholder"] = field.get("placeholder") or "Select " + field.label + "..." field["placeholder"] = field.get("placeholder") or "Select " + field.label + "..."
obj["options"] = [{"label": option, "value": option} for option in field.options.split("\n")] field["options"] = [{"label": option, "value": option} for option in field.options.split("\n")]
if field.read_only: if field.read_only:
obj["tooltip"] = "This field is read only and cannot be edited." field["tooltip"] = "This field is read only and cannot be edited."
return obj return field
def get_assigned_users(doctype, name, default_assigned_to=None): def get_assigned_users(doctype, name, default_assigned_to=None):

View File

@ -60,6 +60,7 @@ def get_fields_layout(doctype: str, type: str, no_reactivity=False):
"read_only": field.read_only, "read_only": field.read_only,
"placeholder": field.get("placeholder"), "placeholder": field.get("placeholder"),
"filters": field.get("link_filters"), "filters": field.get("link_filters"),
"hidden": field.get("hidden"),
"depends_on": "" if no_reactivity else field.get("depends_on"), "depends_on": "" if no_reactivity else field.get("depends_on"),
"mandatory_depends_on": "" "mandatory_depends_on": ""
if no_reactivity if no_reactivity

View File

@ -56,7 +56,7 @@
> >
<template <template
v-for="field in section.columns[0].fields || []" v-for="field in section.columns[0].fields || []"
:key="field.name" :key="field.fieldname"
> >
<div <div
v-if="field.visible" v-if="field.visible"
@ -79,15 +79,15 @@
<div <div
v-if=" v-if="
field.read_only && field.read_only &&
!['Check', 'Dropdown'].includes(field.type) !['Check', 'Dropdown'].includes(field.fieldtype)
" "
class="flex h-7 cursor-pointer items-center px-2 py-1 text-ink-gray-5" class="flex h-7 cursor-pointer items-center px-2 py-1 text-ink-gray-5"
> >
<Tooltip :text="__(field.tooltip)"> <Tooltip :text="__(field.tooltip)">
<div>{{ data[field.name] }}</div> <div>{{ data[field.fieldname] }}</div>
</Tooltip> </Tooltip>
</div> </div>
<div v-else-if="field.type === 'Dropdown'"> <div v-else-if="field.fieldtype === 'Dropdown'">
<NestedPopover> <NestedPopover>
<template #target="{ open }"> <template #target="{ open }">
<Button <Button
@ -149,12 +149,16 @@
</NestedPopover> </NestedPopover>
</div> </div>
<FormControl <FormControl
v-else-if="field.type == 'Check'" v-else-if="field.fieldtype == 'Check'"
class="form-control" class="form-control"
type="checkbox" type="checkbox"
v-model="data[field.name]" v-model="data[field.fieldname]"
@change.stop=" @change.stop="
emit('update', field.name, $event.target.checked) emit(
'update',
field.fieldname,
$event.target.checked,
)
" "
:disabled="Boolean(field.read_only)" :disabled="Boolean(field.read_only)"
/> />
@ -165,45 +169,47 @@
'Text', 'Text',
'Long Text', 'Long Text',
'Code', 'Code',
].includes(field.type) ].includes(field.fieldtype)
" "
class="form-control" class="form-control"
type="textarea" type="textarea"
:value="data[field.name]" :value="data[field.fieldname]"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, $event.target.value) emit('update', field.fieldname, $event.target.value)
" "
/> />
<FormControl <FormControl
v-else-if="field.type === 'Select'" v-else-if="field.fieldtype === 'Select'"
class="form-control cursor-pointer [&_select]:cursor-pointer truncate" class="form-control cursor-pointer [&_select]:cursor-pointer truncate"
type="select" type="select"
v-model="data[field.name]" v-model="data[field.fieldname]"
:options="field.options" :options="field.options"
:placeholder="field.placeholder" :placeholder="field.placeholder"
@change.stop=" @change.stop="
emit('update', field.name, $event.target.value) emit('update', field.fieldname, $event.target.value)
" "
/> />
<Link <Link
v-else-if="field.type === 'User'" v-else-if="field.fieldtype === 'User'"
class="form-control" class="form-control"
:value=" :value="
data[field.name] && data[field.fieldname] &&
getUser(data[field.name]).full_name getUser(data[field.fieldname]).full_name
" "
doctype="User" doctype="User"
:filters="field.filters" :filters="field.filters"
@change="(data) => emit('update', field.name, data)" @change="
(data) => emit('update', field.fieldname, data)
"
:placeholder="'Select' + ' ' + field.label + '...'" :placeholder="'Select' + ' ' + field.label + '...'"
:hideMe="true" :hideMe="true"
> >
<template v-if="data[field.name]" #prefix> <template v-if="data[field.fieldname]" #prefix>
<UserAvatar <UserAvatar
class="mr-1.5" class="mr-1.5"
:user="data[field.name]" :user="data[field.fieldname]"
size="sm" size="sm"
/> />
</template> </template>
@ -223,117 +229,135 @@
</template> </template>
</Link> </Link>
<Link <Link
v-else-if="field.type === 'Link'" v-else-if="field.fieldtype === 'Link'"
class="form-control select-text" class="form-control select-text"
:value="data[field.name]" :value="data[field.fieldname]"
:doctype="field.options" :doctype="field.options"
:filters="field.filters" :filters="field.filters"
:placeholder="field.placeholder" :placeholder="field.placeholder"
@change="(data) => emit('update', field.name, data)" @change="
(data) => emit('update', field.fieldname, data)
"
:onCreate="field.create" :onCreate="field.create"
/> />
<div <div
v-else-if="field.type === 'Datetime'" v-else-if="field.fieldtype === 'Datetime'"
class="form-control" class="form-control"
> >
<DateTimePicker <DateTimePicker
icon-left="" icon-left=""
:value="data[field.name]" :value="data[field.fieldname]"
:formatter=" :formatter="
(date) => getFormat(date, '', true, true) (date) => getFormat(date, '', true, true)
" "
:placeholder="field.placeholder" :placeholder="field.placeholder"
placement="left-start" placement="left-start"
@change="(data) => emit('update', field.name, data)" @change="
(data) => emit('update', field.fieldname, data)
"
/> />
</div> </div>
<div <div
v-else-if="field.type === 'Date'" v-else-if="field.fieldtype === 'Date'"
class="form-control" class="form-control"
> >
<DatePicker <DatePicker
icon-left="" icon-left=""
:value="data[field.name]" :value="data[field.fieldname]"
:formatter="(date) => getFormat(date, '', true)" :formatter="(date) => getFormat(date, '', true)"
:placeholder="field.placeholder" :placeholder="field.placeholder"
placement="left-start" placement="left-start"
@change="(data) => emit('update', field.name, data)" @change="
(data) => emit('update', field.fieldname, data)
"
/> />
</div> </div>
<FormControl <FormControl
v-else-if="field.type === 'Percent'" v-else-if="field.fieldtype === 'Percent'"
class="form-control" class="form-control"
type="text" type="text"
:value="getFormattedPercent(field.name, data)" :value="getFormattedPercent(field.fieldname, data)"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, flt($event.target.value)) emit(
'update',
field.fieldname,
flt($event.target.value),
)
" "
/> />
<FormControl <FormControl
v-else-if="field.type === 'Int'" v-else-if="field.fieldtype === 'Int'"
class="form-control" class="form-control"
type="number" type="number"
v-model="data[field.name]" v-model="data[field.fieldname]"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, $event.target.value) emit('update', field.fieldname, $event.target.value)
" "
/> />
<FormControl <FormControl
v-else-if="field.type === 'Float'" v-else-if="field.fieldtype === 'Float'"
class="form-control" class="form-control"
type="text" type="text"
:value="getFormattedFloat(field.name, data)" :value="getFormattedFloat(field.fieldname, data)"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, flt($event.target.value)) emit(
'update',
field.fieldname,
flt($event.target.value),
)
" "
/> />
<FormControl <FormControl
v-else-if="field.type === 'Currency'" v-else-if="field.fieldtype === 'Currency'"
class="form-control" class="form-control"
type="text" type="text"
:value="getFormattedCurrency(field.name, data)" :value="getFormattedCurrency(field.fieldname, data)"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, flt($event.target.value)) emit(
'update',
field.fieldname,
flt($event.target.value),
)
" "
/> />
<FormControl <FormControl
v-else v-else
class="form-control" class="form-control"
type="text" type="text"
:value="data[field.name]" :value="data[field.fieldname]"
:placeholder="field.placeholder" :placeholder="field.placeholder"
:debounce="500" :debounce="500"
@change.stop=" @change.stop="
emit('update', field.name, $event.target.value) emit('update', field.fieldname, $event.target.value)
" "
/> />
</div> </div>
<div class="ml-1"> <div class="ml-1">
<ArrowUpRightIcon <ArrowUpRightIcon
v-if=" v-if="
field.type === 'Link' && field.fieldtype === 'Link' &&
field.link && field.link &&
data[field.name] data[field.fieldname]
" "
class="h-4 w-4 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8" class="h-4 w-4 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
@click.stop="field.link(data[field.name])" @click.stop="field.link(data[field.fieldname])"
/> />
<EditIcon <EditIcon
v-if=" v-if="
field.type === 'Link' && field.fieldtype === 'Link' &&
field.edit && field.edit &&
data[field.name] data[field.fieldname]
" "
class="size-3.5 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8" class="size-3.5 shrink-0 cursor-pointer text-ink-gray-5 hover:text-ink-gray-8"
@click.stop="field.edit(data[field.name])" @click.stop="field.edit(data[field.fieldname])"
/> />
</div> </div>
</div> </div>
@ -398,56 +422,73 @@ const _sections = computed(() => {
if (!props.sections?.length) return [] if (!props.sections?.length) return []
let editButtonAdded = false let editButtonAdded = false
return props.sections.map((section) => { return props.sections.map((section) => {
let isContactSection = section.name == 'contacts_section'
if (section.columns?.length) { if (section.columns?.length) {
section.columns[0].fields = section.columns[0].fields.map((field) => { section.columns[0].fields = section.columns[0].fields.map((field) => {
let df = field?.all_properties || {} return parsedField(field)
if (field.type === 'Link' && df.options === 'User') {
field.options = df.options
field.type = 'User'
}
let _field = {
...field,
depends_on: df.depends_on,
mandatory_depends_on: df.mandatory_depends_on,
display_via_depends_on: evaluateDependsOnValue(
df.depends_on,
data.value,
),
mandatory_via_depends_on: evaluateDependsOnValue(
df.mandatory_depends_on,
data.value,
),
filters: df.link_filters && JSON.parse(df.link_filters),
placeholder: field.placeholder || field.label,
}
_field.visible = isFieldVisible(_field)
return _field
}) })
} }
let _section = parsedSection(section, editButtonAdded)
section.showEditButton = !( if (_section.showEditButton) {
!isManager() ||
isContactSection ||
editButtonAdded
)
if (section.showEditButton) {
editButtonAdded = true editButtonAdded = true
} }
return _section
section.visible =
isContactSection ||
section.columns?.[0].fields.filter((f) => f.visible).length
return section
}) })
}) })
function parsedField(field) {
if (field.fieldtype == 'Select' && typeof field.options === 'string') {
field.options = field.options.split('\n').map((option) => {
return { label: option, value: option }
})
if (field.options[0].value !== '') {
field.options.unshift({ label: '', value: '' })
}
}
if (field.fieldtype === 'Link' && field.options === 'User') {
field.options = field.options
field.fieldtype = 'User'
}
let _field = {
...field,
filters: field.link_filters && JSON.parse(field.link_filters),
placeholder: field.placeholder || field.label,
display_via_depends_on: evaluateDependsOnValue(
field.depends_on,
data.value,
),
mandatory_via_depends_on: evaluateDependsOnValue(
field.mandatory_depends_on,
data.value,
),
}
_field.visible = isFieldVisible(_field)
return _field
}
function parsedSection(section, editButtonAdded) {
let isContactSection = section.name == 'contacts_section'
section.showEditButton = !(
!isManager() ||
isContactSection ||
editButtonAdded
)
section.visible =
isContactSection ||
section.columns?.[0].fields.filter((f) => f.visible).length
return section
}
function isFieldVisible(field) { function isFieldVisible(field) {
if (props.preview) return true
return ( return (
(field.type == 'Check' || (field.fieldtype == 'Check' ||
(field.read_only && data.value[field.name]) || (field.read_only && data.value[field.fieldname]) ||
!field.read_only) && !field.read_only) &&
(!field.depends_on || field.display_via_depends_on) && (!field.depends_on || field.display_via_depends_on) &&
!field.hidden !field.hidden

View File

@ -56,7 +56,7 @@
<Draggable <Draggable
:list="section.columns?.[0].fields || []" :list="section.columns?.[0].fields || []"
group="fields" group="fields"
item-key="name" item-key="fieldname"
class="flex flex-col gap-1.5" class="flex flex-col gap-1.5"
handle=".cursor-grab" handle=".cursor-grab"
> >

View File

@ -347,11 +347,11 @@ function getParsedSections(_sections) {
return _sections.map((section) => { return _sections.map((section) => {
section.columns = section.columns.map((column) => { section.columns = section.columns.map((column) => {
column.fields = column.fields.map((field) => { column.fields = column.fields.map((field) => {
if (field.name === 'email_id') { if (field.fieldname === 'email_id') {
return { return {
...field, ...field,
read_only: false, read_only: false,
type: 'Dropdown', fieldtype: 'Dropdown',
options: options:
contact.data?.email_ids?.map((email) => { contact.data?.email_ids?.map((email) => {
return { return {
@ -404,11 +404,11 @@ function getParsedSections(_sections) {
}) })
}, },
} }
} else if (field.name === 'mobile_no') { } else if (field.fieldname === 'mobile_no') {
return { return {
...field, ...field,
read_only: false, read_only: false,
type: 'Dropdown', fieldtype: 'Dropdown',
options: options:
contact.data?.phone_nos?.map((phone) => { contact.data?.phone_nos?.map((phone) => {
return { return {
@ -462,7 +462,7 @@ function getParsedSections(_sections) {
}) })
}, },
} }
} else if (field.name === 'address') { } else if (field.fieldname === 'address') {
return { return {
...field, ...field,
create: (value, close) => { create: (value, close) => {

View File

@ -541,7 +541,7 @@ function getParsedSections(_sections) {
_sections.forEach((section) => { _sections.forEach((section) => {
if (section.name == 'contacts_section') return if (section.name == 'contacts_section') return
section.columns[0].fields.forEach((field) => { section.columns[0].fields.forEach((field) => {
if (field.name == 'organization') { if (field.fieldname == 'organization') {
field.create = (value, close) => { field.create = (value, close) => {
_organization.value.organization_name = value _organization.value.organization_name = value
showOrganizationModal.value = true showOrganizationModal.value = true

View File

@ -347,7 +347,7 @@ function getParsedSections(_sections) {
return _sections.map((section) => { return _sections.map((section) => {
section.columns = section.columns.map((column) => { section.columns = section.columns.map((column) => {
column.fields = column.fields.map((field) => { column.fields = column.fields.map((field) => {
if (field.name === 'address') { if (field.fieldname === 'address') {
return { return {
...field, ...field,
create: (value, close) => { create: (value, close) => {