| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- <template>
- <q-select
- v-model="selectedAddress"
- :options="filteredAddresses"
- :label="label"
- outlined
- use-input
- clearable
- input-debounce="300"
- option-label="label"
- option-value="value"
- :rules="rules"
- :error="error"
- :error-message="errorMessage"
- :disabled="disabled"
- :loading="loading"
- @filter="filterFn"
- @update:model-value="updateValue"
- >
- <template #no-option>
- <q-item>
- <q-item-section class="text-grey">
- {{ disabled ? $t('common.messages.select_client_first') : $t('common.status.no_results') }}
- </q-item-section>
- </q-item>
- </template>
- </q-select>
- </template>
- <script setup>
- import { reactive, ref, watch } from 'vue'
- import { getAddresses } from 'src/api/address'
- import { normalizeString } from 'src/helpers/utils'
- const props = defineProps({
- label: {
- type: String,
- default: 'Endereço'
- },
- rules: {
- type: Array,
- default: () => []
- },
- error: {
- type: Boolean,
- default: false
- },
- errorMessage: {
- type: String,
- default: ''
- },
- initialId: {
- type: Number,
- default: null
- },
- clientId: {
- type: Number,
- default: null
- },
- disabled: {
- type: Boolean,
- default: false
- },
- type: {
- type: String,
- default: null // home / commercial
- }
- })
- const model = defineModel({
- type: Object,
- default: null
- })
- const emit = defineEmits(['update:modelValue'])
- const addresses = ref([])
- let filteredAddresses = reactive([])
- const selectedAddress = ref(null)
- const loading = ref(false)
- const loadAddresses = async () => {
- if (!props.clientId) {
- addresses.value = []
- filteredAddresses = []
- return
- }
- loading.value = true
- try {
- const response = await getAddresses('client', props.clientId);
- addresses.value = response.map((address) => ({
- label: `${address.address_full}`,
- value: address.id,
- ...address
- }));
- filteredAddresses = addresses.value;
- if (props.initialId) {
- selectAddressById(props.initialId);
- }
- } catch (error) {
- console.error('Error loading addresses:', error);
- } finally {
- loading.value = false;
- }
- }
- const filterFn = (val, update) => {
- update(() => {
- const needle = normalizeString(val);
- filteredAddresses = addresses.value.filter((address) => {
- const addressString = normalizeString(address.label);
- return addressString.includes(needle);
- })
- })
- }
- const updateValue = (value) => {
- model.value = value;
- emit('update:modelValue', value);
- }
- const selectAddressById = (id) => {
- const address = addresses.value.find((a) => a.value === id);
- if (address) {
- selectedAddress.value = address;
- updateValue(address);
- }
- }
- watch(() => props.clientId, (newClientId) => {
- if (newClientId) {
- loadAddresses()
- } else {
- addresses.value = []
- filteredAddresses = []
- selectedAddress.value = null
- updateValue(null)
- }
- }, { immediate: true });
- watch(() => props.type, (newType) => {
- if (newType) {
- filteredAddresses = addresses.value.filter(addr => addr.address_type === newType);
- } else {
- loadAddresses()
- }
- })
- watch(() => props.initialId, (newId) => {
- if (newId && addresses.value.length > 0) {
- selectAddressById(newId)
- }
- })
- </script>
|