From a0d1ff05cca1dd51e20d50e3066521122a4e8b88 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Mon, 24 Mar 2025 17:10:08 +0100 Subject: [PATCH 01/11] adapt existing search demo to dupplicate queries to localities PR deploy --- samples/localities-search/index.njk | 3 +- samples/localities-search/index.ts | 48 +++++++++++++++++++++++----- samples/localities-search/style.scss | 36 +++++++++++++++++++++ 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/samples/localities-search/index.njk b/samples/localities-search/index.njk index d25cc684..3e9a0d14 100644 --- a/samples/localities-search/index.njk +++ b/samples/localities-search/index.njk @@ -25,7 +25,8 @@ - + + {% include '../../src/_includes/country-selector.njk' %} diff --git a/samples/localities-search/index.ts b/samples/localities-search/index.ts index e7dea6fc..dc5e16d3 100644 --- a/samples/localities-search/index.ts +++ b/samples/localities-search/index.ts @@ -4,6 +4,8 @@ let marker: woosmap.map.Marker; let infoWindow: woosmap.map.InfoWindow; let localitiesService: woosmap.map.LocalitiesService; let debouncedLocalitiesSearch: (...args: any[]) => Promise; +let debouncedPRSearch: (...args: any[]) => Promise; +let PR_NUMBER = "1234" let input: string; let detailsHTML: HTMLElement; let detailsResultContainer: HTMLElement; @@ -36,6 +38,7 @@ function initMap(): void { localitiesService = new window.woosmap.map.LocalitiesService(); debouncedLocalitiesSearch = debouncePromise(fetchLocalitiesSearch, 0); + debouncedPRSearch = debouncePromise(fetchPRSearch, 0); manageCountrySelector(); } @@ -59,6 +62,26 @@ https://api.woosmap.com/localities/search?types=point_of_interest|locality|admin } }; +const fetchPRSearch = async (input: any): Promise => { + const center = map.getCenter(); + const radius = map.getZoom() > 10 ? (map.getZoom() > 14 ? "1000" : "10000") : "100000"; + const componentsArgs: string = (componentsRestriction.country as string[]) + .map((country) => `country:${country}`) + .join("|"); + + + try { + const response = await fetch( + ` +https://develop-api.woosmap.com/${PR_NUMBER}/localities/search?types=point_of_interest|locality|admin_level|postal_code|address&input=${encodeURIComponent(input)}&location=${center.lat()},${center.lng()}&radius=${radius}&key=woos-b2f35903-92d8-3a95-9b35-dd503c752a51&components=${componentsArgs}` + ); + return await response.json(); + } catch (error) { + console.error("Error fetching PR:", error); + throw error; + } +}; + function fillDetailsResult(detailsResult: any) { const details: string[] = []; detailsHTML.innerHTML = ""; @@ -105,6 +128,9 @@ const inputElement = document.getElementById( const suggestionsList = document.getElementById( "suggestions-list" ) as HTMLUListElement; +const prSuggestionsList = document.getElementById( + "pr-suggestions-list" +) as HTMLUListElement; const clearSearchBtn = document.getElementsByClassName( "clear-searchButton" )[0] as HTMLButtonElement; @@ -145,6 +171,11 @@ function handleAutocomplete(): void { .catch((error) => console.error("Error autocomplete localities:", error) ); + debouncedPRSearch(input) + .then((results) => displaySuggestions(results, prSuggestionsList)) + .catch((error) => + console.error("Error autocomplete localities:", error) + ); } else { suggestionsList.style.display = "none"; clearSearchBtn.style.display = "none"; @@ -190,9 +221,12 @@ function displayResult(result: woosmap.map.localities.LocalitiesDetailsResult) { } } -function displaySuggestions(localitiesPredictions: any) { +function displaySuggestions(localitiesPredictions: any, container:any=null) { + if (container == null) { + container=suggestionsList + } if (inputElement && suggestionsList) { - suggestionsList.innerHTML = ""; + container.innerHTML = ""; if (localitiesPredictions.results.length > 0 && input) { localitiesPredictions.results.forEach((result) => { const li = document.createElement("li"); @@ -204,10 +238,10 @@ function displaySuggestions(localitiesPredictions: any) { desc.className = "localities-search-description"; li.addEventListener("click", () => { inputElement.value = result.title ?? ""; - suggestionsList.style.display = "none"; + container.style.display = "none"; handleDetails(result.public_id); }); - suggestionsList.appendChild(li); + container.appendChild(li); li.appendChild(title); title.appendChild(desc); if (result.categories) { @@ -222,10 +256,10 @@ function displaySuggestions(localitiesPredictions: any) { title.appendChild(type); } }); - suggestionsList.style.display = "block"; + container.style.display = "block"; clearSearchBtn.style.display = "block"; } else { - suggestionsList.style.display = "none"; + container.style.display = "none"; } } } @@ -242,7 +276,6 @@ document.addEventListener("click", (event) => { }); // [START woosmap_localities_search_debounce_promise] -let PRESERVE_COMMENT_ABOVE; // force tsc to maintain the comment above eslint-disable-line type DebouncePromiseFunction = ( ...args: Args @@ -281,7 +314,6 @@ function debouncePromise( } // [END woosmap_localities_search_debounce_promise] */ -PRESERVE_COMMENT_ABOVE; // force tsc to maintain the comment above eslint-disable-line declare global { interface Window { diff --git a/samples/localities-search/style.scss b/samples/localities-search/style.scss index 729e9f05..7cae16e2 100644 --- a/samples/localities-search/style.scss +++ b/samples/localities-search/style.scss @@ -92,6 +92,42 @@ body { align-self: flex-end; } +.suggestions-list { + border-radius: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); + box-sizing: border-box; + position: absolute; + max-width: 320px; + width: 100%; + top: 100%; + left: 0; + z-index: 1; + list-style: none; + max-height: 80vh; + margin: 5px 0 0; + padding: 0; + display: none; + overflow-y: auto; + background-color: #fff; +} + +#pr-suggestion-list.suggestion-list { + left:325px +} +.suggestions-list.visible { + display: block; +} + +.suggestions-list li { + padding: 12px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.suggestions-list li:hover { + background-color: #f2f2f2; +} + .detailsResult { display: none; From 55e1a81c5d103062c1a666cc4dd32d24cb254473 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Mon, 24 Mar 2025 18:32:12 +0100 Subject: [PATCH 02/11] missing semi-coma in css --- samples/localities-search/style.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/localities-search/style.scss b/samples/localities-search/style.scss index 7cae16e2..6333aec4 100644 --- a/samples/localities-search/style.scss +++ b/samples/localities-search/style.scss @@ -112,8 +112,9 @@ body { } #pr-suggestion-list.suggestion-list { - left:325px + left:325px; } + .suggestions-list.visible { display: block; } From 53c74a4a4ac6e486ef4166f93c70cbc316357a84 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Tue, 25 Mar 2025 09:14:23 +0100 Subject: [PATCH 03/11] fix class name --- samples/localities-search/index.njk | 4 ++-- samples/localities-search/style.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/localities-search/index.njk b/samples/localities-search/index.njk index 3e9a0d14..6dcdbfb5 100644 --- a/samples/localities-search/index.njk +++ b/samples/localities-search/index.njk @@ -25,8 +25,8 @@ -
    -
      +
        +
          {% include '../../src/_includes/country-selector.njk' %} diff --git a/samples/localities-search/style.scss b/samples/localities-search/style.scss index 6333aec4..8b3eaf23 100644 --- a/samples/localities-search/style.scss +++ b/samples/localities-search/style.scss @@ -111,7 +111,7 @@ body { background-color: #fff; } -#pr-suggestion-list.suggestion-list { +#pr-suggestions-list.suggestions-list { left:325px; } From 7719f5a4ef7fabcf7da84858a0ecd49feb5876f3 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Tue, 25 Mar 2025 12:59:15 +0100 Subject: [PATCH 04/11] adapt geocode demo to hit both prod and PR deploy and show both results --- samples/localities-geocode/index.ts | 80 ++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index c2ab6083..2f46ce79 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -1,8 +1,13 @@ // [START woosmap_localities_geocode] // Initialize and add the map +import LocalitiesGeocodeRequest = woosmap.map.localities.LocalitiesGeocodeRequest; + let map: woosmap.map.Map; let marker: woosmap.map.Marker; let infoWindow: woosmap.map.InfoWindow; +let pr_marker: woosmap.map.Marker; +let pr_infoWindow: HTMLElement | null; +let PR_NUMBER = "1216" let localitiesService: woosmap.map.LocalitiesService; const request: woosmap.map.localities.LocalitiesGeocodeRequest = {}; @@ -15,6 +20,7 @@ function initMap() { }, ); infoWindow = new woosmap.map.InfoWindow({}); + pr_infoWindow = document.getElementById("instructions") localitiesService = new woosmap.map.LocalitiesService(); map.addListener("click", (e) => { handleGeocode(e.latlng); @@ -49,9 +55,49 @@ clearSearchBtn.addEventListener("click", () => { marker.setMap(null); infoWindow.close(); } + if (pr_marker) { + pr_marker.setMap(null); + } inputElement.focus(); }); +function buildQueryString(params: object) { + const queryStringParts = []; + + for (const key in params) { + if (params[key]) { + const value = params[key]; + queryStringParts.push( + `${encodeURIComponent(key)}=${encodeURIComponent(value)}` as never, + ); + } + } + return queryStringParts.join("&"); +} + +const pr_reverse_geocode = async (latLng:woosmap.map.LatLngLiteral|woosmap.map.LatLng): Promise => { + let params = { + "latlng": `${latLng.lat},${latLng.lng}`, + "key": "woos-b2f35903-92d8-3a95-9b35-dd503c752a51" + } + if(request.components) { + params["components"] = (request.components.country as string[]) + .map((country) => `country:${country}`) + .join("|"); + } + + try { + const response = await fetch( + ` +https://develop-api.woosmap.com/${PR_NUMBER}/localities/geocode?${buildQueryString(params)}` + ); + return await response.json(); + } catch (error) { + console.error("Error fetching PR:", error); + throw error; + } +}; + function handleGeocode(latlng: woosmap.map.LatLngLiteral | null) { if (latlng) { request.latLng = latlng; @@ -66,6 +112,10 @@ function handleGeocode(latlng: woosmap.map.LatLngLiteral | null) { .geocode(request) .then((localities) => displayLocality(localities.results[0])) .catch((error) => console.error("Error geocoding localities:", error)); + if (request.latLng) { + pr_reverse_geocode(request.latLng).then((localities) => displayPRLocality(localities.results[0])) + .catch((error) => console.error("Error geocoding localities:", error)); + } } } @@ -92,7 +142,35 @@ function displayLocality( infoWindow.setContent(`${locality.formatted_address}`); infoWindow.open(map, marker); map.setCenter(locality.geometry.location); - map.setZoom(14); + if (map.getZoom() < 14) { + map.setZoom(14); + } + } +} + +function displayPRLocality( + locality: woosmap.map.localities.LocalitiesGeocodeResult | null, +) { + if (pr_marker) { + pr_marker.setMap(null); + } + + if (locality?.geometry) { + pr_marker = new woosmap.map.Marker({ + position: locality.geometry.location, + icon: { + url: "https://images.woosmap.com/marker-red.png", + scaledSize: { + height: 50, + width: 32, + }, + }, + }); + pr_marker.setMap(map); + if (pr_infoWindow) { + pr_infoWindow.textContent = `[PR says] ${locality.formatted_address} (red marker)`; + } + } } From 62c9d0a9a53deca14ca63fdb51c8b0050edd7120 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Tue, 25 Mar 2025 13:03:10 +0100 Subject: [PATCH 05/11] center on italy --- samples/localities-geocode/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index 2f46ce79..58dde252 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -15,7 +15,7 @@ function initMap() { map = new window.woosmap.map.Map( document.getElementById("map") as HTMLElement, { - center: { lat: 51.50940214, lng: -0.133012 }, + center: { lat: 43.77751768293183, lng: 11.2553439740075 }, zoom: 12, }, ); From d0a85356b1ff2dd616dc23afde26b90bef2d0f52 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Wed, 26 Mar 2025 10:00:17 +0100 Subject: [PATCH 06/11] adapt advanced autocomplete to compare prod and PR deploy --- .../index.njk | 3 +- .../index.ts | 50 ++++++++++++++++--- .../style.scss | 3 ++ shared/scss/_autocomplete_list.scss | 33 ++++++++++++ 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/samples/localities-api-autocomplete-advanced/index.njk b/samples/localities-api-autocomplete-advanced/index.njk index 41d201df..f94b3506 100644 --- a/samples/localities-api-autocomplete-advanced/index.njk +++ b/samples/localities-api-autocomplete-advanced/index.njk @@ -18,7 +18,8 @@ -
            +
              +
                
                diff --git a/samples/localities-api-autocomplete-advanced/index.ts b/samples/localities-api-autocomplete-advanced/index.ts
                index 473ce870..b38990aa 100644
                --- a/samples/localities-api-autocomplete-advanced/index.ts
                +++ b/samples/localities-api-autocomplete-advanced/index.ts
                @@ -4,8 +4,13 @@ const woosmap_key = "YOUR_API_KEY";
                 let debouncedAutocomplete: (
                   ...args: any[]
                 ) => Promise;
                +let debouncedAutocompletePR: (
                +  ...args: any[]
                +) => Promise;
                +let PR_NUMBER= "1237"
                 let inputElement: HTMLInputElement;
                 let suggestionsList: HTMLUListElement;
                +let prSuggestionsList: HTMLUListElement;
                 let clearSearchBtn: HTMLButtonElement;
                 let responseElement: HTMLElement;
                 
                @@ -29,6 +34,7 @@ function init(): void {
                     inputElement.focus();
                   });
                   debouncedAutocomplete = debouncePromise(autocompleteAddress, 0);
                +  debouncedAutocompletePR = debouncePromise(autocompleteAddressPR, 0);
                 }
                 
                 function handleAutocomplete(): void {
                @@ -45,8 +51,14 @@ function handleAutocomplete(): void {
                         .catch((error) =>
                           console.error("Error autocomplete localities:", error),
                         );
                +      debouncedAutocompletePR(input, componentsArgs, woosmap_key)
                +        .then(({ localities }) => displaySuggestions(localities, prSuggestionsList))
                +        .catch((error) =>
                +          console.error("Error autocomplete localities:", error),
                +        );
                     } else {
                       suggestionsList.style.display = "none";
                +      prSuggestionsList.style.display = "none";
                       clearSearchBtn.style.display = "none";
                     }
                   }
                @@ -54,24 +66,25 @@ function handleAutocomplete(): void {
                 
                 function displaySuggestions(
                   localitiesPredictions: woosmap.map.localities.LocalitiesPredictions[],
                +  container: HTMLUListElement = suggestionsList
                 ) {
                -  if (inputElement && suggestionsList) {
                -    suggestionsList.innerHTML = "";
                +  if (inputElement && container) {
                +    container.innerHTML = "";
                     if (localitiesPredictions.length > 0) {
                       localitiesPredictions.forEach((locality) => {
                         const li = document.createElement("li");
                         li.innerHTML = formatPredictionList(locality) ?? "";
                         li.addEventListener("click", () => {
                           inputElement.value = locality.description ?? "";
                -          suggestionsList.style.display = "none";
                +          container.style.display = "none";
                           displayLocalitiesResponse(locality);
                         });
                -        suggestionsList.appendChild(li);
                +        container.appendChild(li);
                       });
                -      suggestionsList.style.display = "block";
                +      container.style.display = "block";
                       clearSearchBtn.style.display = "block";
                     } else {
                -      suggestionsList.style.display = "none";
                +      container.style.display = "none";
                     }
                   }
                 }
                @@ -147,6 +160,28 @@ function autocompleteAddress(
                   ).then((response) => response.json());
                 }
                 
                +function autocompleteAddressPR(
                +  input: string,
                +  components: string,
                +  woosmap_key: string,
                +): Promise {
                +  const args = {
                +    key: "woos-b2f35903-92d8-3a95-9b35-dd503c752a51",
                +    input,
                +    types: "locality|postal_code|address",
                +    components: "country:fr|country:gb|country:it|country:es|country:de",
                +  };
                +
                +  if (components !== "") {
                +    if (args["components"]) {
                +      args["components"] = components;
                +    }
                +  }
                +  return fetch(
                +    `https://develop-api.woosmap.com/${PR_NUMBER}/localities/autocomplete/?${buildQueryString(args)}`,
                +  ).then((response) => response.json());
                +}
                +
                 function buildQueryString(params: object) {
                   const queryStringParts = [];
                 
                @@ -204,6 +239,9 @@ document.addEventListener("DOMContentLoaded", () => {
                   suggestionsList = document.getElementById(
                     "suggestions-list",
                   ) as HTMLUListElement;
                +  prSuggestionsList = document.getElementById(
                +    "pr-suggestions-list",
                +  ) as HTMLUListElement;
                   clearSearchBtn = document.getElementsByClassName(
                     "clear-searchButton",
                   )[0] as HTMLButtonElement;
                diff --git a/samples/localities-api-autocomplete-advanced/style.scss b/samples/localities-api-autocomplete-advanced/style.scss
                index 242e5681..ef15bdf6 100644
                --- a/samples/localities-api-autocomplete-advanced/style.scss
                +++ b/samples/localities-api-autocomplete-advanced/style.scss
                @@ -6,4 +6,7 @@
                 @include meta.load-css("../../shared/scss/_autocomplete_list.scss");
                 @include meta.load-css("../../shared/scss/_autocomplete_without_map.scss");
                 
                +#pr-suggestions-list.suggestions-list {
                +  left:325px;
                +}
                 /* [END woosmap_localities_api_autocomplete_advanced] */
                diff --git a/shared/scss/_autocomplete_list.scss b/shared/scss/_autocomplete_list.scss
                index 6246f6eb..eb42cc33 100644
                --- a/shared/scss/_autocomplete_list.scss
                +++ b/shared/scss/_autocomplete_list.scss
                @@ -30,3 +30,36 @@
                 #suggestions-list li:hover {
                   background-color: #f2f2f2;
                 }
                +
                +.suggestions-list {
                +  border-radius: 12px;
                +  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02);
                +  box-sizing: border-box;
                +  position: absolute;
                +  max-width: 320px;
                +  width: 100%;
                +  top: 100%;
                +  left: 0;
                +  z-index: 1;
                +  list-style: none;
                +  max-height: 80vh;
                +  margin: 5px 0 0;
                +  padding: 0;
                +  display: none;
                +  overflow-y: auto;
                +  background-color: #fff;
                +
                +  &.visible {
                +    display: block;
                +  }
                +}
                +
                +.suggestions-list li {
                +  padding: 12px;
                +  cursor: pointer;
                +  transition: background-color 0.3s ease;
                +}
                +
                +.suggestions-list li:hover {
                +  background-color: #f2f2f2;
                +}
                
                From 2d6a279fffa99dca5276d5414a89270ca5b0243b Mon Sep 17 00:00:00 2001
                From: christopher dartnell 
                Date: Wed, 26 Mar 2025 17:27:21 +0100
                Subject: [PATCH 07/11] enable PR/develop selection on adapted samples
                 (autocomplete-adv, geocode & search)
                
                ---
                 .../index.njk                                 |  10 +-
                 .../index.ts                                  |  12 +-
                 .../style.scss                                |   6 +-
                 samples/localities-geocode/index.njk          |  14 ++-
                 samples/localities-geocode/index.ts           |  11 +-
                 samples/localities-geocode/style.scss         |  15 ++-
                 samples/localities-search/index.njk           |  19 ++-
                 samples/localities-search/index.ts            |  13 +-
                 samples/localities-search/style.scss          |  17 ++-
                 shared/scss/_autocomplete_list.scss           |  32 -----
                 shared/scss/_pr_test.scss                     | 111 ++++++++++++++++++
                 11 files changed, 204 insertions(+), 56 deletions(-)
                 create mode 100644 shared/scss/_pr_test.scss
                
                diff --git a/samples/localities-api-autocomplete-advanced/index.njk b/samples/localities-api-autocomplete-advanced/index.njk
                index f94b3506..645e442d 100644
                --- a/samples/localities-api-autocomplete-advanced/index.njk
                +++ b/samples/localities-api-autocomplete-advanced/index.njk
                @@ -7,7 +7,7 @@
                             Restrictions on "locality|postal_code|address", country "fr|gb|it|es|de"
                         

                -
                +
                {% svgIcon 'search.svg' %}
                  +
                  
                       
                  diff --git a/samples/localities-api-autocomplete-advanced/index.ts b/samples/localities-api-autocomplete-advanced/index.ts index b38990aa..b11d4361 100644 --- a/samples/localities-api-autocomplete-advanced/index.ts +++ b/samples/localities-api-autocomplete-advanced/index.ts @@ -7,7 +7,6 @@ let debouncedAutocomplete: ( let debouncedAutocompletePR: ( ...args: any[] ) => Promise; -let PR_NUMBER= "1237" let inputElement: HTMLInputElement; let suggestionsList: HTMLUListElement; let prSuggestionsList: HTMLUListElement; @@ -160,6 +159,14 @@ function autocompleteAddress( ).then((response) => response.json()); } +function getSecondaryUrl():string { + let secondary_target = document.getElementById("secondary-target") as HTMLInputElement + if (secondary_target && secondary_target.value) { + return `https://develop-api.woosmap.com/${secondary_target.value}` + } + return "https://develop-api.woosmap.com" +} + function autocompleteAddressPR( input: string, components: string, @@ -177,8 +184,9 @@ function autocompleteAddressPR( args["components"] = components; } } + return fetch( - `https://develop-api.woosmap.com/${PR_NUMBER}/localities/autocomplete/?${buildQueryString(args)}`, + `${getSecondaryUrl()}/localities/autocomplete/?${buildQueryString(args)}`, ).then((response) => response.json()); } diff --git a/samples/localities-api-autocomplete-advanced/style.scss b/samples/localities-api-autocomplete-advanced/style.scss index ef15bdf6..4091c512 100644 --- a/samples/localities-api-autocomplete-advanced/style.scss +++ b/samples/localities-api-autocomplete-advanced/style.scss @@ -2,11 +2,9 @@ /* [START woosmap_localities_api_autocomplete_advanced] */ @include meta.load-css("../../shared/scss/_default.scss"); -@include meta.load-css("../../shared/scss/_autocomplete_input.scss"); +/*@include meta.load-css("../../shared/scss/_autocomplete_input.scss");*/ @include meta.load-css("../../shared/scss/_autocomplete_list.scss"); @include meta.load-css("../../shared/scss/_autocomplete_without_map.scss"); +@include meta.load-css("../../shared/scss/_pr_test.scss"); -#pr-suggestions-list.suggestions-list { - left:325px; -} /* [END woosmap_localities_api_autocomplete_advanced] */ diff --git a/samples/localities-geocode/index.njk b/samples/localities-geocode/index.njk index de919713..ef5d85a5 100644 --- a/samples/localities-geocode/index.njk +++ b/samples/localities-geocode/index.njk @@ -2,6 +2,8 @@ {% block html %}
                  +
                  +
                  {% svgIcon 'search.svg' %}
                  - + +
                  Enter an address to geocode or click on the map to reverse geocode.
                  -
                  +
                  {% endblock %} diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index 58dde252..411b75fd 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -7,7 +7,6 @@ let marker: woosmap.map.Marker; let infoWindow: woosmap.map.InfoWindow; let pr_marker: woosmap.map.Marker; let pr_infoWindow: HTMLElement | null; -let PR_NUMBER = "1216" let localitiesService: woosmap.map.LocalitiesService; const request: woosmap.map.localities.LocalitiesGeocodeRequest = {}; @@ -74,6 +73,13 @@ function buildQueryString(params: object) { } return queryStringParts.join("&"); } +function getSecondaryUrl():string { + let secondary_target = document.getElementById("secondary-target") as HTMLInputElement + if (secondary_target && secondary_target.value) { + return `https://develop-api.woosmap.com/${secondary_target.value}` + } + return "https://develop-api.woosmap.com" +} const pr_reverse_geocode = async (latLng:woosmap.map.LatLngLiteral|woosmap.map.LatLng): Promise => { let params = { @@ -88,8 +94,7 @@ const pr_reverse_geocode = async (latLng:woosmap.map.LatLngLiteral|woosmap.map.L try { const response = await fetch( - ` -https://develop-api.woosmap.com/${PR_NUMBER}/localities/geocode?${buildQueryString(params)}` + `${getSecondaryUrl()}/localities/geocode?${buildQueryString(params)}` ); return await response.json(); } catch (error) { diff --git a/samples/localities-geocode/style.scss b/samples/localities-geocode/style.scss index 0a3a943c..baa978c4 100644 --- a/samples/localities-geocode/style.scss +++ b/samples/localities-geocode/style.scss @@ -2,13 +2,24 @@ /* [START woosmap_localities_geocode] */ @include meta.load-css("../../shared/scss/_default.scss"); -@include meta.load-css("../../shared/scss/_autocomplete_input.scss"); +/* @include meta.load-css("../../shared/scss/_autocomplete_input.scss");*/ @import "../../shared/scss/mixins.scss"; +@include meta.load-css("../../shared/scss/_pr_test.scss"); #app { height: 100%; } - +#map{ + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +.search-container { + top: 10px; + left: 10px; +} .btn { @include button($background: #3d5afe, $display: inline, $position: relative, $height: 38px); } diff --git a/samples/localities-search/index.njk b/samples/localities-search/index.njk index 6dcdbfb5..d13af8dd 100644 --- a/samples/localities-search/index.njk +++ b/samples/localities-search/index.njk @@ -11,9 +11,7 @@
                  -
                  -
                  -
                  +
                  {% svgIcon 'search.svg' %}
                    - {% include '../../src/_includes/country-selector.njk' %} + + + {% include '../../src/_includes/country-selector.njk' %} +
                    +
                    +
                    +
                    {% endblock %} diff --git a/samples/localities-search/index.ts b/samples/localities-search/index.ts index dc5e16d3..4d931c9f 100644 --- a/samples/localities-search/index.ts +++ b/samples/localities-search/index.ts @@ -5,7 +5,6 @@ let infoWindow: woosmap.map.InfoWindow; let localitiesService: woosmap.map.LocalitiesService; let debouncedLocalitiesSearch: (...args: any[]) => Promise; let debouncedPRSearch: (...args: any[]) => Promise; -let PR_NUMBER = "1234" let input: string; let detailsHTML: HTMLElement; let detailsResultContainer: HTMLElement; @@ -62,6 +61,14 @@ https://api.woosmap.com/localities/search?types=point_of_interest|locality|admin } }; +function getSecondaryUrl():string { + let secondary_target = document.getElementById("secondary-target") as HTMLInputElement + if (secondary_target && secondary_target.value) { + return `https://develop-api.woosmap.com/${secondary_target.value}` + } + return "https://develop-api.woosmap.com" +} + const fetchPRSearch = async (input: any): Promise => { const center = map.getCenter(); const radius = map.getZoom() > 10 ? (map.getZoom() > 14 ? "1000" : "10000") : "100000"; @@ -72,8 +79,7 @@ const fetchPRSearch = async (input: any): Promise => { try { const response = await fetch( - ` -https://develop-api.woosmap.com/${PR_NUMBER}/localities/search?types=point_of_interest|locality|admin_level|postal_code|address&input=${encodeURIComponent(input)}&location=${center.lat()},${center.lng()}&radius=${radius}&key=woos-b2f35903-92d8-3a95-9b35-dd503c752a51&components=${componentsArgs}` + `${getSecondaryUrl()}/localities/search?types=point_of_interest|locality|admin_level|postal_code|address&input=${encodeURIComponent(input)}&location=${center.lat()},${center.lng()}&radius=${radius}&key=woos-b2f35903-92d8-3a95-9b35-dd503c752a51&components=${componentsArgs}` ); return await response.json(); } catch (error) { @@ -82,6 +88,7 @@ https://develop-api.woosmap.com/${PR_NUMBER}/localities/search?types=point_of_in } }; + function fillDetailsResult(detailsResult: any) { const details: string[] = []; detailsHTML.innerHTML = ""; diff --git a/samples/localities-search/style.scss b/samples/localities-search/style.scss index 8b3eaf23..b0b373cf 100644 --- a/samples/localities-search/style.scss +++ b/samples/localities-search/style.scss @@ -6,6 +6,7 @@ @include meta.load-css("../../shared/scss/_autocomplete_list.scss"); @include meta.load-css("../../shared/scss/_dropdown.scss"); @import "../../shared/scss/mixins.scss"; +@include meta.load-css("../../shared/scss/_pr_test.scss"); #app { height: 100%; @@ -16,12 +17,21 @@ body { overflow-y: hidden; } -#countrySelector { +#map{ position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +#countrySelector { + left: 10px; + top: 0; +} +.search-container { top: 10px; - left: 335px; + left: 10px; } - .country { .country-name { display: flex; @@ -138,6 +148,7 @@ body { border-radius: 6px; max-width: 240px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); + z-index: 1; overflow: hidden; diff --git a/shared/scss/_autocomplete_list.scss b/shared/scss/_autocomplete_list.scss index eb42cc33..07668489 100644 --- a/shared/scss/_autocomplete_list.scss +++ b/shared/scss/_autocomplete_list.scss @@ -31,35 +31,3 @@ background-color: #f2f2f2; } -.suggestions-list { - border-radius: 12px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); - box-sizing: border-box; - position: absolute; - max-width: 320px; - width: 100%; - top: 100%; - left: 0; - z-index: 1; - list-style: none; - max-height: 80vh; - margin: 5px 0 0; - padding: 0; - display: none; - overflow-y: auto; - background-color: #fff; - - &.visible { - display: block; - } -} - -.suggestions-list li { - padding: 12px; - cursor: pointer; - transition: background-color 0.3s ease; -} - -.suggestions-list li:hover { - background-color: #f2f2f2; -} diff --git a/shared/scss/_pr_test.scss b/shared/scss/_pr_test.scss new file mode 100644 index 00000000..e25cbfd0 --- /dev/null +++ b/shared/scss/_pr_test.scss @@ -0,0 +1,111 @@ +.search-container { + display: flex; + position: relative; + min-height: 45px; +} +#autocomplete-container, .autocomplete-container { + display: flex; + position: initial!important; + margin-right:5px; + z-index: 1; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); + background: #fff; + border-radius: 12px; + padding: 0 12px; + max-width: 320px; + width: 100%; + height: 42px; + border: none; + box-sizing: border-box; + align-items: center; + cursor: text; + font-size: 15px; + + .search-icon, .clear-icon { + color: inherit; + flex-shrink: 0; + height: 16px; + width: 16px; + } + + .clear-icon { + transform: scale(1.3); + } +} + +#secondary-target.autocomplete-input{ + margin-left: 5px; + border-radius: 10px; + border-color: transparent; + height: 38px; + padding: 0 8px; + width: 40px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); +} + +#autocomplete-input { + box-sizing: border-box; + padding: 0; + height: 40px; + line-height: 24px; + vertical-align: top; + transition-property: color; + transition-duration: .3s; + width: 100%; + text-overflow: ellipsis; + background: transparent; + border-radius: 0; + border: 0; + margin: 0 8px; + outline: 0; + overflow: visible; + appearance: textfield; + font-size: 100%; +} +#pr-suggestions-list.suggestions-list { + left:325px; +} + +.clear-searchButton { + display: none; + height: 18px; + width: 22px; + background: none; + border: none; + vertical-align: middle; + pointer-events: all; + cursor: pointer; +} + +.suggestions-list { + border-radius: 12px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 -1px 0px rgba(0, 0, 0, 0.02); + box-sizing: border-box; + position: absolute; + max-width: 320px; + width: 100%; + top: 100%; + left: 0; + z-index: 1; + list-style: none; + max-height: 80vh; + margin: 5px 0 0; + padding: 0; + display: none; + overflow-y: auto; + background-color: #fff; + + &.visible { + display: block; + } +} + +.suggestions-list li { + padding: 12px; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.suggestions-list li:hover { + background-color: #f2f2f2; +} \ No newline at end of file From 802ec76ef723a33a2132c7cac52aed5fda8d3d65 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Thu, 27 Mar 2025 18:17:06 +0100 Subject: [PATCH 08/11] run geocode against pr also, add country selector --- samples/localities-geocode/index.njk | 10 +++ samples/localities-geocode/index.ts | 119 ++++++++++++++++++++++++-- samples/localities-geocode/style.scss | 1 + 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/samples/localities-geocode/index.njk b/samples/localities-geocode/index.njk index ef5d85a5..49a48fd8 100644 --- a/samples/localities-geocode/index.njk +++ b/samples/localities-geocode/index.njk @@ -1,3 +1,12 @@ +---json +{ +"countries": [ +{ "code": "GB", "name": "United Kingdom", "selected": true }, +{ "code": "FR", "name": "France" }, +{ "code": "DZ", "name": "Algeria" } +] +} +--- {% extends '../../src/_includes/layout.njk' %} {% block html %} @@ -23,6 +32,7 @@ class="autocomplete-input" hint="PR number or empty for develop" /> + {% include '../../src/_includes/country-selector.njk' %}
                    Enter an address to geocode or click on the map to reverse geocode. diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index 411b75fd..d146aad6 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -9,6 +9,8 @@ let pr_marker: woosmap.map.Marker; let pr_infoWindow: HTMLElement | null; let localitiesService: woosmap.map.LocalitiesService; const request: woosmap.map.localities.LocalitiesGeocodeRequest = {}; +const componentsRestriction: woosmap.map.localities.LocalitiesComponentRestrictions = + { country: [] }; function initMap() { map = new window.woosmap.map.Map( @@ -24,6 +26,7 @@ function initMap() { map.addListener("click", (e) => { handleGeocode(e.latlng); }); + manageCountrySelector(); } const inputElement = document.getElementById( @@ -81,15 +84,20 @@ function getSecondaryUrl():string { return "https://develop-api.woosmap.com" } -const pr_reverse_geocode = async (latLng:woosmap.map.LatLngLiteral|woosmap.map.LatLng): Promise => { +const pr_reverse_geocode = async (request:LocalitiesGeocodeRequest): Promise => { let params = { - "latlng": `${latLng.lat},${latLng.lng}`, "key": "woos-b2f35903-92d8-3a95-9b35-dd503c752a51" } + if (request.latLng) { + params["latlng"] = `${request.latLng.lat},${request.latLng.lng}`; + } + if (request.address) { + params["address"] = request.address; + } if(request.components) { params["components"] = (request.components.country as string[]) - .map((country) => `country:${country}`) - .join("|"); + .map((country) => `country:${country}`) + .join("|"); } try { @@ -111,16 +119,16 @@ function handleGeocode(latlng: woosmap.map.LatLngLiteral | null) { request.address = inputElement.value; delete request.latLng; } + request.components = componentsRestriction if (request.latLng || request.address) { localitiesService .geocode(request) .then((localities) => displayLocality(localities.results[0])) .catch((error) => console.error("Error geocoding localities:", error)); - if (request.latLng) { - pr_reverse_geocode(request.latLng).then((localities) => displayPRLocality(localities.results[0])) + pr_reverse_geocode(request).then((localities:woosmap.map.localities.LocalitiesGeocodeResponse) => displayPRLocality(localities.results[0])) .catch((error) => console.error("Error geocoding localities:", error)); - } + } } @@ -187,4 +195,101 @@ declare global { window.initMap = initMap; // [END woosmap_localities_geocode] +function manageCountrySelector() { + const countryElements = document.querySelectorAll(".country"); + countryElements.forEach((countryElement: Element) => { + countryElement.addEventListener("click", () => { + toggleCountry(countryElement); + }); + if (countryElement.classList.contains("active")) { + const countryCode = (countryElement as HTMLElement).dataset + .countrycode as string; + componentsRestriction.country = [ + ...(componentsRestriction.country as string[]), + countryCode, + ]; + } + }); + + const dropdownButtons = document.querySelectorAll( + ".dropdown .dropdown-button", + ); + dropdownButtons.forEach((button: Element) => + button.addEventListener("click", toggleDropdown), + ); + + // Hide dropdowns when clicking outside + const dropdowns = document.querySelectorAll(".dropdown"); + document.addEventListener("click", (event: Event) => { + dropdowns.forEach((dropdown: Element) => { + if (!dropdown.contains(event.target as Node)) { + hideDropdown(dropdown); + } + }); + }); +} + +function toggleDropdown(event: Event) { + event.stopPropagation(); + const dropdown = (event.target as Element).closest(".dropdown"); + if (dropdown) { + if (dropdown.classList.contains("active")) { + hideDropdown(dropdown); + } else { + showDropdown(dropdown); + } + } +} + +function hideDropdown(dropdown: Element) { + const dropdownContent = dropdown.querySelector( + ".dropdown-content", + ) as HTMLElement; + dropdownContent?.classList.remove("visible"); + dropdown.classList.remove("active"); +} + +function showDropdown(dropdown: Element) { + const dropdownContent = dropdown.querySelector( + ".dropdown-content", + ) as HTMLElement; + dropdownContent?.classList.add("visible"); + dropdown.classList.add("active"); +} + +function toggleCountry(country: Element) { + const isActive = country.classList.toggle("active"); + const countryCode = (country as HTMLElement).dataset.countrycode; + + if (countryCode) { + if (isActive) { + componentsRestriction.country = [ + ...(componentsRestriction.country as string[]), + countryCode, + ]; + } else { + componentsRestriction.country = ( + componentsRestriction.country as string[] + ).filter((code) => code !== countryCode); + } + updateCountrySelectorText(); + } +} + +function updateCountrySelectorText() { + const dropdownText = document.querySelector( + ".dropdown-button span", + ) as HTMLElement; + const inputPlaceholder = document.querySelector("#autocomplete-input") as HTMLInputElement; + if (componentsRestriction.country.length > 0) { + inputElement.readOnly = false; + dropdownText.innerHTML = `Selected countries: ${(componentsRestriction.country as string[]).join(", ")}`; + inputPlaceholder.placeholder = `Search for a place in ${(componentsRestriction.country as string[]).join(" or ")}...` + } else { + dropdownText.textContent = "Select countries"; + inputElement.readOnly = true; + inputPlaceholder.placeholder = "Select at least one country to proceed." + } +} + export {}; diff --git a/samples/localities-geocode/style.scss b/samples/localities-geocode/style.scss index baa978c4..b031f51a 100644 --- a/samples/localities-geocode/style.scss +++ b/samples/localities-geocode/style.scss @@ -3,6 +3,7 @@ /* [START woosmap_localities_geocode] */ @include meta.load-css("../../shared/scss/_default.scss"); /* @include meta.load-css("../../shared/scss/_autocomplete_input.scss");*/ +@include meta.load-css("../../shared/scss/_dropdown.scss"); @import "../../shared/scss/mixins.scss"; @include meta.load-css("../../shared/scss/_pr_test.scss"); From 6820d2c65c70bdc03f24e048063bd15582cb4d9f Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Fri, 28 Mar 2025 19:21:21 +0100 Subject: [PATCH 09/11] add list sub buildings param, but useless untill we show address lists --- samples/localities-geocode/index.njk | 40 +++++++++++++++------------ samples/localities-geocode/index.ts | 6 +++- samples/localities-geocode/style.scss | 16 ++++++++++- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/samples/localities-geocode/index.njk b/samples/localities-geocode/index.njk index 49a48fd8..d8217399 100644 --- a/samples/localities-geocode/index.njk +++ b/samples/localities-geocode/index.njk @@ -13,26 +13,30 @@
                    -
                    - {% svgIcon 'search.svg' %} +
                    + {% svgIcon 'search.svg' %} + + +
                    - -
                    - - {% include '../../src/_includes/country-selector.njk' %} + {% include '../../src/_includes/country-selector.njk' %} +
                    + + +
                    Enter an address to geocode or click on the map to reverse geocode. diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index d146aad6..920f9f57 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -99,7 +99,11 @@ const pr_reverse_geocode = async (request:LocalitiesGeocodeRequest): Promise `country:${country}`) .join("|"); } - + let list_sub_buildings: HTMLInputElement= document.getElementById("list-sub-buildings") as HTMLInputElement; + if (list_sub_buildings && list_sub_buildings.value) { + console.log("list sub buildings") + params["list_sub_buildings"] = "1"; + } try { const response = await fetch( `${getSecondaryUrl()}/localities/geocode?${buildQueryString(params)}` diff --git a/samples/localities-geocode/style.scss b/samples/localities-geocode/style.scss index b031f51a..05f0c232 100644 --- a/samples/localities-geocode/style.scss +++ b/samples/localities-geocode/style.scss @@ -28,7 +28,21 @@ .btnText { @include actionText($color: #fff); } - +.checkbox-container{ + margin: 0 5px; + border-radius: 10px; + border-color: transparent; + height: 42px; + padding: 0 8px; + align-content: center; + font-size: 14px; + font-weight: 400; + background: #f9fbfd; + box-shadow: 0 2px 4px #0003, 0 -1px #00000005; +} +#countrySelector{ + margin: 0 5px; +} #instructions { max-width: 300px; font-size: 17px; From 60accf7f19378d28d5ac68723bd0fa9242a051f7 Mon Sep 17 00:00:00 2001 From: christopher dartnell Date: Mon, 31 Mar 2025 16:10:26 +0200 Subject: [PATCH 10/11] fix list_sub_buildings --- samples/localities-geocode/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/localities-geocode/index.ts b/samples/localities-geocode/index.ts index 920f9f57..17d98dfb 100644 --- a/samples/localities-geocode/index.ts +++ b/samples/localities-geocode/index.ts @@ -100,7 +100,7 @@ const pr_reverse_geocode = async (request:LocalitiesGeocodeRequest): Promise Date: Tue, 1 Apr 2025 09:17:30 +0200 Subject: [PATCH 11/11] show sub_buildings on reverse geocode --- samples/localities-geocode/index.njk | 2 ++ samples/localities-geocode/index.ts | 49 +++++++++++++++++++++++++--- shared/scss/_pr_test.scss | 2 +- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/samples/localities-geocode/index.njk b/samples/localities-geocode/index.njk index d8217399..7168f43d 100644 --- a/samples/localities-geocode/index.njk +++ b/samples/localities-geocode/index.njk @@ -23,6 +23,8 @@ +
                      +
                        { handleGeocode(e.latlng); }); @@ -63,6 +71,26 @@ clearSearchBtn.addEventListener("click", () => { inputElement.focus(); }); +function displaySuggestions( + localitiesPredictions: woosmap.map.localities.LocalitiesDetailsSummary[], + container: HTMLUListElement = suggestionsList +) { + if (inputElement && container) { + container.innerHTML = ""; + if (localitiesPredictions.length > 0) { + localitiesPredictions.forEach((locality) => { + const li = document.createElement("li"); + li.innerHTML = locality["description"] ?? ""; + container.appendChild(li); + }); + container.style.display = "block"; + clearSearchBtn.style.display = "block"; + } else { + container.style.display = "none"; + } + } +} + function buildQueryString(params: object) { const queryStringParts = []; @@ -76,6 +104,7 @@ function buildQueryString(params: object) { } return queryStringParts.join("&"); } + function getSecondaryUrl():string { let secondary_target = document.getElementById("secondary-target") as HTMLInputElement if (secondary_target && secondary_target.value) { @@ -99,11 +128,14 @@ const pr_reverse_geocode = async (request:LocalitiesGeocodeRequest): Promise `country:${country}`) .join("|"); } - let list_sub_buildings: HTMLInputElement= document.getElementById("list-sub-buildings") as HTMLInputElement; - if (list_sub_buildings && list_sub_buildings.checked) { - console.log("list sub buildings") + if (request.list_sub_buildings) { params["list_sub_buildings"] = "1"; } + // let list_sub_buildings: HTMLInputElement= document.getElementById("list-sub-buildings") as HTMLInputElement; + // if (list_sub_buildings && list_sub_buildings.checked) { + // console.log("list sub buildings") + // params["list_sub_buildings"] = "1"; + // } try { const response = await fetch( `${getSecondaryUrl()}/localities/geocode?${buildQueryString(params)}` @@ -124,7 +156,11 @@ function handleGeocode(latlng: woosmap.map.LatLngLiteral | null) { delete request.latLng; } request.components = componentsRestriction + let list_sub_buildings: HTMLInputElement= document.getElementById("list-sub-buildings") as HTMLInputElement; + request.list_sub_buildings = (list_sub_buildings && list_sub_buildings.checked); + displaySuggestions([], suggestionsList) + displaySuggestions([], prSuggestionsList) if (request.latLng || request.address) { localitiesService .geocode(request) @@ -162,6 +198,9 @@ function displayLocality( if (map.getZoom() < 14) { map.setZoom(14); } + if (locality.sub_buildings){ + displaySuggestions(locality.sub_buildings, suggestionsList) + } } } @@ -187,7 +226,9 @@ function displayPRLocality( if (pr_infoWindow) { pr_infoWindow.textContent = `[PR says] ${locality.formatted_address} (red marker)`; } - + if (locality.sub_buildings){ + displaySuggestions(locality.sub_buildings, prSuggestionsList) + } } } diff --git a/shared/scss/_pr_test.scss b/shared/scss/_pr_test.scss index e25cbfd0..3120c9b1 100644 --- a/shared/scss/_pr_test.scss +++ b/shared/scss/_pr_test.scss @@ -88,7 +88,7 @@ left: 0; z-index: 1; list-style: none; - max-height: 80vh; + max-height: 300px; margin: 5px 0 0; padding: 0; display: none;