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:
|
if not kanban_fields:
|
||||||
kanban_fields = ["name"]
|
kanban_fields = ["name"]
|
||||||
|
|
||||||
if "name" not in kanban_fields:
|
|
||||||
kanban_fields.append("name")
|
|
||||||
|
|
||||||
for field in kanban_fields:
|
for field in kanban_fields:
|
||||||
if field not in rows:
|
if field not in rows:
|
||||||
rows.append(field)
|
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 = frappe.get_meta(doctype).fields
|
||||||
fields = [field for field in fields if field.fieldtype not in not_allowed_fieldtypes]
|
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:
|
if as_array:
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@ -585,21 +608,3 @@ def get_fields(doctype: str, allow_all_fieldtypes: bool = False):
|
|||||||
})
|
})
|
||||||
|
|
||||||
return _fields
|
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>
|
</Button>
|
||||||
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
<Dialog v-model="showDialog" :options="{ title: __('Kanban Settings') }">
|
||||||
<template #body-content>
|
<template #body-content>
|
||||||
<div class="text-base text-gray-800 mb-2">Column Field</div>
|
<div>
|
||||||
<Autocomplete
|
<div class="text-base text-gray-800 mb-2">{{ __('Column Field') }}</div>
|
||||||
v-if="fields.data"
|
<Autocomplete
|
||||||
value=""
|
v-if="columnFields"
|
||||||
:options="fields.data"
|
value=""
|
||||||
@change="(f) => (column_field = f)"
|
:options="columnFields"
|
||||||
>
|
@change="(f) => (column_field = f)"
|
||||||
<template #target="{ togglePopover }">
|
>
|
||||||
<Button
|
<template #target="{ togglePopover }">
|
||||||
class="w-full !justify-start"
|
<Button
|
||||||
variant="subtle"
|
class="w-full !justify-start"
|
||||||
@click="togglePopover()"
|
variant="subtle"
|
||||||
:label="column_field.label"
|
@click="togglePopover()"
|
||||||
/>
|
:label="column_field.label"
|
||||||
</template>
|
/>
|
||||||
</Autocomplete>
|
</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>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button
|
<Button
|
||||||
@ -38,9 +91,11 @@
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import DragVerticalIcon from '@/components/Icons/DragVerticalIcon.vue'
|
||||||
import KanbanIcon from '@/components/Icons/KanbanIcon.vue'
|
import KanbanIcon from '@/components/Icons/KanbanIcon.vue'
|
||||||
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
||||||
import { Dialog, createResource } from 'frappe-ui'
|
import { Dialog, createResource } from 'frappe-ui'
|
||||||
|
import Draggable from 'vuedraggable'
|
||||||
import { ref, computed, nextTick } from 'vue'
|
import { ref, computed, nextTick } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -59,28 +114,75 @@ const column_field = computed({
|
|||||||
get: () => {
|
get: () => {
|
||||||
let fieldname = list.value?.params?.column_field
|
let fieldname = list.value?.params?.column_field
|
||||||
if (!fieldname) return ''
|
if (!fieldname) return ''
|
||||||
return fields.data.find((field) => field.name === fieldname)
|
|
||||||
|
return columnFields.value?.find((field) => field.fieldname === fieldname)
|
||||||
},
|
},
|
||||||
set: (val) => {
|
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({
|
const fields = createResource({
|
||||||
url: 'crm.api.doc.get_kanban_fields',
|
url: 'crm.api.doc.get_fields_meta',
|
||||||
params: { doctype: props.doctype },
|
params: { doctype: props.doctype, as_array: true},
|
||||||
cache: ['kanban_fields', props.doctype],
|
cache: ['kanban_fields', props.doctype],
|
||||||
auto: true,
|
auto: true,
|
||||||
onSuccess: (data) => {
|
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() {
|
function apply() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
showDialog.value = false
|
showDialog.value = false
|
||||||
emit('update', {
|
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