diff --git a/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.html b/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.html index c2edb7e..216db13 100644 --- a/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.html +++ b/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.html @@ -1,13 +1,8 @@
-
- - - - -
-
+

Selected

@@ -18,9 +13,9 @@ }}
- +
+ @if (showSelectedPlaces) { @for (p of selectedPlaces; track p.id) {

List

- Available points + Available Places @defer { +
+ + + + + +
+ + + + + + @if (boundariesFiltering) {} + @else {} +
+
+ + @if (boundariesFiltering) { +
+

Filtering for location: {{ googleGeocodeInput.value }}

+ +
+ } + @for (p of displayedPlaces; track p.id) {
} @empty { -
-

Nothing to see

+
+

Nothing to see

} diff --git a/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.ts b/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.ts index 9a74a2e..f76980d 100644 --- a/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.ts +++ b/src/src/app/modals/trip-place-select-modal/trip-place-select-modal.component.ts @@ -4,20 +4,25 @@ import { ButtonModule } from 'primeng/button'; import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; import { FloatLabelModule } from 'primeng/floatlabel'; import { InputTextModule } from 'primeng/inputtext'; -import { Place } from '../../types/poi'; +import { GoogleBoundaries, Place } from '../../types/poi'; import { ApiService } from '../../services/api.service'; import { SkeletonModule } from 'primeng/skeleton'; import { UtilsService } from '../../services/utils.service'; +import { take } from 'rxjs'; +import { isPointInBounds } from '../../shared/map'; +import { TooltipModule } from 'primeng/tooltip'; @Component({ selector: 'app-trip-place-select-modal', - imports: [FloatLabelModule, InputTextModule, ButtonModule, ReactiveFormsModule, SkeletonModule], + imports: [FloatLabelModule, InputTextModule, ButtonModule, ReactiveFormsModule, SkeletonModule, TooltipModule], standalone: true, templateUrl: './trip-place-select-modal.component.html', styleUrl: './trip-place-select-modal.component.scss', }) export class TripPlaceSelectModalComponent { searchInput = new FormControl(''); + googleGeocodeInput = new FormControl(''); + boundariesFiltering?: GoogleBoundaries; selectedPlaces: Place[] = []; showSelectedPlaces: boolean = false; @@ -48,17 +53,7 @@ export class TripPlaceSelectModalComponent { } this.searchInput.valueChanges.subscribe({ - next: (value) => { - if (!value) { - this.displayedPlaces = this.places; - return; - } - - const v = value.toLowerCase(); - this.displayedPlaces = this.places.filter( - (p) => p.name.toLowerCase().includes(v) || p.description?.toLowerCase().includes(v), - ); - }, + next: () => this.filterPlaces(), }); } @@ -86,7 +81,43 @@ export class TripPlaceSelectModalComponent { this.selectedPlaces.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)); } + filterPlaces() { + const searchInputValue = (this.searchInput.value || '').toLowerCase(); + this.displayedPlaces = this.places.filter((place) => { + if (this.boundariesFiltering) { + if (!isPointInBounds(place.lat, place.lng, this.boundariesFiltering)) return false; + } + + if (!searchInputValue) return true; + return ( + place.name.toLowerCase().includes(searchInputValue) || + place.description?.toLowerCase().includes(searchInputValue) + ); + }); + } + + resetGeocodeFilters() { + this.boundariesFiltering = undefined; + this.googleGeocodeInput.setValue(''); + this.filterPlaces(); + } + closeDialog() { this.ref.close(this.selectedPlaces); } + + gmapsGeocodeFilter() { + const value = this.googleGeocodeInput.value; + if (!value) return; + + this.apiService + .gmapsGeocodeBoundaries(value) + .pipe(take(1)) + .subscribe({ + next: (boundaries) => { + this.boundariesFiltering = boundaries; + this.filterPlaces(); + }, + }); + } } diff --git a/src/src/app/shared/map.ts b/src/src/app/shared/map.ts index 020cb74..af99ea5 100644 --- a/src/src/app/shared/map.ts +++ b/src/src/app/shared/map.ts @@ -1,7 +1,7 @@ import * as L from 'leaflet'; import 'leaflet.markercluster'; import 'leaflet-contextmenu'; -import { Place } from '../types/poi'; +import { GoogleBoundaries, Place } from '../types/poi'; export const DEFAULT_TILE_URL = 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png'; export interface ContextMenuItem { @@ -143,3 +143,14 @@ export function gpxToPolyline(gpx: string): L.Polyline { return L.polyline(latlngs, { color: 'blue' }); } + +export function isPointInBounds(lat: number, lng: number, bounds: GoogleBoundaries): boolean { + if (!bounds || !bounds.northeast || !bounds.southwest) return false; + + const ne = bounds.northeast; + const sw = bounds.southwest; + + if (lat < sw.lat || lat > ne.lat) return false; + + return sw.lng <= ne.lng ? lng >= sw.lng && lng <= ne.lng : lng >= sw.lng || lng <= ne.lng; +}