diff --git a/server/src/domain/person/person.repository.ts b/server/src/domain/person/person.repository.ts index 3c8432be1..973d940cd 100644 --- a/server/src/domain/person/person.repository.ts +++ b/server/src/domain/person/person.repository.ts @@ -4,6 +4,7 @@ export const IPersonRepository = 'IPersonRepository'; export interface PersonSearchOptions { minimumFaceCount: number; + withHidden: boolean; } export interface UpdateFacesData { diff --git a/server/src/domain/person/person.service.spec.ts b/server/src/domain/person/person.service.spec.ts index 7aaa875f2..e5bca7c83 100644 --- a/server/src/domain/person/person.service.spec.ts +++ b/server/src/domain/person/person.service.spec.ts @@ -47,7 +47,7 @@ describe(PersonService.name, () => { visible: 1, people: [responseDto], }); - expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); + expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: false }); }); it('should get all visible people with thumbnails', async () => { personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]); @@ -56,7 +56,7 @@ describe(PersonService.name, () => { visible: 1, people: [responseDto], }); - expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); + expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: false }); }); it('should get all hidden and visible people with thumbnails', async () => { personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]); @@ -73,7 +73,7 @@ describe(PersonService.name, () => { }, ], }); - expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); + expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: true }); }); }); diff --git a/server/src/domain/person/person.service.ts b/server/src/domain/person/person.service.ts index 0f66447f1..187ef3358 100644 --- a/server/src/domain/person/person.service.ts +++ b/server/src/domain/person/person.service.ts @@ -26,8 +26,10 @@ export class PersonService { ) {} async getAll(authUser: AuthUserDto, dto: PersonSearchDto): Promise { - const people = await this.repository.getAll(authUser.id, { minimumFaceCount: 1 }); - + const people = await this.repository.getAll(authUser.id, { + minimumFaceCount: 1, + withHidden: dto.withHidden || false, + }); const persons: PersonResponseDto[] = people // with thumbnails .filter((person) => !!person.thumbnailPath) diff --git a/server/src/infra/repositories/person.repository.ts b/server/src/infra/repositories/person.repository.ts index 859548436..1203bba38 100644 --- a/server/src/infra/repositories/person.repository.ts +++ b/server/src/infra/repositories/person.repository.ts @@ -51,16 +51,22 @@ export class PersonRepository implements IPersonRepository { } getAll(userId: string, options?: PersonSearchOptions): Promise { - return this.personRepository + const queryBuilder = this.personRepository .createQueryBuilder('person') .leftJoin('person.faces', 'face') .where('person.ownerId = :userId', { userId }) - .orderBy('COUNT(face.assetId)', 'DESC') + .orderBy('person.isHidden', 'ASC') + .addOrderBy("NULLIF(person.name, '') IS NULL", 'ASC') + .addOrderBy('COUNT(face.assetId)', 'DESC') .addOrderBy("NULLIF(person.name, '')", 'ASC', 'NULLS LAST') .having('COUNT(face.assetId) >= :faces', { faces: options?.minimumFaceCount || 1 }) .groupBy('person.id') - .limit(500) - .getMany(); + .limit(500); + if (!options?.withHidden) { + queryBuilder.andWhere('person.isHidden = false'); + } + + return queryBuilder.getMany(); } getAllWithoutFaces(): Promise {