add sort with angular material

This commit is contained in:
Marcel-Anker
2025-11-22 16:25:04 +01:00
parent 6c13b5ab3f
commit c10da6f213
3 changed files with 102 additions and 95 deletions

View File

@@ -28,6 +28,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { MatPaginatorModule } from '@angular/material/paginator'; import { MatPaginatorModule } from '@angular/material/paginator';
import { MatTableModule } from '@angular/material/table'; import { MatTableModule } from '@angular/material/table';
import {MatSelectModule} from '@angular/material/select'; import {MatSelectModule} from '@angular/material/select';
import { MatSortModule } from '@angular/material/sort';
import { HeaderComponent } from './header/header.component'; import { HeaderComponent } from './header/header.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
@@ -78,6 +79,7 @@ import { PricelistComponent } from './pricelist/pricelist.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
App, App,
@@ -128,39 +130,40 @@ import { PricelistComponent } from './pricelist/pricelist.component';
CancelOrderDialog, CancelOrderDialog,
PricelistComponent, PricelistComponent,
], ],
imports: [ imports: [
AppRoutingModule, AppRoutingModule,
BrowserModule, BrowserModule,
ReactiveFormsModule, ReactiveFormsModule,
CommonModule, CommonModule,
FormsModule, FormsModule,
MatIconModule, MatIconModule,
MatTabsModule, MatTabsModule,
MatToolbarModule, MatToolbarModule,
MatProgressBarModule, MatProgressBarModule,
MatProgressSpinnerModule, MatProgressSpinnerModule,
MatSnackBarModule, MatSnackBarModule,
MatAutocompleteModule, MatAutocompleteModule,
MatInputModule, MatInputModule,
MatFormFieldModule, MatFormFieldModule,
MatIconButton, MatIconButton,
MatDividerModule, MatDividerModule,
MatButtonModule, MatButtonModule,
MatDialogClose, MatDialogClose,
MatDialogTitle, MatDialogTitle,
MatDialogContent, MatDialogContent,
MatDialogActions, MatDialogActions,
MatCheckboxModule, MatCheckboxModule,
MatStepperModule, MatStepperModule,
NgxMaskDirective, NgxMaskDirective,
NgxMaskPipe, NgxMaskPipe,
QRCodeComponent, QRCodeComponent,
MatBadgeModule, MatBadgeModule,
MatTooltipModule, MatTooltipModule,
MatPaginatorModule, MatPaginatorModule,
MatTableModule, MatTableModule,
MatSelectModule, MatSelectModule,
], MatSortModule,
],
providers: [ providers: [
provideBrowserGlobalErrorListeners(), provideBrowserGlobalErrorListeners(),
provideHttpClient( provideHttpClient(

View File

@@ -2,40 +2,29 @@
<h2 class="text-2xl font-bold flex flex justify-center gradient-text"> Movie-Statistiken </h2> <h2 class="text-2xl font-bold flex flex justify-center gradient-text"> Movie-Statistiken </h2>
<mat-form-field appearance="fill">
<mat-label>Filter</mat-label>
<mat-select (selectionChange)="filterByCategory($event.value)">
<mat-option value="na" class="flex justify-center"></mat-option>
@for(filterValue of valuesToFilter; track $index){
<mat-option [value]="filterValue" class="flex justify-center"> {{filterValue}} </mat-option>
}
</mat-select>
</mat-form-field>
<div class="table-table-container"> <div class="table-table-container">
<table mat-table [dataSource]="movies" class="example-table"> <table mat-table [dataSource]="moviesDS" matSort #movieSort="matSort" class="example-table">
<ng-container matColumnDef="id"> <ng-container matColumnDef="movieId">
<th mat-header-cell *matHeaderCellDef>ID</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="movieId" sortActionDescription="Sort by movieId">ID</th>
<td mat-cell *matCellDef="let row">{{row.movieId}}</td> <td mat-cell *matCellDef="let row">{{row.movieId}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="title"> <ng-container matColumnDef="movieTitle">
<th mat-header-cell *matHeaderCellDef>Titel</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="movieTitle" sortActionDescription="Sort by movieTitle">Titel</th>
<td mat-cell *matCellDef="let row">{{row.movieTitle}}</td> <td mat-cell *matCellDef="let row">{{row.movieTitle}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="earnings"> <ng-container matColumnDef="movieEarnings">
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell *matHeaderCellDef mat-sort-header="earnings" sortActionDescription="Sort by movieEarnings">
Umsatz Umsatz
</th> </th>
<td mat-cell *matCellDef="let row">{{(row.earnings/100).toFixed(2)}} €</td> <td mat-cell *matCellDef="let row">{{(row.earnings/100).toFixed(2)}} €</td>
</ng-container> </ng-container>
<ng-container matColumnDef="tickets"> <ng-container matColumnDef="movieTickets">
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell *matHeaderCellDef mat-sort-header="tickets" sortActionDescription="Sort by movieTickets">
Gebuchte Tickets Gebuchte Tickets
</th> </th>
<td mat-cell *matCellDef="let row">{{row.tickets}}</td> <td mat-cell *matCellDef="let row">{{row.tickets}}</td>
@@ -52,38 +41,38 @@
<h2 class="text-2xl font-bold flex flex justify-center gradient-text"> Show-Statistiken </h2> <h2 class="text-2xl font-bold flex flex justify-center gradient-text"> Show-Statistiken </h2>
<div class="show-table-container"> <div class="show-table-container">
<table mat-table [dataSource]="shows" class="example-table"> <table mat-table [dataSource]="showsDS" matSort #showSort="matSort" class="example-table">
<ng-container matColumnDef="id"> <ng-container matColumnDef="showId">
<th mat-header-cell *matHeaderCellDef>ID</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="showId">ID</th>
<td mat-cell *matCellDef="let row">{{row.showId}}</td> <td mat-cell *matCellDef="let row">{{row.showId}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="hall"> <ng-container matColumnDef="showHall">
<th mat-header-cell *matHeaderCellDef>Kinosaal</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="showHallName">Kinosaal</th>
<td mat-cell *matCellDef="let row">{{row.showHallName}}</td> <td mat-cell *matCellDef="let row">{{row.showHallName}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="movie_title"> <ng-container matColumnDef="showMovieTitle">
<th mat-header-cell *matHeaderCellDef>Film Name</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="movieTitle">Film Name</th>
<td mat-cell *matCellDef="let row">{{row.movieTitle}}</td> <td mat-cell *matCellDef="let row">{{row.movieTitle}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="date"> <ng-container matColumnDef="showDate">
<th mat-header-cell *matHeaderCellDef>Datum</th> <th mat-header-cell *matHeaderCellDef mat-sort-header="showStart">Datum</th>
<td mat-cell *matCellDef="let row">{{formatDate(row.showStart)}}</td> <td mat-cell *matCellDef="let row">{{formatDate(row.showStart)}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="earnings"> <ng-container matColumnDef="showEarnings">
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell *matHeaderCellDef mat-sort-header="earnings">
Umsatz Umsatz
</th> </th>
<td mat-cell *matCellDef="let row">{{(row.earnings/100).toFixed(2)}} €</td> <td mat-cell *matCellDef="let row">{{(row.earnings/100).toFixed(2)}} €</td>
</ng-container> </ng-container>
<ng-container matColumnDef="tickets"> <ng-container matColumnDef="showTickets">
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell *matHeaderCellDef mat-sort-header="tickets">
Gebuchte Tickets Gebuchte Tickets
</th> </th>
<td mat-cell *matCellDef="let row">{{row.tickets}}</td> <td mat-cell *matCellDef="let row">{{row.tickets}}</td>

View File

@@ -1,11 +1,15 @@
import {Component, inject} from '@angular/core'; import {Component, effect, inject, signal, ViewChild} from '@angular/core';
import {MatSort, Sort, MatSortModule} from '@angular/material/sort';
import {HttpService} from '../http.service'; import {HttpService} from '../http.service';
import { import {
StatisticsFilm, StatisticsFilm,
StatisticsVorstellung, StatisticsVorstellung,
} from '@infinimotion/model-frontend'; } from '@infinimotion/model-frontend';
import {LoadingService} from '../loading.service'; import {LoadingService} from '../loading.service';
import {filter, firstValueFrom, forkJoin} from 'rxjs'; import {firstValueFrom} from 'rxjs';
import {MatTableDataSource} from '@angular/material/table';
import {MatPaginatorModule} from '@angular/material/paginator';
@Component({ @Component({
selector: 'app-statistics', selector: 'app-statistics',
@@ -15,19 +19,30 @@ import {filter, firstValueFrom, forkJoin} from 'rxjs';
}) })
export class StatisticsComponent { export class StatisticsComponent {
private http = inject(HttpService); private http = inject(HttpService);
protected movies: StatisticsFilm[] = []; protected movies = signal<StatisticsFilm[]>([]);
protected shows: StatisticsVorstellung[] = []; protected shows = signal<StatisticsVorstellung[]>([]);
protected moviesDisplayedColumns: string[] = ['id', 'title', 'earnings', 'tickets']; protected moviesDisplayedColumns: string[] = ['movieId', 'movieTitle', 'movieEarnings', 'movieTickets'];
protected showsDisplayedColumns: string[] = ['id', 'hall', 'movie_title', 'date', 'earnings', 'tickets']; protected showsDisplayedColumns: string[] = ['showId', 'showHall', 'showMovieTitle', 'showDate', 'showEarnings', 'showTickets'];
protected valuesToFilter: string[] = ['title', 'date', 'earnings', 'tickets'];
protected movieResultsLength: number = 0; protected movieResultsLength: number = 0;
protected showsResultLength: number = 0; protected showsResultLength: number = 0;
protected moviesDS = new MatTableDataSource<StatisticsFilm>();
protected showsDS = new MatTableDataSource<StatisticsVorstellung>();
// Sorting + Pagination
@ViewChild('movieSort') movieSort!: MatSort;
@ViewChild('showSort') showSort!: MatSort;
private loading = inject(LoadingService); private loading = inject(LoadingService);
ngOnInit(): void { ngOnInit(): void {
this.loading.show() this.loading.show()
this.loadData().then(); this.loadData().then();
this.setupSortingAccessors()
}
ngAfterViewInit() {
this.moviesDS.sort = this.movieSort;
this.showsDS.sort = this.showSort;
} }
async loadData() { async loadData() {
@@ -35,8 +50,10 @@ export class StatisticsComponent {
let showRequest = this.http.getShowStatistics(); let showRequest = this.http.getShowStatistics();
let movieResponse = await firstValueFrom(movieRequest); let movieResponse = await firstValueFrom(movieRequest);
let showResponse = await firstValueFrom(showRequest); let showResponse = await firstValueFrom(showRequest);
this.movies = movieResponse this.movies.set(movieResponse);
this.shows = showResponse this.shows.set(showResponse);
this.moviesDS.data = movieResponse;
this.showsDS.data = showResponse;
if (this.movies.length / 30 < 1) { if (this.movies.length / 30 < 1) {
this.movieResultsLength = 1; this.movieResultsLength = 1;
} else { } else {
@@ -54,26 +71,24 @@ export class StatisticsComponent {
return new Date(date).toLocaleString("de"); return new Date(date).toLocaleString("de");
} }
filterByCategory(filter: string) { private setupSortingAccessors() {
switch (filter) { // Movies
case this.valuesToFilter[0]: //title this.moviesDS.sortingDataAccessor = (item, property) => {
this.movies = this.movies.sort((a, b) => a.movieTitle.localeCompare(b.movieTitle)); switch (property) {
this.shows = this.shows.sort((a, b) => a.movieTitle.localeCompare(b.movieTitle)); case 'earnings': return item.earnings;
//console.log(this.movies, this.shows); case 'tickets': return item.tickets;
break; default: return (item as any)[property];
case this.valuesToFilter[1]: //date }
this.shows = this.shows.sort((a,b) => new Date(a.showStart).getTime() - new Date(b.showStart).getTime()); };
break;
case this.valuesToFilter[2]: //earnings
this.movies = this.movies.sort((a, b) => a.earnings - b.earnings);
this.shows = this.shows.sort((a, b) => a.earnings - b.earnings);
break;
case this.valuesToFilter[3]: //tickets
this.movies = this.movies.sort((a, b) => a.tickets - b.tickets);
this.shows = this.shows.sort((a, b) => a.tickets - b.tickets);
break;
default:
}
// Shows
this.showsDS.sortingDataAccessor = (item, property) => {
switch (property) {
case 'showStart': return new Date(item.showStart).getTime();
case 'earnings': return item.earnings;
case 'tickets': return item.tickets;
default: return (item as any)[property];
}
};
} }
} }