event subscriptions
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<h1>Gesammelte Veranstaltungen</h1>
|
||||
<p>
|
||||
<button matButton="filled" (click)="subscribe()">Abbonieren</button>
|
||||
<button matButton="filled" class="secondary-btn" (click)="unsubscribe()">
|
||||
Abmelden
|
||||
</button>
|
||||
</p>
|
||||
<div class="table-container">
|
||||
<table mat-table [dataSource]="datasource" matSort>
|
||||
<ng-container matColumnDef="source">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Gefunden bei
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [href]="element.source"
|
||||
>{{truncateSource(element.source)}}</a
|
||||
>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="url">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Link</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a
|
||||
matButton
|
||||
[href]="element.url"
|
||||
target="_blank"
|
||||
[ellipsis]="80"
|
||||
>{{element.url}}</a
|
||||
>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="eventDate">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Ausrichtungsdatum
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.eventDate}}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="title">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>Titel</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.title}}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="description">
|
||||
<th mat-header-cell mat-sort-header *matHeaderCellDef>
|
||||
Beschreibung
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.description}}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="attachedFiles">
|
||||
<th mat-header-cell *matHeaderCellDef>Anhänge</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
@for(attachment of element.attachedFiles; track attachment.id){
|
||||
<a matButton="outlined" [href]="attachment.url" target="_blank"
|
||||
>{{attachment.title??'?'}}</a
|
||||
>
|
||||
}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr
|
||||
mat-header-row
|
||||
*matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
:host {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
// overflow: auto;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow: auto;
|
||||
border: 1px solid var(--mat-sys-outline);
|
||||
min-height: 400px;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { Events } from './events';
|
||||
|
||||
describe('Events', () => {
|
||||
let component: Events;
|
||||
let fixture: ComponentFixture<Events>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [Events]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(Events);
|
||||
component = fixture.componentInstance;
|
||||
await fixture.whenStable();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
inject,
|
||||
OnInit,
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatSort, MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
||||
import { parse } from 'date-fns';
|
||||
import { Ellipsis } from '../../directives/ellipsis/ellipsis';
|
||||
import * as api from '../../generated-api/api';
|
||||
import { PushService } from '../../services/push/pushService';
|
||||
|
||||
@Component({
|
||||
selector: 'app-events',
|
||||
imports: [MatTableModule, MatSortModule, MatButtonModule, Ellipsis],
|
||||
templateUrl: './events.html',
|
||||
styleUrl: './events.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class Events implements OnInit {
|
||||
private readonly pushService = inject(PushService);
|
||||
protected readonly datasource = new MatTableDataSource<api.FoundEventDto>();
|
||||
protected readonly sort = viewChild.required(MatSort);
|
||||
protected readonly displayedColumns = [
|
||||
'eventDate',
|
||||
'title',
|
||||
'description',
|
||||
'attachedFiles',
|
||||
'url',
|
||||
'source',
|
||||
];
|
||||
|
||||
public async ngOnInit(): Promise<void> {
|
||||
this.datasource.sort = this.sort();
|
||||
const originalSortingAccessor = this.datasource.sortingDataAccessor;
|
||||
this.datasource.sortingDataAccessor = (item, property) => {
|
||||
if (property != 'eventDate') {
|
||||
return originalSortingAccessor(item, property);
|
||||
}
|
||||
|
||||
if (!item.eventDate) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
const parts = item.eventDate.split('-');
|
||||
if (parts.length == 1) {
|
||||
return parse(parts[0]!, 'dd.MM.yyyy', new Date()).valueOf();
|
||||
}
|
||||
if (parts.length == 2) {
|
||||
const p2 = parts[1].split('.');
|
||||
p2.splice(0, 1, parts[0]);
|
||||
return parse(p2.join('.'), 'dd.MM.yyyy', new Date()).valueOf();
|
||||
}
|
||||
|
||||
console.warn('unknown date format:', property);
|
||||
return originalSortingAccessor(item, property);
|
||||
};
|
||||
const data = await api.getFutureEvents();
|
||||
this.datasource.data = data;
|
||||
}
|
||||
|
||||
protected truncateSource(sourceUrl: string): string {
|
||||
if (!URL.canParse(sourceUrl)) {
|
||||
return sourceUrl;
|
||||
}
|
||||
const url = new URL(sourceUrl);
|
||||
return url.hostname;
|
||||
}
|
||||
|
||||
protected async unsubscribe() {
|
||||
await this.pushService.resetSubscriptions();
|
||||
}
|
||||
protected async subscribe() {
|
||||
this.pushService.subscribeToEvents();
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,24 @@
|
||||
Mitgliederliste
|
||||
</button>
|
||||
</mat-list-item>
|
||||
<mat-list-item [claimGuard]="Claim.Useradmin">
|
||||
<mat-list-item>
|
||||
<button
|
||||
matButton="filled"
|
||||
class="tertiary-btn"
|
||||
[routerLink]="['/events']">
|
||||
Veranstaltungen
|
||||
</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">
|
||||
</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> -->
|
||||
<mat-list-item>
|
||||
<button
|
||||
matButton="outlined"
|
||||
|
||||
Reference in New Issue
Block a user