mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-05 21:09:43 +00:00
143 lines
4.1 KiB
Vue
143 lines
4.1 KiB
Vue
<script setup lang="ts">
|
|
import {Address, AddressReference} from "ChillMainAssets/types";
|
|
import SearchBar from "ChillMainAssets/vuejs/AddressPicker/Component/SearchBar.vue";
|
|
import {
|
|
AddressAggregated,
|
|
AssociatedPostalCode, fetchAddressReference,
|
|
getAddressesAggregated,
|
|
getPostalCodes,
|
|
} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
|
|
import {computed, Ref, ref} from "vue";
|
|
import AddressAggregatedList from "ChillMainAssets/vuejs/AddressPicker/Component/AddressAggregatedList.vue";
|
|
import AddressDetailsForm from "ChillMainAssets/vuejs/AddressPicker/Component/AddressDetailsForm.vue";
|
|
|
|
interface AddressPickerProps {
|
|
suggestions?: Address[];
|
|
}
|
|
|
|
const props = withDefaults(defineProps<AddressPickerProps>(), {
|
|
suggestions: () => [],
|
|
});
|
|
|
|
const addresses: Ref<AddressAggregated[]> = ref([]);
|
|
const postalCodes: Ref<AssociatedPostalCode[]> = ref([]);
|
|
const searchTokens: Ref<string[]> = ref([]);
|
|
const addressReference: Ref<AddressReference|null> = ref(null);
|
|
|
|
let abortControllerSearchAddress: null | AbortController = null;
|
|
let abortControllerSearchPostalCode: null | AbortController = null;
|
|
|
|
const searchResultsClasses = computed(() => ({
|
|
"mid-size": addressReference !== null,
|
|
}));
|
|
|
|
|
|
const onSearch = async function (search: string): Promise<void> {
|
|
performSearchForAddress(search);
|
|
performSearchForPostalCode(search);
|
|
searchTokens.value = [search];
|
|
};
|
|
|
|
const onPickPosition = async (id: string) => {
|
|
console.log('Pick Position', id);
|
|
addressReference.value = await fetchAddressReference(id);
|
|
}
|
|
|
|
const performSearchForAddress = async (search: string): Promise<void> => {
|
|
if (null !== abortControllerSearchAddress) {
|
|
abortControllerSearchAddress.abort();
|
|
}
|
|
|
|
if ("" === search) {
|
|
addresses.value = [];
|
|
abortControllerSearchAddress = null;
|
|
return;
|
|
}
|
|
|
|
abortControllerSearchAddress = new AbortController();
|
|
|
|
console.log("onSearch", search);
|
|
try {
|
|
addresses.value = await getAddressesAggregated(
|
|
search,
|
|
abortControllerSearchAddress,
|
|
);
|
|
abortControllerSearchAddress = null;
|
|
|
|
// check if there is only one result
|
|
if (addresses.value.length === 1 && Object.keys(addresses.value[0].positions).length === 1) {
|
|
onPickPosition(Object.keys(addresses.value[0].positions)[0]);
|
|
}
|
|
} catch (e: unknown) {
|
|
if (e instanceof DOMException && e.name === "AbortError") {
|
|
console.log("search aborted for:", search);
|
|
|
|
return;
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
};
|
|
|
|
const performSearchForPostalCode = async (search: string): Promise<void> => {
|
|
if (null !== abortControllerSearchPostalCode) {
|
|
abortControllerSearchPostalCode.abort();
|
|
}
|
|
|
|
if ("" === search) {
|
|
addresses.value = [];
|
|
abortControllerSearchPostalCode = null;
|
|
return;
|
|
}
|
|
|
|
abortControllerSearchPostalCode = new AbortController();
|
|
|
|
console.log("onSearch", search);
|
|
try {
|
|
postalCodes.value = await getPostalCodes(
|
|
search,
|
|
abortControllerSearchPostalCode,
|
|
);
|
|
abortControllerSearchPostalCode = null;
|
|
} catch (e: unknown) {
|
|
if (e instanceof DOMException && e.name === "AbortError") {
|
|
console.log("search postal code aborted for:", search);
|
|
|
|
return;
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<search-bar @search="onSearch"></search-bar>
|
|
<div class="address-pick-content">
|
|
<div class="search-results" :class="searchResultsClasses">
|
|
<address-aggregated-list :addresses="addresses" :search-tokens="searchTokens" @pick-position="(id) => onPickPosition(id)"></address-aggregated-list>
|
|
</div>
|
|
<div v-if="addressReference !== null" class="address-details-form">
|
|
<address-details-form :address="addressReference"></address-details-form>
|
|
</div>
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.address-pick-content {
|
|
display: flex;
|
|
flex-direction: row;
|
|
gap: 1rem;
|
|
|
|
.search-results {
|
|
&.mid-size {
|
|
width: 50%;
|
|
}
|
|
}
|
|
.address-details-form {
|
|
width: 50%;
|
|
}
|
|
}
|
|
</style>
|