Moisés de Jesús Cortés Castellanos 28c5ba153b
UPDATE: Actualización de dependencias mayor (#6)
- TailwindCSS 3 => 4
- Diseño cuadrado
- Otras dependencias.
2025-03-04 23:20:48 -06:00

166 lines
4.5 KiB
Vue

<script setup>
import { computed, onMounted, ref, watch, watchEffect } from 'vue'
import { lang } from '@Lang/i18n';
import GoogleIcon from '@Shared/GoogleIcon.vue';
import PrimaryButton from '../../Button/Primary.vue';
import Input from '../../Form/Input.vue';
import Selectable from '../../Form/Selectable.vue';
/** Eventos */
const emit = defineEmits([
'update:modelValue'
]);
/** Propiedades */
const props = defineProps({
itemATitle: String,
itemBTitle: String,
items: Object,
modelValue: Object,
title: String,
type: {
default: 'text',
type: String
}
})
// Elementos primarios (controlador)
const itemA = ref()
const itemsASelected = ref([]);
const itemsAUnselected = ref([]);
// Elementos secundarios
const itemB = ref();
/** Propiedades computadas */
const values = computed({
get() {
return props.modelValue
},
set(val) {
emit('update:modelValue', val)
}
})
/** Métodos */
function add() {
if (itemA.value) {
if(itemB.value) {
values.value.push({
item: {
_id: itemA.value._id,
name: itemA.value.name,
},
value: itemB.value,
});
let x = itemsAUnselected.value.filter((o) => {
return o._id != itemA.value._id
})
itemsAUnselected.value = x
itemsASelected.value.push({...itemA.value}),
itemA.value = null
itemB.value = null
} else {
Notify.warning(Lang('todo.uniqueSub.b.required', {name:Lang('subclassification')}))
}
} else {
Notify.warning(Lang('todo.uniqueSub.a.required', {name:Lang('classification')}))
}
}
function remove(index, provider) {
itemsAUnselected.value.push({...provider})
itemsASelected.value.splice(itemsASelected.value.indexOf(provider), 1)
values.value.splice(index, 1)
}
/** Exposiciones */
defineExpose({
itemA,
itemB,
add,
})
/** Observadores */
watchEffect(() => {
if(props.items.length > 0) {
itemsAUnselected.value = props.items
}
})
watch(itemA, () => {
emit('updateItemsB', itemA.value?.id)
if(!itemA.value) {
itemB.value = null
}
})
/** Ciclos */
onMounted(() => {
if(values.value) {
values.value.forEach((i) => {
itemsASelected.value.push({...i})
})
}
})
</script>
<template>
<div class="rounded-sm border border-primary dark:border-primary-d p-2">
<p>{{ title }}</p>
<div class="w-full grid gap-2 grid-cols-2 dark:bg-primary-d/50 rounded-md">
<Selectable
v-model="itemA"
:title="itemATitle"
:options="itemsAUnselected"
/>
<Input
v-model="itemB"
:title="itemBTitle"
:type="type"
@keyup.enter="add"
/>
<div class="col-span-2 flex justify-center">
<PrimaryButton
type="button"
@click="add"
>
{{ $t('add') }}
</PrimaryButton>
</div>
<div class="col-span-2 text-sm">
<p><b>{{ $t('items') }}</b> ({{ values.length }})</p>
</div>
<div class="col-span-2 space-y-2 ">
<template v-for="item, index in values">
<div class="relative rounded-sm border border-primary/50">
<div class="grid gap-2 grid-cols-2 w-full items-center p-2 dark:bg-primary-d/50">
<Input
v-model="item.item.name"
:title="itemATitle"
disabled
/>
<Input
v-model="item.value"
:title="itemBTitle"
/>
</div>
<div class="absolute right-1 top-1">
<GoogleIcon
class="btn-icon-primary"
name="close"
@click="remove(index, item.item)"
/>
</div>
</div>
</template>
</div>
<slot />
</div>
</div>
</template>