1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-12-01 22:52:06 +02:00

improve query builder for distance search fix #1012

This commit is contained in:
Patrik J. Braun
2025-08-01 21:49:14 +02:00
parent 790b28715e
commit 9a63ac8feb
2 changed files with 54 additions and 9 deletions

View File

@@ -111,15 +111,15 @@
</div>
<div class="col-md-8">
<div class="input-group">
<label class="control-label me-2" [for]="'maxResolution_'+id">From</label>
<input [name]="'maxResolution_'+id"
[id]="'maxResolution_'+id"
title="From"
placeholder="New York"
<label class="control-label me-2" [for]="'locationInput'+id" i18n>From</label>
<input [name]="'locationInput'+id"
[id]="'locationInput'+id"
title="Location or coordinates (lat, lng)"
placeholder="New York or 40.7128, -74.0060"
i18n-title
class="form-control input-md rounded-2"
[(ngModel)]="AsDistanceQuery.from.text"
(ngModelChange)="onChange()"
[ngModel]="locationInputText"
(ngModelChange)="onLocationInputChange($event)"
type="text">
</div>
</div>

View File

@@ -58,6 +58,8 @@ export class GallerySearchQueryEntryComponent
@Output() delete = new EventEmitter<void>();
@Input() id = 'NA';
public locationInputText: string = '';
constructor() {
this.SearchQueryTypesEnum = Utils.enumToArray(SearchQueryTypes);
// Range queries need to be added as AND with min and max sub entry
@@ -172,8 +174,13 @@ export class GallerySearchQueryEntryComponent
delete this.AsListQuery.list;
}
if (this.queryEntry.type === SearchQueryTypes.distance) {
this.AsDistanceQuery.from = {text: ''};
this.AsDistanceQuery.distance = 1;
// Initialize location input text
if (this.AsDistanceQuery.from?.GPSData) {
this.locationInputText = `${this.AsDistanceQuery.from.GPSData.latitude}, ${this.AsDistanceQuery.from.GPSData.longitude}`;
} else {
this.locationInputText = this.AsDistanceQuery.from?.text || '';
}
} else {
delete this.AsDistanceQuery.from;
delete this.AsDistanceQuery.distance;
@@ -197,6 +204,35 @@ export class GallerySearchQueryEntryComponent
this.onChange();
}
onLocationInputChange(value: string): void {
// Check if input matches coordinate pattern (number, number)
const coordMatch = value.match(/^\s*(-?\d+\.?\d*)\s*,\s*(-?\d+\.?\d*)\s*$/);
if (coordMatch) {
// It's coordinates
const latitude = parseFloat(coordMatch[1]);
const longitude = parseFloat(coordMatch[2]);
// Validate coordinate ranges
if (latitude >= -90 && latitude <= 90 && longitude >= -180 && longitude <= 180) {
this.AsDistanceQuery.from = {
GPSData: {
latitude,
longitude
}
};
} else {
// Invalid coordinates, treat as text
this.AsDistanceQuery.from = { text: value };
}
} else {
// It's a location name
this.AsDistanceQuery.from = { text: value };
}
this.locationInputText = value;
this.onChange();
}
deleteItem(): void {
this.delete.emit();
}
@@ -212,6 +248,16 @@ export class GallerySearchQueryEntryComponent
public writeValue(obj: SearchQueryDTO): void {
this.queryEntry = obj;
// Initialize location input text if this is a distance search
if (obj?.type === SearchQueryTypes.distance) {
const distanceSearch = obj as DistanceSearch;
if (distanceSearch.from?.GPSData) {
this.locationInputText = `${distanceSearch.from.GPSData.latitude}, ${distanceSearch.from.GPSData.longitude}`;
} else {
this.locationInputText = distanceSearch.from?.text || '';
}
}
}
registerOnChange(fn: (_: unknown) => void): void {
@@ -235,4 +281,3 @@ export class GallerySearchQueryEntryComponent
private propagateTouch = (_: unknown): void => {
};
}