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:
@@ -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": {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user