feat: Added notifications outbox to admin panel
This commit is contained in:
@@ -182,6 +182,11 @@ export class AdminCommService {
|
||||
},
|
||||
getGroups: () => {
|
||||
return this.http.get<Group[]>(environment.apiEndpoint+"/admin/notif/groups", {withCredentials: true})
|
||||
},
|
||||
outbox: {
|
||||
getSent: () => {
|
||||
return this.http.get<any[]>(environment.apiEndpoint+"/admin/notif/outbox", {withCredentials: true})
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@@ -1,17 +1,4 @@
|
||||
<mat-toolbar color="accent">
|
||||
<button mat-icon-button (click)="drawer.toggle()"><mat-icon>menu</mat-icon></button>
|
||||
<span>{{title.getTitle()}}</span>
|
||||
<span style="flex: 1 1 auto"></span>
|
||||
<button mat-icon-button *ngIf="toolbar.menu" [matMenuTriggerFor]="menu"><mat-icon>more_vert</mat-icon></button>
|
||||
</mat-toolbar>
|
||||
<mat-menu #menu="matMenu">
|
||||
@for (item of toolbar.menu; track $index) {
|
||||
<button mat-menu-item *ngIf="item.check" (click)="toolbar.comp[item.fn]()">
|
||||
<mat-icon *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span>{{item.title}}</span>
|
||||
</button>
|
||||
}
|
||||
</mat-menu>
|
||||
<app-toolbar [drawer]="drawer"/>
|
||||
<mat-sidenav-container>
|
||||
<mat-sidenav #drawer mode="over" autoFocus="false">
|
||||
<mat-nav-list>
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<!-- TODO: Remake the notifications module -->
|
||||
<form [formGroup]="form" (ngSubmit)="submit()">
|
||||
<div formGroupName="recp">
|
||||
<mat-radio-group formControlName="type">
|
||||
|
||||
@@ -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<NotificationForm>({
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<p>Wysłane wiadomości:</p>
|
||||
<div class="cardContainer">
|
||||
@for (item of messages; track $index) {
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>
|
||||
{{item.message.title}}
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>{{item.sentDate.format('[Wysłano] dddd DD MMMM YYYYr. o HH:mm')}}</mat-card-subtitle>
|
||||
</mat-card-title-group>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p>
|
||||
{{item.message.body}}
|
||||
</p>
|
||||
<hr>
|
||||
<ul>
|
||||
@for (user of item.rcpt; track $index) {
|
||||
<li>
|
||||
<span *ngIf="user.room">{{user.room}}: </span>{{user.fname}} {{user.surname}} <span style="color: gray" >({{user.uname}})</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
}
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
.cardContainer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1ch;
|
||||
margin: 1ch;
|
||||
}
|
||||
|
||||
mat-card-title {
|
||||
font-size: 24pt;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { OutboxComponent } from './outbox.component';
|
||||
|
||||
describe('OutboxComponent', () => {
|
||||
let component: OutboxComponent;
|
||||
let fixture: ComponentFixture<OutboxComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [OutboxComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(OutboxComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
38
src/app/admin-view/notifications/outbox/outbox.component.ts
Normal file
38
src/app/admin-view/notifications/outbox/outbox.component.ts
Normal file
@@ -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)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
14
src/app/admin-view/toolbar/toolbar.component.html
Normal file
14
src/app/admin-view/toolbar/toolbar.component.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<mat-toolbar color="accent">
|
||||
<button mat-icon-button (click)="drawer.toggle()"><mat-icon>menu</mat-icon></button>
|
||||
<span>{{title.getTitle()}}</span>
|
||||
<span style="flex: 1 1 auto"></span>
|
||||
<button mat-icon-button *ngIf="toolbar.menu" [matMenuTriggerFor]="menu" (click)="openMenu()"><mat-icon>more_vert</mat-icon></button>
|
||||
</mat-toolbar>
|
||||
<mat-menu #menu="matMenu">
|
||||
@for (item of _menu; track $index) {
|
||||
<button mat-menu-item *ngIf="item.check ?? true" (click)="toolbar.comp[item.fn]()">
|
||||
<mat-icon *ngIf="item.icon">{{item.icon}}</mat-icon>
|
||||
<span>{{item.title}}</span>
|
||||
</button>
|
||||
}
|
||||
</mat-menu>
|
||||
0
src/app/admin-view/toolbar/toolbar.component.scss
Normal file
0
src/app/admin-view/toolbar/toolbar.component.scss
Normal file
23
src/app/admin-view/toolbar/toolbar.component.spec.ts
Normal file
23
src/app/admin-view/toolbar/toolbar.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ToolbarComponent } from './toolbar.component';
|
||||
|
||||
describe('ToolbarComponent', () => {
|
||||
let component: ToolbarComponent;
|
||||
let fixture: ComponentFixture<ToolbarComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ToolbarComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ToolbarComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
26
src/app/admin-view/toolbar/toolbar.component.ts
Normal file
26
src/app/admin-view/toolbar/toolbar.component.ts
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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}[]
|
||||
|
||||
}
|
||||
@@ -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: [
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<h1>Domyślna strona po logowaniu</h1>
|
||||
<h1 mat-dialog-title>Domyślna strona po logowaniu</h1>
|
||||
<mat-dialog-content>
|
||||
<p>Wpisz link względem /ipwa/ w poniższym polu.</p>
|
||||
<p>Przykład: /app/menu</p>
|
||||
<p style="color: red">Jeśli nie wiesz co tu wpisać, najlepiej nie zmieniaj tego ustawienia</p>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" [(ngModel)]="redirect">
|
||||
<mat-label>Link</mat-label>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user