fix: added search complete component which loads data of link field in autocomplete control
This commit is contained in:
parent
352bebcd69
commit
8270ca75e7
@ -1 +1 @@
|
||||
Subproject commit 33b6d102341624e9bdf87ea9fdd38e0560a63b99
|
||||
Subproject commit 283183e7841bb97ddf3fd4d32dd60ad39153f690
|
||||
@ -14,7 +14,7 @@
|
||||
</template>
|
||||
<template #body="{ close }">
|
||||
<div class="rounded-lg border border-gray-100 bg-white shadow-xl my-2">
|
||||
<div class="p-2 min-w-[500px]">
|
||||
<div class="p-2 min-w-[400px]">
|
||||
<div
|
||||
v-if="filterValues.length"
|
||||
v-for="(filter, i) in filterValues"
|
||||
@ -38,11 +38,11 @@
|
||||
:options="getOperators(filter.fieldtype)"
|
||||
placeholder="Operator"
|
||||
/>
|
||||
<FormControl
|
||||
class="!w-36"
|
||||
<component
|
||||
:is="getValSelect(filter.fieldtype, filter.options)"
|
||||
v-model="filter.value"
|
||||
type="text"
|
||||
placeholder="Value"
|
||||
class="!min-w-[140px]"
|
||||
/>
|
||||
<Button variant="ghost" icon="x" @click="removeFilter(i)" />
|
||||
</div>
|
||||
@ -89,6 +89,7 @@
|
||||
<script setup>
|
||||
import NestedPopover from '@/components/NestedPopover.vue'
|
||||
import FilterIcon from '@/components/Icons/FilterIcon.vue'
|
||||
import SearchComplete from '@/components/SearchComplete.vue'
|
||||
import {
|
||||
FeatherIcon,
|
||||
Button,
|
||||
@ -96,7 +97,7 @@ import {
|
||||
FormControl,
|
||||
createResource,
|
||||
} from 'frappe-ui'
|
||||
import { ref } from 'vue'
|
||||
import { ref, h } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
doctype: {
|
||||
@ -133,7 +134,7 @@ const typeString = ['Data', 'Long Text', 'Small Text', 'Text Editor', 'Text']
|
||||
|
||||
function getOperators(fieldtype) {
|
||||
let options = []
|
||||
if (typeString.includes(fieldtype) || typeNumber.includes(fieldtype)) {
|
||||
if (typeString.includes(fieldtype)) {
|
||||
options.push(
|
||||
...[
|
||||
{ label: 'Equals', value: 'equals' },
|
||||
@ -163,17 +164,61 @@ function getOperators(fieldtype) {
|
||||
]
|
||||
)
|
||||
}
|
||||
if (typeCheck.includes(fieldtype)) {
|
||||
options.push(...[{ label: 'Equals', value: 'equals' }])
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
function getValSelect(fieldtype, options) {
|
||||
if (typeLink.includes(fieldtype)) {
|
||||
return h(SearchComplete, { doctype: options })
|
||||
} else if (typeSelect.includes(fieldtype) || typeCheck.includes(fieldtype)) {
|
||||
const _options =
|
||||
fieldtype == 'Check' ? ['Yes', 'No'] : getSelectOptions(options)
|
||||
return h(FormControl, {
|
||||
type: 'select',
|
||||
options: _options.map((o) => ({
|
||||
label: o,
|
||||
value: o,
|
||||
})),
|
||||
})
|
||||
} else {
|
||||
return h(FormControl, { type: 'text' })
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultValue(field) {
|
||||
if (typeSelect.includes(field.fieldtype)) {
|
||||
return getSelectOptions(field.options)[0]
|
||||
}
|
||||
if (typeCheck.includes(field.fieldtype)) {
|
||||
return 'Yes'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getDefaultOperator(fieldtype) {
|
||||
if (typeSelect.includes(fieldtype) || typeLink.includes(fieldtype)) {
|
||||
return 'is'
|
||||
}
|
||||
if (typeCheck.includes(fieldtype) || typeNumber.includes(fieldtype)) {
|
||||
return 'equals'
|
||||
}
|
||||
return 'like'
|
||||
}
|
||||
|
||||
function getSelectOptions(options) {
|
||||
return options.split('\n')
|
||||
}
|
||||
|
||||
function setfilter(data) {
|
||||
let operator = getOperators(data.fieldtype)[0].value
|
||||
filterValues.value = [
|
||||
...filterValues.value,
|
||||
{
|
||||
field: data.value,
|
||||
operator: operator,
|
||||
value: '',
|
||||
operator: getDefaultOperator(data.fieldtype),
|
||||
value: getDefaultValue(data),
|
||||
label: data.label,
|
||||
fieldtype: data.fieldtype,
|
||||
options: data.options,
|
||||
@ -182,11 +227,10 @@ function setfilter(data) {
|
||||
}
|
||||
|
||||
function updateFilter(data, index) {
|
||||
let operator = getOperators(data.fieldtype)[0].value
|
||||
filterValues.value[index] = {
|
||||
field: data.value,
|
||||
operator: operator,
|
||||
value: '',
|
||||
operator: getDefaultOperator(data.fieldtype),
|
||||
value: getDefaultValue(data),
|
||||
label: data.label,
|
||||
fieldtype: data.fieldtype,
|
||||
options: data.options,
|
||||
|
||||
88
frontend/src/components/SearchComplete.vue
Normal file
88
frontend/src/components/SearchComplete.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<Autocomplete
|
||||
placeholder="Select an option"
|
||||
:options="options"
|
||||
:value="selection"
|
||||
@update:query="(q) => onUpdateQuery(q)"
|
||||
@change="(v) => (selection = v)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Autocomplete,
|
||||
createListResource,
|
||||
} from 'frappe-ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
doctype: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
searchField: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'name',
|
||||
},
|
||||
labelField: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'name',
|
||||
},
|
||||
valueField: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'name',
|
||||
},
|
||||
pageLength: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 10,
|
||||
},
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.doctype,
|
||||
(value) => {
|
||||
r.doctype = value
|
||||
r.reload()
|
||||
}
|
||||
)
|
||||
|
||||
const r = createListResource({
|
||||
doctype: props.doctype,
|
||||
pageLength: props.pageLength,
|
||||
cache: ['link_doctype', props.doctype],
|
||||
auto: true,
|
||||
fields: [props.labelField, props.searchField, props.valueField],
|
||||
onSuccess: () => {
|
||||
selection.value = props.value
|
||||
? options.value.find((o) => o.value === props.value)
|
||||
: null
|
||||
},
|
||||
})
|
||||
const options = computed(
|
||||
() =>
|
||||
r.data?.map((result) => ({
|
||||
label: result[props.labelField],
|
||||
value: result[props.valueField],
|
||||
})) || []
|
||||
)
|
||||
const selection = ref(null)
|
||||
|
||||
function onUpdateQuery(query) {
|
||||
r.update({
|
||||
filters: {
|
||||
[props.searchField]: ['like', `%${query}%`],
|
||||
},
|
||||
})
|
||||
|
||||
r.reload()
|
||||
}
|
||||
</script>
|
||||
Loading…
x
Reference in New Issue
Block a user