Refactor pagination logic and add error handling in history
Introduced `updatePageSize` for better page size management and added checks to prevent rapid page changes. Enhanced error handling in `history.component` with retry logic on failure. Implemented `RemoveTrailingPeriodPipe` for cleaner UI formatting.
This commit is contained in:
parent
53f67a5075
commit
21f2b3e4a5
|
|
@ -48,7 +48,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="historyTable">
|
<div class="historyTable">
|
||||||
<app-history [userType]="userType" [punishmentType]="punishmentType"
|
<app-history [userType]="userType" [punishmentType]="punishmentType"
|
||||||
[page]="page" [searchTerm]="finalSearchTerm" (pageChange)="pageSize = $event">
|
[page]="page" [searchTerm]="finalSearchTerm" (pageChange)="updatePageSize($event)">
|
||||||
</app-history>
|
</app-history>
|
||||||
</div>
|
</div>
|
||||||
<div class="changePageButtons">
|
<div class="changePageButtons">
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,14 @@ export class BansComponent implements OnInit {
|
||||||
public finalSearchTerm: string = '';
|
public finalSearchTerm: string = '';
|
||||||
public searchTerm: string = '';
|
public searchTerm: string = '';
|
||||||
public filteredNames: string[] = [];
|
public filteredNames: string[] = [];
|
||||||
public pageSize = 0;
|
public pageSize = 10;
|
||||||
public historyCount: HistoryCount = {
|
public historyCount: HistoryCount = {
|
||||||
bans: 0,
|
bans: 0,
|
||||||
mutes: 0,
|
mutes: 0,
|
||||||
kicks: 0,
|
kicks: 0,
|
||||||
warnings: 0
|
warnings: 0
|
||||||
}
|
}
|
||||||
|
private actualPage: number = 0;
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.historyApi.getUserNames(this.userType, this.punishmentType).subscribe(names => {
|
this.historyApi.getUserNames(this.userType, this.punishmentType).subscribe(names => {
|
||||||
|
|
@ -108,17 +109,21 @@ export class BansComponent implements OnInit {
|
||||||
if (this.page === this.getMaxPage()) {
|
if (this.page === this.getMaxPage()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setPage(++this.page)
|
this.setPage(this.page + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
public previousPage() {
|
public previousPage() {
|
||||||
if (this.page === 0) {
|
if (this.page === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setPage(--this.page)
|
this.setPage(this.page - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPage(page: number) {
|
public setPage(page: number) {
|
||||||
|
if (this.actualPage !== this.page) {
|
||||||
|
console.warn('Changing page too quickly, the previous page change has not loaded yet');
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.pushState();
|
this.pushState();
|
||||||
this.page = page
|
this.page = page
|
||||||
}
|
}
|
||||||
|
|
@ -159,4 +164,13 @@ export class BansComponent implements OnInit {
|
||||||
}
|
}
|
||||||
return this.page !== compare;
|
return this.page !== compare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public updatePageSize(pageSize: number) {
|
||||||
|
if (pageSize < 0) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.actualPage = this.page;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
<span>{{ entry.punishedBy }}</span>
|
<span>{{ entry.punishedBy }}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="historyReason">{{ entry.reason }}</td>
|
<td class="historyReason">{{ entry.reason | removeTrailingPeriod }}</td>
|
||||||
<td class="historyDate">{{ getPunishmentTime(entry) }}</td>
|
<td class="historyDate">{{ getPunishmentTime(entry) }}</td>
|
||||||
<td class="historyDate">{{ getExpiredTime(entry) }}</td>
|
<td class="historyDate">{{ getExpiredTime(entry) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
|
||||||
import {BASE_PATH, HistoryService, PunishmentHistoryInner} from '../../../api';
|
import {BASE_PATH, HistoryService, PunishmentHistoryInner} from '../../../api';
|
||||||
import {map, Observable, shareReplay} from 'rxjs';
|
import {catchError, map, Observable, shareReplay} from 'rxjs';
|
||||||
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
|
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
|
||||||
import {CookieService} from 'ngx-cookie-service';
|
import {CookieService} from 'ngx-cookie-service';
|
||||||
|
import {RemoveTrailingPeriodPipe} from '../../util/RemoveTrailingPeriodPipe';
|
||||||
|
import {HttpErrorResponse} from '@angular/common/http';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-history',
|
selector: 'app-history',
|
||||||
imports: [
|
imports: [
|
||||||
NgIf,
|
NgIf,
|
||||||
NgForOf,
|
NgForOf,
|
||||||
NgOptimizedImage
|
NgOptimizedImage,
|
||||||
|
RemoveTrailingPeriodPipe
|
||||||
],
|
],
|
||||||
templateUrl: './history.component.html',
|
templateUrl: './history.component.html',
|
||||||
styleUrl: './history.component.scss',
|
styleUrl: './history.component.scss',
|
||||||
|
|
@ -36,7 +39,6 @@ export class HistoryComponent implements OnInit, OnChanges {
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
this.reloadHistory();
|
this.reloadHistory();
|
||||||
this.pageChange.emit(this.history.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
@ -57,6 +59,27 @@ export class HistoryComponent implements OnInit, OnChanges {
|
||||||
historyObservable.pipe(
|
historyObservable.pipe(
|
||||||
map(history => {
|
map(history => {
|
||||||
this.history = history;
|
this.history = history;
|
||||||
|
this.pageChange.emit(this.history.length);
|
||||||
|
}),
|
||||||
|
catchError(err => {
|
||||||
|
this.pageChange.emit(-1);
|
||||||
|
let retrySeconds = 5;
|
||||||
|
|
||||||
|
if (err instanceof HttpErrorResponse) {
|
||||||
|
const headers = err.headers;
|
||||||
|
const retryAfterHeader = headers.get('Retry-After');
|
||||||
|
console.warn(err.error);
|
||||||
|
if (retryAfterHeader) {
|
||||||
|
const retryAfter = parseInt(retryAfterHeader || '0', 10);
|
||||||
|
if (!isNaN(retryAfter) && retryAfter > 0) {
|
||||||
|
retrySeconds = retryAfter + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
setTimeout(() => this.reloadHistory(), retrySeconds * 1000);
|
||||||
|
return this.history;
|
||||||
}),
|
}),
|
||||||
shareReplay(1)
|
shareReplay(1)
|
||||||
).subscribe();
|
).subscribe();
|
||||||
|
|
|
||||||
15
frontend/src/app/util/RemoveTrailingPeriodPipe.ts
Normal file
15
frontend/src/app/util/RemoveTrailingPeriodPipe.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'removeTrailingPeriod',
|
||||||
|
standalone: true
|
||||||
|
})
|
||||||
|
export class RemoveTrailingPeriodPipe implements PipeTransform {
|
||||||
|
transform(value: string): string {
|
||||||
|
if (!value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.endsWith('.') ? value.slice(0, -1) : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user