fix: allow adding field in kanban settings modal
This commit is contained in:
parent
5ae3d8f44e
commit
28cd0bbe0a
@ -314,9 +314,6 @@ def get_data(
|
||||
if not kanban_fields:
|
||||
kanban_fields = ["name"]
|
||||
|
||||
if "name" not in kanban_fields:
|
||||
kanban_fields.append("name")
|
||||
|
||||
for field in kanban_fields:
|
||||
if field not in rows:
|
||||
rows.append(field)
|
||||
@ -444,6 +441,32 @@ def get_fields_meta(doctype, restricted_fieldtypes=None, as_array=False):
|
||||
fields = frappe.get_meta(doctype).fields
|
||||
fields = [field for field in fields if field.fieldtype not in not_allowed_fieldtypes]
|
||||
|
||||
standard_fields = [
|
||||
{"fieldname": "name", "fieldtype": "Link", "label": "ID", "options": doctype},
|
||||
{
|
||||
"fieldname": "owner",
|
||||
"fieldtype": "Link",
|
||||
"label": "Created By",
|
||||
"options": "User"
|
||||
},
|
||||
{
|
||||
"fieldname": "modified_by",
|
||||
"fieldtype": "Link",
|
||||
"label": "Last Updated By",
|
||||
"options": "User",
|
||||
},
|
||||
{"fieldname": "_user_tags", "fieldtype": "Data", "label": "Tags"},
|
||||
{"fieldname": "_liked_by", "fieldtype": "Data", "label": "Like"},
|
||||
{"fieldname": "_comments", "fieldtype": "Text", "label": "Comments"},
|
||||
{"fieldname": "_assign", "fieldtype": "Text", "label": "Assigned To"},
|
||||
{"fieldname": "creation", "fieldtype": "Datetime", "label": "Created On"},
|
||||
{"fieldname": "modified", "fieldtype": "Datetime", "label": "Last Updated On"},
|
||||
]
|
||||
|
||||
for field in standard_fields:
|
||||
if not restricted_fieldtypes or field.get('fieldtype') not in restricted_fieldtypes:
|
||||
fields.append(field)
|
||||
|
||||
if as_array:
|
||||
return fields
|
||||
|
||||
@ -585,21 +608,3 @@ def get_fields(doctype: str, allow_all_fieldtypes: bool = False):
|
||||
})
|
||||
|
||||
return _fields
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_kanban_fields(doctype):
|
||||
allowed_fieldtypes = ["Link", "Select"]
|
||||
fields = frappe.get_meta(doctype).fields
|
||||
fields = [field for field in fields if field.fieldtype in allowed_fieldtypes]
|
||||
fields = [
|
||||
{
|
||||
"label": _(field.label),
|
||||
"name": field.fieldname,
|
||||
"type": field.fieldtype,
|
||||
"options": field.options,
|
||||
}
|
||||
for field in fields
|
||||
if field.label and field.fieldname
|
||||
]
|
||||
|
||||
return fields
|
||||
@ -10,22 +10,75 @@
|
||||
</Button>
|
||||
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
||||
<template #body-content>
|
||||
<div class="text-base text-gray-800 mb-2">Column Field</div>
|
||||
<Autocomplete
|
||||
v-if="fields.data"
|
||||
value=""
|
||||
:options="fields.data"
|
||||
@change="(f) => (column_field = f)"
|
||||
>
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full !justify-start"
|
||||
variant="subtle"
|
||||
@click="togglePopover()"
|
||||
:label="column_field.label"
|
||||
/>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
<div>
|
||||
<div class="text-base text-gray-800 mb-2">{{ __('Column Field') }}</div>
|
||||
<Autocomplete
|
||||
v-if="columnFields"
|
||||
value=""
|
||||
:options="columnFields"
|
||||
@change="(f) => (column_field = f)"
|
||||
>
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full !justify-start"
|
||||
variant="subtle"
|
||||
@click="togglePopover()"
|
||||
:label="column_field.label"
|
||||
/>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<div class="text-base text-gray-800 mb-2">{{ __('Fields Order') }}</div>
|
||||
<Draggable
|
||||
:list="allFields"
|
||||
@end="reorder"
|
||||
group="fields"
|
||||
item-key="name"
|
||||
class="flex flex-col gap-1"
|
||||
>
|
||||
<template #item="{ element: field }">
|
||||
<div
|
||||
class="px-1 py-0.5 border rounded text-base text-gray-800 flex items-center justify-between gap-2"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<DragVerticalIcon class="h-3.5 cursor-grab" />
|
||||
<div>{{ field.label }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="ghost" icon="x" @click="removeField(field)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
<Autocomplete
|
||||
v-if="fields.data"
|
||||
value=""
|
||||
:options="fields.data"
|
||||
@change="(e) => addField(e)"
|
||||
>
|
||||
<template #target="{ togglePopover }">
|
||||
<Button
|
||||
class="w-full mt-2"
|
||||
variant="outline"
|
||||
@click="togglePopover()"
|
||||
:label="__('Add Field')"
|
||||
>
|
||||
<template #prefix>
|
||||
<FeatherIcon name="plus" class="h-4" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
<template #item-label="{ option }">
|
||||
<div class="flex flex-col gap-1">
|
||||
<div>{{ option.label }}</div>
|
||||
<div class="text-gray-500 text-sm">
|
||||
{{ `${option.fieldname} - ${option.fieldtype}` }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
</div>
|
||||
</template>
|
||||
<template #actions>
|
||||
<Button
|
||||
@ -38,9 +91,11 @@
|
||||
</Dialog>
|
||||
</template>
|
||||
<script setup>
|
||||
import DragVerticalIcon from '@/components/Icons/DragVerticalIcon.vue'
|
||||
import KanbanIcon from '@/components/Icons/KanbanIcon.vue'
|
||||
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
||||
import { Dialog, createResource } from 'frappe-ui'
|
||||
import Draggable from 'vuedraggable'
|
||||
import { ref, computed, nextTick } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
@ -59,28 +114,75 @@ const column_field = computed({
|
||||
get: () => {
|
||||
let fieldname = list.value?.params?.column_field
|
||||
if (!fieldname) return ''
|
||||
return fields.data.find((field) => field.name === fieldname)
|
||||
|
||||
return columnFields.value?.find((field) => field.fieldname === fieldname)
|
||||
},
|
||||
set: (val) => {
|
||||
list.value.params.column_field = val.name
|
||||
list.value.params.column_field = val.fieldname
|
||||
},
|
||||
})
|
||||
|
||||
const columnFields = computed(() => {
|
||||
return (
|
||||
fields.data?.filter((field) => ['Link', 'Select'].includes(field.fieldtype)) ||
|
||||
[]
|
||||
)
|
||||
})
|
||||
|
||||
const fields = createResource({
|
||||
url: 'crm.api.doc.get_kanban_fields',
|
||||
params: { doctype: props.doctype },
|
||||
url: 'crm.api.doc.get_fields_meta',
|
||||
params: { doctype: props.doctype, as_array: true},
|
||||
cache: ['kanban_fields', props.doctype],
|
||||
auto: true,
|
||||
onSuccess: (data) => {
|
||||
// data
|
||||
data
|
||||
},
|
||||
})
|
||||
|
||||
const allFields = computed({
|
||||
get: () => {
|
||||
let rows = list.value?.params?.kanban_fields
|
||||
if (!rows) return []
|
||||
|
||||
if (typeof rows === 'string') {
|
||||
rows = JSON.parse(rows)
|
||||
}
|
||||
|
||||
if (rows && fields.data) {
|
||||
rows = rows.map((row) => {
|
||||
return fields.data.find((field) => field.fieldname === row) || {}
|
||||
})
|
||||
}
|
||||
return rows.filter((row) => row.label)
|
||||
},
|
||||
set: (val) => {
|
||||
list.value.params.kanban_fields = val
|
||||
},
|
||||
})
|
||||
|
||||
function reorder() {
|
||||
allFields.value = allFields.value.map(row => row.fieldname)
|
||||
}
|
||||
|
||||
function addField(field) {
|
||||
if (!field) return
|
||||
let rows = allFields.value || []
|
||||
rows.push(field)
|
||||
allFields.value = rows.map((row) => row.fieldname)
|
||||
}
|
||||
|
||||
function removeField(field) {
|
||||
let rows = allFields.value
|
||||
rows = rows.filter((row) => row.fieldname !== field.fieldname)
|
||||
allFields.value = rows.map((row) => row.fieldname)
|
||||
}
|
||||
|
||||
function apply() {
|
||||
nextTick(() => {
|
||||
showDialog.value = false
|
||||
emit('update', {
|
||||
column_field: column_field.value.name,
|
||||
column_field: column_field.value.fieldname,
|
||||
kanban_fields: allFields.value.map((row) => row.fieldname),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user