Browse Source

implements multi addresses support

Olivier Massot 4 years ago
parent
commit
7d13aee79f

+ 7 - 6
components/Ui/Map/Structures.vue

@@ -133,10 +133,10 @@ export default Vue.extend({
       // populate new layer
       const clusters = L.markerClusterGroup()
       for (const s of this.structures) {
-        if (!s.latitude || !s.longitude) { continue }
+        if (!s.mapAddress || !s.mapAddress.latitude || !s.mapAddress.longitude) { continue }
 
-        const marker = L.marker([s.latitude, s.longitude])
-        marker.bindPopup(`<b>${s.name}</b><br/>${s.postalCode} ${s.addressCity}<br/><a href="${s.website}" target="_blank">${s.website}</a>`)
+        const marker = L.marker([s.mapAddress.latitude, s.mapAddress.longitude])
+        marker.bindPopup(`<b>${s.name}</b><br/>${s.mapAddress.postalCode} ${s.mapAddress.addressCity}<br/><a href="${s.website}" target="_blank">${s.website}</a>`)
         clusters.addLayer(marker)
       }
       this.map.addLayer(clusters)
@@ -167,12 +167,13 @@ export default Vue.extend({
       const coords: L.LatLngBoundsLiteral = this.structures.filter(
         (s: Structure) => {
           return (
-            s.latitude && typeof s.latitude !== 'undefined' &&
-            s.longitude && typeof s.latitude !== 'undefined'
+            s.mapAddress !== null &&
+            s.mapAddress.latitude && typeof s.mapAddress.latitude !== 'undefined' &&
+            s.mapAddress.longitude && typeof s.mapAddress.latitude !== 'undefined'
           )
         }
       ).map(
-        (s: Structure) => { return [s.latitude as number, s.longitude as number] as L.LatLngTuple }
+        (s: Structure) => { return [(s.mapAddress as Address).latitude as number, (s.mapAddress as Address).longitude as number] as L.LatLngTuple }
       )
 
       if (!(coords.length > 0)) {

+ 2 - 2
components/Ui/Search/Address.vue

@@ -91,10 +91,10 @@ export default Vue.extend({
   },
   data () {
     return {
-      model: null as Address | null,
+      model: null as UiSearchAddressItem | null,
       search: null,
       features: [] as Array<Feature>,
-      items: [] as Array<Address>,
+      items: [] as Array<UiSearchAddressItem>,
       loading: false,
       errorMsg: '',
       geolocalized: false

+ 4 - 4
pages/structures/_id.vue

@@ -126,9 +126,9 @@
                 <font-awesome-icon class="icon" :icon="['fas', 'map-marker-alt']" />
               </td>
               <td class="mx-2">
-                <span v-if="structure.streetAddress">{{ structure.streetAddress }}<br></span>
-                <span v-if="structure.postalCode">{{ structure.postalCode }} </span>
-                {{ structure.addressCity }}
+                <span v-if="structure.postalAddress.streetAddress">{{ structure.postalAddress.streetAddress }}<br></span>
+                <span v-if="structure.postalAddress.postalCode">{{ structure.postalAddress.postalCode }} </span>
+                {{ structure.postalAddress.addressCity }}
               </td>
             </tr>
             <tr>
@@ -213,7 +213,7 @@
                 >
                   <l-popup>
                     <b>{{ structure.name }}</b><br>
-                    {{ structure.postalCode }} {{ structure.addressCity }}<br>
+                    {{ structure.mapAddress.postalCode }} {{ structure.mapAddress.addressCity }}<br>
                     <a :href="structure.website" target="_blank">{{ structure.website }}</a>
                   </l-popup>
                 </l-marker>

+ 20 - 16
pages/structures/index.vue

@@ -198,7 +198,7 @@
                     outlined
                     :class="'structure-card pa-3 d-flex ' + ((mapview || $vuetify.breakpoint.smAndDown) ? 'flex-column' : 'flex-row align-items-center')"
                   >
-                    <div class="d-flex justify-center max-w100" >
+                    <div class="d-flex justify-center max-w100">
                       <v-img
                         v-if="structure.logoId"
                         :src="'https://api.opentalent.fr/app.php/_internal/secure/files/' + structure.logoId"
@@ -209,11 +209,10 @@
                         :contain="true"
                         style="margin: 12px;"
                       />
-                      <div v-else style="height: 104px; width: 264px"></div>
+                      <div v-else style="height: 104px; width: 264px" />
                     </div>
 
                     <div :class="'d-flex flex-column' + (listview ? ' flex-grow-1' : '')">
-
                       <v-card-title class="title">
                         <nuxt-link :to="{path: '/structures/' + structure.id, query: { parent: parent, view: view, theme: theme }}">
                           {{ structure.name }}
@@ -227,9 +226,9 @@
                               <font-awesome-icon class="icon" :icon="['fas', 'map-marker-alt']" />
                             </td>
                             <td>
-                              <span v-if="structure.streetAddress">{{ structure.streetAddress }}<br></span>
-                              <span v-if="structure.postalCode" class="postalCode">{{ structure.postalCode }} </span>
-                              {{ structure.addressCity }}
+                              <span v-if="structure.mapAddress.streetAddress">{{ structure.mapAddress.streetAddress }}<br></span>
+                              <span v-if="structure.mapAddress.postalCode" class="postalCode">{{ structure.mapAddress.postalCode }} </span>
+                              {{ structure.mapAddress.addressCity }}
                             </td>
                           </tr>
                           <tr>
@@ -486,12 +485,15 @@ export default Vue.extend({
      */
     matchLocationFilter (structure: Structure): boolean {
       if (!this.locationFilter) { return true }
-      if (!structure.latitude || !structure.longitude) { return false }
+      if (structure.mapAddress === null || !structure.mapAddress.latitude || !structure.mapAddress.longitude) { return false }
 
       const radius = Number(this.distanceFilter) ?? 5
 
       return sphericDistance(
-        this.locationFilter.latitude, this.locationFilter.longitude, structure.latitude, structure.longitude
+        this.locationFilter.latitude,
+        this.locationFilter.longitude,
+        structure.mapAddress.latitude,
+        structure.mapAddress.longitude
       ) <= radius
     },
     /**
@@ -510,10 +512,12 @@ export default Vue.extend({
      */
     matchDepartmentFilter (structure: Structure): boolean {
       if (!this.departmentFilter) { return true }
-      return structure.postalCode !== null &&
+      return structure.mapAddress !== null &&
+        typeof structure.mapAddress.postalCode !== 'undefined' &&
+        structure.mapAddress.postalCode !== null &&
         (
-          structure.postalCode.startsWith(this.departmentFilter) ||
-          (['2A', '2B'].includes(this.departmentFilter) && structure.postalCode.startsWith('20'))
+          structure.mapAddress.postalCode.startsWith(this.departmentFilter) ||
+          (['2A', '2B'].includes(this.departmentFilter) && structure.mapAddress.postalCode.startsWith('20'))
         )
     },
     /**
@@ -532,11 +536,11 @@ export default Vue.extend({
      */
     matchMapBounds (structure: Structure): boolean {
       if (!this.mapBoundsFilter) { return true }
-      if (!(structure.latitude && structure.longitude)) { return false }
-      return this.mapBoundsFilter.getSouth() <= structure.latitude &&
-             structure.latitude <= this.mapBoundsFilter.getNorth() &&
-             this.mapBoundsFilter.getWest() <= structure.longitude &&
-             structure.longitude <= this.mapBoundsFilter.getEast()
+      if (structure.mapAddress === null || !(structure.mapAddress.latitude && structure.mapAddress.longitude)) { return false }
+      return this.mapBoundsFilter.getSouth() <= structure.mapAddress.latitude &&
+             structure.mapAddress.latitude <= this.mapBoundsFilter.getNorth() &&
+             this.mapBoundsFilter.getWest() <= structure.mapAddress.longitude &&
+             structure.mapAddress.longitude <= this.mapBoundsFilter.getEast()
     },
     /**
      * Does the structure match each of the page filters

+ 14 - 0
services/data/StructuresProvider.ts

@@ -1,4 +1,5 @@
 import BaseProvider from '~/services/data/BaseProvider'
+import Address from '~/components/Ui/Search/Address.vue'
 
 class StructuresProvider extends BaseProvider {
   protected normalize (s: any) : Structure {
@@ -8,6 +9,19 @@ class StructuresProvider extends BaseProvider {
     s.n4Id = s.n4Id ? parseInt(s.n4Id) : null
     s.n5Id = s.n5Id ? parseInt(s.n5Id) : null
     s.practices = s.practices ? s.practices.split(',') : []
+    s.addresses = (s.addresses && s.addresses !== '{}') ? JSON.parse('[' + s.addresses + ']') : []
+
+    // Define the map address according to priorities
+    s.mapAddress = s.addresses.find((a: Address) => { return a.type === 'ADDRESS_PRACTICE' }) ||
+                   s.addresses.find((a: Address) => { return a.type === 'ADDRESS_HEAD_OFFICE' }) ||
+                   s.addresses.find((a: Address) => { return a.type === 'ADDRESS_CONTACT' }) ||
+                   null
+
+    // Define the postal address according to priorities
+    s.postalAddress = s.addresses.find((a: Address) => { return a.type === 'ADDRESS_CONTACT' }) ||
+                      s.addresses.find((a: Address) => { return a.type === 'ADDRESS_HEAD_OFFICE' }) ||
+                      null
+
     s.latitude = s.latitude ? parseFloat(s.latitude) : null
     s.longitude = s.longitude ? parseFloat(s.longitude) : null
     s.parents = s.parents ? s.parents.split(',').map((i: string) => Number(i)) : []

+ 16 - 7
types/interfaces.d.ts

@@ -1,18 +1,27 @@
 /**
  * Structures data as returned by the API and consumed by the structures page
  */
+
+interface Address {
+  type: string,
+  // type: 'ADDRESS_PRACTICE' | 'ADDRESS_OTHER' | 'ADDRESS_HEAD_OFFICE' | 'ADDRESS_CONTACT' | 'ADDRESS_BILL',
+  latitude: number,
+  longitude: number,
+  streetAddress: string,
+  postalCode: string,
+  addressCity: string,
+  country: string
+}
+
 interface Structure {
   readonly id: number,
   name: string,
   logoId: string | null,
   principalType: string | null,
   website: string | null,
-  latitude: number | null,
-  longitude: number | null,
-  streetAddress: string | null,
-  postalCode: string | null,
-  addressCity: string | null,
-  country: string | null,
+  mapAddress: Address | null,
+  postalAddress: Address | null,
+  addresses: Array<Address>,
   telphone: string | null,
   email: string | null,
   facebook: string | null,
@@ -40,7 +49,7 @@ interface Coordinates {
 /**
  * Items of the UiSearchAddress component
  */
-interface Address {
+interface UiSearchAddressItem {
   text: string,
   value: Coordinates,
   disabled?: boolean