127 lines
3.0 KiB
Vue
127 lines
3.0 KiB
Vue
<template>
|
|
<v-dialog
|
|
max-width="560"
|
|
:model-value="visible"
|
|
@update:model-value="onUpdateVisible"
|
|
>
|
|
<v-card>
|
|
<v-card-title>Proveedores del producto</v-card-title>
|
|
<v-card-text>
|
|
<p v-if="product" class="text-subtitle-1 mb-3">
|
|
{{ product.name }}
|
|
</p>
|
|
<v-autocomplete
|
|
v-model="selectedIds"
|
|
chips
|
|
closable-chips
|
|
item-title="name"
|
|
item-value="id"
|
|
:items="supplierItems"
|
|
label="Proveedores"
|
|
multiple
|
|
:search-input="searchQuery"
|
|
/>
|
|
<v-chip
|
|
v-if="selectedIds.length > 0"
|
|
class="mt-3"
|
|
color="primary"
|
|
variant="tonal"
|
|
>
|
|
Seleccionados ({{ selectedIds.length }})
|
|
</v-chip>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer />
|
|
<v-btn variant="text" @click="close">Cancelar</v-btn>
|
|
<v-btn
|
|
color="primary"
|
|
data-testid="supplier-link-save"
|
|
:disabled="saving"
|
|
variant="elevated"
|
|
@click="save"
|
|
>
|
|
Guardar
|
|
</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, inject, ref, watch } from 'vue'
|
|
|
|
const props = defineProps({
|
|
visible: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
product: {
|
|
type: Object,
|
|
default: null,
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits(['update:visible'])
|
|
|
|
const api = inject('api')
|
|
const suppliers = ref([])
|
|
const selectedIds = ref([])
|
|
const searchQuery = ref('')
|
|
const saving = ref(false)
|
|
|
|
const supplierItems = computed(() => {
|
|
const query = searchQuery.value.trim().toLowerCase()
|
|
let filtered = suppliers.value
|
|
if (query) {
|
|
filtered = suppliers.value.filter(supplier => {
|
|
return (supplier.name || '').toLowerCase().includes(query)
|
|
})
|
|
}
|
|
const selected = selectedIds.value.map(Number)
|
|
for (const supplier of suppliers.value) {
|
|
const isSelected = selected.includes(supplier.id)
|
|
const alreadyIncluded = filtered.some(item => item.id === supplier.id)
|
|
if (isSelected && !alreadyIncluded) filtered = [supplier, ...filtered]
|
|
}
|
|
return filtered
|
|
})
|
|
|
|
async function load () {
|
|
suppliers.value = await api.getSuppliers()
|
|
if (props.product) {
|
|
const detail = await api.getProduct(props.product.id)
|
|
selectedIds.value = detail.suppliers || []
|
|
} else {
|
|
selectedIds.value = []
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => props.visible,
|
|
async isVisible => {
|
|
if (isVisible) await load()
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
async function save () {
|
|
saving.value = true
|
|
try {
|
|
await api.updateProduct(props.product.id, { suppliers: selectedIds.value })
|
|
close()
|
|
} catch (error) {
|
|
console.error('Error al guardar proveedores del producto:', error)
|
|
} finally {
|
|
saving.value = false
|
|
}
|
|
}
|
|
|
|
function onUpdateVisible (value) {
|
|
emit('update:visible', value)
|
|
}
|
|
|
|
function close () {
|
|
emit('update:visible', false)
|
|
}
|
|
</script>
|