AltitudeWeb/frontend/src/app/bans/bans.component.ts
Peter 96cc4610dd Add pagination display and update button styling
Introduce a page number display to the pagination controls for better navigation transparency. Update button styles to use CSS variables for improved theme consistency and maintainability.
2025-04-18 21:54:36 +02:00

214 lines
5.7 KiB
TypeScript

import {Component, OnInit} from '@angular/core';
import {HeaderComponent} from "../header/header.component";
import {HistoryComponent} from './history/history.component';
import {HistoryCount, HistoryService} from '../../api';
import {NgClass, NgForOf, NgIf} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {catchError, map, Observable} from 'rxjs';
@Component({
selector: 'app-bans',
imports: [
HeaderComponent,
HistoryComponent,
NgIf,
FormsModule,
NgForOf,
NgClass
],
templateUrl: './bans.component.html',
styleUrl: './bans.component.scss'
})
export class BansComponent implements OnInit {
constructor(public historyApi: HistoryService) {
}
private PAGE_SIZE: number = 10;
private uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
private actualPage: number = 0;
private totalSearchResults: number = -1;
public active: string = '';
public userType: 'player' | 'staff' = "player";
public punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = "all";
public page: number = 0;
public names: string[] = [];
public finalSearchTerm: string = '';
public searchTerm: string = '';
public filteredNames: string[] = [];
public pageSize = 10;
public historyCount: HistoryCount = {
bans: 0,
mutes: 0,
kicks: 0,
warnings: 0
}
ngOnInit() {
this.historyApi.getUserNames(this.userType, this.punishmentType).subscribe(names => {
this.names = names;
});
this.historyApi.getTotalPunishments().subscribe(totalPunishments => {
this.historyCount = totalPunishments;
})
this.pushState();
window.addEventListener('popstate', (event) => {
if (event.state && event.state.searchTerm !== undefined) {
this.searchTerm = event.state.searchTerm;
this.finalSearchTerm = event.state.searchTerm;
this.page = event.state.page;
this.userType = event.state.userType;
this.punishmentType = event.state.punishmentType;
}
});
}
public getCurrentButtonId(options: 'all' | 'ban' | 'mute' | 'kick' | 'warn') {
if (options == this.punishmentType) {
return 'currentButton'
}
return null;
}
public getCurrentUserTypeButtonId(options: 'player' | 'staff') {
if (options == this.userType) {
return 'currentButton'
}
return null;
}
public filterNames() {
if (!this.searchTerm) {
this.filteredNames = [];
return;
}
this.filteredNames = this.names.filter(name =>
name.toLowerCase().startsWith(this.searchTerm.toLowerCase())
).slice(0, 10);
}
public selectName(name: string) {
this.searchTerm = name;
this.filteredNames = [];
this.search();
}
public search() {
this.pushState()
this.finalSearchTerm = this.searchTerm;
this.page = 0;
if (this.finalSearchTerm.length === 0) {
this.totalSearchResults = -1
return
}
let totalSearchResultsObservable: Observable<number>;
if (this.uuidRegex.test(this.finalSearchTerm)) {
totalSearchResultsObservable = this.historyApi.getTotalResultsForUuidSearch(this.userType, this.punishmentType, this.finalSearchTerm);
} else {
totalSearchResultsObservable = this.historyApi.getTotalResultsForUserSearch(this.userType, this.punishmentType, this.finalSearchTerm);
}
totalSearchResultsObservable.pipe(
map(totalSearchResults => {
this.totalSearchResults = totalSearchResults;
}),
catchError(err => {
console.error(err);
return [];
})
).subscribe();
}
public changeUserType(type: 'player' | 'staff') {
this.pushState();
this.userType = type;
this.page = 0;
this.finalSearchTerm = '';
this.searchTerm = '';
this.filteredNames = [];
}
public changeHistoryPunishment(type: 'all' | 'ban' | 'mute' | 'kick' | 'warn') {
this.pushState();
this.punishmentType = type;
this.page = 0;
}
public nextPage() {
if (this.page === this.getMaxPage()) {
return;
}
this.setPage(this.page + 1)
}
public previousPage() {
if (this.page === 0) {
return;
}
this.setPage(this.page - 1)
}
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.page = page
}
private pushState() {
const state = {
searchTerm: this.searchTerm,
page: this.page,
userType: this.userType,
punishmentType: this.punishmentType
};
const title = 'Altitude Bans';
const url = window.location.href;
window.history.pushState(state, title, url);
}
public getMaxPage() {
const all = this.historyCount.bans + this.historyCount.mutes + this.historyCount.warnings;
if (this.finalSearchTerm.length !== 0) {
return Math.floor(this.totalSearchResults / this.PAGE_SIZE);
}
switch (this.punishmentType) {
case 'all':
return Math.floor(all / this.PAGE_SIZE);
case 'ban':
return Math.floor(this.historyCount.bans / this.PAGE_SIZE);
case 'mute':
return Math.floor(this.historyCount.mutes / this.PAGE_SIZE);
case 'kick':
return Math.floor(this.historyCount.kicks / this.PAGE_SIZE);
case 'warn':
return Math.floor(this.historyCount.warnings / this.PAGE_SIZE);
default:
return 0;
}
}
public buttonActive(compare: number): boolean {
if (compare !== 0 && this.pageSize < this.PAGE_SIZE) {
return false;
}
return this.page !== compare;
}
public updatePageSize(pageSize: number) {
if (pageSize < 0) {
return;
} else {
this.pageSize = pageSize;
this.actualPage = this.page;
}
}
}