mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-06 05:19:43 +00:00
[WIP] refactorization to show details of an address
This commit is contained in:
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user