Merge pull request 'Imrpove VnLocation to show less fields' () from fix_8018 into master

Reviewed-on: 
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
This commit is contained in:
Javier Segarra 2024-09-30 11:14:30 +00:00
commit 48b7b879f2
9 changed files with 167 additions and 34 deletions

View File

@ -2,21 +2,68 @@
import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
import VnSelectDialog from 'components/common/VnSelectDialog.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { ref } from 'vue';
const { t } = useI18n(); const { t } = useI18n();
const value = defineModel({ type: [String, Number, Object] }); const emit = defineEmits(['update:model-value', 'update:options']);
const props = defineProps({
location: {
type: Object,
default: null,
},
});
const formatLocation = (obj, properties) => {
const parts = properties.map((prop) => {
if (typeof prop === 'string') {
return obj[prop];
} else if (typeof prop === 'function') {
return prop(obj);
}
return null;
});
const filteredParts = parts.filter(
(part) => part !== null && part !== undefined && part !== ''
);
return filteredParts.join(', ');
};
const locationProperties = [
'postcode',
(obj) =>
obj.city
? `${obj.city}${obj.province?.name ? `(${obj.province.name})` : ''}`
: null,
(obj) => obj.country?.name,
];
const modelValue = ref(
props.location ? formatLocation(props.location, locationProperties) : null
);
const handleModelValue = (data) => {
emit('update:model-value', data);
};
function showLabel(data) { function showLabel(data) {
return `${data.code} - ${data.town}(${data.province}), ${data.country}`; const dataProperties = [
'code',
(obj) => (obj.town ? `${obj.town}(${obj.province})` : null),
'country',
];
return formatLocation(data, dataProperties);
} }
</script> </script>
<template> <template>
<VnSelectDialog <VnSelectDialog
v-model="value" v-model="modelValue"
option-value="code"
option-filter-value="search" option-filter-value="search"
:option-label="(opt) => showLabel(opt)" :option-label="
(opt) => (typeof modelValue === 'string' ? modelValue : showLabel(opt))
"
url="Postcodes/filter" url="Postcodes/filter"
@update:model-value="handleModelValue"
:use-like="false" :use-like="false"
:label="t('Location')" :label="t('Location')"
:placeholder="t('search_by_postalcode')" :placeholder="t('search_by_postalcode')"
@ -27,7 +74,14 @@ function showLabel(data) {
:emit-value="false" :emit-value="false"
> >
<template #form> <template #form>
<CreateNewPostcode @on-data-saved="(newValue) => (value = newValue)" /> <CreateNewPostcode
@on-data-saved="
(newValue) => {
modelValue = newValue;
emit('update:model-value', newValue);
}
"
/>
</template> </template>
<template #option="{ itemProps, opt }"> <template #option="{ itemProps, opt }">
<QItem v-bind="itemProps"> <QItem v-bind="itemProps">

View File

@ -93,8 +93,9 @@ function handleLocation(data, location) {
<VnRow> <VnRow>
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']" :roles-allowed-to-create="['deliveryAssistant', 'administrative']"
v-model="data.postcode" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
:location="data"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
/> />
</VnRow> </VnRow>

View File

@ -86,7 +86,7 @@ function handleLocation(data, location) {
<VnRow> <VnRow>
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
v-model="data.location" v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
> >

View File

@ -2,6 +2,7 @@
import { ref, computed, markRaw } from 'vue'; import { ref, computed, markRaw } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnTable from 'components/VnTable/VnTable.vue'; import VnTable from 'components/VnTable/VnTable.vue';
import VnLocation from 'src/components/common/VnLocation.vue'; import VnLocation from 'src/components/common/VnLocation.vue';
import VnSearchbar from 'components/ui/VnSearchbar.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue';
@ -69,7 +70,7 @@ const columns = computed(() => [
optionFilter: 'firstName', optionFilter: 'firstName',
useLike: false, useLike: false,
}, },
create: true, create: false,
columnField: { columnField: {
component: null, component: null,
}, },
@ -195,6 +196,8 @@ const columns = computed(() => [
component: 'select', component: 'select',
attrs: { attrs: {
url: 'BusinessTypes', url: 'BusinessTypes',
fields: ['code', 'description'],
sortBy: 'description ASC ',
optionLabel: 'description', optionLabel: 'description',
optionValue: 'code', optionValue: 'code',
}, },
@ -353,12 +356,13 @@ const columns = computed(() => [
{ {
title: t('Client ticket list'), title: t('Client ticket list'),
icon: 'vn:ticket', icon: 'vn:ticket',
action: redirectToCreateView, action: redirectToTicketsList,
isPrimary: true, isPrimary: true,
}, },
{ {
title: t('components.smartCard.viewSummary'), title: t('components.smartCard.viewSummary'),
icon: 'preview', icon: 'preview',
isPrimary: true,
action: (row) => viewSummary(row.id, CustomerSummary), action: (row) => viewSummary(row.id, CustomerSummary),
}, },
], ],
@ -366,11 +370,12 @@ const columns = computed(() => [
]); ]);
const { viewSummary } = useSummaryDialog(); const { viewSummary } = useSummaryDialog();
const redirectToCreateView = (row) => { const redirectToTicketsList = (row) => {
router.push({ router.push({
name: 'TicketList', name: 'TicketList',
query: { query: {
params: JSON.stringify({ table: JSON.stringify({
clientFk: row.id, clientFk: row.id,
}), }),
}, },
@ -395,10 +400,10 @@ function handleLocation(data, location) {
<VnTable <VnTable
ref="tableRef" ref="tableRef"
data-key="Customer" data-key="Customer"
url="Clients/extendedListFilter" url="Clients/filter"
:create="{ :create="{
urlCreate: 'Clients/createWithUser', urlCreate: 'Clients/createWithUser',
title: 'Create client', title: t('globals.pageTitles.customerCreate'),
onDataSaved: ({ id }) => tableRef.redirect(id), onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: { formInitialData: {
active: true, active: true,
@ -411,8 +416,41 @@ function handleLocation(data, location) {
auto-load auto-load
> >
<template #more-create-dialog="{ data }"> <template #more-create-dialog="{ data }">
<VnSelect
url="Workers/search"
v-model="data.salesPersonFk"
:label="t('customer.basicData.salesPerson')"
:params="{
departmentCodes: ['VT', 'shopping'],
}"
:fields="['id', 'nickname']"
sort-by="nickname ASC"
:use-like="false"
emit-value
auto-load
>
<template #prepend>
<VnAvatar
:worker-id="data.salesPersonFk"
color="primary"
:title="title"
/>
</template>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption
>{{ scope.opt?.nickname }},
{{ scope.opt?.code }}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnLocation <VnLocation
:roles-allowed-to-create="['deliveryAssistant']" :acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
v-model="data.location" v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
/> />

View File

@ -57,12 +57,12 @@ function handleLocation(data, location) {
</script> </script>
<template> <template>
<fetch-data <FetchData
@on-fetch="(data) => (agencyModes = data)" @on-fetch="(data) => (agencyModes = data)"
auto-load auto-load
url="AgencyModes/isActive" url="AgencyModes/isActive"
/> />
<fetch-data @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" /> <FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
<FormModel <FormModel
:form-initial-data="formInitialData" :form-initial-data="formInitialData"
@ -92,7 +92,7 @@ function handleLocation(data, location) {
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
v-model="data.location" v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
/> />

View File

@ -113,18 +113,18 @@ function handleLocation(data, location) {
</script> </script>
<template> <template>
<fetch-data <FetchData
@on-fetch="(data) => (agencyModes = data)" @on-fetch="(data) => (agencyModes = data)"
auto-load auto-load
url="AgencyModes/isActive" url="AgencyModes/isActive"
/> />
<fetch-data @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" /> <FetchData @on-fetch="(data) => (incoterms = data)" auto-load url="Incoterms" />
<fetch-data <FetchData
@on-fetch="(data) => (customsAgents = data)" @on-fetch="(data) => (customsAgents = data)"
auto-load auto-load
url="CustomsAgents" url="CustomsAgents"
/> />
<fetch-data @on-fetch="getData" auto-load url="ObservationTypes" /> <FetchData @on-fetch="getData" auto-load url="ObservationTypes" />
<FormModel <FormModel
:observe-form-changes="false" :observe-form-changes="false"
@ -176,8 +176,13 @@ function handleLocation(data, location) {
<div class="col"> <div class="col">
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
v-model="data.postalCode" :location="{
postcode: data.postalCode,
city: data.city,
province: data.province,
country: data.province.country,
}"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
></VnLocation> ></VnLocation>
</div> </div>
@ -267,16 +272,17 @@ function handleLocation(data, location) {
</div> </div>
</VnRow> </VnRow>
<QIcon <QBtn
@click.stop="addNote()" @click.stop="addNote()"
class="cursor-pointer add-icon q-mt-md" class="cursor-pointer add-icon q-mt-md"
name="add" flat
size="sm" icon="add"
shortcut="+"
> >
<QTooltip> <QTooltip>
{{ t('Add note') }} {{ t('Add note') }}
</QTooltip> </QTooltip>
</QIcon> </QBtn>
</template> </template>
</FormModel> </FormModel>
</template> </template>

View File

@ -21,6 +21,7 @@ const newAddressForm = reactive({
provinceFk: null, provinceFk: null,
phone: null, phone: null,
mobile: null, mobile: null,
province: null,
}); });
const onDataSaved = () => { const onDataSaved = () => {
@ -84,7 +85,17 @@ function handleLocation(data, location) {
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant']" :roles-allowed-to-create="['deliveryAssistant']"
v-model="data.location" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
:location="
data.postalCode
? {
postcode: data.postalCode,
city: data.city,
province: data.province,
country: data.province.country,
}
: null
"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
> >
</VnLocation> </VnLocation>

View File

@ -51,6 +51,23 @@ function handleLocation(data, location) {
:url="`Suppliers/${route.params.id}`" :url="`Suppliers/${route.params.id}`"
:url-update="`Suppliers/${route.params.id}/updateFiscalData`" :url-update="`Suppliers/${route.params.id}/updateFiscalData`"
model="supplier" model="supplier"
:filter="{
fields: ['id', 'name', 'city', 'postCode', 'countryFk', 'provinceFk'],
include: [
{
relation: 'province',
scope: {
fields: ['id', 'name'],
},
},
{
relation: 'country',
scope: {
fields: ['id', 'name'],
},
},
],
}"
auto-load auto-load
:clear-store-on-unmount="false" :clear-store-on-unmount="false"
> >
@ -130,7 +147,13 @@ function handleLocation(data, location) {
<VnLocation <VnLocation
:rules="validate('Worker.postcode')" :rules="validate('Worker.postcode')"
:roles-allowed-to-create="['deliveryAssistant', 'administrative']" :roles-allowed-to-create="['deliveryAssistant', 'administrative']"
v-model="data.postCode" :acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
:location="{
postcode: data.postCode,
city: data.city,
province: data.province,
country: data.country,
}"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
> >
</VnLocation> </VnLocation>

View File

@ -263,8 +263,8 @@ async function autofillBic(worker) {
<VnRow> <VnRow>
<VnLocation <VnLocation
:roles-allowed-to-create="['deliveryAssistant']" :roles-allowed-to-create="['deliveryAssistant']"
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
:options="postcodesOptions" :options="postcodesOptions"
v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)" @update:model-value="(location) => handleLocation(data, location)"
:disable="data.isFreelance" :disable="data.isFreelance"
> >
@ -311,7 +311,7 @@ async function autofillBic(worker) {
option-label="name" option-label="name"
option-value="id" option-value="id"
hide-selected hide-selected
:roles-allowed-to-create="['salesAssistant', 'hr']" :acls="[{ model: 'BankEntity', props: '*', accessType: 'WRITE' }]"
:disable="data.isFreelance" :disable="data.isFreelance"
@update:model-value="autofillBic(data)" @update:model-value="autofillBic(data)"
:filter-options="['bic', 'name']" :filter-options="['bic', 'name']"