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>
|
||||||
<template #body="{ close }">
|
<template #body="{ close }">
|
||||||
<div class="rounded-lg border border-gray-100 bg-white shadow-xl my-2">
|
<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
|
<div
|
||||||
v-if="filterValues.length"
|
v-if="filterValues.length"
|
||||||
v-for="(filter, i) in filterValues"
|
v-for="(filter, i) in filterValues"
|
||||||
@ -38,11 +38,11 @@
|
|||||||
:options="getOperators(filter.fieldtype)"
|
:options="getOperators(filter.fieldtype)"
|
||||||
placeholder="Operator"
|
placeholder="Operator"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<component
|
||||||
class="!w-36"
|
:is="getValSelect(filter.fieldtype, filter.options)"
|
||||||
v-model="filter.value"
|
v-model="filter.value"
|
||||||
type="text"
|
|
||||||
placeholder="Value"
|
placeholder="Value"
|
||||||
|
class="!min-w-[140px]"
|
||||||
/>
|
/>
|
||||||
<Button variant="ghost" icon="x" @click="removeFilter(i)" />
|
<Button variant="ghost" icon="x" @click="removeFilter(i)" />
|
||||||
</div>
|
</div>
|
||||||
@ -89,6 +89,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import NestedPopover from '@/components/NestedPopover.vue'
|
import NestedPopover from '@/components/NestedPopover.vue'
|
||||||
import FilterIcon from '@/components/Icons/FilterIcon.vue'
|
import FilterIcon from '@/components/Icons/FilterIcon.vue'
|
||||||
|
import SearchComplete from '@/components/SearchComplete.vue'
|
||||||
import {
|
import {
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
Button,
|
Button,
|
||||||
@ -96,7 +97,7 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
createResource,
|
createResource,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { ref } from 'vue'
|
import { ref, h } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
doctype: {
|
doctype: {
|
||||||
@ -133,7 +134,7 @@ const typeString = ['Data', 'Long Text', 'Small Text', 'Text Editor', 'Text']
|
|||||||
|
|
||||||
function getOperators(fieldtype) {
|
function getOperators(fieldtype) {
|
||||||
let options = []
|
let options = []
|
||||||
if (typeString.includes(fieldtype) || typeNumber.includes(fieldtype)) {
|
if (typeString.includes(fieldtype)) {
|
||||||
options.push(
|
options.push(
|
||||||
...[
|
...[
|
||||||
{ label: 'Equals', value: 'equals' },
|
{ label: 'Equals', value: 'equals' },
|
||||||
@ -163,17 +164,61 @@ function getOperators(fieldtype) {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if (typeCheck.includes(fieldtype)) {
|
||||||
|
options.push(...[{ label: 'Equals', value: 'equals' }])
|
||||||
|
}
|
||||||
return options
|
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) {
|
function setfilter(data) {
|
||||||
let operator = getOperators(data.fieldtype)[0].value
|
|
||||||
filterValues.value = [
|
filterValues.value = [
|
||||||
...filterValues.value,
|
...filterValues.value,
|
||||||
{
|
{
|
||||||
field: data.value,
|
field: data.value,
|
||||||
operator: operator,
|
operator: getDefaultOperator(data.fieldtype),
|
||||||
value: '',
|
value: getDefaultValue(data),
|
||||||
label: data.label,
|
label: data.label,
|
||||||
fieldtype: data.fieldtype,
|
fieldtype: data.fieldtype,
|
||||||
options: data.options,
|
options: data.options,
|
||||||
@ -182,11 +227,10 @@ function setfilter(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateFilter(data, index) {
|
function updateFilter(data, index) {
|
||||||
let operator = getOperators(data.fieldtype)[0].value
|
|
||||||
filterValues.value[index] = {
|
filterValues.value[index] = {
|
||||||
field: data.value,
|
field: data.value,
|
||||||
operator: operator,
|
operator: getDefaultOperator(data.fieldtype),
|
||||||
value: '',
|
value: getDefaultValue(data),
|
||||||
label: data.label,
|
label: data.label,
|
||||||
fieldtype: data.fieldtype,
|
fieldtype: data.fieldtype,
|
||||||
options: data.options,
|
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