fix theming + ui improvements
This commit is contained in:
@@ -1,14 +1,26 @@
|
||||
<h1>Startseite</h1>
|
||||
<ul>
|
||||
<!--TODO fix theming/colors-->
|
||||
<button matButton="outlined" class="warn-button" [routerLink]="['/test']">
|
||||
Entwichlungsinformationen
|
||||
</button>
|
||||
<button matButton="filled" color="primary" [routerLink]="['/list']">Mitglieder</button>
|
||||
<button matButton="filled" color="warn" [routerLink]="['/manageUsers']">
|
||||
Benutzer Verwalten
|
||||
</button>
|
||||
<button matButton="filled" color="primary" [routerLink]="['/exam']">
|
||||
Prüfungsanmeldung
|
||||
</button>
|
||||
</ul>
|
||||
<mat-list>
|
||||
<mat-list-item [claimGuard]="Claim.Memberadmin">
|
||||
<button matButton="filled" color="primary" [routerLink]="['/list']">
|
||||
Mitgliederliste
|
||||
</button>
|
||||
</mat-list-item>
|
||||
<mat-list-item [claimGuard]="Claim.Useradmin">
|
||||
<button matButton="filled" color="warn" [routerLink]="['/manageUsers']">
|
||||
Benutzer Verwalten
|
||||
</button>
|
||||
</mat-list-item>
|
||||
<mat-list-item [claimGuard]="Claim.Memberadmin">
|
||||
<button matButton="filled" color="primary" [routerLink]="['/exam']">
|
||||
Prüfungsanmeldung
|
||||
</button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<button
|
||||
matButton="outlined"
|
||||
class="warn-button"
|
||||
[routerLink]="['/test']">
|
||||
Entwichlungsinformationen
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { ClaimGuardDirective } from '../../directives/claim-guard.directive';
|
||||
import { Claim } from '../../generated-api/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
imports: [RouterModule, MatButtonModule],
|
||||
templateUrl: './home.html',
|
||||
styleUrl: './home.scss',
|
||||
selector: 'app-home',
|
||||
imports: [
|
||||
RouterModule,
|
||||
MatButtonModule,
|
||||
MatListModule,
|
||||
ClaimGuardDirective,
|
||||
],
|
||||
templateUrl: './home.html',
|
||||
styleUrl: './home.scss',
|
||||
})
|
||||
export class Home {
|
||||
|
||||
protected Claim = Claim;
|
||||
}
|
||||
|
||||
@@ -1,142 +1,180 @@
|
||||
<h1>Mitglieder & Sportlerübersicht</h1>
|
||||
<button mat-raised-button color="accent" (click)="newMember()">
|
||||
Neues Mitglied
|
||||
</button>
|
||||
<div class="filter-container mat-elevation-z8">
|
||||
<div class="filter-header">
|
||||
<mat-form-field>
|
||||
<label>Filter:</label>
|
||||
<div>
|
||||
<h1>Mitglieder & Sportlerübersicht</h1>
|
||||
</div>
|
||||
<div>
|
||||
<button matButton="filled" class="primary-btn" (click)="newMember()">
|
||||
Neues Mitglied
|
||||
</button>
|
||||
</div>
|
||||
<div class="filter-container">
|
||||
<mat-form-field>
|
||||
<label>Filter:</label>
|
||||
<input matInput [formControl]="filterControl" placeholder="Filter" />
|
||||
</mat-form-field>
|
||||
<div class="status-filters">
|
||||
<mat-radio-group [formControl]="statusControl">
|
||||
<mat-radio-button [value]="MemberStatusFilter.ACTIVE"
|
||||
>Aktiv</mat-radio-button
|
||||
>
|
||||
<mat-radio-button [value]="MemberStatusFilter.INACTIVE"
|
||||
>Inaktiv</mat-radio-button
|
||||
>
|
||||
<mat-radio-button [value]="MemberStatusFilter.ALL"
|
||||
>Alle</mat-radio-button
|
||||
>
|
||||
</mat-radio-group>
|
||||
<mat-form-field
|
||||
matTooltip="Zeigt nur Mitglieder, die zum angegebenen Datum den ausgewählten status hatten"
|
||||
matTooltipPosition="above">
|
||||
<label>Zum Datum:</label>
|
||||
<input
|
||||
matInput
|
||||
[formControl]="filterControl"
|
||||
placeholder="Filter" />
|
||||
[matDatepicker]="picker"
|
||||
[formControl]="statusDateControl"
|
||||
placeholder="Aktiv bis" />
|
||||
<mat-hint>DD.MM.YYYY</mat-hint>
|
||||
<mat-datepicker-toggle
|
||||
matIconSuffix
|
||||
[disabled]="statusControl.value===MemberStatusFilter.ALL"
|
||||
[for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<div class="status-filters">
|
||||
<mat-radio-group [formControl]="statusControl">
|
||||
<mat-radio-button [value]="MemberStatusFilter.ACTIVE"
|
||||
>Aktiv</mat-radio-button
|
||||
>
|
||||
<mat-radio-button [value]="MemberStatusFilter.INACTIVE"
|
||||
>Inaktiv</mat-radio-button
|
||||
>
|
||||
<mat-radio-button [value]="MemberStatusFilter.ALL"
|
||||
>Alle</mat-radio-button
|
||||
>
|
||||
</mat-radio-group>
|
||||
<mat-form-field
|
||||
matTooltip="Zeigt nur Mitglieder, die zum angegebenen Datum den ausgewählten status hatten"
|
||||
matTooltipPosition="above">
|
||||
<label>Zum Datum:</label>
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="picker"
|
||||
[formControl]="statusDateControl"
|
||||
[disabled]="statusControl.value===MemberStatusFilter.ALL"
|
||||
placeholder="Aktiv bis" />
|
||||
<mat-hint>DD.MM.YYYY</mat-hint>
|
||||
<mat-datepicker-toggle
|
||||
matIconSuffix
|
||||
[disabled]="statusControl.value===MemberStatusFilter.ALL"
|
||||
[for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-checkbox [formControl]="onlyWithID"
|
||||
>Nur mit Passnummer</mat-checkbox
|
||||
>
|
||||
</div>
|
||||
<mat-checkbox [formControl]="onlyWithID">Nur mit Passnummer</mat-checkbox>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<!--TODO implement row count, selecting and alternating colors-->
|
||||
<table
|
||||
mat-table
|
||||
[dataSource]="dataSource"
|
||||
class="member-table"
|
||||
matSort
|
||||
matSortActive="vorname"
|
||||
matSortDirection="asc"
|
||||
matSortDisableClear>
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>Bearb.</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
mat-mini-fab-button
|
||||
(click)="editMember(element.id)"
|
||||
aria-label="Edit Member">
|
||||
<mat-icon fontIcon="edit"></mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!--TODO implement row count, selecting and alternating colors-->
|
||||
<table mat-table matSort [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<ng-container matColumnDef="edit">
|
||||
<th mat-header-cell *matHeaderCellDef>Bearb.</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
mat-mini-fab-button
|
||||
(click)="editMember(element.id)"
|
||||
aria-label="Edit Member">
|
||||
<mat-icon fontIcon="edit"></mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef>Entf.</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
mat-mini-fab-button
|
||||
(click)="deleteMember(element.id)"
|
||||
aria-label="Delete Member">
|
||||
<mat-icon fontIcon="delete"></mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="vorname">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Vorname</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span [innerHTML]="element.vorname | stylizeNames"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="nachname">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Nachname</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span [innerHTML]="element.nachname | stylizeNames"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geschlecht">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Geschlecht</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.geschlecht }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="passnummer">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Passnummer</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.passnummer | nobreakHyphen }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geburtsdatum">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Geburtsdatum</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.geburtsdatum | datePipe }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geburtsort">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Geburtsort</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.geburtsort }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="verein">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Vereinsmitgliedschaft
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@if(element.verein){
|
||||
<mat-icon
|
||||
class="positive"
|
||||
aria-label="Verein Check"
|
||||
fontIcon="check"></mat-icon>
|
||||
}@else {
|
||||
<ng-container matColumnDef="index" sticky>
|
||||
<th mat-header-cell *matHeaderCellDef>Nr.</th>
|
||||
<td mat-cell *matCellDef="let element; let i=index">{{i+1}}</td>
|
||||
</ng-container>
|
||||
|
||||
<mat-icon
|
||||
class="negative"
|
||||
aria-label="Verein Cross"
|
||||
fontIcon="close"></mat-icon>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="vorname">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Vorname</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span [innerHTML]="element.vorname | stylizeNames"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="nachname">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Nachname</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span [innerHTML]="element.nachname | stylizeNames"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geschlecht">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Geschlecht
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.geschlecht }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="passnummer">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Passnummer
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.passnummer | nobreakHyphen }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geburtsdatum">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Geburtsdatum
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.geburtsdatum | datePipe }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="geburtsort">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Geburtsort
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.geburtsort }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="verein">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Vereinsmitgliedschaft
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@if(element.verein){
|
||||
<mat-icon
|
||||
class="positive"
|
||||
aria-label="Verein Check"
|
||||
fontIcon="check"></mat-icon>
|
||||
}@else {
|
||||
|
||||
<ng-container matColumnDef="kontakt">
|
||||
<th mat-header-cell *matHeaderCellDef>Kontakt</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.kontakt }}</td>
|
||||
</ng-container>
|
||||
<mat-icon
|
||||
class="negative"
|
||||
aria-label="Verein Cross"
|
||||
fontIcon="close"></mat-icon>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="kuendigungzum">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Kündigung zum
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ (element.kuendigungzum | datePipe) ?? "-" }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="kontakt">
|
||||
<th mat-header-cell *matHeaderCellDef>Kontakt</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.kontakt }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
<ng-container matColumnDef="kuendigungzum">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Kündigung zum
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ (element.kuendigungzum | datePipe) ?? "-" }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="delete">
|
||||
<th mat-header-cell *matHeaderCellDef>Entf.</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button
|
||||
mat-mini-fab-button
|
||||
(click)="deleteMember(element.id)"
|
||||
aria-label="Delete Member">
|
||||
<mat-icon fontIcon="delete"></mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="totalCount">
|
||||
<td
|
||||
colspan="100%"
|
||||
mat-footer-cell
|
||||
*matFooterCellDef
|
||||
class="footer-entry">
|
||||
Zeige {{dataSource.filteredData.length}} von
|
||||
{{dataSource.data.length}} Mitgliedern
|
||||
@if(dataSource.filteredData.length !== dataSource.data.length)
|
||||
{(gefiltert) }
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr
|
||||
mat-header-row
|
||||
*matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr
|
||||
mat-row
|
||||
*matRowDef="let row; columns: displayedColumns"
|
||||
class="table-row"></tr>
|
||||
<tr mat-footer-row *matFooterRowDef="['totalCount']; sticky: true"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
mat-radio-group {
|
||||
@use "@angular/material" as mat;
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
// overflow: auto;
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
.filter-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
justify-content: start;
|
||||
gap: 5vw;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow: auto;
|
||||
border: 1px solid var(--mat-sys-outline);
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mat-radio-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.status-filters {
|
||||
@@ -19,3 +36,16 @@ mat-form-field {
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid var(--mat-sys-outline-variant);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.table-row:nth-child(even) {
|
||||
background-color: var(--mat-sys-surface-variant);
|
||||
}
|
||||
|
||||
.table-row:nth-child(odd) {
|
||||
background-color: var(--mat-sys-surface);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AfterViewInit, Component, viewChild } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCheckbox } from '@angular/material/checkbox';
|
||||
@@ -62,7 +63,7 @@ export class ViewMembers implements AfterViewInit {
|
||||
|
||||
protected readonly displayedColumns: string[] = [
|
||||
'edit',
|
||||
'delete',
|
||||
'index',
|
||||
'vorname',
|
||||
'nachname',
|
||||
'geschlecht',
|
||||
@@ -72,6 +73,7 @@ export class ViewMembers implements AfterViewInit {
|
||||
'verein',
|
||||
'kontakt',
|
||||
'kuendigungzum',
|
||||
'delete',
|
||||
];
|
||||
|
||||
protected deleteMember(memberId: any) {
|
||||
@@ -157,6 +159,7 @@ export class ViewMembers implements AfterViewInit {
|
||||
return originalFilterPredicate(
|
||||
{
|
||||
...data,
|
||||
id: null,
|
||||
geburtsdatum: this.datePipe.transform(
|
||||
data.geburtsdatum ?? undefined,
|
||||
),
|
||||
@@ -189,7 +192,22 @@ export class ViewMembers implements AfterViewInit {
|
||||
const date = combined[2];
|
||||
const onlyWithID = combined[3];
|
||||
this.dataSource.filter = `${filter?.replaceAll(';', '') ?? ''};${status};${date?.toISOString()};${onlyWithID}`;
|
||||
console.log('filter', this.dataSource.filter);
|
||||
});
|
||||
|
||||
this.statusControl.valueChanges
|
||||
.pipe(takeUntilDestroyed())
|
||||
.subscribe(value => {
|
||||
if (
|
||||
value === MemberStatusFilter.ALL &&
|
||||
this.statusDateControl.enabled
|
||||
) {
|
||||
return this.statusDateControl.disable();
|
||||
} else if (
|
||||
value !== MemberStatusFilter.ALL &&
|
||||
this.statusDateControl.disabled
|
||||
) {
|
||||
return this.statusDateControl.enable();
|
||||
}
|
||||
});
|
||||
|
||||
this.updateData();
|
||||
@@ -202,8 +220,6 @@ export class ViewMembers implements AfterViewInit {
|
||||
|
||||
private async updateData(): Promise<void> {
|
||||
const members = await api.getMembers();
|
||||
console.log('Members loaded');
|
||||
console.dir(members);
|
||||
this.dataSource.data = members;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user