From 03d67ef362d75056482e88c97fd8c2e86d428e68 Mon Sep 17 00:00:00 2001 From: csimonis Date: Wed, 23 Apr 2025 11:37:11 +0200 Subject: [PATCH] feat: add pagination support for user transactions retrieval --- .../casino/deposit/TransactionRepository.java | 4 +- .../transaction/GetTransactionService.java | 4 +- .../transaction/TransactionController.java | 8 +++- .../transaction-history.component.html | 39 ++++++++++++++-- .../transaction-history.component.ts | 44 +++++++++++++++++-- .../src/app/service/transaction.service.ts | 10 +++-- 6 files changed, 92 insertions(+), 17 deletions(-) diff --git a/backend/src/main/java/de/szut/casino/deposit/TransactionRepository.java b/backend/src/main/java/de/szut/casino/deposit/TransactionRepository.java index 6d092f9..c5a98c6 100644 --- a/backend/src/main/java/de/szut/casino/deposit/TransactionRepository.java +++ b/backend/src/main/java/de/szut/casino/deposit/TransactionRepository.java @@ -16,6 +16,6 @@ public interface TransactionRepository extends JpaRepository findAllByUserId(UserEntity id); - @Query("SELECT t FROM TransactionEntity t WHERE t.user = ?1 ORDER BY t.createdAt DESC LIMIT ?2") - List findByUserIdWithLimit(UserEntity userEntity, Integer limit); + @Query("SELECT t FROM TransactionEntity t WHERE t.user = ?1 ORDER BY t.createdAt DESC LIMIT ?2 OFFSET ?3") + List findByUserIdWithLimit(UserEntity userEntity, Integer limit, Integer offset); } diff --git a/backend/src/main/java/de/szut/casino/user/transaction/GetTransactionService.java b/backend/src/main/java/de/szut/casino/user/transaction/GetTransactionService.java index 5b8cce4..6a83aa7 100644 --- a/backend/src/main/java/de/szut/casino/user/transaction/GetTransactionService.java +++ b/backend/src/main/java/de/szut/casino/user/transaction/GetTransactionService.java @@ -20,11 +20,11 @@ public class GetTransactionService { @Autowired private TransactionRepository transactionRepository; - public List getUserTransactions(String authToken, Integer limit) { + public List getUserTransactions(String authToken, Integer limit, Integer offset) { Optional user = this.userService.getCurrentUser(authToken); if (user.isPresent()) { if (limit != null && limit > 0) { - return this.transactionRepository.findByUserIdWithLimit(user.get(), limit); + return this.transactionRepository.findByUserIdWithLimit(user.get(), limit, offset); } else { return this.transactionRepository.findAllByUserId(user.get()); } diff --git a/backend/src/main/java/de/szut/casino/user/transaction/TransactionController.java b/backend/src/main/java/de/szut/casino/user/transaction/TransactionController.java index c813753..3beb492 100644 --- a/backend/src/main/java/de/szut/casino/user/transaction/TransactionController.java +++ b/backend/src/main/java/de/szut/casino/user/transaction/TransactionController.java @@ -18,8 +18,12 @@ public class TransactionController { private GetTransactionService transactionService; @GetMapping("/user/transactions") - public ResponseEntity> getUserTransactions(@RequestHeader("Authorization") String authToken, @RequestParam(value = "limit", required = false) Integer limit) { - List transactionEntities = this.transactionService.getUserTransactions(authToken, limit); + public ResponseEntity> getUserTransactions( + @RequestHeader("Authorization") String authToken, + @RequestParam(value = "limit", required = false) Integer limit, + @RequestParam(value = "offset", required = false) Integer offset + ) { + List transactionEntities = this.transactionService.getUserTransactions(authToken, limit, offset); return ResponseEntity.ok(this.transactionService.mapTransactionsToDtos(transactionEntities)); } diff --git a/frontend/src/app/feature/transaction-history/transaction-history.component.html b/frontend/src/app/feature/transaction-history/transaction-history.component.html index 8455ed0..78ad158 100644 --- a/frontend/src/app/feature/transaction-history/transaction-history.component.html +++ b/frontend/src/app/feature/transaction-history/transaction-history.component.html @@ -1,10 +1,41 @@ diff --git a/frontend/src/app/feature/transaction-history/transaction-history.component.ts b/frontend/src/app/feature/transaction-history/transaction-history.component.ts index b24ef40..2b658fe 100644 --- a/frontend/src/app/feature/transaction-history/transaction-history.component.ts +++ b/frontend/src/app/feature/transaction-history/transaction-history.component.ts @@ -1,10 +1,21 @@ -import { ChangeDetectionStrategy, Component, EventEmitter, inject, Input, Output } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + EventEmitter, + inject, + Input, + Output, + signal, + WritableSignal, +} from '@angular/core'; import { TransactionService } from '@service/transaction.service'; import { Observable } from 'rxjs'; import { Transaction } from '../../model/Transaction'; import { AsyncPipe, CurrencyPipe, DatePipe, NgForOf, NgIf } from '@angular/common'; import { AnimatedNumberComponent } from '@blackjack/components/animated-number/animated-number.component'; +const PER_PAGE = 5 + @Component({ standalone: true, selector: 'app-transaction-history', @@ -18,18 +29,43 @@ import { AnimatedNumberComponent } from '@blackjack/components/animated-number/a ], templateUrl: './transaction-history.component.html', styleUrl: './transaction-history.component.css', - changeDetection: ChangeDetectionStrategy.OnPush, + changeDetection: ChangeDetectionStrategy.OnPush }) export class TransactionHistoryComponent { @Input() isOpen: boolean = false; - private transactionService: TransactionService = inject(TransactionService); + loading: WritableSignal = signal(true); + skeletonItems = Array(PER_PAGE).fill({}); @Output() closeEventEmitter = new EventEmitter(); - transactions$: Observable = this.transactionService.getUsersTransactions(); + + private offset: number = 0; + + private transactionService: TransactionService = inject(TransactionService); + transactions$: Observable = this.loadTransactions(); closeDialog() { this.isOpen = false; this.closeEventEmitter.emit(); } + + forward() { + this.offset++; + this.transactions$ = this.loadTransactions(); + } + + back() { + this.offset--; + this.transactions$ = this.loadTransactions(); + } + + loadTransactions() { + this.loading.set(true); + + const transactions$ = this.transactionService.getUsersTransactions(PER_PAGE, this.offset * PER_PAGE); + + transactions$.subscribe({complete: () => this.loading.set(false)}) + + return transactions$; + } } diff --git a/frontend/src/app/service/transaction.service.ts b/frontend/src/app/service/transaction.service.ts index a060d77..7fcb659 100644 --- a/frontend/src/app/service/transaction.service.ts +++ b/frontend/src/app/service/transaction.service.ts @@ -7,11 +7,15 @@ import { HttpClient } from '@angular/common/http'; export class TransactionService { private http: HttpClient = inject(HttpClient); - public getUsersTransactions(limit: number|null = null) { - const baseUrl = '/backend/user/transactions'; + public getUsersTransactions(limit: number|null = null, offset: number|null = null) { + let baseUrl = new URL(`${window.location.origin}/backend/user/transactions`); if (limit !== null) { - return this.http.get(`${baseUrl}?limit=${limit}`); + baseUrl.searchParams.append('limit', limit.toString()); + } + + if (offset !== null) { + baseUrl.searchParams.append('offset', offset.toString()); } return this.http.get(`${baseUrl}`);