Aplicar VnSelectCreate a los inputs de postcode

This commit is contained in:
William Buezas 2023-12-19 12:10:58 -03:00
parent d309f04a8f
commit f2a0c731ad
8 changed files with 298 additions and 182 deletions

View File

@ -60,7 +60,7 @@ const closeForm = () => {
<QIcon name="close" size="22px" /> <QIcon name="close" size="22px" />
</span> </span>
<h1 class="title">{{ t('title') }}</h1> <h1 class="title">{{ t('title') }}</h1>
<span class="q-mb-md">{{ t('subtitle') }}</span> <p class="q-mb-md">{{ t('subtitle') }}</p>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput <QInput

View File

@ -0,0 +1,157 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FormModel from 'components/FormModel.vue';
const emit = defineEmits(['onDataSaved']);
const { t } = useI18n();
const postcodeFormData = reactive({
code: null,
countryFk: null,
provinceFk: null,
townFk: null,
});
const closeButton = ref(null);
const countriesOptions = ref([]);
const isLoading = ref(false);
const provincesOptions = ref([]);
const townsLocationOptions = ref([]);
const onDataSaved = () => {
emit('onDataSaved');
closeForm();
};
const closeForm = () => {
if (closeButton.value) closeButton.value.click();
};
</script>
<template>
<FetchData
@on-fetch="(data) => (townsLocationOptions = data)"
auto-load
url="Towns/location"
/>
<FetchData
@on-fetch="(data) => (provincesOptions = data)"
auto-load
url="Provinces"
/>
<FetchData
@on-fetch="(data) => (countriesOptions = data)"
auto-load
url="Countries"
/>
<FormModel
:form-initial-data="postcodeFormData"
:observe-form-changes="false"
:default-actions="false"
url-create="postcodes"
model="postcode"
@on-data-saved="onDataSaved()"
>
<template #form="{ data, validate }">
<span ref="closeButton" class="close-icon" v-close-popup>
<QIcon name="close" size="22px" />
</span>
<h1 class="title">{{ t('New postcode') }}</h1>
<p>{{ t('Please, ensure you put the correct data!') }}</p>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Postcode')"
v-model="data.code"
:rules="validate('postcode.code')"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('City')"
:options="townsLocationOptions"
hide-selected
option-label="name"
option-value="id"
v-model="data.townFk"
:rules="validate('postcode.city')"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-xl">
<div class="col">
<VnSelectFilter
:label="t('Province')"
:options="provincesOptions"
hide-selected
option-label="name"
option-value="id"
v-model="data.provinceFk"
:rules="validate('postcode.provinceFk')"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('Country')"
:options="countriesOptions"
hide-selected
option-label="country"
option-value="id"
v-model="data.countryFk"
:rules="validate('postcode.countryFk')"
/>
</div>
</VnRow>
<div class="q-mt-lg row justify-end">
<QBtn
:label="t('globals.save')"
type="submit"
color="primary"
:disabled="isLoading"
:loading="isLoading"
/>
<QBtn
:label="t('globals.cancel')"
type="reset"
color="primary"
flat
class="q-ml-sm"
:disabled="isLoading"
:loading="isLoading"
v-close-popup
/>
</div>
</template>
</FormModel>
</template>
<style lang="scss" scoped>
.close-icon {
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
}
.title {
font-size: 17px;
font-weight: bold;
line-height: 20px;
}
</style>
<i18n>
es:
New postcode: Nuevo código postal
Please, ensure you put the correct data!: ¡Por favor, asegúrese de poner los datos correctos!
City: Ciudad
Province: Provincia
Country: País
Postcode: Código postal
</i18n>

View File

@ -220,6 +220,7 @@ watch(formUrl, async () => {
:showing="isLoading" :showing="isLoading"
:label="t('globals.pleaseWait')" :label="t('globals.pleaseWait')"
color="primary" color="primary"
style="min-width: 100%"
/> />
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -5,7 +5,7 @@ import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import { useRole } from 'src/composables/useRole'; import { useRole } from 'src/composables/useRole';
const emit = defineEmits(['update:modelValue', 'update:options']); const emit = defineEmits(['update:modelValue']);
const $props = defineProps({ const $props = defineProps({
modelValue: { modelValue: {

View File

@ -2,11 +2,12 @@
import { reactive, ref } from 'vue'; import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import CustomerCreateNewPostcode from './CustomerCreateNewPostcode.vue'; import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue'; import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnSelectCreate from 'src/components/common/VnSelectCreate.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -27,11 +28,17 @@ const newClientForm = reactive({
isEqualizated: false, isEqualizated: false,
}); });
const postcodeFetchDataRef = ref(null);
const workersOptions = ref([]); const workersOptions = ref([]);
const businessTypesOptions = ref([]); const businessTypesOptions = ref([]);
const citiesLocationOptions = ref([]); const citiesLocationOptions = ref([]);
const provincesLocationOptions = ref([]); const provincesLocationOptions = ref([]);
const countriesOptions = ref([]); const countriesOptions = ref([]);
const postcodesOptions = ref([]);
const onPostcodeCreated = async () => {
postcodeFetchDataRef.value.fetch();
};
</script> </script>
<template> <template>
@ -40,6 +47,12 @@ const countriesOptions = ref([]);
auto-load auto-load
url="Workers/search?departmentCodes" url="Workers/search?departmentCodes"
/> />
<FetchData
ref="postcodeFetchDataRef"
url="Postcodes/location"
@on-fetch="(data) => (postcodesOptions = data)"
auto-load
/>
<FetchData <FetchData
@on-fetch="(data) => (businessTypesOptions = data)" @on-fetch="(data) => (businessTypesOptions = data)"
auto-load auto-load
@ -123,26 +136,38 @@ const countriesOptions = ref([]);
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput v-model="data.postcode" :label="t('Postcode')"> <VnSelectCreate
<template #append> v-model="data.postcode"
<QBtn :label="t('Postcode')"
class="cursor-pointer" :rules="validate('Worker.postcode')"
color="primary" :roles-allowed-to-create="['deliveryAssistant']"
dense :options="postcodesOptions"
icon="add" option-label="code"
round option-value="code"
size="xs" hide-selected
> >
<QPopupProxy <template #form>
cover <CustomerCreateNewPostcode
transition-hide="scale" @on-data-saved="onPostcodeCreated($event)"
transition-show="scale" />
>
<CustomerCreateNewPostcode />
</QPopupProxy>
</QBtn>
</template> </template>
</QInput> <template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection v-if="scope.opt">
<QItemLabel>{{ scope.opt.code }}</QItemLabel>
<QItemLabel caption
>{{ scope.opt.code }} -
{{ scope.opt.town.name }} ({{
scope.opt.town.province.name
}},
{{
scope.opt.town.province.country.country
}})</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelectCreate>
</div> </div>
<div class="col"> <div class="col">
<!-- ciudades --> <!-- ciudades -->

View File

@ -1,143 +0,0 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import FetchData from 'components/FetchData.vue';
import useNotify from 'src/composables/useNotify';
import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
const { notify } = useNotify();
const { t } = useI18n();
const data = reactive({
city: null,
code: null,
countryFk: null,
provinceFk: null,
townFk: null,
});
const countriesOptions = ref([]);
const isLoading = ref(false);
const provincesOptions = ref([]);
const townsLocationOptions = ref([]);
async function save() {
isLoading.value = true;
try {
const { city, code, countryFk, provinceFk } = data;
const payload = {
city: city.name,
code,
countryFk,
provinceFk,
townFk: city.id,
};
await axios.patch('/postcodes', payload);
} catch (err) {
notify('errors.create', 'negative');
}
isLoading.value = false;
}
</script>
<template>
<FetchData
@on-fetch="(data) => (townsLocationOptions = data)"
auto-load
url="Towns/location"
/>
<FetchData
@on-fetch="(data) => (provincesOptions = data)"
auto-load
url="Provinces"
/>
<FetchData
@on-fetch="(data) => (countriesOptions = data)"
auto-load
url="Countries"
/>
<div class="q-pa-lg">
<h6 class="q-my-xs">{{ t('New postcode') }}</h6>
<p>{{ t('Please, ensure you put the correct data!') }}</p>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<QInput label="Postcode" v-model="data.code" />
</div>
<div class="col">
<VnSelectFilter
:label="t('City')"
:options="townsLocationOptions"
hide-selected
option-label="name"
option-value="city"
v-model="data.city"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-xl">
<div class="col">
<VnSelectFilter
:label="t('Province')"
:options="provincesOptions"
hide-selected
option-label="name"
option-value="id"
v-model="data.provinceFk"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('Country')"
:options="countriesOptions"
hide-selected
option-label="country"
option-value="id"
v-model="data.countryFk"
/>
</div>
</VnRow>
<div class="flex justify-end">
<QBtn
:label="t('globals.cancel')"
class="q-mr-lg"
color="primary"
outline
v-close-popup
/>
<QBtn
:label="t('globals.save')"
@click="save"
color="primary"
v-close-popup
/>
</div>
</div>
<QInnerLoading
:showing="isLoading"
:label="t('globals.pleaseWait')"
color="primary"
/>
</template>
<style lang="scss" scoped>
.card {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-gap: 20px;
}
</style>
<i18n>
es:
New postcode: Nuevo código postal
Please, ensure you put the correct data!: ¡Por favor, asegúrese de poner los datos correctos!
City: Ciudad
Province: Provincia
Country: País
</i18n>

View File

@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
import VnSearchbar from 'components/ui/VnSearchbar.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue';
import FormModel from 'components/FormModel.vue'; import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { onMounted, ref, reactive } from 'vue'; import { onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
@ -9,6 +9,8 @@ import VnInputDate from 'components/common/VnInputDate.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue'; import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnSelectCreate from 'src/components/common/VnSelectCreate.vue'; import VnSelectCreate from 'src/components/common/VnSelectCreate.vue';
import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue'; import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
import VnInput from 'src/components/common/VnInput.vue';
import { useUserConfig } from 'src/composables/useUserConfig'; import { useUserConfig } from 'src/composables/useUserConfig';
@ -46,21 +48,27 @@ const newWorkerForm = ref({
bankEntityFk: null, bankEntityFk: null,
}); });
const postcodeFetchDataRef = ref(null);
const provincesOptions = ref([]); const provincesOptions = ref([]);
const townsOptions = ref([]); const townsOptions = ref([]);
const companiesOptions = ref([]); const companiesOptions = ref([]);
const workersOptions = ref([]); const workersOptions = ref([]);
const payMethodsOptions = ref([]); const payMethodsOptions = ref([]);
const bankEntitiesOptions = ref([]); const bankEntitiesOptions = ref([]);
const postcodesOptions = ref([]);
const onFetchWorkerConfig = (workerConfig) => { const onFetchWorkerConfig = (workerConfig) => {
newWorkerForm.value.payMethodFk = workerConfig.payMethodFk; newWorkerForm.value.payMethodFk = workerConfig.payMethodFk;
}; };
const onDataSaved = (data) => { const onBankEntityCreated = (data) => {
bankEntitiesOptions.value.push(data); bankEntitiesOptions.value.push(data);
}; };
const onPostcodeCreated = async () => {
postcodeFetchDataRef.value.fetch();
};
onMounted(async () => { onMounted(async () => {
const userInfo = await useUserConfig().fetch(); const userInfo = await useUserConfig().fetch();
newWorkerForm.value = { companyFk: userInfo.companyFk }; newWorkerForm.value = { companyFk: userInfo.companyFk };
@ -74,6 +82,12 @@ onMounted(async () => {
:filter="workerConfigFilter" :filter="workerConfigFilter"
auto-load auto-load
/> />
<FetchData
ref="postcodeFetchDataRef"
url="Postcodes/location"
@on-fetch="(data) => (postcodesOptions = data)"
auto-load
/>
<FetchData <FetchData
url="Provinces/location" url="Provinces/location"
@on-fetch="(data) => (provincesOptions = data)" @on-fetch="(data) => (provincesOptions = data)"
@ -114,48 +128,91 @@ onMounted(async () => {
<div id="st-actions"></div> <div id="st-actions"></div>
</QToolbar> </QToolbar>
<FormModel <FormModel
url-create="Countries" url-create="Workers/new"
model="worker" model="worker"
:form-initial-data="newWorkerForm" :form-initial-data="newWorkerForm"
> >
<template #form="{ data }"> <template #form="{ data, validate }">
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput <VnInput
v-model="data.firstName" v-model="data.firstName"
:label="t('worker.create.name')" :label="t('worker.create.name')"
:rules="validate('Worker.firstName')"
/> />
</div> </div>
<div class="col"> <div class="col">
<QInput <VnInput
v-model="data.lastNames" v-model="data.lastNames"
:label="t('worker.create.lastName')" :label="t('worker.create.lastName')"
:rules="validate('Worker.lastNames')"
/> />
</div> </div>
<div class="col"> <div class="col">
<VnInputDate <VnInputDate
v-model="data.birth" v-model="data.birth"
:label="t('worker.create.birth')" :label="t('worker.create.birth')"
:rules="validate('Worker.birth')"
/> />
</div> </div>
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput v-model="data.fi" :label="t('worker.create.fi')" /> <VnInput
v-model="data.fi"
:label="t('worker.create.fi')"
:rules="validate('Worker.fi')"
/>
</div> </div>
<div class="col"> <div class="col">
<QInput v-model="data.code" :label="t('worker.create.code')" /> <VnInput
v-model="data.code"
:label="t('worker.create.code')"
:rules="validate('Worker.code')"
/>
</div> </div>
<div class="col"> <div class="col">
<QInput v-model="data.phone" :label="t('worker.create.phone')" /> <VnInput
v-model="data.phone"
:label="t('worker.create.phone')"
:rules="validate('Worker.phone')"
/>
</div> </div>
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput <VnSelectCreate
v-model="data.postcode" v-model="data.postcode"
:label="t('worker.create.postcode')" :label="t('worker.create.postcode')"
:rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']"
:options="postcodesOptions"
option-label="code"
option-value="code"
hide-selected
>
<template #form>
<CustomerCreateNewPostcode
@on-data-saved="onPostcodeCreated($event)"
/> />
</template>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection v-if="scope.opt">
<QItemLabel>{{ scope.opt.code }}</QItemLabel>
<QItemLabel caption
>{{ scope.opt.code }} -
{{ scope.opt.town.name }} ({{
scope.opt.town.province.name
}},
{{
scope.opt.town.province.country.country
}})</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelectCreate>
</div> </div>
<div class="col"> <div class="col">
<VnSelectFilter <VnSelectFilter
@ -165,6 +222,7 @@ onMounted(async () => {
option-value="id" option-value="id"
option-label="name" option-label="name"
hide-selected hide-selected
:rules="validate('Worker.provinceFk')"
/> />
</div> </div>
</VnRow> </VnRow>
@ -177,6 +235,7 @@ onMounted(async () => {
option-value="name" option-value="name"
option-label="name" option-label="name"
hide-selected hide-selected
:rules="validate('Worker.city')"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -194,20 +253,26 @@ onMounted(async () => {
</VnSelectFilter> </VnSelectFilter>
</div> </div>
<div class="col"> <div class="col">
<QInput <VnInput
:label="t('worker.create.street')" :label="t('worker.create.street')"
v-model="data.street" v-model="data.street"
:rules="validate('Worker.street')"
/> />
</div> </div>
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QInput v-model="data.name" :label="t('worker.create.webUser')" /> <VnInput
v-model="data.name"
:label="t('worker.create.webUser')"
:rules="validate('Worker.name')"
/>
</div> </div>
<div class="col"> <div class="col">
<QInput <VnInput
v-model="data.email" v-model="data.email"
:label="t('worker.create.personalEmail')" :label="t('worker.create.personalEmail')"
:rules="validate('Worker.email')"
/> />
</div> </div>
</VnRow> </VnRow>
@ -220,6 +285,7 @@ onMounted(async () => {
option-value="id" option-value="id"
option-label="code" option-label="code"
hide-selected hide-selected
:rules="validate('Worker.company')"
/> />
</div> </div>
<div class="col"> <div class="col">
@ -230,6 +296,7 @@ onMounted(async () => {
option-value="id" option-value="id"
option-label="name" option-label="name"
hide-selected hide-selected
:rules="validate('Worker.boss')"
> >
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -253,12 +320,18 @@ onMounted(async () => {
:options="payMethodsOptions" :options="payMethodsOptions"
option-value="id" option-value="id"
option-label="name" option-label="name"
map-options
hide-selected hide-selected
:rules="validate('Worker.payMethodFk')"
/> />
</div> </div>
<div class="col"> <div class="col">
<QInput v-model="data.iban" :label="t('worker.create.iban')" /> <VnInput
v-model="data.iban"
:label="t('worker.create.iban')"
:rules="validate('Worker.iban')"
/>
</div> </div>
<VnSelectCreate <VnSelectCreate
:label="t('worker.create.bankEntity')" :label="t('worker.create.bankEntity')"
@ -268,9 +341,12 @@ onMounted(async () => {
option-value="id" option-value="id"
hide-selected hide-selected
:roles-allowed-to-create="['salesAssistant', 'hr']" :roles-allowed-to-create="['salesAssistant', 'hr']"
:rules="validate('Worker.bankEntity')"
> >
<template #form> <template #form>
<CreateBankEntityForm @on-data-saved="onDataSaved($event)" /> <CreateBankEntityForm
@on-data-saved="onBankEntityCreated($event)"
/>
</template> </template>
<template #option="scope"> <template #option="scope">
<QItem v-bind="scope.itemProps"> <QItem v-bind="scope.itemProps">
@ -284,7 +360,6 @@ onMounted(async () => {
</template> </template>
</VnSelectCreate> </VnSelectCreate>
</VnRow> </VnRow>
<pre>data:: {{ data }}</pre>
</template> </template>
</FormModel> </FormModel>
</QPage> </QPage>