|
1 | 1 | <script setup lang="ts"> |
2 | | -import type { InferSerializable } from '../../../../src/types' |
3 | 2 | import type BelongsTo from '../../../../src/fields/belongs_to' |
4 | | -import { ref } from 'vue' |
| 3 | +import { computed, ref, toValue } from 'vue' |
5 | 4 | import { useResourceApi } from '../../../composables/resource' |
6 | 5 | import Select from 'primevue/select' |
| 6 | +import { useField } from '../../../composables/field' |
| 7 | +import InputText from 'primevue/inputtext' |
| 8 | +import { useFormValues } from 'vee-validate' |
| 9 | +import { useSearchParams } from '../../../composables/route' |
| 10 | +import { ViaRelationship } from '../../../types' |
7 | 11 |
|
8 | 12 | defineOptions({ |
9 | 13 | inheritAttrs: false, |
10 | 14 | }) |
11 | 15 |
|
12 | | -const props = defineProps<{ |
13 | | - error?: string[] |
14 | | - field: InferSerializable<BelongsTo> |
15 | | - record: any |
16 | | -}>() |
17 | | -
|
18 | 16 | const filter = ref('') |
19 | | -const model = defineModel() |
| 17 | +const params = useSearchParams<{ via?: ViaRelationship }>() |
| 18 | +const record = useFormValues() |
| 19 | +const { field, name, value, errorMessage, setValue, handleBlur } = useField<BelongsTo>() |
| 20 | +const { data, isLoading } = useResourceApi.list(field.resource.slug, { search: filter }) |
| 21 | +
|
| 22 | +const options = computed(() => { |
| 23 | + // TODO: This might not be really performant |
| 24 | + const options = data.value ? [...data.value.data] : [] |
| 25 | + if (!options.some((r) => r[field.resource.idKey] === value.value)) { |
| 26 | + options.unshift(record.value[field.relationship.relationName]) |
| 27 | + } |
| 28 | + return options |
| 29 | +}) |
| 30 | +
|
| 31 | +const isVia = params.via?.foreignKey === toValue(name) |
20 | 32 |
|
21 | | -const { data, isLoading } = useResourceApi.list(props.field.resource.slug, { search: filter }) |
| 33 | +if (isVia) { |
| 34 | + setValue(params.via?.value) |
| 35 | +} |
22 | 36 | </script> |
23 | 37 |
|
24 | 38 | <template> |
25 | 39 | <div class="flex flex-col gap-2"> |
26 | 40 | <Select |
27 | | - v-model="model" |
28 | | - :options="data?.data ?? []" |
| 41 | + :id="name" |
| 42 | + :name="name" |
| 43 | + v-model="value" |
| 44 | + :options="options" |
29 | 45 | :loading="isLoading" |
30 | 46 | :option-label="field.resource.titleKey" |
31 | 47 | :option-value="field.resource.idKey" |
32 | | - :placeholder="`Select ${field.resource.name}`" |
| 48 | + :placeholder="`Select ${field.resource.label}`" |
| 49 | + :disabled="isVia" |
33 | 50 | v-bind="field.attributes" |
| 51 | + @blur="handleBlur" |
34 | 52 | > |
35 | 53 | <template #header> |
36 | 54 | <div class="p-2"> |
37 | 55 | <InputText class="w-full" v-model="filter" /> |
38 | 56 | </div> |
39 | 57 | </template> |
40 | 58 | </Select> |
41 | | - <small class="text-red-400" v-if="error">{{ error.join('\n') }}</small> |
| 59 | + <errorMessage /> |
42 | 60 | </div> |
43 | 61 | </template> |
0 commit comments