forked from verdnatura/salix-front
feat: vnLocation changes
This commit is contained in:
parent
fdec25dc88
commit
3a0204d27b
|
@ -1,18 +1,23 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRefs, computed, watch, onMounted } from 'vue';
|
import { ref, toRefs, onMounted, nextTick } from 'vue';
|
||||||
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 FetchData from 'components/FetchData.vue';
|
const emit = defineEmits(['update:selected', 'update:options']);
|
||||||
const emit = defineEmits(['update:modelValue', 'update:options']);
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const postcodesOptions = ref([]);
|
const postcodesOptions = ref([]);
|
||||||
const postcodesRef = ref(null);
|
const postcodesOptionsOriginal = ref([]);
|
||||||
|
// const postcodesRef = ref(null);
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
modelValue: {
|
postalCodeKey: {
|
||||||
type: [String, Number, Object],
|
type: String,
|
||||||
|
default: 'postalCode',
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
|
@ -41,89 +46,115 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { options } = toRefs($props);
|
const selectedId = ref(null);
|
||||||
const myOptions = ref([]);
|
const mySelect = ref();
|
||||||
const myOptionsOriginal = ref([]);
|
const modelValue = ref($props.location[$props.postalCodeKey]);
|
||||||
|
const arrayData = useArrayData('postcodes', {
|
||||||
const value = computed({
|
url: 'Postcodes/filter',
|
||||||
get() {
|
limit: 1,
|
||||||
return $props.modelValue;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
emit(
|
|
||||||
'update:modelValue',
|
|
||||||
postcodesOptions.value.find((p) => p.code === value)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
function sanitizePostcode(data) {
|
||||||
locationFilter($props.modelValue);
|
return data.map((postcode) => ({
|
||||||
});
|
...postcode,
|
||||||
|
original: postcode,
|
||||||
|
id: sanitizeId(postcode),
|
||||||
|
label: sanitizeLabel(postcode),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeId(postcode) {
|
||||||
|
return `${postcode.code ?? postcode[$props.postalCodeKey]}_${postcode.provinceFk}_${
|
||||||
|
postcode.countryFk
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
onMounted(async () => {
|
||||||
|
await retriveOptions();
|
||||||
|
nextTick(() => mySelect.value.showPopup());
|
||||||
|
});
|
||||||
|
async function retriveOptions() {
|
||||||
|
let options = [];
|
||||||
|
if (modelValue.value) {
|
||||||
|
await locationFilter(modelValue.value, () => {});
|
||||||
|
options = arrayData.store.data;
|
||||||
|
} else {
|
||||||
|
const { data } = await arrayData.fetch({ updateRouter: false, append: true });
|
||||||
|
options = data;
|
||||||
|
}
|
||||||
|
setOptions(options);
|
||||||
|
}
|
||||||
|
function findOptionById(postcode) {
|
||||||
|
return postcodesOptions.value.find((p) => p.id === postcode);
|
||||||
|
}
|
||||||
function setOptions(data) {
|
function setOptions(data) {
|
||||||
myOptions.value = JSON.parse(JSON.stringify(data));
|
postcodesOptions.value = sanitizePostcode(data);
|
||||||
myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
|
if (modelValue.value) {
|
||||||
}
|
const { [$props.postalCodeKey]: code } = $props.location;
|
||||||
setOptions(options.value);
|
selectedId.value =
|
||||||
|
findOptionById(sanitizeId({ ...$props.location, code })) ??
|
||||||
watch(options, (newValue) => {
|
sanitizePostcode([$props.location])[0];
|
||||||
setOptions(newValue);
|
}
|
||||||
});
|
postcodesOptionsOriginal.value = JSON.parse(JSON.stringify(postcodesOptions.value));
|
||||||
|
|
||||||
function showLabel(data) {
|
|
||||||
return `${data.code} - ${data.town}(${data.province}), ${data.country}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function locationFilter(search = '') {
|
async function handleInput(value) {
|
||||||
if (
|
if (value) emit('update:selected', findOptionById(value));
|
||||||
search &&
|
if (modelValue.value) {
|
||||||
(search.includes('undefined') || search.startsWith(`${$props.modelValue} - `))
|
modelValue.value = value;
|
||||||
)
|
arrayData.store.userFilter = {};
|
||||||
|
await retriveOptions();
|
||||||
|
mySelect.value.showPopup();
|
||||||
|
} else postcodesOptions.value = postcodesOptionsOriginal.value;
|
||||||
|
}
|
||||||
|
function sanitizeLabel(postcode) {
|
||||||
|
return `${postcode.code ?? postcode[$props.postalCodeKey]} - ${postcode.town}(${
|
||||||
|
postcode.province
|
||||||
|
}), ${postcode.country}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function locationFilter(search, update) {
|
||||||
|
if (search.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
let where = { search };
|
let where = { search };
|
||||||
postcodesRef.value.fetch({ filter: { where }, limit: 30 });
|
arrayData.store.userFilter = { filter: { where } };
|
||||||
|
await arrayData.fetch({ append: false, updateRouter: false });
|
||||||
|
|
||||||
|
update(() => {
|
||||||
|
postcodesOptions.value = sanitizePostcode(arrayData.store.data);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFetch(data) {
|
|
||||||
postcodesOptions.value = data;
|
|
||||||
}
|
|
||||||
function onDataSaved(newPostcode) {
|
function onDataSaved(newPostcode) {
|
||||||
postcodesOptions.value.push(newPostcode);
|
postcodesOptions.value.push(newPostcode);
|
||||||
value.value = newPostcode.code;
|
selectedId.value = newPostcode.code ?? newPostcode[$props.postalCodeKey];
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
ref="postcodesRef"
|
|
||||||
url="Postcodes/filter"
|
|
||||||
@on-fetch="(data) => handleFetch(data)"
|
|
||||||
/>
|
|
||||||
<VnSelectDialog
|
<VnSelectDialog
|
||||||
v-if="postcodesRef"
|
ref="mySelect"
|
||||||
:option-label="(opt) => showLabel(opt) ?? 'code'"
|
option-label="label"
|
||||||
:option-value="(opt) => opt.code"
|
option-value="id"
|
||||||
v-model="value"
|
v-model="selectedId"
|
||||||
:options="postcodesOptions"
|
:options="postcodesOptions"
|
||||||
:label="t('Location')"
|
:label="t('Location')"
|
||||||
|
@update:model-value="handleInput"
|
||||||
:placeholder="t('search_by_postalcode')"
|
:placeholder="t('search_by_postalcode')"
|
||||||
@input-value="locationFilter"
|
@filter="locationFilter"
|
||||||
:default-filter="false"
|
|
||||||
:input-debounce="300"
|
:input-debounce="300"
|
||||||
:class="{ required: $attrs.required }"
|
:class="{ required: $attrs.required }"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
clearable
|
clearable
|
||||||
|
emit-value
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<CreateNewPostcode
|
<CreateNewPostcode @on-data-saved="onDataSaved" />
|
||||||
@on-data-saved="onDataSaved"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #option="{ itemProps, opt }">
|
<template #option="{ itemProps, opt }">
|
||||||
<QItem v-bind="itemProps">
|
<QItem v-bind="itemProps">
|
||||||
<QItemSection v-if="opt.code">
|
<QItemSection v-if="opt.code">
|
||||||
<QItemLabel>{{ opt.code }}</QItemLabel>
|
<QItemLabel>{{ opt.code }}</QItemLabel>
|
||||||
<QItemLabel caption>{{ showLabel(opt) }}</QItemLabel>
|
<QItemLabel caption>{{ opt.label }}</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -95,9 +95,9 @@ function handleLocation(data, location) {
|
||||||
<VnLocation
|
<VnLocation
|
||||||
:rules="validate('Worker.postcode')"
|
:rules="validate('Worker.postcode')"
|
||||||
:roles-allowed-to-create="['deliveryAssistant']"
|
:roles-allowed-to-create="['deliveryAssistant']"
|
||||||
:options="postcodesOptions"
|
:location="data"
|
||||||
v-model="data.postcode"
|
postal-code-key="postcode"
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:selected="(location) => handleLocation(data, location)"
|
||||||
>
|
>
|
||||||
</VnLocation>
|
</VnLocation>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
|
@ -17,11 +17,10 @@ const sageTaxTypesOptions = ref([]);
|
||||||
const sageWithholdingsOptions = ref([]);
|
const sageWithholdingsOptions = ref([]);
|
||||||
const sageTransactionTypesOptions = ref([]);
|
const sageTransactionTypesOptions = ref([]);
|
||||||
const supplierActivitiesOptions = ref([]);
|
const supplierActivitiesOptions = ref([]);
|
||||||
const postcodesOptions = ref([]);
|
|
||||||
|
|
||||||
function handleLocation(data, location) {
|
function handleLocation(data, location) {
|
||||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
const { town, label, provinceFk, countryFk } = location ?? {};
|
||||||
data.postCode = code;
|
data.postCode = label;
|
||||||
data.city = town;
|
data.city = town;
|
||||||
data.provinceFk = provinceFk;
|
data.provinceFk = provinceFk;
|
||||||
data.countryFk = countryFk;
|
data.countryFk = countryFk;
|
||||||
|
@ -131,9 +130,8 @@ function handleLocation(data, location) {
|
||||||
<VnLocation
|
<VnLocation
|
||||||
:rules="validate('Worker.postcode')"
|
:rules="validate('Worker.postcode')"
|
||||||
:roles-allowed-to-create="['deliveryAssistant']"
|
:roles-allowed-to-create="['deliveryAssistant']"
|
||||||
:options="postcodesOptions"
|
:location="data"
|
||||||
v-model="data.postCode"
|
@update:selected="(location) => handleLocation(data, location)"
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
|
||||||
>
|
>
|
||||||
</VnLocation>
|
</VnLocation>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
|
@ -17,7 +17,7 @@ describe('VnLocation', () => {
|
||||||
cy.get(inputLocation).click();
|
cy.get(inputLocation).click();
|
||||||
cy.get(inputLocation).clear();
|
cy.get(inputLocation).clear();
|
||||||
cy.get(inputLocation).type('al');
|
cy.get(inputLocation).type('al');
|
||||||
cy.get(locationOptions).should('have.length.at.least', 3);
|
cy.get(locationOptions).should('have.length.at.least', 4);
|
||||||
});
|
});
|
||||||
it('input filter location as "ecuador"', function () {
|
it('input filter location as "ecuador"', function () {
|
||||||
cy.get(inputLocation).click();
|
cy.get(inputLocation).click();
|
||||||
|
|
Loading…
Reference in New Issue