80 lines
2.3 KiB
Vue
80 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import { getSelectedProfile } from '@/api/profile'
|
|
import { TransactionApiClient, type TransactionVendor } from '@/api/transaction'
|
|
import { onMounted, ref, watch, type Ref } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import VueSelect, { type Option } from 'vue3-select-component'
|
|
|
|
const model = defineModel<TransactionVendor | null>({ required: true })
|
|
|
|
const route = useRoute()
|
|
const options: Ref<Option<string>[]> = ref([])
|
|
const existingVendors: Ref<TransactionVendor[]> = ref([])
|
|
const selectedVendorName: Ref<string | null> = ref(null)
|
|
|
|
watch(model, (newValue) => {
|
|
if (newValue === null) {
|
|
selectedVendorName.value = null
|
|
} else {
|
|
selectedVendorName.value = newValue.name
|
|
}
|
|
})
|
|
|
|
onMounted(() => {
|
|
const api = new TransactionApiClient(getSelectedProfile(route))
|
|
if (model.value !== null) {
|
|
selectedVendorName.value = model.value?.name
|
|
}
|
|
api.getVendors().then((vendors) => {
|
|
existingVendors.value = vendors
|
|
options.value = vendors.map((v) => {
|
|
return { label: v.name, value: v.name }
|
|
})
|
|
})
|
|
})
|
|
|
|
function onOptionCreated(value: string) {
|
|
const existingVendor = existingVendors.value.find((obj) => obj.name === value)
|
|
if (existingVendor) {
|
|
selectedVendorName.value = existingVendor.name
|
|
model.value = existingVendor
|
|
return
|
|
}
|
|
// Clear out any previously-added custom value from the list of options.
|
|
options.value = options.value.filter((opt) =>
|
|
existingVendors.value.some((v) => v.name === opt.value),
|
|
)
|
|
// Then add the new custom value, select it, and set the model.
|
|
options.value.push({ label: value, value: value })
|
|
selectedVendorName.value = value
|
|
model.value = { id: -1, name: value, description: null }
|
|
}
|
|
|
|
function onOptionSelected() {
|
|
model.value = existingVendors.value.find((v) => v.name === selectedVendorName.value) ?? null
|
|
}
|
|
|
|
function onOptionDeselected() {
|
|
model.value = null
|
|
}
|
|
</script>
|
|
<template>
|
|
<VueSelect
|
|
class="vendor-select"
|
|
v-model="selectedVendorName"
|
|
:options="options"
|
|
placeholder="Select a vendor"
|
|
is-taggable
|
|
@option-created="onOptionCreated"
|
|
@option-selected="onOptionSelected"
|
|
@option-deselected="onOptionDeselected"
|
|
>
|
|
<template #taggable-no-options> Add a new vendor. </template>
|
|
</VueSelect>
|
|
</template>
|
|
<style lang="css">
|
|
.vendor-select {
|
|
--vs-line-height: 1;
|
|
}
|
|
</style>
|