From 375bb1ceb4b06ade603409c3efddb15417b66c1e Mon Sep 17 00:00:00 2001 From: Jan Szumotalski Date: Sat, 31 May 2025 16:57:58 +0200 Subject: [PATCH] feat: Added notifications outbox to admin panel --- src/app/admin-view/admin-comm.service.ts | 5 +++ src/app/admin-view/admin-view.component.html | 15 +------- src/app/admin-view/admin-view.component.ts | 4 +- .../attendence-summary.component.ts | 2 +- src/app/admin-view/grades/grades.component.ts | 2 +- .../grades/summary/summary.component.ts | 2 +- .../notifications.component.html | 1 - .../notifications/notifications.component.ts | 26 +++++++++++-- .../outbox/outbox.component.html | 28 ++++++++++++++ .../outbox/outbox.component.scss | 10 +++++ .../outbox/outbox.component.spec.ts | 23 +++++++++++ .../notifications/outbox/outbox.component.ts | 38 +++++++++++++++++++ .../admin-view/toolbar/toolbar.component.html | 14 +++++++ .../admin-view/toolbar/toolbar.component.scss | 0 .../toolbar/toolbar.component.spec.ts | 23 +++++++++++ .../admin-view/toolbar/toolbar.component.ts | 26 +++++++++++++ .../{ => toolbar}/toolbar.service.spec.ts | 0 .../{ => toolbar}/toolbar.service.ts | 7 +--- src/app/app-routing.module.ts | 6 ++- .../extra/redirect/redirect.component.html | 3 +- src/app/app.module.ts | 4 ++ 21 files changed, 208 insertions(+), 31 deletions(-) create mode 100644 src/app/admin-view/notifications/outbox/outbox.component.html create mode 100644 src/app/admin-view/notifications/outbox/outbox.component.scss create mode 100644 src/app/admin-view/notifications/outbox/outbox.component.spec.ts create mode 100644 src/app/admin-view/notifications/outbox/outbox.component.ts create mode 100644 src/app/admin-view/toolbar/toolbar.component.html create mode 100644 src/app/admin-view/toolbar/toolbar.component.scss create mode 100644 src/app/admin-view/toolbar/toolbar.component.spec.ts create mode 100644 src/app/admin-view/toolbar/toolbar.component.ts rename src/app/admin-view/{ => toolbar}/toolbar.service.spec.ts (100%) rename src/app/admin-view/{ => toolbar}/toolbar.service.ts (57%) diff --git a/src/app/admin-view/admin-comm.service.ts b/src/app/admin-view/admin-comm.service.ts index bee8779..73ac336 100644 --- a/src/app/admin-view/admin-comm.service.ts +++ b/src/app/admin-view/admin-comm.service.ts @@ -182,6 +182,11 @@ export class AdminCommService { }, getGroups: () => { return this.http.get(environment.apiEndpoint+"/admin/notif/groups", {withCredentials: true}) + }, + outbox: { + getSent: () => { + return this.http.get(environment.apiEndpoint+"/admin/notif/outbox", {withCredentials: true}) + } } } //#endregion diff --git a/src/app/admin-view/admin-view.component.html b/src/app/admin-view/admin-view.component.html index e8cfc0b..60b4a15 100644 --- a/src/app/admin-view/admin-view.component.html +++ b/src/app/admin-view/admin-view.component.html @@ -1,17 +1,4 @@ - - - {{title.getTitle()}} - - - - - @for (item of toolbar.menu; track $index) { - - } - + diff --git a/src/app/admin-view/admin-view.component.ts b/src/app/admin-view/admin-view.component.ts index 38fe929..717b90d 100644 --- a/src/app/admin-view/admin-view.component.ts +++ b/src/app/admin-view/admin-view.component.ts @@ -1,9 +1,7 @@ import { Component } from '@angular/core'; -import { Title } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { LocalStorageService } from '../services/local-storage.service'; import { Link } from '../types/link'; -import { ToolbarService } from './toolbar.service'; @Component({ selector: 'app-admin-view', @@ -26,7 +24,7 @@ export class AdminViewComponent { public get LINKS(): Link[] { return this._LINKS.filter(v => v.enabled); } - constructor(readonly title: Title, readonly router: Router, readonly ls: LocalStorageService, protected toolbar: ToolbarService) { } + constructor(readonly router: Router, readonly ls: LocalStorageService) { } goNormal() { this.router.navigateByUrl('app') } diff --git a/src/app/admin-view/grades/attendence-summary/attendence-summary.component.ts b/src/app/admin-view/grades/attendence-summary/attendence-summary.component.ts index 900ab29..ccb30a4 100644 --- a/src/app/admin-view/grades/attendence-summary/attendence-summary.component.ts +++ b/src/app/admin-view/grades/attendence-summary/attendence-summary.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { ToolbarService } from '../../toolbar.service'; +import { ToolbarService } from '../../toolbar/toolbar.service'; import { Router, ActivatedRoute } from '@angular/router'; import { MatTableDataSource } from '@angular/material/table'; import { AdminCommService } from '../../admin-comm.service'; diff --git a/src/app/admin-view/grades/grades.component.ts b/src/app/admin-view/grades/grades.component.ts index 5c75ce1..de2a2d2 100644 --- a/src/app/admin-view/grades/grades.component.ts +++ b/src/app/admin-view/grades/grades.component.ts @@ -4,7 +4,7 @@ import * as moment from 'moment'; import { FormArray, FormBuilder } from '@angular/forms'; import { weekendFilter } from 'src/app/fd.da'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { ToolbarService } from '../toolbar.service'; +import { ToolbarService } from '../toolbar/toolbar.service'; import { ActivatedRoute, Router } from '@angular/router'; import { MatDialog } from '@angular/material/dialog'; import { AttendenceComponent } from './attendence/attendence.component'; diff --git a/src/app/admin-view/grades/summary/summary.component.ts b/src/app/admin-view/grades/summary/summary.component.ts index 5f8b10d..1a0859d 100644 --- a/src/app/admin-view/grades/summary/summary.component.ts +++ b/src/app/admin-view/grades/summary/summary.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { ToolbarService } from '../../toolbar.service'; +import { ToolbarService } from '../../toolbar/toolbar.service'; import { ActivatedRoute, Router } from '@angular/router'; import { AdminCommService } from '../../admin-comm.service'; import * as moment from 'moment'; diff --git a/src/app/admin-view/notifications/notifications.component.html b/src/app/admin-view/notifications/notifications.component.html index 0be7e21..f4720b7 100644 --- a/src/app/admin-view/notifications/notifications.component.html +++ b/src/app/admin-view/notifications/notifications.component.html @@ -1,4 +1,3 @@ -
diff --git a/src/app/admin-view/notifications/notifications.component.ts b/src/app/admin-view/notifications/notifications.component.ts index 9b5de2e..1335e9b 100644 --- a/src/app/admin-view/notifications/notifications.component.ts +++ b/src/app/admin-view/notifications/notifications.component.ts @@ -1,20 +1,31 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { AdminCommService } from '../admin-comm.service'; import { Notification } from 'src/app/types/notification'; import { Group } from 'src/app/types/group'; import { LocalStorageService } from 'src/app/services/local-storage.service'; +import { ToolbarService } from '../toolbar/toolbar.service'; +import { ActivatedRoute, Router } from '@angular/router'; @Component({ selector: 'app-notifications', templateUrl: './notifications.component.html', styleUrls: ['./notifications.component.scss'] }) -export class NotificationsComponent implements OnInit { +export class NotificationsComponent implements OnInit, OnDestroy { groups!: Group[] - constructor (private readonly acs: AdminCommService, readonly ls: LocalStorageService) { } + constructor (private readonly acs: AdminCommService, readonly ls: LocalStorageService, private toolbar: ToolbarService, private router: Router, private route: ActivatedRoute ) { + this.toolbar.comp = this + this.toolbar.menu = [ + { title: "Wysłane", fn: "outbox", icon: "outbox" } + ] + } + + outbox() { + this.router.navigate(["outbox"], { relativeTo: this.route }) + } ngOnInit(): void { this.acs.notif.getGroups().subscribe((v) => { @@ -22,6 +33,15 @@ export class NotificationsComponent implements OnInit { }) } + ngOnDestroy(): void { + this.toolbar.comp = undefined + this.toolbar.menu = undefined + } + + public inbox() { + + } + success?: { sent: number; possible: number; }; form = new FormGroup({ diff --git a/src/app/admin-view/notifications/outbox/outbox.component.html b/src/app/admin-view/notifications/outbox/outbox.component.html new file mode 100644 index 0000000..cec270c --- /dev/null +++ b/src/app/admin-view/notifications/outbox/outbox.component.html @@ -0,0 +1,28 @@ +

Wysłane wiadomości:

+
+ @for (item of messages; track $index) { + + + + + {{item.message.title}} + + {{item.sentDate.format('[Wysłano] dddd DD MMMM YYYYr. o HH:mm')}} + + + +

+ {{item.message.body}} +

+
+
    + @for (user of item.rcpt; track $index) { +
  • + {{user.room}}: {{user.fname}} {{user.surname}} ({{user.uname}}) +
  • + } +
+
+
+ } +
\ No newline at end of file diff --git a/src/app/admin-view/notifications/outbox/outbox.component.scss b/src/app/admin-view/notifications/outbox/outbox.component.scss new file mode 100644 index 0000000..3879d78 --- /dev/null +++ b/src/app/admin-view/notifications/outbox/outbox.component.scss @@ -0,0 +1,10 @@ +.cardContainer { + display: flex; + flex-wrap: wrap; + gap: 1ch; + margin: 1ch; +} + +mat-card-title { + font-size: 24pt; +} \ No newline at end of file diff --git a/src/app/admin-view/notifications/outbox/outbox.component.spec.ts b/src/app/admin-view/notifications/outbox/outbox.component.spec.ts new file mode 100644 index 0000000..8802dca --- /dev/null +++ b/src/app/admin-view/notifications/outbox/outbox.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OutboxComponent } from './outbox.component'; + +describe('OutboxComponent', () => { + let component: OutboxComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [OutboxComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(OutboxComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin-view/notifications/outbox/outbox.component.ts b/src/app/admin-view/notifications/outbox/outbox.component.ts new file mode 100644 index 0000000..8d87892 --- /dev/null +++ b/src/app/admin-view/notifications/outbox/outbox.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { AdminCommService } from '../../admin-comm.service'; +import { Router, ActivatedRoute } from '@angular/router'; +import { ToolbarService } from '../../toolbar/toolbar.service'; +import * as moment from 'moment'; + +@Component({ + selector: 'app-outbox', + templateUrl: './outbox.component.html', + styleUrl: './outbox.component.scss' +}) +export class OutboxComponent implements OnInit { + + messages!: any[] + + constructor (private readonly acs: AdminCommService, private toolbar: ToolbarService, private router: Router, private route: ActivatedRoute ) { + this.toolbar.comp = this + this.toolbar.menu = [ + { title: "Powiadomienia", fn: "goBack", icon: "arrow_back" } + ] + } + + goBack() { + this.router.navigate(['../'], {relativeTo: this.route}) + } + + ngOnInit(): void { + this.acs.notif.outbox.getSent().subscribe((v) => { + this.messages = v.map(i => { + return { + ...i, + sentDate: moment(i.sentDate) + } + }) + }) + } + +} diff --git a/src/app/admin-view/toolbar/toolbar.component.html b/src/app/admin-view/toolbar/toolbar.component.html new file mode 100644 index 0000000..24706ab --- /dev/null +++ b/src/app/admin-view/toolbar/toolbar.component.html @@ -0,0 +1,14 @@ + + + {{title.getTitle()}} + + + + + @for (item of _menu; track $index) { + + } + \ No newline at end of file diff --git a/src/app/admin-view/toolbar/toolbar.component.scss b/src/app/admin-view/toolbar/toolbar.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/admin-view/toolbar/toolbar.component.spec.ts b/src/app/admin-view/toolbar/toolbar.component.spec.ts new file mode 100644 index 0000000..a699881 --- /dev/null +++ b/src/app/admin-view/toolbar/toolbar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ToolbarComponent } from './toolbar.component'; + +describe('ToolbarComponent', () => { + let component: ToolbarComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ToolbarComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ToolbarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/admin-view/toolbar/toolbar.component.ts b/src/app/admin-view/toolbar/toolbar.component.ts new file mode 100644 index 0000000..137863c --- /dev/null +++ b/src/app/admin-view/toolbar/toolbar.component.ts @@ -0,0 +1,26 @@ +import { Component, Input, ViewChild } from '@angular/core'; +import { MatDrawer } from '@angular/material/sidenav'; +import { Title } from '@angular/platform-browser'; +import { ToolbarService } from './toolbar.service'; +import { MatMenuTrigger } from '@angular/material/menu'; + +@Component({ + selector: 'app-toolbar', + templateUrl: './toolbar.component.html', + styleUrl: './toolbar.component.scss' +}) +export class ToolbarComponent { + @Input() drawer!: MatDrawer; + @ViewChild(MatMenuTrigger) trigger!: MatMenuTrigger; + + protected _menu?: typeof this.toolbar.menu + + constructor(readonly title: Title, protected toolbar: ToolbarService) { + + } + + openMenu () { + this._menu = this.toolbar.menu + this.trigger.openMenu() + } +} diff --git a/src/app/admin-view/toolbar.service.spec.ts b/src/app/admin-view/toolbar/toolbar.service.spec.ts similarity index 100% rename from src/app/admin-view/toolbar.service.spec.ts rename to src/app/admin-view/toolbar/toolbar.service.spec.ts diff --git a/src/app/admin-view/toolbar.service.ts b/src/app/admin-view/toolbar/toolbar.service.ts similarity index 57% rename from src/app/admin-view/toolbar.service.ts rename to src/app/admin-view/toolbar/toolbar.service.ts index 80c69ff..6bd02da 100644 --- a/src/app/admin-view/toolbar.service.ts +++ b/src/app/admin-view/toolbar/toolbar.service.ts @@ -6,9 +6,6 @@ import { Injectable } from '@angular/core'; export class ToolbarService { public comp?: any; - public menu?: {title: string, check: boolean, icon?: string, fn: string}[] - - constructor() { } - - + public menu?: {title: string, check?: boolean, icon?: string, fn: string}[] + } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c27adbb..4504679 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -19,6 +19,7 @@ import { SummaryComponent } from './admin-view/grades/summary/summary.component' import { SettingsComponent } from './admin-view/settings/settings.component'; import { AttendenceSummaryComponent } from './admin-view/grades/attendence-summary/attendence-summary.component'; import { NotificationsComponent } from './admin-view/notifications/notifications.component'; +import { OutboxComponent } from './admin-view/notifications/outbox/outbox.component'; const routes: Routes = [ {path: "", redirectTo: "login", pathMatch: "full"}, @@ -33,7 +34,10 @@ const routes: Routes = [ {path: "news", title: "Edytowanie wiadomości", component: NewsEditComponent}, {path: "menu", title: "Edytowanie jadłospisu", component: MenuNewComponent}, {path: "accounts", title: "Użytkownicy", component: AccountMgmtComponent}, - {path: "notifications", title: "Powiadomienia", component: NotificationsComponent}, + {path: "notifications", children: [ + {path: "", pathMatch: "full", title: "Powiadomienia", component: NotificationsComponent}, + {path: "outbox", title: "Wysłane", component: OutboxComponent} + ]}, {path: "groups", title: "Grupy", component: GroupsComponent}, {path: "keys", title: "Klucze", component: AdminKeyComponent}, {path: "grades", children: [ diff --git a/src/app/app-view/personal/extra/redirect/redirect.component.html b/src/app/app-view/personal/extra/redirect/redirect.component.html index 1dc4d9a..caed671 100644 --- a/src/app/app-view/personal/extra/redirect/redirect.component.html +++ b/src/app/app-view/personal/extra/redirect/redirect.component.html @@ -1,7 +1,8 @@ -

Domyślna strona po logowaniu

+

Domyślna strona po logowaniu

Wpisz link względem /ipwa/ w poniższym polu.

Przykład: /app/menu

+

Jeśli nie wiesz co tu wpisać, najlepiej nie zmieniaj tego ustawienia

Link diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 229946c..94a5065 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -81,6 +81,8 @@ import { AboutComponent } from './app-view/personal/about/about.component'; import { environment } from 'src/environments/environment'; import { ExtraComponent } from './app-view/personal/extra/extra.component'; import { RedirectComponent } from './app-view/personal/extra/redirect/redirect.component'; +import { OutboxComponent } from './admin-view/notifications/outbox/outbox.component'; +import { ToolbarComponent } from './admin-view/toolbar/toolbar.component'; @NgModule({ declarations: [ @@ -126,6 +128,8 @@ import { RedirectComponent } from './app-view/personal/extra/redirect/redirect.c AboutComponent, ExtraComponent, RedirectComponent, + OutboxComponent, + ToolbarComponent, ], imports: [ BrowserModule,