From 2fc64672131c06151a89d4be2ba90aa0822387f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Obernd=C3=B6rfer?= Date: Sat, 7 Dec 2024 13:07:05 +0100 Subject: [PATCH 1/5] added possibility to order by task + replaced backupData.dto.ts by BackupData.entity.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Oberndörfer --- .../app/backupData/backupData.controller.ts | 12 +++--- .../src/app/backupData/backupData.service.ts | 25 ++++++++++--- .../src/app/backupData/dto/backupData.dto.ts | 37 ------------------- .../dto/backupDataOrderOptions.dto.ts | 1 + 4 files changed, 27 insertions(+), 48 deletions(-) delete mode 100644 apps/backend/src/app/backupData/dto/backupData.dto.ts diff --git a/apps/backend/src/app/backupData/backupData.controller.ts b/apps/backend/src/app/backupData/backupData.controller.ts index a83e069..936cc78 100644 --- a/apps/backend/src/app/backupData/backupData.controller.ts +++ b/apps/backend/src/app/backupData/backupData.controller.ts @@ -15,12 +15,12 @@ import { ApiTags, } from '@nestjs/swagger'; import { BackupDataService } from './backupData.service'; -import { BackupDataDto } from './dto/backupData.dto'; import { CreateBackupDataDto } from './dto/createBackupData.dto'; import { PaginationDto } from '../utils/pagination/PaginationDto'; import { PaginationOptionsDto } from '../utils/pagination/PaginationOptionsDto'; import { BackupDataFilterDto } from './dto/backupDataFilter.dto'; import { BackupDataOrderOptionsDto } from './dto/backupDataOrderOptions.dto'; +import { BackupDataEntity } from './entity/backupData.entity'; @ApiTags('Backup Data') @Controller('backupData') @@ -31,8 +31,8 @@ export class BackupDataController { @Get(':id') @ApiOperation({ summary: 'Returns the backupData Object with the given id.' }) - @ApiOkResponse({ type: BackupDataDto }) - async getById(@Param('id') id: string): Promise { + @ApiOkResponse({ type: BackupDataEntity }) + async getById(@Param('id') id: string): Promise { const entity = await this.backupDataService.findOneById(id); if (!entity) { throw new NotFoundException(); @@ -48,7 +48,7 @@ export class BackupDataController { @Query() paginationOptionsDto: PaginationOptionsDto, @Query() backupDataFilterDto: BackupDataFilterDto, @Query() backupDataOrderOptionsDto: BackupDataOrderOptionsDto - ): Promise> { + ): Promise> { return this.backupDataService.findAll( paginationOptionsDto, backupDataOrderOptionsDto, @@ -59,12 +59,12 @@ export class BackupDataController { @Post() @ApiOperation({ summary: 'Creates a new backupData Object.' }) @ApiCreatedResponse({ - type: BackupDataDto, + type: BackupDataEntity, description: 'The created Backup Data Object.', }) async create( @Body() createBackupDataDto: CreateBackupDataDto - ): Promise { + ): Promise { return this.backupDataService.create(createBackupDataDto); } diff --git a/apps/backend/src/app/backupData/backupData.service.ts b/apps/backend/src/app/backupData/backupData.service.ts index 1a837f2..04c0026 100644 --- a/apps/backend/src/app/backupData/backupData.service.ts +++ b/apps/backend/src/app/backupData/backupData.service.ts @@ -2,6 +2,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Between, + FindOptionsOrder, FindOptionsWhere, ILike, LessThanOrEqual, @@ -13,10 +14,13 @@ import { CreateBackupDataDto } from './dto/createBackupData.dto'; import { PaginationOptionsDto } from '../utils/pagination/PaginationOptionsDto'; import { PaginationDto } from '../utils/pagination/PaginationDto'; import { PaginationService } from '../utils/pagination/paginationService'; -import { BackupDataDto } from './dto/backupData.dto'; import { BackupDataFilterDto } from './dto/backupDataFilter.dto'; -import { BackupDataOrderOptionsDto } from './dto/backupDataOrderOptions.dto'; +import { + BackupDataOrderByOptions, + BackupDataOrderOptionsDto, +} from './dto/backupDataOrderOptions.dto'; import { BackupType } from './dto/backupType'; +import { SortOrder } from '../utils/pagination/SortOrder'; @Injectable() export class BackupDataService extends PaginationService { @@ -42,7 +46,7 @@ export class BackupDataService extends PaginationService { paginationOptionsDto: PaginationOptionsDto, backupDataOrderOptionsDto: BackupDataOrderOptionsDto, backupDataFilterDto: BackupDataFilterDto - ): Promise> { + ): Promise> { return await this.paginate( this.backupDataRepository, this.createOrderClause(backupDataOrderOptionsDto), @@ -160,10 +164,21 @@ export class BackupDataService extends PaginationService { * Create order clause. * @param backupDataOrderOptionsDto */ - createOrderClause(backupDataOrderOptionsDto: BackupDataOrderOptionsDto) { + createOrderClause( + backupDataOrderOptionsDto: BackupDataOrderOptionsDto + ): FindOptionsOrder { + if ( + backupDataOrderOptionsDto.orderBy === BackupDataOrderByOptions.TASK_NAME + ) { + return { + taskId: { + displayName: backupDataOrderOptionsDto.sortOrder ?? SortOrder.DESC, + }, + }; + } return { [backupDataOrderOptionsDto.orderBy ?? 'creationDate']: - backupDataOrderOptionsDto.sortOrder ?? 'DESC', + backupDataOrderOptionsDto.sortOrder ?? SortOrder.DESC, }; } } diff --git a/apps/backend/src/app/backupData/dto/backupData.dto.ts b/apps/backend/src/app/backupData/dto/backupData.dto.ts deleted file mode 100644 index da9b516..0000000 --- a/apps/backend/src/app/backupData/dto/backupData.dto.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {ApiProperty} from '@nestjs/swagger'; -import { IsEnum, IsNumber, IsString, IsUUID } from 'class-validator'; -import { BackupType } from './backupType'; - -export class BackupDataDto { - @ApiProperty({ - description: 'Uuid', - required: true, - }) - @IsUUID() - id!: string; - - @ApiProperty({ - description: 'Size of Backup in MB', - nullable: false, - required: true, - }) - @IsNumber() - sizeMB!: number; - - @ApiProperty({ - description: 'Backup Type', - nullable: false, - required: true, - enum: BackupType - }) - @IsEnum(BackupType) - type!: BackupType; - - @ApiProperty({ - description: 'Creation Date of Backup', - nullable: false, - required: true, - }) - @IsString() - creationDate!: Date; -} \ No newline at end of file diff --git a/apps/backend/src/app/backupData/dto/backupDataOrderOptions.dto.ts b/apps/backend/src/app/backupData/dto/backupDataOrderOptions.dto.ts index 883f324..eca0276 100644 --- a/apps/backend/src/app/backupData/dto/backupDataOrderOptions.dto.ts +++ b/apps/backend/src/app/backupData/dto/backupDataOrderOptions.dto.ts @@ -6,6 +6,7 @@ export enum BackupDataOrderByOptions { ID = 'id', SIZE = 'sizeMB', BACKUP_DATE = 'creationDate', + TASK_NAME = 'taskName' } export class BackupDataOrderOptionsDto { From 911e13c18092efb413509e8b3ac14db5b3ecb701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Obernd=C3=B6rfer?= Date: Sat, 7 Dec 2024 13:14:31 +0100 Subject: [PATCH 2/5] Added Task column + possibility to order by task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Oberndörfer --- .../backups/backups/backupfilter.ts | 6 +++-- .../backups/backups/backups.component.html | 27 ++++++++++++++++--- .../backups/backups/backups.component.ts | 9 ++++++- .../app/shared/types/backup-filter-type.ts | 2 ++ apps/frontend/src/app/shared/types/backup.ts | 4 +++ 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts b/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts index 345173b..f68e1ae 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts +++ b/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts @@ -9,18 +9,20 @@ export class CustomFilter implements ClrDatagridFilterInterface { fromSizeMB: number | null; toSizeMB: number | null; id: string | null; + taskName: string | null; } = { fromDate: null, toDate: null, fromSizeMB: null, toSizeMB: null, id: null, + taskName: null, }; public changes = new Subject(); - public filterType: 'date' | 'size' | 'id'; + public filterType: 'date' | 'size' | 'id' | 'task'; - constructor(filterType: 'date' | 'size' | 'id') { + constructor(filterType: 'date' | 'size' | 'id' | 'task') { this.filterType = filterType; } diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.html b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.html index 4e1bc3a..d8dee7e 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.html +++ b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.html @@ -82,11 +82,13 @@

All Backups:

clrInput type="string" [(ngModel)]="backupIdFilter.ranges.id" - (ngModelChange)="backupSizeFilter.updateRanges({ id: $event })" + (ngModelChange)="backupIdFilter.updateRanges({ id: $event })" /> - + + + Size (MB) @@ -117,6 +119,24 @@

All Backups:

+ + + Task + + + + + + + + + All Backups: {{ backup.id }} {{ backup.sizeMB }} + {{ backup.taskId?.displayName ?? '' }} {{ backup.creationDate | date }} diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts index c225fc9..d021b1e 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts +++ b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts @@ -46,11 +46,12 @@ export class BackupsComponent implements AfterViewInit, OnDestroy, OnInit { map((config) => config.range) ); - loading: boolean = false; + loading = false; pageSize = 10; backupSizeFilter: CustomFilter; backupDateFilter: CustomFilter; backupIdFilter: CustomFilter; + taskFilter: CustomFilter; readonly backups$: Observable>; readonly chartBackups$: Observable>; @@ -67,6 +68,7 @@ export class BackupsComponent implements AfterViewInit, OnDestroy, OnInit { this.backupSizeFilter = new CustomFilter('size'); this.backupDateFilter = new CustomFilter('date'); this.backupIdFilter = new CustomFilter('id'); + this.taskFilter = new CustomFilter('task'); this.backups$ = this.filterOptions$.pipe( switchMap((params) => this.backupService.getAllBackups(params)), @@ -111,6 +113,7 @@ export class BackupsComponent implements AfterViewInit, OnDestroy, OnInit { this.backupDateFilter.changes.pipe(startWith(null)), this.backupSizeFilter.changes.pipe(startWith(null)), this.backupIdFilter.changes.pipe(startWith(null)), + this.taskFilter.changes.pipe(startWith(null)), ]) .pipe( map(() => this.buildFilterParams()), @@ -176,6 +179,10 @@ export class BackupsComponent implements AfterViewInit, OnDestroy, OnInit { params.id = this.backupIdFilter.ranges.id; } + if (this.taskFilter.isActive()) { + params.taskName = this.taskFilter.ranges.taskName; + } + return params; } diff --git a/apps/frontend/src/app/shared/types/backup-filter-type.ts b/apps/frontend/src/app/shared/types/backup-filter-type.ts index 82d3b14..4c1309d 100644 --- a/apps/frontend/src/app/shared/types/backup-filter-type.ts +++ b/apps/frontend/src/app/shared/types/backup-filter-type.ts @@ -8,4 +8,6 @@ export type BackupFilterParams = { fromSizeMB?: number | null; toSizeMB?: number | null; id?: string | null; + taskId?: string | null; + taskName?: string | null; }; diff --git a/apps/frontend/src/app/shared/types/backup.ts b/apps/frontend/src/app/shared/types/backup.ts index 55bb358..33783ac 100644 --- a/apps/frontend/src/app/shared/types/backup.ts +++ b/apps/frontend/src/app/shared/types/backup.ts @@ -2,4 +2,8 @@ export interface Backup { id: string; sizeMB: number; creationDate: Date; + taskId: { + id: string; + displayName: string; + }; } From 83116765c92a9ad7fdad016437735f3e3bdb6461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Obernd=C3=B6rfer?= Date: Sat, 7 Dec 2024 13:25:53 +0100 Subject: [PATCH 3/5] Fixed task filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Oberndörfer --- .../app/backups-overview/backups/backups/backupfilter.ts | 6 ++++-- .../backups-overview/backups/backups/backups.component.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts b/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts index f68e1ae..bc83eca 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts +++ b/apps/frontend/src/app/backups-overview/backups/backups/backupfilter.ts @@ -20,9 +20,9 @@ export class CustomFilter implements ClrDatagridFilterInterface { }; public changes = new Subject(); - public filterType: 'date' | 'size' | 'id' | 'task'; + public filterType: 'date' | 'size' | 'id' | 'taskName'; - constructor(filterType: 'date' | 'size' | 'id' | 'task') { + constructor(filterType: 'date' | 'size' | 'id' | 'taskName') { this.filterType = filterType; } @@ -31,6 +31,8 @@ export class CustomFilter implements ClrDatagridFilterInterface { return !!(this.ranges.fromDate || this.ranges.toDate); } else if (this.filterType === 'size') { return !!(this.ranges.fromSizeMB || this.ranges.toSizeMB); + } else if (this.filterType === 'taskName') { + return !!this.ranges.taskName; } else { return !!this.ranges.id; } diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts index d021b1e..666d3cb 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts +++ b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.ts @@ -68,7 +68,7 @@ export class BackupsComponent implements AfterViewInit, OnDestroy, OnInit { this.backupSizeFilter = new CustomFilter('size'); this.backupDateFilter = new CustomFilter('date'); this.backupIdFilter = new CustomFilter('id'); - this.taskFilter = new CustomFilter('task'); + this.taskFilter = new CustomFilter('taskName'); this.backups$ = this.filterOptions$.pipe( switchMap((params) => this.backupService.getAllBackups(params)), From b0ee8a347369a182872df34dc2d8a8b8fd188397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Obernd=C3=B6rfer?= Date: Sat, 7 Dec 2024 13:30:58 +0100 Subject: [PATCH 4/5] added test for task filter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Florian Oberndörfer --- .../backups/backups/backups.component.spec.ts | 24 ++++++++++++++++++- apps/frontend/src/app/shared/types/backup.ts | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.spec.ts b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.spec.ts index fd47ac4..f31d584 100644 --- a/apps/frontend/src/app/backups-overview/backups/backups/backups.component.spec.ts +++ b/apps/frontend/src/app/backups-overview/backups/backups/backups.component.spec.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; @@ -126,6 +126,7 @@ describe('BackupsComponent', () => { id: null, fromSizeMB: null, toSizeMB: null, + taskName: null, }; (dateFilter.ranges as any)['_isActive'] = true; @@ -145,6 +146,7 @@ describe('BackupsComponent', () => { fromSizeMB: 100, toSizeMB: 500, id: null, + taskName: null, }; (sizeFilter.ranges as any)['_isActive'] = true; @@ -164,6 +166,7 @@ describe('BackupsComponent', () => { fromSizeMB: null, toSizeMB: null, id: '000d88', + taskName: null, }; (idFilter.ranges as any)['_isActive'] = true; @@ -173,6 +176,25 @@ describe('BackupsComponent', () => { expect(params.id).toBe(idFilter.ranges.id); }); + + it('should build filter params with active task filter', () => { + const taskFilter = new CustomFilter('taskName'); + taskFilter.ranges = { + fromDate: null, + toDate: null, + fromSizeMB: null, + toSizeMB: null, + id: null, + taskName: 'test', + }; + (taskFilter.ranges as any)['_isActive'] = true; + + component['taskFilter'] = taskFilter; + + const params = component['buildFilterParams'](); + + expect(params.taskName).toBe(taskFilter.ranges.taskName); + }); }); describe('Lifecycle Hooks', () => { diff --git a/apps/frontend/src/app/shared/types/backup.ts b/apps/frontend/src/app/shared/types/backup.ts index 33783ac..c3b2a44 100644 --- a/apps/frontend/src/app/shared/types/backup.ts +++ b/apps/frontend/src/app/shared/types/backup.ts @@ -2,7 +2,7 @@ export interface Backup { id: string; sizeMB: number; creationDate: Date; - taskId: { + taskId?: { id: string; displayName: string; }; From 58f7e7932f919be8c463eb88e90e278c50c1a133 Mon Sep 17 00:00:00 2001 From: Christoph Klingenberg Date: Sun, 8 Dec 2024 16:30:15 +0100 Subject: [PATCH 5/5] test error fixed Signed-off-by: Christoph Klingenberg --- apps/backend/src/app/backupData/backupData.controller.ts | 4 +--- apps/backend/src/app/backupData/backupData.service.ts | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/apps/backend/src/app/backupData/backupData.controller.ts b/apps/backend/src/app/backupData/backupData.controller.ts index d756141..664b67d 100644 --- a/apps/backend/src/app/backupData/backupData.controller.ts +++ b/apps/backend/src/app/backupData/backupData.controller.ts @@ -53,11 +53,9 @@ export class BackupDataController { async findAll( @Query() paginationOptionsDto: PaginationOptionsDto, @Query() backupDataFilterDto: BackupDataFilterDto, - @Query() backupDataOrderOptionsDto: BackupDataOrderOptionsDto - ): Promise> { @Query() backupDataOrderOptionsDto: BackupDataOrderOptionsDto, @Body() backupDataFilterByTaskIdsDto?: BackupDataFilterByTaskIdsDto - ): Promise> { + ): Promise> { return this.backupDataService.findAll( paginationOptionsDto, backupDataOrderOptionsDto, diff --git a/apps/backend/src/app/backupData/backupData.service.ts b/apps/backend/src/app/backupData/backupData.service.ts index b08e7fb..11f416b 100644 --- a/apps/backend/src/app/backupData/backupData.service.ts +++ b/apps/backend/src/app/backupData/backupData.service.ts @@ -47,11 +47,9 @@ export class BackupDataService extends PaginationService { async findAll( paginationOptionsDto: PaginationOptionsDto, backupDataOrderOptionsDto: BackupDataOrderOptionsDto, - backupDataFilterDto: BackupDataFilterDto - ): Promise> { backupDataFilterDto: BackupDataFilterDto, backupDataFilterByTaskIdsDto?: BackupDataFilterByTaskIdsDto - ): Promise> { + ): Promise> { return await this.paginate( this.backupDataRepository, this.createOrderClause(backupDataOrderOptionsDto), @@ -59,7 +57,6 @@ export class BackupDataService extends PaginationService { paginationOptionsDto ); } - /** * Create a new backup data entity. * @param createBackupDataDto