custom notifications service
This commit is contained in:
@@ -14,6 +14,7 @@ import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core';
|
|||||||
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MomentDateAdapter } from '@angular/material-moment-adapter';
|
import { MAT_MOMENT_DATE_ADAPTER_OPTIONS, MomentDateAdapter } from '@angular/material-moment-adapter';
|
||||||
import { registerLocaleData } from '@angular/common';
|
import { registerLocaleData } from '@angular/common';
|
||||||
import localePl from '@angular/common/locales/pl';
|
import localePl from '@angular/common/locales/pl';
|
||||||
|
import { NotificationsComponent } from './components/notifications/notifications.component';
|
||||||
|
|
||||||
registerLocaleData(localePl, 'pl-PL');
|
registerLocaleData(localePl, 'pl-PL');
|
||||||
|
|
||||||
@@ -21,7 +22,8 @@ registerLocaleData(localePl, 'pl-PL');
|
|||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
MainViewComponent,
|
MainViewComponent,
|
||||||
LoginPageComponent
|
LoginPageComponent,
|
||||||
|
NotificationsComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, NgZone, OnInit } from '@angular/core';
|
import { Component, NgZone, OnInit } from '@angular/core';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import jwt_decode from "jwt-decode";
|
import jwt_decode from "jwt-decode";
|
||||||
import { AuthService } from 'src/app/auth/auth.service';
|
import { AuthService } from 'src/app/auth/auth.service';
|
||||||
import { User } from 'src/app/models/user.model';
|
import { User } from 'src/app/models/user.model';
|
||||||
|
import { NotificationsService } from 'src/app/services/notifications.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -17,14 +17,12 @@ export class LoginPageComponent implements OnInit {
|
|||||||
private router$: Router,
|
private router$: Router,
|
||||||
private auth$: AuthService,
|
private auth$: AuthService,
|
||||||
private ngZone$: NgZone,
|
private ngZone$: NgZone,
|
||||||
private snackBar$: MatSnackBar
|
private notifications$: NotificationsService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.snackBar$.open("", "", { duration: 1 });
|
|
||||||
console.log('Envs', environment);
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.onGoogleLibraryLoad = () => {
|
window.onGoogleLibraryLoad = () => {
|
||||||
@@ -68,11 +66,18 @@ export class LoginPageComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
console.error('handleCredentialResponse', e);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (e.status === 401) {
|
if (e.status === 401) {
|
||||||
this.snackBar$.open("Użytkownik nie istnieje w bazie danych aplikacji DiunaBI.", "", { duration: 3000 });
|
this.notifications$.add({
|
||||||
|
text: "Użytkownik nie istnieje w bazie danych aplikacji DiunaBI.",
|
||||||
|
duration: 2500
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.snackBar$.open("Błąd połączenia z serwerem. Skontaktuj się z administratorem.", "", { duration: 3000 });
|
this.notifications$.add({
|
||||||
|
text: "Błąd połączenia z serwerem. Skontaktuj się z administratorem.",
|
||||||
|
duration: 2500
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<mat-card *ngFor="let msg of notifications$.messages">
|
||||||
|
<mat-card-content>
|
||||||
|
<span class="text">{{msg.text}}</span>
|
||||||
|
<span class="btn" *ngIf="msg.btn">
|
||||||
|
<a class="action-button" (click)="notifications$.doAction(msg)">{{msg.btn}}</a>
|
||||||
|
</span>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
mat-card {
|
||||||
|
margin-bottom: 3px;
|
||||||
|
background-color: rgba(255, 145, 0, 0.4);
|
||||||
|
}
|
||||||
|
.action-button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
display: inline-block;
|
||||||
|
width: 70%;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
width: 30%;
|
||||||
|
text-align: right;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { NotificationsComponent } from './notifications.component';
|
||||||
|
|
||||||
|
describe('NotificationsComponent', () => {
|
||||||
|
let component: NotificationsComponent;
|
||||||
|
let fixture: ComponentFixture<NotificationsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ NotificationsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(NotificationsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { NotificationsService } from 'src/app/services/notifications.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-notifications',
|
||||||
|
templateUrl: './notifications.component.html',
|
||||||
|
styleUrls: ['./notifications.component.scss'],
|
||||||
|
})
|
||||||
|
export class NotificationsComponent {
|
||||||
|
constructor(
|
||||||
|
public notifications$: NotificationsService
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -120,106 +120,9 @@ textarea[disabled] {
|
|||||||
color: rgb(205, 206, 177);
|
color: rgb(205, 206, 177);
|
||||||
font-size: larger;
|
font-size: larger;
|
||||||
}
|
}
|
||||||
.errorMsg {
|
|
||||||
font-size: small;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* links */
|
/* links */
|
||||||
a:link,
|
a:link,
|
||||||
a:visited {
|
a:visited {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
.stock-state-error {
|
|
||||||
color: red;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.listContainer {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
overflow: scroll;
|
|
||||||
}
|
|
||||||
.listItem {
|
|
||||||
height: 40px;
|
|
||||||
font-size: medium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.listItem:hover {
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
background: rgba(130, 130, 130, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* snack bars */
|
|
||||||
.snack-error {
|
|
||||||
background: #f44336;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-right {
|
|
||||||
display: block;
|
|
||||||
direction: rtl;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-red {
|
|
||||||
background-color: rgba(255, 0, 0, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-orange {
|
|
||||||
background-color: rgba(255, 145, 0, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-green {
|
|
||||||
background-color: rgba(0, 255, 0, 0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-grey {
|
|
||||||
background-color: rgba(100, 100, 100, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-mdc-dialog-container {
|
|
||||||
padding: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-loader {
|
|
||||||
width: 25px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-border {
|
|
||||||
border-left: 1px solid #e0e0e0;
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-background {
|
|
||||||
background-color: #eeeeee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumbs {
|
|
||||||
width: 100%;
|
|
||||||
text-align: right;
|
|
||||||
font-size: small;
|
|
||||||
color: gray;
|
|
||||||
margin-top: 0px;
|
|
||||||
padding-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumbs a {
|
|
||||||
color: gray;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep snack-bar-container.custom-snackbar-error {
|
|
||||||
background: #ff3452;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep snack-bar-container.custom-snackbar-success {
|
|
||||||
background: #9ad284;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .mat-mdc-simple-snack-bar {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
::ng-deep .mat-mdc-snack-bar-action {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@ import { environment } from 'src/environments/environment';
|
|||||||
import { AuthService } from '../auth/auth.service';
|
import { AuthService } from '../auth/auth.service';
|
||||||
import { DataService } from '../services/data.service';
|
import { DataService } from '../services/data.service';
|
||||||
import { DeviceService } from '../services/device.service';
|
import { DeviceService } from '../services/device.service';
|
||||||
|
import { NotificationsService } from '../services/notifications.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-main-view',
|
selector: 'app-main-view',
|
||||||
@@ -30,7 +31,7 @@ export class MainViewComponent {
|
|||||||
private router$: Router,
|
private router$: Router,
|
||||||
private swUpdate$: SwUpdate,
|
private swUpdate$: SwUpdate,
|
||||||
private ngZone$: NgZone,
|
private ngZone$: NgZone,
|
||||||
public auth$: AuthService
|
public auth$: AuthService,
|
||||||
) {
|
) {
|
||||||
this.swUpdate$.versionUpdates.subscribe(() => {
|
this.swUpdate$.versionUpdates.subscribe(() => {
|
||||||
this.reloadApp();
|
this.reloadApp();
|
||||||
|
|||||||
@@ -1,72 +1,72 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
//import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
//import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
//import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
import { MatChipsModule } from '@angular/material/chips';
|
//import { MatChipsModule } from '@angular/material/chips';
|
||||||
import { MatStepperModule } from '@angular/material/stepper';
|
//import { MatStepperModule } from '@angular/material/stepper';
|
||||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
//import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
//import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { MatExpansionModule } from '@angular/material/expansion';
|
//import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
import { MatGridListModule } from '@angular/material/grid-list';
|
import { MatGridListModule } from '@angular/material/grid-list';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatListModule } from '@angular/material/list';
|
import { MatListModule } from '@angular/material/list';
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
//import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
//import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { MatRadioModule } from '@angular/material/radio';
|
//import { MatRadioModule } from '@angular/material/radio';
|
||||||
import { MatRippleModule } from '@angular/material/core';
|
//import { MatRippleModule } from '@angular/material/core';
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||||
import { MatSliderModule } from '@angular/material/slider';
|
//import { MatSliderModule } from '@angular/material/slider';
|
||||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
//import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|
||||||
import { MatSortModule } from '@angular/material/sort';
|
import { MatSortModule } from '@angular/material/sort';
|
||||||
import { MatTableModule } from '@angular/material/table';
|
import { MatTableModule } from '@angular/material/table';
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
//import { MatTabsModule } from '@angular/material/tabs';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
//import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import {CdkTableModule} from '@angular/cdk/table';
|
//import {CdkTableModule} from '@angular/cdk/table';
|
||||||
import {MatBadgeModule} from '@angular/material/badge';
|
//import {MatBadgeModule} from '@angular/material/badge';
|
||||||
|
import {MatBottomSheetModule} from '@angular/material/bottom-sheet';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
exports: [
|
exports: [
|
||||||
CdkTableModule,
|
// CdkTableModule,
|
||||||
MatAutocompleteModule,
|
// MatAutocompleteModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatButtonToggleModule,
|
// MatButtonToggleModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatCheckboxModule,
|
// MatCheckboxModule,
|
||||||
MatChipsModule,
|
// MatChipsModule,
|
||||||
MatStepperModule,
|
// MatStepperModule,
|
||||||
MatDatepickerModule,
|
// MatDatepickerModule,
|
||||||
MatDialogModule,
|
// MatDialogModule,
|
||||||
MatExpansionModule,
|
// MatExpansionModule,
|
||||||
MatGridListModule,
|
MatGridListModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatListModule,
|
MatListModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatProgressBarModule,
|
// MatProgressBarModule,
|
||||||
MatProgressSpinnerModule,
|
// MatProgressSpinnerModule,
|
||||||
MatRadioModule,
|
// MatRadioModule,
|
||||||
MatRippleModule,
|
// MatRippleModule,
|
||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatSidenavModule,
|
// MatSidenavModule,
|
||||||
MatSliderModule,
|
// MatSliderModule,
|
||||||
MatSlideToggleModule,
|
// MatSlideToggleModule,
|
||||||
MatSnackBarModule,
|
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatTabsModule,
|
// MatTabsModule,
|
||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatTooltipModule,
|
// MatTooltipModule,
|
||||||
MatSidenavModule,
|
MatSidenavModule,
|
||||||
MatBadgeModule
|
// MatBadgeModule,
|
||||||
|
MatBottomSheetModule
|
||||||
],
|
],
|
||||||
providers: []
|
providers: []
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ import { DatePipe } from '@angular/common';
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
|
import { UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { MatSort, MatSortable } from '@angular/material/sort';
|
import { MatSort, MatSortable } from '@angular/material/sort';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { AuthService } from 'src/app/auth/auth.service';
|
import { AuthService } from 'src/app/auth/auth.service';
|
||||||
import { Layer } from 'src/app/models/layer.model';
|
import { Layer } from 'src/app/models/layer.model';
|
||||||
import { Record } from 'src/app/models/record.model';
|
import { Record } from 'src/app/models/record.model';
|
||||||
|
import { NotificationsService } from 'src/app/services/notifications.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -29,12 +28,11 @@ export class LayerDetailComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private fb$: UntypedFormBuilder,
|
private fb$: UntypedFormBuilder,
|
||||||
private router$: Router,
|
|
||||||
private http$: HttpClient,
|
private http$: HttpClient,
|
||||||
private route$: ActivatedRoute,
|
private route$: ActivatedRoute,
|
||||||
private auth$: AuthService,
|
private auth$: AuthService,
|
||||||
private snackBar: MatSnackBar,
|
private datePipe: DatePipe,
|
||||||
private datePipe: DatePipe
|
private notifications$: NotificationsService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@@ -55,9 +53,13 @@ export class LayerDetailComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
async export() {
|
async export() {
|
||||||
if (await Layer.exportToGoogleSheet(this.document.id || "", this.http$)) {
|
if (await Layer.exportToGoogleSheet(this.document.id || "", this.http$)) {
|
||||||
this.snackBar.open("Plik został zapisany na dysku Google", "OK");
|
this.notifications$.add({
|
||||||
|
text: "Plik został zapisany na dysku Google.",
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.snackBar.open("Zapis się nie udał.", "OK");
|
this.notifications$.add({
|
||||||
|
text: "Zapis się nie udał.",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
|||||||
59
Frontend/src/app/services/notifications.service.ts
Normal file
59
Frontend/src/app/services/notifications.service.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { MatBottomSheet, MatBottomSheetRef } from '@angular/material/bottom-sheet';
|
||||||
|
import { NotificationsComponent } from '../components/notifications/notifications.component';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import moment, { Moment } from 'moment';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class NotificationsService {
|
||||||
|
|
||||||
|
public messages: Message[] = [];
|
||||||
|
private handler?: MatBottomSheetRef;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private bottomSheet$: MatBottomSheet
|
||||||
|
) { }
|
||||||
|
public add(message: Message) {
|
||||||
|
message.id = uuidv4();
|
||||||
|
message.createdAt = moment();
|
||||||
|
this.messages.push(message);
|
||||||
|
this.sortMessages();
|
||||||
|
if (this.messages.length === 1) {
|
||||||
|
this.handler = this.bottomSheet$.open(NotificationsComponent, {
|
||||||
|
hasBackdrop: false,
|
||||||
|
disableClose: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.remove(message);
|
||||||
|
}, message.duration ? message.duration : 5000);
|
||||||
|
}
|
||||||
|
private remove(message: Message) {
|
||||||
|
this.messages = this.messages.filter(x => x.id!==message.id);
|
||||||
|
this.sortMessages();
|
||||||
|
if (this.messages.length === 0 && this.handler) {
|
||||||
|
this.handler.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private sortMessages() {
|
||||||
|
this.messages = this.messages.sort((a, b) => {
|
||||||
|
return a.createdAt && a.createdAt.isAfter(b.createdAt) ? 1 : -1;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
doAction(message: Message) {
|
||||||
|
if (message.action) { message.action(); }
|
||||||
|
this.remove(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Message {
|
||||||
|
id?: string;
|
||||||
|
text: string;
|
||||||
|
duration?: number;
|
||||||
|
btn?: string;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
action?: Function;
|
||||||
|
createdAt?: Moment
|
||||||
|
}
|
||||||
@@ -44,14 +44,6 @@ body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
|||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.snackbar-success {
|
|
||||||
background: #BEFF33;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snackbar-error {
|
|
||||||
background: #e7334b;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--avatar-size: 30px;
|
--avatar-size: 30px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"SQLDatabase": "Server=tcp:127.0.0.1,1433;Initial Catalog=diuna;Persist Security Info=False;User ID=SA;Password=v](8Lc|RfG;MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=False;Connection Timeout=30;"
|
"SQLDatabase": "Server=tcp:127.0.0.1,1433;Initial Catalog=diunabi-morska;Persist Security Info=False;User ID=SA;Password=v](8Lc|RfG;MultipleActiveResultSets=False;Encrypt=False;TrustServerCertificate=False;Connection Timeout=30;"
|
||||||
},
|
},
|
||||||
"GoogleClientId": "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com",
|
"GoogleClientId": "107631825312-bkfe438ehr9k9ecb2h76g802tj6advma.apps.googleusercontent.com",
|
||||||
"Secret": "8393AF8EAEF8478CB738D44858690F9C7E2D19F65896DD9FBAA3EB2A6F493E80",
|
"Secret": "8393AF8EAEF8478CB738D44858690F9C7E2D19F65896DD9FBAA3EB2A6F493E80",
|
||||||
|
|||||||
Reference in New Issue
Block a user