|
4 | 4 | import { |
5 | 5 | FormAutocompleteLocalFieldData, |
6 | 6 | FormAutocompleteRemoteFieldData, |
7 | | - FormTextFieldData, |
8 | | - SelectFilterData |
9 | 7 | } from "@/types"; |
10 | 8 | import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; |
11 | 9 | import { ref } from "vue"; |
12 | 10 | import { Button } from "@/components/ui/button"; |
13 | 11 | import { __ } from "@/utils/i18n"; |
14 | | - import { Check, ChevronsUpDown } from 'lucide-vue-next'; |
| 12 | + import { ChevronsUpDown, X } from 'lucide-vue-next'; |
15 | 13 | import { cn } from "@/utils/cn"; |
16 | 14 | import { |
17 | 15 | Command, |
|
21 | 19 | CommandList, |
22 | 20 | CommandSeparator |
23 | 21 | } from "@/components/ui/command"; |
24 | | - import { Checkbox } from "@/components/ui/checkbox"; |
25 | | - import { useDebounceFn } from "@vueuse/core"; |
26 | 22 | import { route } from "@/utils/url"; |
27 | 23 | import { api } from "@/api/api"; |
28 | 24 | import { useParentForm } from "@/form/useParentForm"; |
29 | 25 | import debounce from "lodash/debounce"; |
| 26 | + import { fuzzySearch } from "@/utils/search"; |
30 | 27 |
|
31 | 28 | const props = defineProps<FormFieldProps<FormAutocompleteLocalFieldData | FormAutocompleteRemoteFieldData>>(); |
32 | 29 | const emit = defineEmits<FormFieldEmits<FormAutocompleteLocalFieldData | FormAutocompleteRemoteFieldData>>(); |
|
36 | 33 | const searchTerm = ref(''); |
37 | 34 | const results = ref([]); |
38 | 35 |
|
39 | | - const remoteSearch = debounce(async (term: string) => { |
| 36 | + const abort = new AbortController(); |
| 37 | + const remoteSearch = debounce(async (query: string) => { |
40 | 38 | results.value = await api.get(route('code16.sharp.api.form.autocomplete.index', { |
41 | 39 | entityKey: form.entityKey, |
42 | 40 | autocompleteFieldKey: props.field.key, |
43 | 41 | }), { |
44 | 42 | params: { |
45 | 43 | endpoint: props.field.mode === 'remote' && props.field.remoteEndpoint, |
46 | | - search: term, |
| 44 | + search: query, |
47 | 45 | }, |
| 46 | + signal: abort.signal, |
48 | 47 | }) |
49 | 48 | .then(response => response.data.data); |
50 | 49 | }, 300); |
51 | 50 |
|
52 | | - const search = useDebounceFn(async (term) => { |
| 51 | + function search(query: string) { |
53 | 52 | if(props.field.mode === 'remote') { |
54 | | - remoteSearch(term); |
| 53 | + if(query.length >= props.field.searchMinChars) { |
| 54 | + remoteSearch(query); |
| 55 | + } |
55 | 56 | } else { |
| 57 | + if(query.length > 0) { |
| 58 | + results.value = fuzzySearch(props.field.localValues, query, { searchKeys: props.field.searchKeys }); |
| 59 | + } |
| 60 | + } |
| 61 | + } |
56 | 62 |
|
| 63 | + if(props.field.mode === 'local' && props.value) { |
| 64 | + const localValue = props.field.localValues |
| 65 | + .find(v => props.value[props.field.itemIdAttribute] == v[props.field.itemIdAttribute]); |
| 66 | + console.log(localValue); |
| 67 | + if(localValue) { |
| 68 | + emit('input', localValue, { force: true }); |
57 | 69 | } |
58 | | - }, 300); |
| 70 | + } |
59 | 71 | </script> |
60 | 72 |
|
61 | 73 | <template> |
62 | 74 | <FormFieldLayout :field="props.field"> |
63 | 75 | <Popover v-model:open="open"> |
64 | 76 | <template v-if="props.value"> |
65 | | - <div class="border border-input rounded-md p-2"> |
66 | | - <div v-html="props.value.toString()"></div> |
| 77 | + <div class="relative border border-input flex items-center rounded-md min-h-10 text-sm px-3 py-2"> |
| 78 | + <div class="flex-1" v-html="props.value._htmlResult ?? props.value._html ?? props.value[props.field.itemIdAttribute]"></div> |
| 79 | + <Button class="absolute right-0 top-1/2 -translate-y-1/2" variant="ghost" size="icon" @click="$emit('input', null)"> |
| 80 | + <X class="size-4" /> |
| 81 | + </Button> |
67 | 82 | </div> |
68 | 83 | </template> |
69 | 84 | <template v-else> |
70 | 85 | <PopoverTrigger as-child> |
71 | | - <Button variant="outline"> |
| 86 | + <Button class="w-full justify-between" variant="outline"> |
72 | 87 | {{ props.field.placeholder ?? __('sharp::form.multiselect.placeholder') }} |
73 | 88 | <ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" /> |
74 | 89 | </Button> |
|
0 commit comments