refactor: refs #7679 better way to update model #581

Merged
alexm merged 2 commits from 7679-vnLocation_improve into master 2024-08-01 08:06:20 +00:00
6 changed files with 56 additions and 47 deletions

View File

@ -19,8 +19,8 @@ const cityFormData = reactive({
const provincesOptions = ref([]);
const onDataSaved = (dataSaved) => {
emit('onDataSaved', dataSaved);
const onDataSaved = (...args) => {
emit('onDataSaved', ...args);
};
</script>
@ -36,7 +36,7 @@ const onDataSaved = (dataSaved) => {
:form-initial-data="cityFormData"
url-create="towns"
model="city"
@on-data-saved="onDataSaved($event)"
@on-data-saved="onDataSaved"
>
<template #form-inputs="{ data, validate }">
<VnRow class="row q-gutter-md q-mb-md">

View File

@ -22,20 +22,17 @@ const postcodeFormData = reactive({
townFk: null,
});
const townsFetchDataRef = ref(null);
const provincesFetchDataRef = ref(null);
const countriesOptions = ref([]);
const provincesOptions = ref([]);
const townsLocationOptions = ref([]);
const town = ref({});
function onDataSaved(formData) {
const newPostcode = {
...formData,
};
const townObject = townsLocationOptions.value.find(
({ id }) => id === formData.townFk
);
newPostcode.town = townObject?.name;
newPostcode.town = town.value.name;
newPostcode.townFk = town.value.id;
const provinceObject = provincesOptions.value.find(
({ id }) => id === formData.provinceFk
);
@ -47,25 +44,23 @@ function onDataSaved(formData) {
emit('onDataSaved', newPostcode);
}
async function onCityCreated({ name, provinceFk }, formData) {
await townsFetchDataRef.value.fetch();
await provincesFetchDataRef.value.fetch();
formData.townFk = townsLocationOptions.value.find((town) => town.name === name).id;
formData.provinceFk = provinceFk;
formData.countryFk = provincesOptions.value.find(
(province) => province.id === provinceFk
).countryFk;
async function onCityCreated(newTown, formData) {
newTown.province = provincesOptions.value.find(
(province) => province.id === newTown.provinceFk
);
formData.townFk = newTown;
setTown(newTown, formData);
}
function setTown(id, data) {
const newTown = townsLocationOptions.value.find((town) => town.id == id);
function setTown(newTown, data) {
if (!newTown) return;
town.value = newTown;
data.provinceFk = newTown.provinceFk;
data.countryFk = newTown.province.countryFk;
}
function setProvince(id, data) {
async function setProvince(id, data) {
await provincesFetchDataRef.value.fetch();
const newProvince = provincesOptions.value.find((province) => province.id == id);
if (!newProvince) return;
@ -74,18 +69,11 @@ function setProvince(id, data) {
</script>
<template>
<FetchData
ref="townsFetchDataRef"
@on-fetch="(data) => (townsLocationOptions = data)"
auto-load
url="Towns/location"
/>
<FetchData
ref="provincesFetchDataRef"
:filter="{ include: { relation: 'country' } }"
@on-fetch="(data) => (provincesOptions = data)"
auto-load
url="Provinces"
url="Provinces/location"
/>
<FetchData
@on-fetch="(data) => (countriesOptions = data)"
@ -98,6 +86,7 @@ function setProvince(id, data) {
:title="t('New postcode')"
:subtitle="t('Please, ensure you put the correct data!')"
:form-initial-data="postcodeFormData"
:mapper="(data) => (data.townFk = data.townFk.id) && data"
@on-data-saved="onDataSaved"
>
<template #form-inputs="{ data, validate }">
@ -109,14 +98,15 @@ function setProvince(id, data) {
/>
<VnSelectDialog
:label="t('City')"
:options="townsLocationOptions"
url="Towns/location"
@update:model-value="(value) => setTown(value, data)"
v-model="data.townFk"
hide-selected
option-label="name"
option-value="id"
:rules="validate('postcode.city')"
:roles-allowed-to-create="['deliveryAssistant']"
:emit-value="false"
clearable
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
@ -130,7 +120,12 @@ function setProvince(id, data) {
</QItem>
</template>
<template #form>
<CreateNewCityForm @on-data-saved="onCityCreated($event, data)" />
<CreateNewCityForm
@on-data-saved="
(_, requestResponse) =>
onCityCreated(requestResponse, data)
"
/>
</template>
</VnSelectDialog>
</VnRow>

View File

@ -20,6 +20,9 @@ const provinceFormData = reactive({
const autonomiesOptions = ref([]);
const onDataSaved = (dataSaved, requestResponse) => {
requestResponse.autonomy = autonomiesOptions.value.find(
(autonomy) => autonomy.id == requestResponse.autonomyFk
);
emit('onDataSaved', dataSaved, requestResponse);
};
</script>
@ -28,7 +31,7 @@ const onDataSaved = (dataSaved, requestResponse) => {
<FetchData
@on-fetch="(data) => (autonomiesOptions = data)"
auto-load
url="Autonomies"
url="Autonomies/location"
/>
<FormModelPopup
:title="t('New province')"
@ -53,7 +56,16 @@ const onDataSaved = (dataSaved, requestResponse) => {
option-value="id"
v-model="data.autonomyFk"
:rules="validate('province.autonomyFk')"
/>
>
<template #option="{ itemProps, opt }">
<QItem v-bind="itemProps">
<QItemSection>
<QItemLabel>{{ opt.name }}</QItemLabel>
<QItemLabel caption> {{ opt.country.name }} </QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
</template>
</FormModelPopup>

View File

@ -7,6 +7,7 @@ import VnSelectDialog from 'components/common/VnSelectDialog.vue';
import FetchData from 'components/FetchData.vue';
import CreateNewProvinceForm from './CreateNewProvinceForm.vue';
const emit = defineEmits(['onProvinceCreated']);
const provinceFk = defineModel({ type: Number });
watch(provinceFk, async () => await provincesFetchDataRef.value.fetch());
@ -16,9 +17,10 @@ const { t } = useI18n();
const provincesOptions = ref();
const provincesFetchDataRef = ref();
async function onProvinceCreated(_, { id }) {
async function onProvinceCreated(_, data) {
await provincesFetchDataRef.value.fetch();
provinceFk.value = id;
provinceFk.value = data.id;
emit('onProvinceCreated', data);
}
</script>

View File

@ -23,8 +23,8 @@ function showLabel(data) {
:input-debounce="300"
:class="{ required: $attrs.required }"
v-bind="$attrs"
@update:model-value="(_, object) => (value = object)"
clearable
:emit-value="false"
>
<template #form>
<CreateNewPostcode @on-data-saved="(newValue) => (value = newValue)" />

View File

@ -88,11 +88,7 @@ const value = computed({
},
set(value) {
setOptions(myOptionsOriginal.value);
emit(
'update:modelValue',
value,
value && myOptions.value.find((o) => o[optionValue.value] == value)
);
emit('update:modelValue', value);
Review

Esto lo puse yo para el VnLocation aposta, ya no hace falta

Esto lo puse yo para el VnLocation aposta, ya no hace falta
Review

Por eso en VnLocation has puesto emit-value= false?

Por eso en VnLocation has puesto emit-value= false?
},
});
@ -187,6 +183,10 @@ async function filterHandler(val, update) {
}
);
}
function nullishToTrue(value) {
return value ?? true;
}
</script>
<template>
@ -205,12 +205,12 @@ async function filterHandler(val, update) {
:option-label="optionLabel"

Podrías hacer una pequeña fn para no tener que escribir cada vez $attrs[x] ?? true.

Podrías hacer una pequeña fn para no tener que escribir cada vez $attrs[x] ?? true.
:option-value="optionValue"
v-bind="$attrs"
emit-value
map-options
use-input
@filter="filterHandler"
hide-selected
fill-input
:emit-value="nullishToTrue($attrs['emit-value'])"
:map-options="nullishToTrue($attrs['map-options'])"
:use-input="nullishToTrue($attrs['use-input'])"
:hide-selected="nullishToTrue($attrs['hide-selected'])"
:fill-input="nullishToTrue($attrs['fill-input'])"
ref="vnSelectRef"
lazy-rules
:class="{ required: $attrs.required }"