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
+19
View File
@@ -4727,6 +4727,15 @@
"type": "string"
}
},
{
"name": "includeNull",
"required": false,
"in": "query",
"description": "This property was added in v111.0.0",
"schema": {
"type": "boolean"
}
},
{
"name": "make",
"required": false,
@@ -9378,9 +9387,11 @@
"type": "string"
},
"city": {
"nullable": true,
"type": "string"
},
"country": {
"nullable": true,
"type": "string"
},
"createdAfter": {
@@ -9426,6 +9437,7 @@
"type": "boolean"
},
"lensModel": {
"nullable": true,
"type": "string"
},
"libraryId": {
@@ -9437,6 +9449,7 @@
"type": "string"
},
"model": {
"nullable": true,
"type": "string"
},
"order": {
@@ -9468,6 +9481,7 @@
"type": "number"
},
"state": {
"nullable": true,
"type": "string"
},
"takenAfter": {
@@ -10611,9 +10625,11 @@
"SmartSearchDto": {
"properties": {
"city": {
"nullable": true,
"type": "string"
},
"country": {
"nullable": true,
"type": "string"
},
"createdAfter": {
@@ -10649,6 +10665,7 @@
"type": "boolean"
},
"lensModel": {
"nullable": true,
"type": "string"
},
"libraryId": {
@@ -10660,6 +10677,7 @@
"type": "string"
},
"model": {
"nullable": true,
"type": "string"
},
"page": {
@@ -10682,6 +10700,7 @@
"type": "number"
},
"state": {
"nullable": true,
"type": "string"
},
"takenAfter": {
+13 -11
View File
@@ -708,8 +708,8 @@ export type SearchExploreResponseDto = {
};
export type MetadataSearchDto = {
checksum?: string;
city?: string;
country?: string;
city?: string | null;
country?: string | null;
createdAfter?: string;
createdBefore?: string;
deviceAssetId?: string;
@@ -723,10 +723,10 @@ export type MetadataSearchDto = {
isNotInAlbum?: boolean;
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
lensModel?: string | null;
libraryId?: string | null;
make?: string;
model?: string;
model?: string | null;
order?: AssetOrder;
originalFileName?: string;
originalPath?: string;
@@ -734,7 +734,7 @@ export type MetadataSearchDto = {
personIds?: string[];
previewPath?: string;
size?: number;
state?: string;
state?: string | null;
takenAfter?: string;
takenBefore?: string;
thumbnailPath?: string;
@@ -782,8 +782,8 @@ export type PlacesResponseDto = {
name: string;
};
export type SmartSearchDto = {
city?: string;
country?: string;
city?: string | null;
country?: string | null;
createdAfter?: string;
createdBefore?: string;
deviceId?: string;
@@ -794,15 +794,15 @@ export type SmartSearchDto = {
isNotInAlbum?: boolean;
isOffline?: boolean;
isVisible?: boolean;
lensModel?: string;
lensModel?: string | null;
libraryId?: string | null;
make?: string;
model?: string;
model?: string | null;
page?: number;
personIds?: string[];
query: string;
size?: number;
state?: string;
state?: string | null;
takenAfter?: string;
takenBefore?: string;
trashedAfter?: string;
@@ -2418,8 +2418,9 @@ export function searchSmart({ smartSearchDto }: {
body: smartSearchDto
})));
}
export function getSearchSuggestions({ country, make, model, state, $type }: {
export function getSearchSuggestions({ country, includeNull, make, model, state, $type }: {
country?: string;
includeNull?: boolean;
make?: string;
model?: string;
state?: string;
@@ -2430,6 +2431,7 @@ export function getSearchSuggestions({ country, make, model, state, $type }: {
data: string[];
}>(`/search/suggestions${QS.query(QS.explode({
country,
includeNull,
make,
model,
state,