feat(server): search unknown place (#10866)

* Allow submission of null country

* Update searchAssetBuilder to handle nulls

andWhere({country:null}) produces `"exifInfo"."country" = NULL`. We want
`"exifInfo"."country" IS NULL`, so we have to treat NULL as a special
case

* Allow null country in frontend

* Make the query code a bit more straightforward

* Remove unused brackets import

* Remove log message

* Don't change whitespace for no reason

* Fix prettier style issue

* Update search.dto.ts validators per @jrasm91's recommendation

* Update api types

* Combine null country and state into one guard clause

* chore: clean up

* chore: add e2e for null/empty city, state, country search

* refactor: server returns suggestion for null values

* chore: clean up

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
Justin Forseth
2024-08-01 21:27:40 -06:00
committed by GitHub
parent 3afb5b497f
commit d3a5490e71
21 changed files with 378 additions and 217 deletions
+18 -18
View File
@@ -1,6 +1,7 @@
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsEnum, IsInt, IsNotEmpty, IsString, Max, Min } from 'class-validator';
import { PropertyLifecycle } from 'src/decorators';
import { AlbumResponseDto } from 'src/dtos/album.dto';
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
import { AssetOrder } from 'src/entities/album.entity';
@@ -75,34 +76,29 @@ class BaseSearchDto {
takenAfter?: Date;
@IsString()
@IsNotEmpty()
@Optional()
city?: string;
@Optional({ nullable: true, emptyToNull: true })
city?: string | null;
@IsString()
@Optional({ nullable: true, emptyToNull: true })
state?: string | null;
@IsString()
@IsNotEmpty()
@Optional()
state?: string;
@Optional({ nullable: true, emptyToNull: true })
country?: string | null;
@IsString()
@IsNotEmpty()
@Optional()
country?: string;
@IsString()
@IsNotEmpty()
@Optional()
@Optional({ nullable: true, emptyToNull: true })
make?: string;
@IsString()
@IsNotEmpty()
@Optional()
model?: string;
@Optional({ nullable: true, emptyToNull: true })
model?: string | null;
@IsString()
@IsNotEmpty()
@Optional()
lensModel?: string;
@Optional({ nullable: true, emptyToNull: true })
lensModel?: string | null;
@IsInt()
@Min(1)
@@ -242,6 +238,10 @@ export class SearchSuggestionRequestDto {
@IsString()
@Optional()
model?: string;
@ValidateBoolean({ optional: true })
@PropertyLifecycle({ addedAt: 'v111.0.0' })
includeNull?: boolean;
}
class SearchFacetCountResponseDto {