mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 04:05:39 -04:00
feat(api): set person color (#15937)
This commit is contained in:
parent
2e5007adef
commit
23014c263b
@ -195,6 +195,7 @@ describe('/people', () => {
|
|||||||
.send({
|
.send({
|
||||||
name: 'New Person',
|
name: 'New Person',
|
||||||
birthDate: '1990-01-01',
|
birthDate: '1990-01-01',
|
||||||
|
color: '#333',
|
||||||
});
|
});
|
||||||
expect(status).toBe(201);
|
expect(status).toBe(201);
|
||||||
expect(body).toMatchObject({
|
expect(body).toMatchObject({
|
||||||
@ -273,6 +274,24 @@ describe('/people', () => {
|
|||||||
expect(body).toMatchObject({ birthDate: null });
|
expect(body).toMatchObject({ birthDate: null });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set a color', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.put(`/people/${visiblePerson.id}`)
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||||
|
.send({ color: '#555' });
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body).toMatchObject({ color: '#555' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clear a color', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.put(`/people/${visiblePerson.id}`)
|
||||||
|
.set('Authorization', `Bearer ${admin.accessToken}`)
|
||||||
|
.send({ color: null });
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body.color).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('should mark a person as favorite', async () => {
|
it('should mark a person as favorite', async () => {
|
||||||
const person = await utils.createPerson(admin.accessToken, {
|
const person = await utils.createPerson(admin.accessToken, {
|
||||||
name: 'visible_person',
|
name: 'visible_person',
|
||||||
|
13
mobile/openapi/lib/model/people_update_item.dart
generated
13
mobile/openapi/lib/model/people_update_item.dart
generated
@ -14,6 +14,7 @@ class PeopleUpdateItem {
|
|||||||
/// Returns a new [PeopleUpdateItem] instance.
|
/// Returns a new [PeopleUpdateItem] instance.
|
||||||
PeopleUpdateItem({
|
PeopleUpdateItem({
|
||||||
this.birthDate,
|
this.birthDate,
|
||||||
|
this.color,
|
||||||
this.featureFaceAssetId,
|
this.featureFaceAssetId,
|
||||||
required this.id,
|
required this.id,
|
||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
@ -24,6 +25,8 @@ class PeopleUpdateItem {
|
|||||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
|
String? color;
|
||||||
|
|
||||||
/// Asset is used to get the feature face thumbnail.
|
/// Asset is used to get the feature face thumbnail.
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
@ -65,6 +68,7 @@ class PeopleUpdateItem {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PeopleUpdateItem &&
|
bool operator ==(Object other) => identical(this, other) || other is PeopleUpdateItem &&
|
||||||
other.birthDate == birthDate &&
|
other.birthDate == birthDate &&
|
||||||
|
other.color == color &&
|
||||||
other.featureFaceAssetId == featureFaceAssetId &&
|
other.featureFaceAssetId == featureFaceAssetId &&
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
@ -75,6 +79,7 @@ class PeopleUpdateItem {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||||
|
(color == null ? 0 : color!.hashCode) +
|
||||||
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
@ -82,7 +87,7 @@ class PeopleUpdateItem {
|
|||||||
(name == null ? 0 : name!.hashCode);
|
(name == null ? 0 : name!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PeopleUpdateItem[birthDate=$birthDate, featureFaceAssetId=$featureFaceAssetId, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
String toString() => 'PeopleUpdateItem[birthDate=$birthDate, color=$color, featureFaceAssetId=$featureFaceAssetId, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -91,6 +96,11 @@ class PeopleUpdateItem {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'birthDate'] = null;
|
// json[r'birthDate'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.color != null) {
|
||||||
|
json[r'color'] = this.color;
|
||||||
|
} else {
|
||||||
|
// json[r'color'] = null;
|
||||||
|
}
|
||||||
if (this.featureFaceAssetId != null) {
|
if (this.featureFaceAssetId != null) {
|
||||||
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
||||||
} else {
|
} else {
|
||||||
@ -125,6 +135,7 @@ class PeopleUpdateItem {
|
|||||||
|
|
||||||
return PeopleUpdateItem(
|
return PeopleUpdateItem(
|
||||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||||
|
color: mapValueOfType<String>(json, r'color'),
|
||||||
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
|
13
mobile/openapi/lib/model/person_create_dto.dart
generated
13
mobile/openapi/lib/model/person_create_dto.dart
generated
@ -14,6 +14,7 @@ class PersonCreateDto {
|
|||||||
/// Returns a new [PersonCreateDto] instance.
|
/// Returns a new [PersonCreateDto] instance.
|
||||||
PersonCreateDto({
|
PersonCreateDto({
|
||||||
this.birthDate,
|
this.birthDate,
|
||||||
|
this.color,
|
||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
this.isHidden,
|
this.isHidden,
|
||||||
this.name,
|
this.name,
|
||||||
@ -22,6 +23,8 @@ class PersonCreateDto {
|
|||||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
|
String? color;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
/// does not include a default value (using the "default:" property), however, the generated
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
@ -51,6 +54,7 @@ class PersonCreateDto {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PersonCreateDto &&
|
bool operator ==(Object other) => identical(this, other) || other is PersonCreateDto &&
|
||||||
other.birthDate == birthDate &&
|
other.birthDate == birthDate &&
|
||||||
|
other.color == color &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
other.isHidden == isHidden &&
|
other.isHidden == isHidden &&
|
||||||
other.name == name;
|
other.name == name;
|
||||||
@ -59,12 +63,13 @@ class PersonCreateDto {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||||
|
(color == null ? 0 : color!.hashCode) +
|
||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
(isHidden == null ? 0 : isHidden!.hashCode) +
|
(isHidden == null ? 0 : isHidden!.hashCode) +
|
||||||
(name == null ? 0 : name!.hashCode);
|
(name == null ? 0 : name!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PersonCreateDto[birthDate=$birthDate, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
String toString() => 'PersonCreateDto[birthDate=$birthDate, color=$color, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -73,6 +78,11 @@ class PersonCreateDto {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'birthDate'] = null;
|
// json[r'birthDate'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.color != null) {
|
||||||
|
json[r'color'] = this.color;
|
||||||
|
} else {
|
||||||
|
// json[r'color'] = null;
|
||||||
|
}
|
||||||
if (this.isFavorite != null) {
|
if (this.isFavorite != null) {
|
||||||
json[r'isFavorite'] = this.isFavorite;
|
json[r'isFavorite'] = this.isFavorite;
|
||||||
} else {
|
} else {
|
||||||
@ -101,6 +111,7 @@ class PersonCreateDto {
|
|||||||
|
|
||||||
return PersonCreateDto(
|
return PersonCreateDto(
|
||||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||||
|
color: mapValueOfType<String>(json, r'color'),
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
||||||
name: mapValueOfType<String>(json, r'name'),
|
name: mapValueOfType<String>(json, r'name'),
|
||||||
|
20
mobile/openapi/lib/model/person_response_dto.dart
generated
20
mobile/openapi/lib/model/person_response_dto.dart
generated
@ -14,6 +14,7 @@ class PersonResponseDto {
|
|||||||
/// Returns a new [PersonResponseDto] instance.
|
/// Returns a new [PersonResponseDto] instance.
|
||||||
PersonResponseDto({
|
PersonResponseDto({
|
||||||
required this.birthDate,
|
required this.birthDate,
|
||||||
|
this.color,
|
||||||
required this.id,
|
required this.id,
|
||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
required this.isHidden,
|
required this.isHidden,
|
||||||
@ -24,6 +25,15 @@ class PersonResponseDto {
|
|||||||
|
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
|
/// This property was added in v1.126.0
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
String? color;
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
||||||
/// This property was added in v1.126.0
|
/// This property was added in v1.126.0
|
||||||
@ -53,6 +63,7 @@ class PersonResponseDto {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PersonResponseDto &&
|
bool operator ==(Object other) => identical(this, other) || other is PersonResponseDto &&
|
||||||
other.birthDate == birthDate &&
|
other.birthDate == birthDate &&
|
||||||
|
other.color == color &&
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
other.isHidden == isHidden &&
|
other.isHidden == isHidden &&
|
||||||
@ -64,6 +75,7 @@ class PersonResponseDto {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||||
|
(color == null ? 0 : color!.hashCode) +
|
||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
(isHidden.hashCode) +
|
(isHidden.hashCode) +
|
||||||
@ -72,7 +84,7 @@ class PersonResponseDto {
|
|||||||
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PersonResponseDto[birthDate=$birthDate, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
String toString() => 'PersonResponseDto[birthDate=$birthDate, color=$color, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -80,6 +92,11 @@ class PersonResponseDto {
|
|||||||
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
||||||
} else {
|
} else {
|
||||||
// json[r'birthDate'] = null;
|
// json[r'birthDate'] = null;
|
||||||
|
}
|
||||||
|
if (this.color != null) {
|
||||||
|
json[r'color'] = this.color;
|
||||||
|
} else {
|
||||||
|
// json[r'color'] = null;
|
||||||
}
|
}
|
||||||
json[r'id'] = this.id;
|
json[r'id'] = this.id;
|
||||||
if (this.isFavorite != null) {
|
if (this.isFavorite != null) {
|
||||||
@ -108,6 +125,7 @@ class PersonResponseDto {
|
|||||||
|
|
||||||
return PersonResponseDto(
|
return PersonResponseDto(
|
||||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||||
|
color: mapValueOfType<String>(json, r'color'),
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
isHidden: mapValueOfType<bool>(json, r'isHidden')!,
|
isHidden: mapValueOfType<bool>(json, r'isHidden')!,
|
||||||
|
13
mobile/openapi/lib/model/person_update_dto.dart
generated
13
mobile/openapi/lib/model/person_update_dto.dart
generated
@ -14,6 +14,7 @@ class PersonUpdateDto {
|
|||||||
/// Returns a new [PersonUpdateDto] instance.
|
/// Returns a new [PersonUpdateDto] instance.
|
||||||
PersonUpdateDto({
|
PersonUpdateDto({
|
||||||
this.birthDate,
|
this.birthDate,
|
||||||
|
this.color,
|
||||||
this.featureFaceAssetId,
|
this.featureFaceAssetId,
|
||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
this.isHidden,
|
this.isHidden,
|
||||||
@ -23,6 +24,8 @@ class PersonUpdateDto {
|
|||||||
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
/// Person date of birth. Note: the mobile app cannot currently set the birth date to null.
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
|
String? color;
|
||||||
|
|
||||||
/// Asset is used to get the feature face thumbnail.
|
/// Asset is used to get the feature face thumbnail.
|
||||||
///
|
///
|
||||||
/// Please note: This property should have been non-nullable! Since the specification file
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
@ -61,6 +64,7 @@ class PersonUpdateDto {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PersonUpdateDto &&
|
bool operator ==(Object other) => identical(this, other) || other is PersonUpdateDto &&
|
||||||
other.birthDate == birthDate &&
|
other.birthDate == birthDate &&
|
||||||
|
other.color == color &&
|
||||||
other.featureFaceAssetId == featureFaceAssetId &&
|
other.featureFaceAssetId == featureFaceAssetId &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
other.isHidden == isHidden &&
|
other.isHidden == isHidden &&
|
||||||
@ -70,13 +74,14 @@ class PersonUpdateDto {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||||
|
(color == null ? 0 : color!.hashCode) +
|
||||||
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
(featureFaceAssetId == null ? 0 : featureFaceAssetId!.hashCode) +
|
||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
(isHidden == null ? 0 : isHidden!.hashCode) +
|
(isHidden == null ? 0 : isHidden!.hashCode) +
|
||||||
(name == null ? 0 : name!.hashCode);
|
(name == null ? 0 : name!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PersonUpdateDto[birthDate=$birthDate, featureFaceAssetId=$featureFaceAssetId, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
String toString() => 'PersonUpdateDto[birthDate=$birthDate, color=$color, featureFaceAssetId=$featureFaceAssetId, isFavorite=$isFavorite, isHidden=$isHidden, name=$name]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -85,6 +90,11 @@ class PersonUpdateDto {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'birthDate'] = null;
|
// json[r'birthDate'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.color != null) {
|
||||||
|
json[r'color'] = this.color;
|
||||||
|
} else {
|
||||||
|
// json[r'color'] = null;
|
||||||
|
}
|
||||||
if (this.featureFaceAssetId != null) {
|
if (this.featureFaceAssetId != null) {
|
||||||
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
json[r'featureFaceAssetId'] = this.featureFaceAssetId;
|
||||||
} else {
|
} else {
|
||||||
@ -118,6 +128,7 @@ class PersonUpdateDto {
|
|||||||
|
|
||||||
return PersonUpdateDto(
|
return PersonUpdateDto(
|
||||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||||
|
color: mapValueOfType<String>(json, r'color'),
|
||||||
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
featureFaceAssetId: mapValueOfType<String>(json, r'featureFaceAssetId'),
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
isHidden: mapValueOfType<bool>(json, r'isHidden'),
|
||||||
|
@ -14,6 +14,7 @@ class PersonWithFacesResponseDto {
|
|||||||
/// Returns a new [PersonWithFacesResponseDto] instance.
|
/// Returns a new [PersonWithFacesResponseDto] instance.
|
||||||
PersonWithFacesResponseDto({
|
PersonWithFacesResponseDto({
|
||||||
required this.birthDate,
|
required this.birthDate,
|
||||||
|
this.color,
|
||||||
this.faces = const [],
|
this.faces = const [],
|
||||||
required this.id,
|
required this.id,
|
||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
@ -25,6 +26,15 @@ class PersonWithFacesResponseDto {
|
|||||||
|
|
||||||
DateTime? birthDate;
|
DateTime? birthDate;
|
||||||
|
|
||||||
|
/// This property was added in v1.126.0
|
||||||
|
///
|
||||||
|
/// Please note: This property should have been non-nullable! Since the specification file
|
||||||
|
/// does not include a default value (using the "default:" property), however, the generated
|
||||||
|
/// source code must fall back to having a nullable type.
|
||||||
|
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||||
|
///
|
||||||
|
String? color;
|
||||||
|
|
||||||
List<AssetFaceWithoutPersonResponseDto> faces;
|
List<AssetFaceWithoutPersonResponseDto> faces;
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
@ -56,6 +66,7 @@ class PersonWithFacesResponseDto {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => identical(this, other) || other is PersonWithFacesResponseDto &&
|
bool operator ==(Object other) => identical(this, other) || other is PersonWithFacesResponseDto &&
|
||||||
other.birthDate == birthDate &&
|
other.birthDate == birthDate &&
|
||||||
|
other.color == color &&
|
||||||
_deepEquality.equals(other.faces, faces) &&
|
_deepEquality.equals(other.faces, faces) &&
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
@ -68,6 +79,7 @@ class PersonWithFacesResponseDto {
|
|||||||
int get hashCode =>
|
int get hashCode =>
|
||||||
// ignore: unnecessary_parenthesis
|
// ignore: unnecessary_parenthesis
|
||||||
(birthDate == null ? 0 : birthDate!.hashCode) +
|
(birthDate == null ? 0 : birthDate!.hashCode) +
|
||||||
|
(color == null ? 0 : color!.hashCode) +
|
||||||
(faces.hashCode) +
|
(faces.hashCode) +
|
||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
@ -77,7 +89,7 @@ class PersonWithFacesResponseDto {
|
|||||||
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
(updatedAt == null ? 0 : updatedAt!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'PersonWithFacesResponseDto[birthDate=$birthDate, faces=$faces, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
String toString() => 'PersonWithFacesResponseDto[birthDate=$birthDate, color=$color, faces=$faces, id=$id, isFavorite=$isFavorite, isHidden=$isHidden, name=$name, thumbnailPath=$thumbnailPath, updatedAt=$updatedAt]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@ -85,6 +97,11 @@ class PersonWithFacesResponseDto {
|
|||||||
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
json[r'birthDate'] = _dateFormatter.format(this.birthDate!.toUtc());
|
||||||
} else {
|
} else {
|
||||||
// json[r'birthDate'] = null;
|
// json[r'birthDate'] = null;
|
||||||
|
}
|
||||||
|
if (this.color != null) {
|
||||||
|
json[r'color'] = this.color;
|
||||||
|
} else {
|
||||||
|
// json[r'color'] = null;
|
||||||
}
|
}
|
||||||
json[r'faces'] = this.faces;
|
json[r'faces'] = this.faces;
|
||||||
json[r'id'] = this.id;
|
json[r'id'] = this.id;
|
||||||
@ -114,6 +131,7 @@ class PersonWithFacesResponseDto {
|
|||||||
|
|
||||||
return PersonWithFacesResponseDto(
|
return PersonWithFacesResponseDto(
|
||||||
birthDate: mapDateTime(json, r'birthDate', r''),
|
birthDate: mapDateTime(json, r'birthDate', r''),
|
||||||
|
color: mapValueOfType<String>(json, r'color'),
|
||||||
faces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'faces']),
|
faces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'faces']),
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
|
@ -10286,6 +10286,10 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"featureFaceAssetId": {
|
"featureFaceAssetId": {
|
||||||
"description": "Asset is used to get the feature face thumbnail.",
|
"description": "Asset is used to get the feature face thumbnail.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -10402,6 +10406,10 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"isFavorite": {
|
"isFavorite": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
@ -10423,6 +10431,10 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"description": "This property was added in v1.126.0",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -10473,6 +10485,10 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"nullable": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"featureFaceAssetId": {
|
"featureFaceAssetId": {
|
||||||
"description": "Asset is used to get the feature face thumbnail.",
|
"description": "Asset is used to get the feature face thumbnail.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -10498,6 +10514,10 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"description": "This property was added in v1.126.0",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"faces": {
|
"faces": {
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/components/schemas/AssetFaceWithoutPersonResponseDto"
|
"$ref": "#/components/schemas/AssetFaceWithoutPersonResponseDto"
|
||||||
@ -12611,7 +12631,6 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"color": {
|
"color": {
|
||||||
"nullable": true,
|
"nullable": true,
|
||||||
"pattern": "^#?([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$",
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -213,6 +213,8 @@ export type AssetFaceWithoutPersonResponseDto = {
|
|||||||
};
|
};
|
||||||
export type PersonWithFacesResponseDto = {
|
export type PersonWithFacesResponseDto = {
|
||||||
birthDate: string | null;
|
birthDate: string | null;
|
||||||
|
/** This property was added in v1.126.0 */
|
||||||
|
color?: string;
|
||||||
faces: AssetFaceWithoutPersonResponseDto[];
|
faces: AssetFaceWithoutPersonResponseDto[];
|
||||||
id: string;
|
id: string;
|
||||||
/** This property was added in v1.126.0 */
|
/** This property was added in v1.126.0 */
|
||||||
@ -493,6 +495,8 @@ export type DuplicateResponseDto = {
|
|||||||
};
|
};
|
||||||
export type PersonResponseDto = {
|
export type PersonResponseDto = {
|
||||||
birthDate: string | null;
|
birthDate: string | null;
|
||||||
|
/** This property was added in v1.126.0 */
|
||||||
|
color?: string;
|
||||||
id: string;
|
id: string;
|
||||||
/** This property was added in v1.126.0 */
|
/** This property was added in v1.126.0 */
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
@ -693,6 +697,7 @@ export type PersonCreateDto = {
|
|||||||
/** Person date of birth.
|
/** Person date of birth.
|
||||||
Note: the mobile app cannot currently set the birth date to null. */
|
Note: the mobile app cannot currently set the birth date to null. */
|
||||||
birthDate?: string | null;
|
birthDate?: string | null;
|
||||||
|
color?: string | null;
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
/** Person visibility */
|
/** Person visibility */
|
||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
@ -703,6 +708,7 @@ export type PeopleUpdateItem = {
|
|||||||
/** Person date of birth.
|
/** Person date of birth.
|
||||||
Note: the mobile app cannot currently set the birth date to null. */
|
Note: the mobile app cannot currently set the birth date to null. */
|
||||||
birthDate?: string | null;
|
birthDate?: string | null;
|
||||||
|
color?: string | null;
|
||||||
/** Asset is used to get the feature face thumbnail. */
|
/** Asset is used to get the feature face thumbnail. */
|
||||||
featureFaceAssetId?: string;
|
featureFaceAssetId?: string;
|
||||||
/** Person id. */
|
/** Person id. */
|
||||||
@ -720,6 +726,7 @@ export type PersonUpdateDto = {
|
|||||||
/** Person date of birth.
|
/** Person date of birth.
|
||||||
Note: the mobile app cannot currently set the birth date to null. */
|
Note: the mobile app cannot currently set the birth date to null. */
|
||||||
birthDate?: string | null;
|
birthDate?: string | null;
|
||||||
|
color?: string | null;
|
||||||
/** Asset is used to get the feature face thumbnail. */
|
/** Asset is used to get the feature face thumbnail. */
|
||||||
featureFaceAssetId?: string;
|
featureFaceAssetId?: string;
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
|
1
server/src/db.d.ts
vendored
1
server/src/db.d.ts
vendored
@ -276,6 +276,7 @@ export interface Partners {
|
|||||||
|
|
||||||
export interface Person {
|
export interface Person {
|
||||||
birthDate: Timestamp | null;
|
birthDate: Timestamp | null;
|
||||||
|
color: string | null;
|
||||||
createdAt: Generated<Timestamp>;
|
createdAt: Generated<Timestamp>;
|
||||||
faceAssetId: string | null;
|
faceAssetId: string | null;
|
||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
|
@ -7,7 +7,14 @@ import { AuthDto } from 'src/dtos/auth.dto';
|
|||||||
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
|
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
|
||||||
import { PersonEntity } from 'src/entities/person.entity';
|
import { PersonEntity } from 'src/entities/person.entity';
|
||||||
import { SourceType } from 'src/enum';
|
import { SourceType } from 'src/enum';
|
||||||
import { IsDateStringFormat, MaxDateString, Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
import {
|
||||||
|
IsDateStringFormat,
|
||||||
|
MaxDateString,
|
||||||
|
Optional,
|
||||||
|
ValidateBoolean,
|
||||||
|
ValidateHexColor,
|
||||||
|
ValidateUUID,
|
||||||
|
} from 'src/validation';
|
||||||
|
|
||||||
export class PersonCreateDto {
|
export class PersonCreateDto {
|
||||||
/**
|
/**
|
||||||
@ -35,6 +42,10 @@ export class PersonCreateDto {
|
|||||||
|
|
||||||
@ValidateBoolean({ optional: true })
|
@ValidateBoolean({ optional: true })
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
|
|
||||||
|
@Optional({ emptyToNull: true, nullable: true })
|
||||||
|
@ValidateHexColor()
|
||||||
|
color?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PersonUpdateDto extends PersonCreateDto {
|
export class PersonUpdateDto extends PersonCreateDto {
|
||||||
@ -102,6 +113,8 @@ export class PersonResponseDto {
|
|||||||
updatedAt?: Date;
|
updatedAt?: Date;
|
||||||
@PropertyLifecycle({ addedAt: 'v1.126.0' })
|
@PropertyLifecycle({ addedAt: 'v1.126.0' })
|
||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
|
@PropertyLifecycle({ addedAt: 'v1.126.0' })
|
||||||
|
color?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PersonWithFacesResponseDto extends PersonResponseDto {
|
export class PersonWithFacesResponseDto extends PersonResponseDto {
|
||||||
@ -176,6 +189,7 @@ export function mapPerson(person: PersonEntity): PersonResponseDto {
|
|||||||
thumbnailPath: person.thumbnailPath,
|
thumbnailPath: person.thumbnailPath,
|
||||||
isHidden: person.isHidden,
|
isHidden: person.isHidden,
|
||||||
isFavorite: person.isFavorite,
|
isFavorite: person.isFavorite,
|
||||||
|
color: person.color ?? undefined,
|
||||||
updatedAt: person.updatedAt,
|
updatedAt: person.updatedAt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Transform } from 'class-transformer';
|
|
||||||
import { IsHexColor, IsNotEmpty, IsString } from 'class-validator';
|
import { IsHexColor, IsNotEmpty, IsString } from 'class-validator';
|
||||||
import { TagEntity } from 'src/entities/tag.entity';
|
import { TagEntity } from 'src/entities/tag.entity';
|
||||||
import { Optional, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateHexColor, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export class TagCreateDto {
|
export class TagCreateDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@ -18,9 +17,8 @@ export class TagCreateDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TagUpdateDto {
|
export class TagUpdateDto {
|
||||||
@Optional({ nullable: true, emptyToNull: true })
|
@Optional({ emptyToNull: true, nullable: true })
|
||||||
@IsHexColor()
|
@ValidateHexColor()
|
||||||
@Transform(({ value }) => (typeof value === 'string' && value[0] !== '#' ? `#${value}` : value))
|
|
||||||
color?: string | null;
|
color?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,4 +52,7 @@ export class PersonEntity {
|
|||||||
|
|
||||||
@Column({ default: false })
|
@Column({ default: false })
|
||||||
isFavorite!: boolean;
|
isFavorite!: boolean;
|
||||||
|
|
||||||
|
@Column({ type: 'varchar', nullable: true, default: null })
|
||||||
|
color?: string | null;
|
||||||
}
|
}
|
||||||
|
14
server/src/migrations/1738889177573-AddPersonColor.ts
Normal file
14
server/src/migrations/1738889177573-AddPersonColor.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class AddPersonColor1738889177573 implements MigrationInterface {
|
||||||
|
name = 'AddPersonColor1738889177573'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "person" ADD "color" character varying`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "person" DROP COLUMN "color"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -355,7 +355,7 @@ describe(PersonService.name, () => {
|
|||||||
sut.reassignFaces(authStub.admin, personStub.noName.id, {
|
sut.reassignFaces(authStub.admin, personStub.noName.id, {
|
||||||
data: [{ personId: personStub.withName.id, assetId: assetStub.image.id }],
|
data: [{ personId: personStub.withName.id, assetId: assetStub.image.id }],
|
||||||
}),
|
}),
|
||||||
).resolves.toEqual([personStub.noName]);
|
).resolves.toBeDefined();
|
||||||
|
|
||||||
expect(jobMock.queueAll).toHaveBeenCalledWith([
|
expect(jobMock.queueAll).toHaveBeenCalledWith([
|
||||||
{
|
{
|
||||||
@ -448,7 +448,7 @@ describe(PersonService.name, () => {
|
|||||||
it('should create a new person', async () => {
|
it('should create a new person', async () => {
|
||||||
personMock.create.mockResolvedValue(personStub.primaryPerson);
|
personMock.create.mockResolvedValue(personStub.primaryPerson);
|
||||||
|
|
||||||
await expect(sut.create(authStub.admin, {})).resolves.toBe(personStub.primaryPerson);
|
await expect(sut.create(authStub.admin, {})).resolves.toBeDefined();
|
||||||
|
|
||||||
expect(personMock.create).toHaveBeenCalledWith({ ownerId: authStub.admin.user.id });
|
expect(personMock.create).toHaveBeenCalledWith({ ownerId: authStub.admin.user.id });
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,7 @@ export class PersonService extends BaseService {
|
|||||||
await this.personRepository.reassignFace(face.id, personId);
|
await this.personRepository.reassignFace(face.id, personId);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push(person);
|
result.push(mapPerson(person));
|
||||||
}
|
}
|
||||||
if (changeFeaturePhoto.length > 0) {
|
if (changeFeaturePhoto.length > 0) {
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
@ -178,20 +178,23 @@ export class PersonService extends BaseService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
create(auth: AuthDto, dto: PersonCreateDto): Promise<PersonResponseDto> {
|
async create(auth: AuthDto, dto: PersonCreateDto): Promise<PersonResponseDto> {
|
||||||
return this.personRepository.create({
|
const person = await this.personRepository.create({
|
||||||
ownerId: auth.user.id,
|
ownerId: auth.user.id,
|
||||||
name: dto.name,
|
name: dto.name,
|
||||||
birthDate: dto.birthDate,
|
birthDate: dto.birthDate,
|
||||||
isHidden: dto.isHidden,
|
isHidden: dto.isHidden,
|
||||||
isFavorite: dto.isFavorite,
|
isFavorite: dto.isFavorite,
|
||||||
|
color: dto.color,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return mapPerson(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(auth: AuthDto, id: string, dto: PersonUpdateDto): Promise<PersonResponseDto> {
|
async update(auth: AuthDto, id: string, dto: PersonUpdateDto): Promise<PersonResponseDto> {
|
||||||
await this.requireAccess({ auth, permission: Permission.PERSON_UPDATE, ids: [id] });
|
await this.requireAccess({ auth, permission: Permission.PERSON_UPDATE, ids: [id] });
|
||||||
|
|
||||||
const { name, birthDate, isHidden, featureFaceAssetId: assetId, isFavorite } = dto;
|
const { name, birthDate, isHidden, featureFaceAssetId: assetId, isFavorite, color } = dto;
|
||||||
// TODO: set by faceId directly
|
// TODO: set by faceId directly
|
||||||
let faceId: string | undefined = undefined;
|
let faceId: string | undefined = undefined;
|
||||||
if (assetId) {
|
if (assetId) {
|
||||||
@ -211,6 +214,7 @@ export class PersonService extends BaseService {
|
|||||||
birthDate,
|
birthDate,
|
||||||
isHidden,
|
isHidden,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
|
color,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (assetId) {
|
if (assetId) {
|
||||||
|
@ -31,6 +31,8 @@ describe(SearchService.name, () => {
|
|||||||
it('should pass options to search', async () => {
|
it('should pass options to search', async () => {
|
||||||
const { name } = personStub.withName;
|
const { name } = personStub.withName;
|
||||||
|
|
||||||
|
personMock.getByName.mockResolvedValue([]);
|
||||||
|
|
||||||
await sut.searchPerson(authStub.user1, { name, withHidden: false });
|
await sut.searchPerson(authStub.user1, { name, withHidden: false });
|
||||||
|
|
||||||
expect(personMock.getByName).toHaveBeenCalledWith(authStub.user1.user.id, name, { withHidden: false });
|
expect(personMock.getByName).toHaveBeenCalledWith(authStub.user1.user.id, name, { withHidden: false });
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
import { AssetMapOptions, AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
|
import { AssetMapOptions, AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { PersonResponseDto } from 'src/dtos/person.dto';
|
import { mapPerson, PersonResponseDto } from 'src/dtos/person.dto';
|
||||||
import {
|
import {
|
||||||
|
mapPlaces,
|
||||||
MetadataSearchDto,
|
MetadataSearchDto,
|
||||||
PlacesResponseDto,
|
PlacesResponseDto,
|
||||||
RandomSearchDto,
|
RandomSearchDto,
|
||||||
@ -12,7 +13,6 @@ import {
|
|||||||
SearchSuggestionRequestDto,
|
SearchSuggestionRequestDto,
|
||||||
SearchSuggestionType,
|
SearchSuggestionType,
|
||||||
SmartSearchDto,
|
SmartSearchDto,
|
||||||
mapPlaces,
|
|
||||||
} from 'src/dtos/search.dto';
|
} from 'src/dtos/search.dto';
|
||||||
import { AssetEntity } from 'src/entities/asset.entity';
|
import { AssetEntity } from 'src/entities/asset.entity';
|
||||||
import { AssetOrder } from 'src/enum';
|
import { AssetOrder } from 'src/enum';
|
||||||
@ -24,7 +24,8 @@ import { isSmartSearchEnabled } from 'src/utils/misc';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchService extends BaseService {
|
export class SearchService extends BaseService {
|
||||||
async searchPerson(auth: AuthDto, dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
async searchPerson(auth: AuthDto, dto: SearchPeopleDto): Promise<PersonResponseDto[]> {
|
||||||
return this.personRepository.getByName(auth.user.id, dto.name, { withHidden: dto.withHidden });
|
const people = await this.personRepository.getByName(auth.user.id, dto.name, { withHidden: dto.withHidden });
|
||||||
|
return people.map((person) => mapPerson(person));
|
||||||
}
|
}
|
||||||
|
|
||||||
async searchPlaces(dto: SearchPlacesDto): Promise<PlacesResponseDto[]> {
|
async searchPlaces(dto: SearchPlacesDto): Promise<PlacesResponseDto[]> {
|
||||||
|
@ -12,6 +12,7 @@ import {
|
|||||||
IsArray,
|
IsArray,
|
||||||
IsBoolean,
|
IsBoolean,
|
||||||
IsDate,
|
IsDate,
|
||||||
|
IsHexColor,
|
||||||
IsNotEmpty,
|
IsNotEmpty,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
IsString,
|
IsString,
|
||||||
@ -97,6 +98,15 @@ export function Optional({ nullable, emptyToNull, ...validationOptions }: Option
|
|||||||
return applyDecorators(...decorators);
|
return applyDecorators(...decorators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ValidateHexColor = () => {
|
||||||
|
const decorators = [
|
||||||
|
IsHexColor(),
|
||||||
|
Transform(({ value }) => (typeof value === 'string' && value[0] !== '#' ? `#${value}` : value)),
|
||||||
|
];
|
||||||
|
|
||||||
|
return applyDecorators(...decorators);
|
||||||
|
};
|
||||||
|
|
||||||
type UUIDOptions = { optional?: boolean; each?: boolean; nullable?: boolean };
|
type UUIDOptions = { optional?: boolean; each?: boolean; nullable?: boolean };
|
||||||
export const ValidateUUID = (options?: UUIDOptions) => {
|
export const ValidateUUID = (options?: UUIDOptions) => {
|
||||||
const { optional, each, nullable } = { optional: false, each: false, nullable: false, ...options };
|
const { optional, each, nullable } = { optional: false, each: false, nullable: false, ...options };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user