fix: added search complete component which loads data of link field in autocomplete control

This commit is contained in:
Shariq Ansari 2023-08-10 19:16:25 +05:30
parent 352bebcd69
commit 8270ca75e7
3 changed files with 145 additions and 13 deletions

@ -1 +1 @@
Subproject commit 33b6d102341624e9bdf87ea9fdd38e0560a63b99
Subproject commit 283183e7841bb97ddf3fd4d32dd60ad39153f690

View File

@ -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,

View 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>