mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 01:08:26 +00:00 
			
		
		
		
	[WIP] refactorization to show details of an address
This commit is contained in:
		| @@ -45,6 +45,7 @@ | ||||
|     "webpack-cli": "^5.0.1" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@fragaria/address-formatter": "^6.6.1", | ||||
|     "@fullcalendar/core": "^6.1.4", | ||||
|     "@fullcalendar/daygrid": "^6.1.4", | ||||
|     "@fullcalendar/interaction": "^6.1.4", | ||||
|   | ||||
| @@ -97,7 +97,9 @@ final readonly class AddressReferenceRepository implements AddressReferenceRepos | ||||
|  | ||||
|         $result = $qb->executeQuery(); | ||||
|  | ||||
|         return $result->iterateAssociative(); | ||||
|         foreach ($result->iterateAssociative() as $row) { | ||||
|             yield [...$row, 'positions' => json_decode($row['positions'], true, 512, JSON_THROW_ON_ERROR)]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -75,6 +75,7 @@ export interface Postcode { | ||||
|     name: string; | ||||
|     code: string; | ||||
|     center: Point; | ||||
|     country: Country; | ||||
| } | ||||
|  | ||||
| export interface Point { | ||||
| @@ -90,6 +91,28 @@ export interface Country { | ||||
|  | ||||
| export type AddressRefStatus = "match" | "to_review" | "reviewed"; | ||||
|  | ||||
| /** | ||||
|  * An interface to create an address | ||||
|  */ | ||||
| export interface AddressCreation { | ||||
|     confidential: boolean; | ||||
|     isNoAddress: boolean; | ||||
|     street: string; | ||||
|     streetNumber: string; | ||||
|     postcode: Postcode; | ||||
|     point: Point; // [number, number]; // [longitude, latitude] | ||||
|     addressReference: AddressReference; | ||||
|     validFrom: DateTime|null; | ||||
|     floor: string; | ||||
|     corridor: string; | ||||
|     steps: string; | ||||
|     flat: string; | ||||
|     buildingName: string; | ||||
|     distribution: string; | ||||
|     extra: string; | ||||
| } | ||||
|  | ||||
|  | ||||
| export interface Address { | ||||
|     type: "address"; | ||||
|     address_id: number; | ||||
| @@ -108,7 +131,7 @@ export interface Address { | ||||
|     confidential: boolean; | ||||
|     lines: string[]; | ||||
|     addressReference: AddressReference | null; | ||||
|     validFrom: DateTime; | ||||
|     validFrom: DateTime  | null; // TODO there is no null for validFrom | ||||
|     validTo: DateTime | null; | ||||
|     point: Point | null; | ||||
|     refStatus: AddressRefStatus; | ||||
|   | ||||
| @@ -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, | ||||
|     } | ||||
| } | ||||
| @@ -4,24 +4,27 @@ | ||||
|         :show-button-details="false" | ||||
|     ></address-render-box> | ||||
|     <address-details-ref-matching | ||||
|         v-if="isAddress(props.address)" | ||||
|         :address="props.address" | ||||
|         @update-address="onUpdateAddress" | ||||
|     ></address-details-ref-matching> | ||||
|     <address-details-map :address="props.address"></address-details-map> | ||||
|     <address-details-geographical-layers | ||||
|         v-if="isAddress(props.address)" | ||||
|         :address="props.address" | ||||
|     ></address-details-geographical-layers> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts" setup> | ||||
| import { Address } from "../../../types"; | ||||
| import {Address, AddressCreation} from "../../../types"; | ||||
| import AddressDetailsMap from "./Parts/AddressDetailsMap.vue"; | ||||
| import AddressRenderBox from "../Entity/AddressRenderBox.vue"; | ||||
| import AddressDetailsGeographicalLayers from "./Parts/AddressDetailsGeographicalLayers.vue"; | ||||
| import AddressDetailsRefMatching from "./Parts/AddressDetailsRefMatching.vue"; | ||||
| import {isAddress} from "ChillMainAssets/vuejs/_components/AddressDetails/helper"; | ||||
|  | ||||
| interface AddressModalContentProps { | ||||
|     address: Address; | ||||
|     address: Address|AddressCreation; | ||||
| } | ||||
|  | ||||
| const props = defineProps<AddressModalContentProps>(); | ||||
|   | ||||
| @@ -22,14 +22,15 @@ import { onMounted, ref } from "vue"; | ||||
| import "leaflet/dist/leaflet.css"; | ||||
| import markerIconPng from "leaflet/dist/images/marker-icon.png"; | ||||
| import L, { LatLngExpression, LatLngTuple } from "leaflet"; | ||||
| import { Address, Point } from "../../../../types"; | ||||
| import {Address, AddressCreation, Point} from "../../../../types"; | ||||
| import {buildAddressLines, getAddressPoint} from "ChillMainAssets/vuejs/_components/AddressDetails/helper"; | ||||
|  | ||||
| const lonLatForLeaflet = (point: Point): LatLngTuple => { | ||||
|     return [point.coordinates[1], point.coordinates[0]]; | ||||
| }; | ||||
|  | ||||
| export interface MapProps { | ||||
|     address: Address; | ||||
|     address: Address|AddressCreation; | ||||
| } | ||||
|  | ||||
| const props = defineProps<MapProps>(); | ||||
| @@ -65,37 +66,39 @@ onMounted(() => { | ||||
|     } | ||||
| }); | ||||
|  | ||||
| const makeUrlGoogleMap = (address: Address): string => { | ||||
| const makeUrlGoogleMap = (address: Address|AddressCreation): string => { | ||||
|     const params = new URLSearchParams(); | ||||
|     params.append("api", "1"); | ||||
|     if (address.point !== null && address.addressReference !== null) { | ||||
|     const point = getAddressPoint(address); | ||||
|     if (point !== null && address.addressReference !== null) { | ||||
|         params.append( | ||||
|             "query", | ||||
|             `${address.point.coordinates[1]} ${address.point.coordinates[0]}`, | ||||
|             `${point.coordinates[1]} ${point.coordinates[0]}`, | ||||
|         ); | ||||
|     } else { | ||||
|         params.append("query", address.lines.join(", ")); | ||||
|         params.append("query", buildAddressLines(address).join(", ")); | ||||
|     } | ||||
|  | ||||
|     return `https://www.google.com/maps/search/?${params.toString()}`; | ||||
| }; | ||||
|  | ||||
| const makeUrlOsm = (address: Address): string => { | ||||
|     if (address.point !== null && address.addressReference !== null) { | ||||
| const makeUrlOsm = (address: Address|AddressCreation): string => { | ||||
|     const point = getAddressPoint(address); | ||||
|     if (point !== null && address.addressReference !== null) { | ||||
|         const params = new URLSearchParams(); | ||||
|         params.append("mlat", `${address.point.coordinates[1]}`); | ||||
|         params.append("mlon", `${address.point.coordinates[0]}`); | ||||
|         params.append("mlat", `${point.coordinates[1]}`); | ||||
|         params.append("mlon", `${point.coordinates[0]}`); | ||||
|         const hashParams = new URLSearchParams(); | ||||
|         hashParams.append( | ||||
|             "map", | ||||
|             `18/${address.point.coordinates[1]}/${address.point.coordinates[0]}`, | ||||
|             `18/${point.coordinates[1]}/${point.coordinates[0]}`, | ||||
|         ); | ||||
|  | ||||
|         return `https://www.openstreetmap.org/?${params.toString()}#${hashParams.toString()}`; | ||||
|     } | ||||
|  | ||||
|     const params = new URLSearchParams(); | ||||
|     params.append("query", address.lines.join(", ")); | ||||
|     params.append("query", buildAddressLines(address).join(", ")); | ||||
|  | ||||
|     return `https://www.openstreetmap.org/search?${params.toString()}`; | ||||
| }; | ||||
|   | ||||
| @@ -0,0 +1,46 @@ | ||||
| import {Address, AddressCreation, Point} from "ChillMainAssets/types"; | ||||
| import addressFormatter, {Input} from "@fragaria/address-formatter"; | ||||
|  | ||||
| /** | ||||
|  * Checks if the given object is of type Address by verifying the existence | ||||
|  * of the `lines` property and confirming that it is an array of strings. | ||||
|  * | ||||
|  * @param {AddressCreation | Address} obj - The object to check. | ||||
|  * @return {boolean} Returns true if the object is of type Address, otherwise false. | ||||
|  */ | ||||
| export function isAddress(obj: AddressCreation | Address): obj is Address { | ||||
|     return (obj as any).lines !== undefined && Array.isArray((obj as any).lines); | ||||
| } | ||||
|  | ||||
| function buildAddressFormatterObject(address: AddressCreation): Input { | ||||
|     return { | ||||
|         city: address.postcode.name, | ||||
|         postcode: address.postcode.code, | ||||
|         countryCode: address.postcode.country.code, | ||||
|         street: address.street, | ||||
|         houseNumber: address.streetNumber, | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| export const buildAddressLines = (address: AddressCreation|Address): string[] => { | ||||
|     if (isAddress(address)) { | ||||
|         return address.lines; | ||||
|     } | ||||
|  | ||||
|     const lines = addressFormatter.format(buildAddressFormatterObject(address), {output: 'array', countryCode: address.addressReference.postcode.country.code }); | ||||
|     console.log('lines:', lines); | ||||
|     return lines; | ||||
| } | ||||
|  | ||||
| export const buildAddressText = (address: AddressCreation|Address): string => { | ||||
|     return buildAddressLines(address).join(' - '); | ||||
| } | ||||
|  | ||||
| export const getAddressPoint = (address: AddressCreation|Address): Point|null => { | ||||
|     if (isAddress(address)) { | ||||
|         return address.point; | ||||
|     } | ||||
|  | ||||
|     return address.addressReference?.point; | ||||
| } | ||||
| @@ -4,14 +4,14 @@ | ||||
|             <div v-if="isConfidential"> | ||||
|                 <confidential :position-btn-far="true"> | ||||
|                     <template #confidential-content> | ||||
|                         <div v-if="isMultiline === true"> | ||||
|                         <div v-if="isMultiline"> | ||||
|                             <p | ||||
|                                 v-for="(l, i) in address.lines" | ||||
|                                 v-for="(l, i) in buildAddressLines(address)" | ||||
|                                 :key="`line-${i}`" | ||||
|                             > | ||||
|                                 {{ l }} | ||||
|                             </p> | ||||
|                             <p v-if="showButtonDetails"> | ||||
|                             <p v-if="showButtonDetails && isAddress(address) "> | ||||
|                                 <address-details-button | ||||
|                                     :address_id="address.address_id" | ||||
|                                     :address_ref_status="address.refStatus" | ||||
| @@ -19,8 +19,8 @@ | ||||
|                             </p> | ||||
|                         </div> | ||||
|                         <div v-else> | ||||
|                             <p v-if="'' !== address.text" class="street"> | ||||
|                                 {{ address.text }} | ||||
|                             <p v-if="'' !== buildAddressText(address)" class="street"> | ||||
|                                 {{ buildAddressText(address) }} | ||||
|                             </p> | ||||
|                             <p | ||||
|                                 v-if="null !== address.postcode" | ||||
| @@ -29,8 +29,8 @@ | ||||
|                                 {{ address.postcode.code }} | ||||
|                                 {{ address.postcode.name }} | ||||
|                             </p> | ||||
|                             <p v-if="null !== address.country" class="country"> | ||||
|                                 {{ localizeString(address.country.name) }} | ||||
|                             <p v-if="null !== address.postcode" class="country"> | ||||
|                                 {{ localizeString(address.postcode.country.name) }} | ||||
|                             </p> | ||||
|                         </div> | ||||
|                     </template> | ||||
| @@ -38,11 +38,11 @@ | ||||
|             </div> | ||||
|  | ||||
|             <div v-if="!isConfidential"> | ||||
|                 <div v-if="isMultiline === true"> | ||||
|                     <p v-for="(l, i) in address.lines" :key="`line-${i}`"> | ||||
|                 <div v-if="isMultiline"> | ||||
|                     <p v-for="(l, i) in buildAddressLines(address)" :key="`line-${i}`"> | ||||
|                         {{ l }} | ||||
|                     </p> | ||||
|                     <p v-if="showButtonDetails"> | ||||
|                     <p v-if="showButtonDetails && isAddress(address) "> | ||||
|                         <address-details-button | ||||
|                             :address_id="address.address_id" | ||||
|                             :address_ref_status="address.refStatus" | ||||
| @@ -50,9 +50,9 @@ | ||||
|                     </p> | ||||
|                 </div> | ||||
|                 <div v-else> | ||||
|                     <p v-if="address.text" class="street"> | ||||
|                         {{ address.text }} | ||||
|                         <template v-if="showButtonDetails"> | ||||
|                     <p v-if="'' !== buildAddressText(address)" class="street"> | ||||
|                         {{ buildAddressText(address)}} | ||||
|                         <template v-if="showButtonDetails && isAddress(address) "> | ||||
|                             <address-details-button | ||||
|                                 :address_id="address.address_id" | ||||
|                                 :address_ref_status="address.refStatus" | ||||
| @@ -63,68 +63,49 @@ | ||||
|             </div> | ||||
|         </component> | ||||
|  | ||||
|         <div v-if="useDatePane === true" class="address-more"> | ||||
|         <div v-if="useDatePane" class="address-more"> | ||||
|             <div v-if="address.validFrom"> | ||||
|                 <span class="validFrom"> | ||||
|                     <b>{{ trans(ADDRESS_VALID_FROM) }}</b | ||||
|                     >: {{ $d(address.validFrom.date) }} | ||||
|                     >: {{ address.validFrom?.datetime8601 }} | ||||
|                 </span> | ||||
|             </div> | ||||
|             <div v-if="address.validTo"> | ||||
|             <div v-if="isAddress(address) && address.validTo !== null"> | ||||
|                 <span class="validTo"> | ||||
|                     <b>{{ trans(ADDRESS_VALID_TO) }}</b | ||||
|                     >: {{ $d(address.validTo.date) }} | ||||
|                     >: {{ address.validTo?.datetime8601 }} | ||||
|                 </span> | ||||
|             </div> | ||||
|         </div> | ||||
|     </component> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| <script setup lang="ts"> | ||||
| import { computed } from "vue"; | ||||
| import Confidential from "ChillMainAssets/vuejs/_components/Confidential.vue"; | ||||
| import AddressDetailsButton from "ChillMainAssets/vuejs/_components/AddressDetails/AddressDetailsButton.vue"; | ||||
| import { trans, ADDRESS_VALID_FROM, ADDRESS_VALID_TO } from "translator"; | ||||
| import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper"; | ||||
| import {Address, AddressCreation} from "ChillMainAssets/types"; | ||||
| import {isAddress, buildAddressLines, buildAddressText} from "ChillMainAssets/vuejs/_components/AddressDetails/helper"; | ||||
|  | ||||
| export default { | ||||
|     name: "AddressRenderBox", | ||||
|     methods: { localizeString }, | ||||
|     components: { | ||||
|         Confidential, | ||||
|         AddressDetailsButton, | ||||
|     }, | ||||
|     props: { | ||||
|         address: { | ||||
|             type: Object, | ||||
|         }, | ||||
|         isMultiline: { | ||||
|             default: true, | ||||
|             type: Boolean, | ||||
|         }, | ||||
|         useDatePane: { | ||||
|             default: false, | ||||
|             type: Boolean, | ||||
|         }, | ||||
|         showButtonDetails: { | ||||
|             default: true, | ||||
|             type: Boolean, | ||||
|         }, | ||||
|     }, | ||||
|     setup() { | ||||
|         return { trans, ADDRESS_VALID_FROM, ADDRESS_VALID_TO }; | ||||
|     }, | ||||
|     computed: { | ||||
|         component() { | ||||
|             return this.isMultiline === true ? "div" : "span"; | ||||
|         }, | ||||
|         multiline() { | ||||
|             return this.isMultiline === true ? "multiline" : ""; | ||||
|         }, | ||||
|         isConfidential() { | ||||
|             return this.address.confidential; | ||||
|         }, | ||||
|     }, | ||||
| }; | ||||
| const props = withDefaults( | ||||
|     defineProps<{ | ||||
|         address: Address|AddressCreation; | ||||
|         isMultiline?: boolean; | ||||
|         useDatePane?: boolean; | ||||
|         showButtonDetails?: boolean; | ||||
|     }>(), | ||||
|     { | ||||
|         isMultiline: true, | ||||
|         useDatePane: false, | ||||
|         showButtonDetails: true, | ||||
|     } | ||||
| ); | ||||
|  | ||||
| const component = computed(() => (props.isMultiline ? "div" : "span")); | ||||
| const multiline = computed(() => (props.isMultiline ? "multiline" : "")); | ||||
| const isConfidential = computed(() => Boolean(props.address?.confidential)); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   | ||||
| @@ -66,6 +66,7 @@ class AddressNormalizer implements ContextAwareNormalizerInterface, NormalizerAw | ||||
|                     'name' => $address->getPostCode()->getName(), | ||||
|                     'code' => $address->getPostCode()->getCode(), | ||||
|                     'center' => $address->getPostcode()->getCenter(), | ||||
|                     'country' => $this->normalizer->normalize($address->getPostCode()->getCountry(), $format, [AbstractNormalizer::GROUPS => ['read']]), | ||||
|                 ], | ||||
|                 'country' => [ | ||||
|                     'id' => $address->getPostCode()->getCountry()->getId(), | ||||
|   | ||||
| @@ -181,6 +181,11 @@ address more: | ||||
|     buildingName: résidence | ||||
|     extra: "" | ||||
|     distribution: cedex | ||||
|  | ||||
| address_picker: | ||||
|     # placeholder | ||||
|     Search for addresses: Chercher des adresses | ||||
|  | ||||
| Create a new address: Créer une nouvelle adresse | ||||
| Create an address: Créer une adresse | ||||
| Update address: Modifier l'adresse | ||||
|   | ||||
		Reference in New Issue
	
	Block a user