feat: #7679 show country provinces
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Javier Segarra 2024-10-01 00:24:34 +02:00
parent e7a2d3aa85
commit 41acf0e1e2
5 changed files with 108 additions and 38 deletions

View File

@ -1,35 +1,42 @@
<script setup> <script setup>
import { reactive, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnSelectProvince from 'components/VnSelectProvince.vue'; import VnSelectProvince from 'components/VnSelectProvince.vue';
import VnInput from 'components/common/VnInput.vue'; import VnInput from 'components/common/VnInput.vue';
import FormModelPopup from './FormModelPopup.vue'; import FormModelPopup from './FormModelPopup.vue';
const emit = defineEmits(['onDataSaved']); const emit = defineEmits(['onDataSaved']);
const $props = defineProps({
countryFk: {
type: Number,
default: null,
},
provinceSelected: {
type: Number,
default: null,
},
provinces: {
type: Array,
default: () => [],
},
});
const { t } = useI18n(); const { t } = useI18n();
const cityFormData = reactive({ const cityFormData = ref({
name: null, name: null,
provinceFk: null, provinceFk: null,
}); });
onMounted(() => {
const provincesOptions = ref([]); cityFormData.value.provinceFk = $props.provinceSelected;
});
const onDataSaved = (...args) => { const onDataSaved = (...args) => {
emit('onDataSaved', ...args); emit('onDataSaved', ...args);
}; };
</script> </script>
<template> <template>
<FetchData
@on-fetch="(data) => (provincesOptions = data)"
auto-load
url="Provinces"
/>
<FormModelPopup <FormModelPopup
:title="t('New city')" :title="t('New city')"
:subtitle="t('Please, ensure you put the correct data!')" :subtitle="t('Please, ensure you put the correct data!')"
@ -41,11 +48,16 @@ const onDataSaved = (...args) => {
<template #form-inputs="{ data, validate }"> <template #form-inputs="{ data, validate }">
<VnRow> <VnRow>
<VnInput <VnInput
:label="t('Name')" :label="t('Names')"
v-model="data.name" v-model="data.name"
:rules="validate('city.name')" :rules="validate('city.name')"
/> />
<VnSelectProvince v-model="data.provinceFk" /> <VnSelectProvince
:province-selected="$props.provinceSelected"
:country-fk="$props.countryFk"
v-model="data.provinceFk"
:provinces="$props.provinces"
/>
</VnRow> </VnRow>
</template> </template>
</FormModelPopup> </FormModelPopup>

View File

@ -63,17 +63,27 @@ function setTown(newTown, data) {
} }
async function setProvince(id, data) { async function setProvince(id, data) {
await provincesFetchDataRef.value.fetch();
const newProvince = provincesOptions.value.find((province) => province.id == id); const newProvince = provincesOptions.value.find((province) => province.id == id);
if (!newProvince) return; if (!newProvince) return;
data.countryFk = newProvince.countryFk; data.countryFk = newProvince.countryFk;
} }
async function onProvinceCreated(data) {
await provincesFetchDataRef.value.fetch({
where: { countryFk: postcodeFormData.countryFk },
});
postcodeFormData.provinceFk.value = data.id;
}
watch( watch(
() => [postcodeFormData.countryFk], () => [postcodeFormData.countryFk],
async (newCountryFk) => { async (newCountryFk, oldValueFk) => {
if (newCountryFk) { if (!!oldValueFk[0] && newCountryFk[0] !== oldValueFk[0]) {
postcodeFormData.provinceFk = null;
postcodeFormData.townFk = null;
}
if ((newCountryFk, newCountryFk !== postcodeFormData.countryFk)) {
await provincesFetchDataRef.value.fetch({ await provincesFetchDataRef.value.fetch({
where: { where: {
countryFk: newCountryFk[0], countryFk: newCountryFk[0],
@ -93,7 +103,7 @@ watch(
watch( watch(
() => postcodeFormData.provinceFk, () => postcodeFormData.provinceFk,
async (newProvinceFk) => { async (newProvinceFk) => {
if (newProvinceFk) { if (newProvinceFk[0] && newProvinceFk[0] !== postcodeFormData.provinceFk) {
await townsFetchDataRef.value.fetch({ await townsFetchDataRef.value.fetch({
where: { provinceFk: newProvinceFk[0] }, where: { provinceFk: newProvinceFk[0] },
}); });
@ -121,6 +131,7 @@ async function handleCountries(data) {
<FetchData <FetchData
ref="townsFetchDataRef" ref="townsFetchDataRef"
@on-fetch="handleTowns" @on-fetch="handleTowns"
:limit="30"
auto-load auto-load
url="Towns/location" url="Towns/location"
/> />
@ -140,6 +151,7 @@ async function handleCountries(data) {
:label="t('Postcode')" :label="t('Postcode')"
v-model="data.code" v-model="data.code"
:rules="validate('postcode.code')" :rules="validate('postcode.code')"
clearable
/> />
<VnSelectDialog <VnSelectDialog
:label="t('City')" :label="t('City')"
@ -151,7 +163,7 @@ async function handleCountries(data) {
:rules="validate('postcode.city')" :rules="validate('postcode.city')"
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
:emit-value="false" :emit-value="false"
clearable :clearable="true"
> >
<template #option="{ itemProps, opt }"> <template #option="{ itemProps, opt }">
<QItem v-bind="itemProps"> <QItem v-bind="itemProps">
@ -166,6 +178,9 @@ async function handleCountries(data) {
</template> </template>
<template #form> <template #form>
<CreateNewCityForm <CreateNewCityForm
:country-fk="data.countryFk"
:province-selected="data.provinceFk"
:provinces="provincesOptions"
@on-data-saved=" @on-data-saved="
(_, requestResponse) => (_, requestResponse) =>
onCityCreated(requestResponse, data) onCityCreated(requestResponse, data)
@ -176,9 +191,13 @@ async function handleCountries(data) {
</VnRow> </VnRow>
<VnRow> <VnRow>
<VnSelectProvince <VnSelectProvince
:country-fk="postcodeFormData.countryFk" :country-fk="data.countryFk"
:province-selected="data.provinceFk"
@update:model-value="(value) => setProvince(value, data)" @update:model-value="(value) => setProvince(value, data)"
v-model="data.provinceFk" v-model="data.provinceFk"
:clearable="true"
:provinces="provincesOptions"
@on-province-created="onProvinceCreated"
/> />
<VnSelect <VnSelect
:label="t('Country')" :label="t('Country')"

View File

@ -16,7 +16,16 @@ const provinceFormData = reactive({
name: null, name: null,
autonomyFk: null, autonomyFk: null,
}); });
const $props = defineProps({
countryFk: {
type: Number,
default: null,
},
provinces: {
type: Array,
default: () => [],
},
});
const autonomiesOptions = ref([]); const autonomiesOptions = ref([]);
const onDataSaved = (dataSaved, requestResponse) => { const onDataSaved = (dataSaved, requestResponse) => {
@ -31,6 +40,11 @@ const onDataSaved = (dataSaved, requestResponse) => {
<FetchData <FetchData
@on-fetch="(data) => (autonomiesOptions = data)" @on-fetch="(data) => (autonomiesOptions = data)"
auto-load auto-load
:filter="{
where: {
countryFk: $props.countryFk,
},
}"
url="Autonomies/location" url="Autonomies/location"
/> />
<FormModelPopup <FormModelPopup

View File

@ -8,18 +8,27 @@ import FetchData from 'components/FetchData.vue';
import CreateNewProvinceForm from './CreateNewProvinceForm.vue'; import CreateNewProvinceForm from './CreateNewProvinceForm.vue';
const emit = defineEmits(['onProvinceCreated']); const emit = defineEmits(['onProvinceCreated']);
const provinceFk = defineModel({ type: Number });
watch(provinceFk, async () => await provincesFetchDataRef.value.fetch());
const $props = defineProps({ const $props = defineProps({
countryFk: { countryFk: {
type: Number, type: Number,
default: null, default: null,
}, },
provinceSelected: {
type: Number,
default: null,
},
provinces: {
type: Array,
default: () => [],
},
}); });
const provinceFk = defineModel({ type: Number, default: null });
const { validate } = useValidator(); const { validate } = useValidator();
const { t } = useI18n(); const { t } = useI18n();
const provincesOptions = ref(); const provincesOptions = ref($props.provinces);
provinceFk.value = $props.provinceSelected;
const provincesFetchDataRef = ref(); const provincesFetchDataRef = ref();
async function onProvinceCreated(_, data) { async function onProvinceCreated(_, data) {
@ -27,16 +36,6 @@ async function onProvinceCreated(_, data) {
provinceFk.value = data.id; provinceFk.value = data.id;
emit('onProvinceCreated', data); emit('onProvinceCreated', data);
} }
watch(
() => $props.countryFk,
async (newProvinceFk) => {
if (newProvinceFk) {
await provincesFetchDataRef.value.fetch({
where: { countryFk: newProvinceFk },
});
}
}
);
async function handleProvinces(data) { async function handleProvinces(data) {
provincesOptions.value = data; provincesOptions.value = data;
} }
@ -45,14 +44,18 @@ async function handleProvinces(data) {
<template> <template>
<FetchData <FetchData
ref="provincesFetchDataRef" ref="provincesFetchDataRef"
:filter="{ include: { relation: 'country' } }" :filter="{
include: { relation: 'country' },
where: {
countryFk: $props.countryFk,
},
}"
@on-fetch="handleProvinces" @on-fetch="handleProvinces"
auto-load
url="Provinces" url="Provinces"
/> />
<VnSelectDialog <VnSelectDialog
:label="t('Province')" :label="t('Province')"
:options="provincesOptions" :options="$props.provinces"
hide-selected hide-selected
v-model="provinceFk" v-model="provinceFk"
:rules="validate && validate('postcode.provinceFk')" :rules="validate && validate('postcode.provinceFk')"
@ -67,7 +70,10 @@ async function handleProvinces(data) {
</QItem> </QItem>
</template> </template>
<template #form> <template #form>
<CreateNewProvinceForm @on-data-saved="onProvinceCreated" /> <CreateNewProvinceForm
:country-fk="$props.countryFk"
@on-data-saved="onProvinceCreated"
/>
</template> </template>
</VnSelectDialog> </VnSelectDialog>
</template> </template>

View File

@ -48,6 +48,25 @@ describe('VnLocation', () => {
`${createForm.prefix} > :nth-child(4) > .q-field:nth-child(3)> ${createForm.sufix}` `${createForm.prefix} > :nth-child(4) > .q-field:nth-child(3)> ${createForm.sufix}`
).should('have.length', 1); ).should('have.length', 1);
}); });
it('should pass selected country', () => {
// Select a country
const country = 'Ecuador';
const province = 'Province five';
cy.selectOption(
`${createForm.prefix} > :nth-child(5) > .q-field:nth-child(5)> ${createForm.sufix}`,
country
);
cy.selectOption(
`${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix}`,
province
);
cy.get(
`${createForm.prefix} > :nth-child(4) > .q-select > ${createForm.sufix} > :nth-child(3) > .q-icon`
).click();
cy.get(
`#q-portal--dialog--4 > .q-dialog > ${createForm.prefix} > .vn-row > .q-select > ${createForm.sufix} > :nth-child(1) input`
).should('have.value', province);
});
}); });
describe('Worker Create', () => { describe('Worker Create', () => {
beforeEach(() => { beforeEach(() => {