NotificationsOverlay WIP
This commit is contained in:
parent
f47d30a4c8
commit
bc68777229
26
src/main/angular/src/app/api/Notification/Notification.ts
Normal file
26
src/main/angular/src/app/api/Notification/Notification.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {FromJson} from "../common/types";
|
||||
import {validateDate, validateString} from "../common/validators";
|
||||
|
||||
export class Notification<T> {
|
||||
|
||||
constructor(
|
||||
readonly uuid: string,
|
||||
readonly title: string,
|
||||
readonly date: Date,
|
||||
readonly type: string,
|
||||
readonly payload: T,
|
||||
) {
|
||||
// -
|
||||
}
|
||||
|
||||
static fromJson<T>(fromJson: FromJson<T>): FromJson<Notification<T>> {
|
||||
return (json: any) => new Notification<T>(
|
||||
validateString(json.uuid),
|
||||
validateString(json.title),
|
||||
validateDate(json.date),
|
||||
validateString(json.type),
|
||||
fromJson(json.payload),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ApiService} from "../common/api.service";
|
||||
import {Notification} from "./Notification";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class NotificationService {
|
||||
|
||||
public notifications: Notification<any>[] = [
|
||||
new Notification('', 'Test', new Date(), 'test', null),
|
||||
];
|
||||
|
||||
constructor(
|
||||
protected readonly api: ApiService,
|
||||
) {
|
||||
// -
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,6 +13,9 @@
|
||||
>
|
||||
{{ userService.user.name }}
|
||||
</div>
|
||||
<div #notificationsButton class="mainMenuItem mainMenuItemRight mainMenuNotifications" [class.mainMenuNotifications_blink]="blink" *ngIf="notificationService.notifications.length" (click)="toggleMenu()">
|
||||
{{ notificationService.notifications.length }}
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="userService.user === null">
|
||||
@ -23,3 +26,15 @@
|
||||
|
||||
</div>
|
||||
<router-outlet (activate)="onActivate($event)"/>
|
||||
|
||||
<div #notificationsOverlayMobile class="notificationsOverlay notificationsOverlayMobile" *ngIf="notificationsOverlayVisible" (window:resize)="onResize()">
|
||||
<div class="notificationOverlayEntry" *ngFor="let notification of notificationService.notifications">
|
||||
{{ notification.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div #notificationsOverlayDesktop class="notificationsOverlay notificationsOverlayDesktop" *ngIf="notificationsOverlayVisible" (window:resize)="onResize()">
|
||||
<div class="notificationOverlayEntry" *ngFor="let notification of notificationService.notifications">
|
||||
{{ notification.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -23,4 +23,56 @@
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
|
||||
.mainMenuNotifications {
|
||||
background-color: lightskyblue;
|
||||
min-width: 2.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mainMenuNotifications_blink {
|
||||
color: white;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.notificationsOverlay {
|
||||
position: fixed;
|
||||
background-color: lightgray;
|
||||
border: 1px solid gray;
|
||||
border-radius: 0 0 @space @space;
|
||||
box-shadow: -0.5em 0.5em 1em rgba(0, 0, 0, 0.5);
|
||||
|
||||
.notificationOverlayEntry {
|
||||
border-bottom: 1px solid gray;
|
||||
padding: @halfSpace;
|
||||
}
|
||||
|
||||
.notificationOverlayEntry:hover {
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.notificationsOverlayMobile {
|
||||
width: calc(100% - 2 * @space);
|
||||
margin: 0 @space;
|
||||
}
|
||||
|
||||
.notificationsOverlayDesktop {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
.notificationsOverlayMobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.notificationsOverlayDesktop {
|
||||
display: unset;
|
||||
width: 500px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,25 +1,52 @@
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import {AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
|
||||
import {NgIf} from "@angular/common";
|
||||
import {JsonPipe, NgForOf, NgIf} from "@angular/common";
|
||||
import {UserService} from "./api/User/user.service";
|
||||
import {Subscription} from "rxjs";
|
||||
import {Subscription, timer} from "rxjs";
|
||||
import {NotificationService} from "./api/Notification/notification.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet, RouterLink, RouterLinkActive, NgIf],
|
||||
imports: [RouterOutlet, RouterLink, RouterLinkActive, NgIf, NgForOf, JsonPipe],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.less'
|
||||
})
|
||||
export class AppComponent implements OnInit, OnDestroy {
|
||||
export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||
|
||||
private readonly subs: Subscription[] = [];
|
||||
|
||||
protected menuVisible = true;
|
||||
|
||||
protected blink: boolean = true;
|
||||
|
||||
private _notificationsButton!: ElementRef;
|
||||
@ViewChild("notificationsButton")
|
||||
set notificationsButton(e: ElementRef) {
|
||||
this._notificationsButton = e;
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
private _notificationsOverlayMobile!: ElementRef;
|
||||
@ViewChild("notificationsOverlayMobile")
|
||||
set notificationsOverlayMobile(e: ElementRef) {
|
||||
this._notificationsOverlayMobile = e;
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
private _notificationsOverlayDesktop!: ElementRef;
|
||||
@ViewChild("notificationsOverlayDesktop")
|
||||
set notificationsOverlayDesktop(e: ElementRef) {
|
||||
this._notificationsOverlayDesktop = e;
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
protected notificationsOverlayVisible: boolean = true;
|
||||
|
||||
constructor(
|
||||
protected readonly router: Router,
|
||||
protected readonly userService: UserService,
|
||||
protected readonly notificationService: NotificationService,
|
||||
) {
|
||||
// -
|
||||
}
|
||||
@ -29,7 +56,11 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// -
|
||||
this.subs.push(timer(500, 500).subscribe(() => this.blink = !this.blink))
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@ -37,4 +68,27 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.subs.length = 0;
|
||||
}
|
||||
|
||||
toggleMenu() {
|
||||
this.notificationsOverlayVisible = !this.notificationsOverlayVisible;
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
onResize() {
|
||||
if (this._notificationsButton) {
|
||||
const button = this._notificationsButton.nativeElement.getBoundingClientRect();
|
||||
|
||||
if (this._notificationsOverlayMobile) {
|
||||
const overlayMobile = this._notificationsOverlayMobile.nativeElement.style;
|
||||
overlayMobile.top = button.bottom + 'px';
|
||||
}
|
||||
|
||||
if (this._notificationsOverlayDesktop) {
|
||||
const overlayDesktopRect = this._notificationsOverlayDesktop.nativeElement.getBoundingClientRect();
|
||||
const overlayDesktopStyle = this._notificationsOverlayDesktop.nativeElement.style;
|
||||
overlayDesktopStyle.top = button.bottom + 'px';
|
||||
overlayDesktopStyle.left = button.right - overlayDesktopRect.width + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user