From bc687772295495db2467d0c2a824d842ac78728a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Ha=C3=9Fel?= Date: Fri, 8 Nov 2024 10:41:48 +0100 Subject: [PATCH] NotificationsOverlay WIP --- .../src/app/api/Notification/Notification.ts | 26 ++++++++ .../api/Notification/notification.service.ts | 20 ++++++ src/main/angular/src/app/app.component.html | 15 +++++ src/main/angular/src/app/app.component.less | 52 +++++++++++++++ src/main/angular/src/app/app.component.ts | 66 +++++++++++++++++-- 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 src/main/angular/src/app/api/Notification/Notification.ts create mode 100644 src/main/angular/src/app/api/Notification/notification.service.ts diff --git a/src/main/angular/src/app/api/Notification/Notification.ts b/src/main/angular/src/app/api/Notification/Notification.ts new file mode 100644 index 0000000..08f29dc --- /dev/null +++ b/src/main/angular/src/app/api/Notification/Notification.ts @@ -0,0 +1,26 @@ +import {FromJson} from "../common/types"; +import {validateDate, validateString} from "../common/validators"; + +export class Notification { + + constructor( + readonly uuid: string, + readonly title: string, + readonly date: Date, + readonly type: string, + readonly payload: T, + ) { + // - + } + + static fromJson(fromJson: FromJson): FromJson> { + return (json: any) => new Notification( + validateString(json.uuid), + validateString(json.title), + validateDate(json.date), + validateString(json.type), + fromJson(json.payload), + ); + } + +} diff --git a/src/main/angular/src/app/api/Notification/notification.service.ts b/src/main/angular/src/app/api/Notification/notification.service.ts new file mode 100644 index 0000000..24e52d3 --- /dev/null +++ b/src/main/angular/src/app/api/Notification/notification.service.ts @@ -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[] = [ + new Notification('', 'Test', new Date(), 'test', null), + ]; + + constructor( + protected readonly api: ApiService, + ) { + // - + } + +} diff --git a/src/main/angular/src/app/app.component.html b/src/main/angular/src/app/app.component.html index 4d4c3af..e6b8afc 100644 --- a/src/main/angular/src/app/app.component.html +++ b/src/main/angular/src/app/app.component.html @@ -13,6 +13,9 @@ > {{ userService.user.name }} + @@ -23,3 +26,15 @@ + +
+
+ {{ notification.title }} +
+
+ +
+
+ {{ notification.title }} +
+
diff --git a/src/main/angular/src/app/app.component.less b/src/main/angular/src/app/app.component.less index 2d816ba..0037082 100644 --- a/src/main/angular/src/app/app.component.less +++ b/src/main/angular/src/app/app.component.less @@ -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; + } + } diff --git a/src/main/angular/src/app/app.component.ts b/src/main/angular/src/app/app.component.ts index 5f4563e..4972edc 100644 --- a/src/main/angular/src/app/app.component.ts +++ b/src/main/angular/src/app/app.component.ts @@ -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'; + } + } + } + }