TD-36: Implement Administration player filter options
All checks were successful
Quality Check / Linting (pull_request) Successful in 31s
Quality Check / Linting (push) Successful in 31s

This commit is contained in:
Rajbir Singh 2025-03-05 23:20:05 +01:00
parent a4f27ed881
commit f0030f9222
6 changed files with 152 additions and 8 deletions

View file

@ -50,7 +50,7 @@
"stylelint-scss": "^6.11.0",
"typescript": "~5.6.2"
},
"api_version": "v0.0.0-rc.2",
"api_version": "v0.0.0-rc.7",
"volta": {
"node": "22.13.1"
}

View file

@ -1,5 +1,6 @@
import { provideHttpClient } from '@angular/common/http';
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import {MAT_FORM_FIELD_DEFAULT_OPTIONS} from '@angular/material/form-field';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideRouter } from '@angular/router';
import { BASE_PATH, Configuration} from '@core/server';
@ -28,6 +29,7 @@ export const appConfig: ApplicationConfig = {
}
}),
{ provide: BASE_PATH, useValue: 'http://localhost:8080/api/v1' }
{ provide: BASE_PATH, useValue: 'http://localhost:8080/api/v1' },
{ provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'outline' } }
]
};

View file

@ -1,4 +1,6 @@
import { Routes } from '@angular/router';
import { DashboardComponent } from '@app/views/dashboard/dashboard.component';
export const routes: Routes = [{ path: '', component: DashboardComponent, title: 'Home' }];
export const routes: Routes = [{ path: '', component: DashboardComponent, title: 'Player Overview'}];

View file

@ -1,3 +1,43 @@
<div class="dashboard">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Facere illo animi quidem repellat perspiciatis, excepturi amet corrupti ipsa sit consequuntur placeat ratione saepe velit asperiores suscipit esse quod minima exercitationem minus, alias laudantium inventore! Beatae cum nobis error suscipit cupiditate, praesentium itaque ut ipsa iusto in doloribus unde quisquam consequuntur.</p>
@if (authService.$user|async) {
<div class="dashboard__search">
<mat-form-field class="dashboard__search__input-field">
<mat-icon matPrefix>search</mat-icon>
<input matInput placeholder="" #searchbar>
</mat-form-field>
<mat-form-field>
<mat-label>Banned</mat-label>
<mat-select>
<mat-option>Reset</mat-option>
<mat-option>Banned</mat-option>
<mat-option>Not Banned</mat-option>
</mat-select>
</mat-form-field>
<button mat-fab class="shadowless" (click)="onSearch(searchbar)">
<mat-icon>check</mat-icon>
</button>
<button mat-fab class="warn shadowless" (click)="resetFilter(searchbar)">
<mat-icon>backspace</mat-icon>
</button>
</div>
<mat-table [dataSource]="usersDataSource" class="dashboard__table">
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef>Username</th>
<td mat-cell *matCellDef="let user"> {{ user.username }}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th>
<td mat-cell *matCellDef="let user">
<button mat-mini-fab class="warn shadowless" (click)="banPlayer(user)">
<mat-icon>block</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</mat-table>
} @else {
<p>Du musst eingeloggt sein, um dies zu sehen</p>
}
</div>

View file

@ -0,0 +1,33 @@
.dashboard {
display: flex;
flex-direction: column;
gap: 1rem;
&__search {
display: flex;
gap: 1rem;
&__input-field {
flex-grow: 1;
}
}
&__table {
tr, td {
display: flex;
height: auto;
}
.mat-column-username {
flex-grow: 1;
}
th.mat-column-actions {
display: none;
}
td.mat-column-actions {
padding: 0.25rem 0;
}
}
}

View file

@ -1,11 +1,78 @@
import { Component } from '@angular/core';
import {AsyncPipe} from '@angular/common';
import {Component, OnInit} from '@angular/core';
import {MatFabButton, MatMiniFabButton} from '@angular/material/button';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatIcon} from '@angular/material/icon';
import {MatInputModule} from '@angular/material/input';
import {MatSelectModule} from '@angular/material/select';
import {
MatTableDataSource, MatTableModule
} from '@angular/material/table';
import {AuthService} from '@core/auth/auth.service';
import UserData from '@core/auth/UserData';
import {AdministratablePlayer, AdminService, PlayerFilter} from '@core/server';
@Component({
selector: 'app-dashboard',
imports: [],
imports: [
AsyncPipe,
MatIcon,
MatInputModule,
MatTableModule,
MatFormFieldModule,
MatMiniFabButton,
MatFabButton,
MatSelectModule
],
templateUrl: './dashboard.component.html',
styleUrl: './dashboard.component.scss'
})
export class DashboardComponent {
export class DashboardComponent implements OnInit {
displayedColumns: Array<string> = ['username', 'actions'];
usersDataSource: MatTableDataSource<AdministratablePlayer> = new MatTableDataSource<AdministratablePlayer>([]);
constructor(private adminService: AdminService, protected authService: AuthService) {
}
ngOnInit(): void {
this.authService.$user.subscribe((user) => {
if (user != undefined) {
return this.fetchPlayers('');
}
});
}
fetchPlayers(querry: string): void {
const filter: PlayerFilter = {
page: 0,
pageSize: 32,
order: PlayerFilter.OrderEnum.Ascending,
username: querry,
sortBy: 'username'
};
this.adminService.getAllPlayers(filter).subscribe(
(players) => {
this.usersDataSource = new MatTableDataSource<AdministratablePlayer>(players);
},
(error) => {
console.error('Error fetching players:', error);
}
);
}
banPlayer(user: UserData): void {
console.log(`Banning user: ${user.username}`);
// TODO: implement banning logic
}
onSearch(searchbar: HTMLInputElement): void {
this.fetchPlayers(searchbar.value);
}
resetFilter(searchbar: HTMLInputElement): void {
searchbar.value = '';
this.fetchPlayers('');
}
}