This commit is contained in:
Evert Prants 2023-01-18 22:48:58 +02:00
parent 43b9dd941b
commit 04aa26288f
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
9 changed files with 100 additions and 37 deletions

View File

@ -54,8 +54,12 @@ import {
import {
StorageCreateRequestDto,
StorageUpdateRequestDto,
StorageWithSetsQueryDto,
} from './dto/storage-request.dto';
import { StorageResponseDto } from './dto/storage-response.dto';
import {
StorageResponseDto,
StorageResponseWithItemCountDto,
} from './dto/storage-response.dto';
import {
StorageSetCreateRequestDto,
StorageSetUpdateRequestDto,
@ -76,10 +80,10 @@ export class AppStorageController {
@Get('storages/:storageId')
@ApiParam({ name: 'storageId', description: 'Storage ID' })
@ApiOperation({ summary: 'Get storage by ID' })
@ApiOkResponse({ type: StorageResponseDto })
@ApiOkResponse({ type: StorageResponseWithItemCountDto })
async getStorage(
@CurrentStorage() storage: Storage,
): Promise<StorageResponseDto> {
): Promise<StorageResponseWithItemCountDto> {
return this.service.getStorageWithItems(storage);
}
@ -147,8 +151,11 @@ export class AppStorageController {
@ApiParam({ name: 'roomId', description: 'Room ID' })
@ApiOperation({ summary: 'Get storages in room' })
@ApiOkResponse({ type: StorageResponseDto, isArray: true })
async getStorages(@CurrentRoom() room: Room) {
return this.service.getStoragesInRoom(room.id);
async getStorages(
@CurrentRoom() room: Room,
@Query() { includeWithSets }: StorageWithSetsQueryDto,
) {
return this.service.getStoragesInRoom(room.id, includeWithSets);
}
@Get('set/room/:roomId')

View File

@ -39,6 +39,7 @@ import {
import {
StorageActorResponse,
StorageResponseDto,
StorageResponseWithItemCountDto,
} from './dto/storage-response.dto';
import {
StorageSetCreateRequestDto,
@ -53,8 +54,11 @@ export class AppStorageService {
private readonly storageService: StorageService,
) {}
async getStoragesInRoom(roomId: number) {
const storages = await this.storageService.getStoragesInRoom(roomId);
async getStoragesInRoom(roomId: number, includeWithSets = false) {
const storages = await this.storageService.getStoragesInRoom(
roomId,
includeWithSets,
);
return storages.map((storage) => this.formatStorageNoItems(storage));
}
@ -358,13 +362,13 @@ export class AppStorageService {
}
async getStorageWithItems(storage: Storage) {
storage = await this.storageService.getStorageById(storage.id, [
'items',
'items.addedBy',
'items.item',
]);
const withItemCount = await this.storageService.getStorageWithItemCount(
storage.id,
);
return this.formatStorageWithItems(storage);
return this.formatStorageNoItems(
withItemCount,
) as StorageResponseWithItemCountDto;
}
private formatActor(input: User): StorageActorResponse {
@ -373,7 +377,7 @@ export class AppStorageService {
private formatStorageNoItems(storage: Storage): StorageResponseDto {
return {
...omit(storage, ['room', 'set', 'items']),
...omit(storage, ['room', 'items']),
addedBy: storage.addedBy && this.formatActor(storage.addedBy),
};
}

View File

@ -1,5 +1,7 @@
import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
IsBoolean,
IsEnum,
IsOptional,
IsString,
@ -36,3 +38,11 @@ export class StorageCreateRequestDto {
export class StorageUpdateRequestDto extends PartialType(
StorageCreateRequestDto,
) {}
export class StorageWithSetsQueryDto {
@ApiPropertyOptional()
@IsBoolean()
@IsOptional()
@Transform(({ value }) => value === 'true' || value === true)
includeWithSets?: boolean;
}

View File

@ -1,4 +1,9 @@
import { ApiPropertyOptional, OmitType, PickType } from '@nestjs/swagger';
import {
ApiProperty,
ApiPropertyOptional,
OmitType,
PickType,
} from '@nestjs/swagger';
import { Storage } from 'src/objects/storage/entities/storage.entity';
import { User } from 'src/objects/user/user.entity';
import { StorageStoredItemResponseDto } from './storage-item-response.dto';
@ -25,3 +30,16 @@ export class StorageResponseDto extends OmitType(Storage, [
})
items?: StorageStoredItemResponseDto[];
}
export class StorageResponseWithItemCountDto extends OmitType(Storage, [
'room',
'items',
'set',
'addedBy',
]) {
@ApiPropertyOptional({ type: StorageActorResponse })
addedBy: StorageActorResponse;
@ApiProperty()
itemCount: number;
}

View File

@ -7,6 +7,9 @@ import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const configService = app.get(ConfigService);
app.enableCors({
origin: configService.get('FRONTEND_URL'),
});
const config = new DocumentBuilder()
.setTitle('Home Manager')
.setDescription('Home manager API')

View File

@ -26,7 +26,7 @@ export class Floor {
number: number;
@ApiProperty()
@Column()
@Column({ type: 'text' })
plan: string;
@ApiProperty({ type: () => Building })

View File

@ -29,7 +29,7 @@ export class Room {
displayName: string;
@ApiProperty()
@Column()
@Column({ type: 'text' })
plan: string;
@ApiProperty()

View File

@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { ILike, Repository } from 'typeorm';
import { ILike, IsNull, Repository } from 'typeorm';
import { StoredItemTransaction } from './entities/item-transaction.entity';
import { Item } from './entities/item.entity';
import { StorageSet } from './entities/storage-set.entity';
@ -31,6 +31,15 @@ export class StorageService {
});
}
async getStorageWithItemCount(storageId: number) {
return this.storageRepository
.createQueryBuilder('storage')
.leftJoinAndSelect('storage.addedBy', 'addedBy')
.loadRelationCountAndMap('storage.itemCount', 'storage.items')
.where('storage.id = :storageId', { storageId })
.getOne();
}
async getStorageByIdAndSub(id: number, sub: string, relations = []) {
return this.storageRepository.findOne({
where: {
@ -127,26 +136,38 @@ export class StorageService {
});
}
async getStoragesInRoom(roomId: number, relations = []) {
return this.storageRepository.find({
where: {
room: {
id: roomId,
},
},
relations,
});
async getStoragesInRoom(roomId: number, includeWithSets = false) {
const qb = this.storageRepository
.createQueryBuilder('storage')
.leftJoin('storage.room', 'storage.room')
.leftJoin('storage.set', 'storage.set')
.loadRelationCountAndMap('storage.itemCount', 'storage.items')
.where('storage.room.id = :roomId', { roomId });
if (!includeWithSets) {
qb.andWhere({ set: IsNull() });
}
qb.addSelect(
'CASE WHEN storage.set IS NULL THEN FALSE ELSE TRUE END',
'storage.hasSet',
);
return qb.getMany();
}
async getStorageSetsInRoom(roomId: number, relations = []) {
return this.storageSetRepository.find({
where: {
room: {
id: roomId,
},
},
relations: ['storages', 'storages.addedBy', ...relations],
});
async getStorageSetsInRoom(roomId: number) {
return this.storageSetRepository
.createQueryBuilder('storageSet')
.leftJoin('storageSet.room', 'storageSet.room')
.leftJoinAndMapMany(
'storageSet.storages',
'storageSet.storages',
'storages',
)
.loadRelationCountAndMap('storages.itemCount', 'storages.items')
.where('storageSet.room.id = :roomId', { roomId })
.getMany();
}
async getItemsInStorage(storageId: number, relations = []) {

View File

@ -34,7 +34,7 @@ export class User {
@Column({ default: false })
emailVerified: boolean;
@Column()
@Column({ type: 'text' })
@Exclude()
password: string;