From 5fff92bf0c3f13c68c87e26cb79de08ad3bb1018 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Fri, 27 Jan 2023 18:26:32 +0200 Subject: [PATCH] building search --- src/app-building/app-building.controller.ts | 13 +++++++++ src/app-building/app-building.service.ts | 10 +++++++ .../dto/building-search-response.dto.ts | 14 +++++++++ .../dto/buildings-search-request.dto.ts | 9 ++++++ src/objects/building/building.service.ts | 29 ++++++++++++++++++- 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/app-building/dto/building-search-response.dto.ts create mode 100644 src/app-building/dto/buildings-search-request.dto.ts diff --git a/src/app-building/app-building.controller.ts b/src/app-building/app-building.controller.ts index 54fbb2e..7b458e0 100644 --- a/src/app-building/app-building.controller.ts +++ b/src/app-building/app-building.controller.ts @@ -8,6 +8,7 @@ import { ParseIntPipe, Patch, Post, + Query, UseGuards, UseInterceptors, } from '@nestjs/common'; @@ -43,6 +44,8 @@ import { BuildingsCreateRoomRequestDto, BuildingsUpdateRoomRequestDto, } from './dto/buildings-create-room-request.dto'; +import { BuildingSearchRequestDto } from './dto/buildings-search-request.dto'; +import { BuildingSearchResponseDto } from './dto/building-search-response.dto'; @Controller({ path: 'buildings', @@ -75,6 +78,16 @@ export class AppBuildingController { return this.service.createBuilding(user, body); } + @Get('search') + @ApiOperation({ summary: 'Search for buildings' }) + @ApiOkResponse({ isArray: true, type: BuildingSearchResponseDto }) + async searchForBuildings( + @LoggedInUser() user: User, + @Query() query: BuildingSearchRequestDto, + ): Promise { + return this.service.searchForBuilding(query, user); + } + @Get(':id') @ApiParam({ name: 'id', description: 'Building ID' }) @ApiOperation({ summary: 'Get building by ID' }) diff --git a/src/app-building/app-building.service.ts b/src/app-building/app-building.service.ts index 4fd2175..4c820b4 100644 --- a/src/app-building/app-building.service.ts +++ b/src/app-building/app-building.service.ts @@ -20,6 +20,8 @@ import { BuildingsUpdateRoomRequestDto, } from './dto/buildings-create-room-request.dto'; import { PlanRendererService } from './plan-renderer/plan-renderer.service'; +import { BuildingSearchRequestDto } from './dto/buildings-search-request.dto'; +import { BuildingSearchResponseDto } from './dto/building-search-response.dto'; @Injectable() export class AppBuildingService { @@ -298,4 +300,12 @@ export class AppBuildingService { return room; } + + async searchForBuilding( + { searchTerm }: BuildingSearchRequestDto, + { sub }: User, + ) { + const list = await this.buildingService.searchBuilding(searchTerm, sub); + return list.map((building) => new BuildingSearchResponseDto(building)); + } } diff --git a/src/app-building/dto/building-search-response.dto.ts b/src/app-building/dto/building-search-response.dto.ts new file mode 100644 index 0000000..52182f3 --- /dev/null +++ b/src/app-building/dto/building-search-response.dto.ts @@ -0,0 +1,14 @@ +import { PickType } from '@nestjs/swagger'; +import { Building } from 'src/objects/building/entities/building.entity'; + +export class BuildingSearchResponseDto extends PickType(Building, [ + 'id', + 'displayName', + 'address', + 'color', +]) { + constructor(obj: Partial) { + super(); + Object.assign(this, obj); + } +} diff --git a/src/app-building/dto/buildings-search-request.dto.ts b/src/app-building/dto/buildings-search-request.dto.ts new file mode 100644 index 0000000..2f413aa --- /dev/null +++ b/src/app-building/dto/buildings-search-request.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString, MinLength } from 'class-validator'; + +export class BuildingSearchRequestDto { + @ApiProperty() + @IsString() + @MinLength(2) + searchTerm: string; +} diff --git a/src/objects/building/building.service.ts b/src/objects/building/building.service.ts index 2192f02..b50cab5 100644 --- a/src/objects/building/building.service.ts +++ b/src/objects/building/building.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; +import { ILike, Repository } from 'typeorm'; import { GroupService } from '../group/group.service'; import { UserBuildingAccessControl } from './entities/acl.entity'; import { Building } from './entities/building.entity'; @@ -62,6 +62,33 @@ export class BuildingService { }); } + async searchBuilding(searchTerm: string, sub: string, relations = []) { + const search = ILike(`%${searchTerm}%`); + return this.buildingRepository.find({ + where: [ + { + displayName: search, + groups: { + members: { + sub, + }, + }, + }, + { + address: search, + groups: { + members: { + sub, + }, + }, + }, + ], + relations, + take: 16, + select: ['id', 'displayName', 'address', 'color'], + }); + } + async getFloorByBuildingAndUserSub( buildingId: number, floorNumber: number,