forked from verdnatura/salix-front
241 lines
7.6 KiB
Vue
241 lines
7.6 KiB
Vue
<script setup>
|
|
import { reactive, ref, watch } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
import FetchData from 'components/FetchData.vue';
|
|
import VnRow from 'components/ui/VnRow.vue';
|
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
import VnSelectProvince from 'src/components/VnSelectProvince.vue';
|
|
import VnInput from 'src/components/common/VnInput.vue';
|
|
import CreateNewCityForm from './CreateNewCityForm.vue';
|
|
import VnSelectDialog from 'components/common/VnSelectDialog.vue';
|
|
import FormModelPopup from './FormModelPopup.vue';
|
|
|
|
const emit = defineEmits(['onDataSaved']);
|
|
|
|
const { t } = useI18n();
|
|
|
|
const postcodeFormData = reactive({
|
|
code: null,
|
|
countryFk: null,
|
|
provinceFk: null,
|
|
townFk: null,
|
|
});
|
|
|
|
const townsFetchDataRef = ref(null);
|
|
const provincesFetchDataRef = ref(null);
|
|
const countriesOptions = ref([]);
|
|
const provincesOptions = ref([]);
|
|
const townsOptions = ref([]);
|
|
const town = ref({});
|
|
|
|
function onDataSaved(formData) {
|
|
const newPostcode = {
|
|
...formData,
|
|
};
|
|
newPostcode.town = town.value.name;
|
|
newPostcode.townFk = town.value.id;
|
|
const provinceObject = provincesOptions.value.find(
|
|
({ id }) => id === formData.provinceFk
|
|
);
|
|
newPostcode.province = provinceObject?.name;
|
|
const countryObject = countriesOptions.value.find(
|
|
({ id }) => id === formData.countryFk
|
|
);
|
|
newPostcode.country = countryObject?.name;
|
|
emit('onDataSaved', newPostcode);
|
|
}
|
|
|
|
async function onCityCreated(newTown, formData) {
|
|
await provincesFetchDataRef.value.fetch();
|
|
newTown.province = provincesOptions.value.find(
|
|
(province) => province.id === newTown.provinceFk
|
|
);
|
|
formData.townFk = newTown;
|
|
setTown(newTown, formData);
|
|
}
|
|
|
|
function setTown(newTown, data) {
|
|
if (!newTown) return;
|
|
town.value = newTown;
|
|
data.provinceFk = newTown.provinceFk;
|
|
data.countryFk = newTown.province.countryFk;
|
|
}
|
|
|
|
async function setProvince(id, data) {
|
|
const newProvince = provincesOptions.value.find((province) => province.id == id);
|
|
if (!newProvince) return;
|
|
|
|
data.countryFk = newProvince.countryFk;
|
|
}
|
|
|
|
async function onProvinceCreated(data) {
|
|
await provincesFetchDataRef.value.fetch({
|
|
where: { countryFk: postcodeFormData.countryFk },
|
|
});
|
|
postcodeFormData.provinceFk.value = data.id;
|
|
}
|
|
|
|
watch(
|
|
() => [postcodeFormData.countryFk],
|
|
async (newCountryFk, oldValueFk) => {
|
|
if (Array.isArray(newCountryFk)) {
|
|
newCountryFk = newCountryFk[0];
|
|
}
|
|
if (Array.isArray(oldValueFk)) {
|
|
oldValueFk = oldValueFk[0];
|
|
}
|
|
if (!!oldValueFk && newCountryFk !== oldValueFk) {
|
|
postcodeFormData.provinceFk = null;
|
|
postcodeFormData.townFk = null;
|
|
}
|
|
if (oldValueFk !== newCountryFk) {
|
|
await provincesFetchDataRef.value.fetch({
|
|
where: {
|
|
countryFk: newCountryFk,
|
|
},
|
|
});
|
|
await townsFetchDataRef.value.fetch({
|
|
where: {
|
|
provinceFk: {
|
|
inq: provincesOptions.value.map(({ id }) => id),
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|
|
);
|
|
|
|
watch(
|
|
() => postcodeFormData.provinceFk,
|
|
async (newProvinceFk, oldValueFk) => {
|
|
if (Array.isArray(newProvinceFk)) {
|
|
newProvinceFk = newProvinceFk[0];
|
|
}
|
|
if (newProvinceFk !== oldValueFk) {
|
|
await townsFetchDataRef.value.fetch({
|
|
where: { provinceFk: newProvinceFk },
|
|
});
|
|
}
|
|
}
|
|
);
|
|
async function handleProvinces(data) {
|
|
provincesOptions.value = data;
|
|
}
|
|
async function handleTowns(data) {
|
|
townsOptions.value = data;
|
|
}
|
|
async function handleCountries(data) {
|
|
countriesOptions.value = data;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<FetchData
|
|
ref="provincesFetchDataRef"
|
|
@on-fetch="handleProvinces"
|
|
:sort-by="['name ASC']"
|
|
:limit="30"
|
|
auto-load
|
|
url="Provinces/location"
|
|
/>
|
|
<FetchData
|
|
ref="townsFetchDataRef"
|
|
:sort-by="['name ASC']"
|
|
:limit="30"
|
|
@on-fetch="handleTowns"
|
|
auto-load
|
|
url="Towns/location"
|
|
/>
|
|
|
|
<FormModelPopup
|
|
url-create="postcodes"
|
|
model="postcode"
|
|
: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 }">
|
|
<VnRow>
|
|
<VnInput
|
|
:label="t('Postcode')"
|
|
v-model="data.code"
|
|
:rules="validate('postcode.code')"
|
|
clearable
|
|
/>
|
|
<VnSelectDialog
|
|
:label="t('City')"
|
|
@update:model-value="(value) => setTown(value, data)"
|
|
:tooltip="t('Create city')"
|
|
v-model="data.townFk"
|
|
:options="townsOptions"
|
|
option-label="name"
|
|
option-value="id"
|
|
:rules="validate('postcode.city')"
|
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
|
:emit-value="false"
|
|
:clearable="true"
|
|
>
|
|
<template #option="{ itemProps, opt }">
|
|
<QItem v-bind="itemProps">
|
|
<QItemSection>
|
|
<QItemLabel>{{ opt.name }}</QItemLabel>
|
|
<QItemLabel caption>
|
|
{{ opt.province.name }},
|
|
{{ opt.province.country.name }}
|
|
</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
<template #form>
|
|
<CreateNewCityForm
|
|
:country-fk="data.countryFk"
|
|
:province-selected="data.provinceFk"
|
|
:provinces="provincesOptions"
|
|
@on-data-saved="
|
|
(_, requestResponse) =>
|
|
onCityCreated(requestResponse, data)
|
|
"
|
|
/>
|
|
</template>
|
|
</VnSelectDialog>
|
|
</VnRow>
|
|
<VnRow>
|
|
<VnSelectProvince
|
|
:country-fk="data.countryFk"
|
|
:province-selected="data.provinceFk"
|
|
@update:model-value="(value) => setProvince(value, data)"
|
|
v-model="data.provinceFk"
|
|
:clearable="true"
|
|
:provinces="provincesOptions"
|
|
@on-province-created="onProvinceCreated"
|
|
/>
|
|
<VnSelect
|
|
url="Countries"
|
|
:sort-by="['name ASC']"
|
|
:label="t('Country')"
|
|
@update:options="handleCountries"
|
|
hide-selected
|
|
option-label="name"
|
|
option-value="id"
|
|
v-model="data.countryFk"
|
|
:rules="validate('postcode.countryFk')"
|
|
/>
|
|
</VnRow>
|
|
</template>
|
|
</FormModelPopup>
|
|
</template>
|
|
|
|
<i18n>
|
|
es:
|
|
New postcode: Nuevo código postal
|
|
Create city: Crear población
|
|
Please, ensure you put the correct data!: ¡Por favor, asegúrese de poner los datos correctos!
|
|
City: Población
|
|
Province: Provincia
|
|
Country: País
|
|
Postcode: Código postal
|
|
</i18n>
|