[WIP] refactorization to show details of an address

This commit is contained in:
2025-08-18 13:14:10 +02:00
parent e3aeab315f
commit 4e61821e5b
17 changed files with 341 additions and 84 deletions

View File

@@ -19,7 +19,7 @@ const closeModal = () => {
</script>
<template>
<modal v-if="showModal" :modal-dialog-class="modalDialogClasses" @close="closeModal">
<modal v-if="showModal" :hide-footer="false" :modal-dialog-class="modalDialogClasses" @close="closeModal">
<template v-slot:header>TODO</template>
<template v-slot:body>
<AddressPicker></AddressPicker>

View File

@@ -1,13 +1,15 @@
<script setup lang="ts">
import { Address } from "ChillMainAssets/types";
import {Address, AddressReference} from "ChillMainAssets/types";
import SearchBar from "ChillMainAssets/vuejs/AddressPicker/Component/SearchBar.vue";
import {
AddressAggregated,
AssociatedPostalCode,
AssociatedPostalCode, fetchAddressReference,
getAddressesAggregated,
getPostalCodes,
} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
import { 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[];
@@ -19,14 +21,23 @@ const props = withDefaults(defineProps<AddressPickerProps>(), {
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 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();
@@ -92,11 +103,20 @@ const performSearchForPostalCode = async (search: string): Promise<void> => {
<template>
<search-bar @search="onSearch"></search-bar>
<p>test</p>
<p v-for="a in addresses" :key="a.row_number">
{{ a.street }}, positions: {{ a.positions[0] }}
</p>
<p v-for="pc in postalCodes" :key="pc.postcode_id">{{ pc }}</p>
<div class="address-pick-content">
<div>
<address-aggregated-list :addresses="addresses" :search-tokens="searchTokens" @pick-position="(id) => onPickPosition(id)"></address-aggregated-list>
</div>
<div v-if="addressReference !== null">
<address-details-form :address="addressReference"></address-details-form>
</div>
</div>
</template>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.address-pick-content {
display: flex;
flex-direction: row;
}
</style>

View File

@@ -0,0 +1,25 @@
<script setup lang="ts">
import {AddressAggregated} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
import AddressAggregatedListItem from "ChillMainAssets/vuejs/AddressPicker/Component/AddressAggregatedListItem.vue";
interface AddressAggregatedListProps {
addresses: AddressAggregated[];
searchTokens: string[];
}
const props = defineProps<AddressAggregatedListProps>();
const emit = defineEmits<{
pickPosition: [id: string]
}>();
</script>
<template>
<template v-for="a in props.addresses" :key="a.row_number">
<address-aggregated-list-item :address="a" :search-tokens="props.searchTokens" @pick-position="(id) => emit('pickPosition', id)"></address-aggregated-list-item>
</template>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,82 @@
<script setup lang="ts">
import {AddressAggregated} from "ChillMainAssets/vuejs/AddressPicker/driver/local-search";
import {computed, ref} from "vue";
interface AddressAggregatedListItemProps {
address: AddressAggregated;
searchTokens: string[];
}
const props = defineProps<AddressAggregatedListItemProps>();
const emit = defineEmits<{
pickPosition: [id: string]
}>();
const showAllPositions = ref<boolean>(false);
const positionsToShow = computed((): Record<string, string> => {
const obj: Record<string, any> = {};
let count = 0;
for (const [id, position] of Object.entries(props.address.positions)) {
obj[id] = position;
count++;
if (count >= 10 && !showAllPositions.value) {
break;
}
}
return obj;
})
const needToShowMorePosition = computed(() => {
return Object.keys(props.address.positions).length > 10;
})
const onClickButton = (id: string) => {
console.log('onClickButton', id);
emit('pickPosition', id);
}
const displayAllPositions = () => {
showAllPositions.value = true;
}
</script>
<template>
<div>
<div class="street">
<span>{{ props.address.street }}</span>
</div>
<div class="postcode">
<span>{{ props.address.code }}</span> <span>{{ address.label }}</span>
</div>
<div class="positions">
<ul>
<li v-for="(position, id) in positionsToShow" :key="id" >
<button type="button" @click="onClickButton(id)" >
{{ position }}
</button>
</li>
<li v-if="needToShowMorePosition">
<button @click="displayAllPositions">show all</button>
</li>
</ul>
</div>
</div>
</template>
<style scoped lang="scss">
.street {
font-variant: small-caps;
font-weight: bold;
}
.postcode {
font-variant: small-caps;
}
.positions ul {
list-style-type: none;
li {
display: inline-block;
margin-right: 2px;
}
}
</style>

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
import {AddressReference} from "ChillMainAssets/types";
import {computed} from "vue";
import {addressReferenceToAddress} from "ChillMainAssets/vuejs/AddressPicker/helper";
import AddressDetailsContent from "ChillMainAssets/vuejs/_components/AddressDetails/AddressDetailsContent.vue";
export interface AddressDetailsFormProps {
address: AddressReference;
}
const props = defineProps<AddressDetailsFormProps>();
const address = computed(() => addressReferenceToAddress(props.address));
</script>
<template>
<div>
FORM
</div>
<div>
<address-details-content :address="address"></address-details-content>
</div>
</template>
<style scoped lang="scss">
</style>

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import { ADDRESS_PICKER_SEARCH_FOR_ADDRESSES, trans } from 'translator';
const emits = defineEmits<{
search: [search: string];
}>();
@@ -25,7 +26,14 @@ const onInput = function (event: InputEvent) {
</script>
<template>
<input type="search" @input="onInput" />
<div class="input-group mb-3">
<span class="input-group-text">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0"/>
</svg>
</span>
<input type="search" class="form-control" @input="onInput" :placeholder="trans(ADDRESS_PICKER_SEARCH_FOR_ADDRESSES)" />
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -1,4 +1,4 @@
import { TranslatableString } from "ChillMainAssets/types";
import {AddressReference, TranslatableString} from "ChillMainAssets/types";
export interface AddressAggregated {
row_number: number;
@@ -58,3 +58,12 @@ export const getPostalCodes = async (
throw new Error(response.statusText);
};
export const fetchAddressReference = async (id: string): Promise<AddressReference> => {
const response = await fetch(`/api/1.0/main/address-reference/${id}.json`);
if (response.ok) {
return await response.json();
}
throw new Error(response.statusText);
}

View File

@@ -0,0 +1,21 @@
import {Address, AddressCreation, AddressReference} from "ChillMainAssets/types";
export const addressReferenceToAddress = (reference: AddressReference): AddressCreation => {
return {
street: reference.street,
streetNumber: reference.streetNumber,
postcode: reference.postcode,
floor: "",
corridor: "",
steps: "",
flat: "",
buildingName: "",
distribution: "",
extra: "",
confidential: false,
addressReference: reference,
point: reference.point,
isNoAddress: false,
validFrom: null,
}
}