feat: replace custom notify to ngx-toastr
#https://github.com/scttcper/ngx-toastr
This commit is contained in:
parent
eded639cc3
commit
3ca6f56fec
15
package-lock.json
generated
15
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"@angular/router": "^18.2.7",
|
||||
"@dhutaryan/ngx-mat-timepicker": "^18.0.2",
|
||||
"@progress/kendo-date-math": "^1.5.13",
|
||||
"ngx-toastr": "^19.0.0",
|
||||
"rxjs": "~7.8.1",
|
||||
"tslib": "^2.7.0",
|
||||
"zone.js": "^0.14.10"
|
||||
@ -9904,6 +9905,20 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ngx-toastr": {
|
||||
"version": "19.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-19.0.0.tgz",
|
||||
"integrity": "sha512-6pTnktwwWD+kx342wuMOWB4+bkyX9221pAgGz3SHOJH0/MI9erLucS8PeeJDFwbUYyh75nQ6AzVtolgHxi52dQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=16.0.0-0",
|
||||
"@angular/core": ">=16.0.0-0",
|
||||
"@angular/platform-browser": ">=16.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/nice-napi": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||
|
@ -23,6 +23,7 @@
|
||||
"@angular/router": "^18.2.7",
|
||||
"@dhutaryan/ngx-mat-timepicker": "^18.0.2",
|
||||
"@progress/kendo-date-math": "^1.5.13",
|
||||
"ngx-toastr": "^19.0.0",
|
||||
"rxjs": "~7.8.1",
|
||||
"tslib": "^2.7.0",
|
||||
"zone.js": "^0.14.10"
|
||||
|
@ -1,12 +1,12 @@
|
||||
import {catchError, distinctUntilChanged, filter, first, mergeMap, Observable, retryWhen, switchMap, timer} from "rxjs";
|
||||
import {HttpClient, HttpErrorResponse} from "@angular/common/http";
|
||||
import {NotifyColor, OpenNotifyService} from "@service/open-notify.service";
|
||||
import {environment} from "@environment";
|
||||
import {Router} from "@angular/router";
|
||||
import {Injectable} from "@angular/core";
|
||||
import {RequestBuilder, RequestData} from "@api/RequestBuilder";
|
||||
import {TokenRefreshService} from "@service/token-refresh.service";
|
||||
import {AuthToken} from "@service/auth.service";
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
|
||||
export function retryWithInterval<T>(): (source: Observable<T>) => Observable<T> {
|
||||
return (source: Observable<T>) =>
|
||||
@ -37,7 +37,7 @@ export enum AvailableVersion {
|
||||
|
||||
@Injectable()
|
||||
export default abstract class ApiService {
|
||||
constructor(private http: HttpClient, private notify: OpenNotifyService, private router: Router, protected tokenRefreshService: TokenRefreshService) {
|
||||
constructor(private http: HttpClient, private notify: ToastrService, private router: Router, protected tokenRefreshService: TokenRefreshService) {
|
||||
}
|
||||
|
||||
private apiUrl = environment.apiUrl;
|
||||
@ -154,6 +154,7 @@ export default abstract class ApiService {
|
||||
}
|
||||
|
||||
let message: string;
|
||||
let description: string | undefined = undefined;
|
||||
if (error.error instanceof ErrorEvent) {
|
||||
message = `Произошла ошибка: ${error.error.message}`;
|
||||
} else {
|
||||
@ -185,9 +186,9 @@ export default abstract class ApiService {
|
||||
break;
|
||||
}
|
||||
if (error.error?.Error) {
|
||||
message += ` ${error.error.Error}`;
|
||||
description = `${error.error.Error}`;
|
||||
}
|
||||
}
|
||||
this.notify.open(message, NotifyColor.Danger);
|
||||
this.notify.error(description, message);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,23 @@ import {provideRouter} from '@angular/router';
|
||||
import {routes} from './app.routes';
|
||||
import {provideAnimationsAsync} from '@angular/platform-browser/animations/async';
|
||||
import {provideHttpClient} from "@angular/common/http";
|
||||
import {provideToastr} from "ngx-toastr";
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideRouter(routes), provideAnimationsAsync(), provideHttpClient()]
|
||||
providers: [
|
||||
provideRouter(routes),
|
||||
provideAnimationsAsync(),
|
||||
provideHttpClient(),
|
||||
provideToastr({
|
||||
timeOut: 5000,
|
||||
extendedTimeOut: 2000,
|
||||
positionClass: "toast-top-right",
|
||||
progressBar: true,
|
||||
progressAnimation: "decreasing",
|
||||
newestOnTop: true,
|
||||
tapToDismiss: true,
|
||||
disableTimeOut: false,
|
||||
autoDismiss: true,
|
||||
maxOpened: 5
|
||||
})]
|
||||
};
|
||||
|
@ -1,59 +0,0 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {NotificationComponent} from "@component/common/notification/notification.component";
|
||||
|
||||
export enum NotifyColor {
|
||||
Basic,
|
||||
Warn,
|
||||
Danger,
|
||||
Success
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
||||
export class OpenNotifyService {
|
||||
constructor(private _snackBar: MatSnackBar) {
|
||||
}
|
||||
|
||||
colorClass: string = '';
|
||||
|
||||
set setColorClass(color: NotifyColor) {
|
||||
switch (color) {
|
||||
case NotifyColor.Warn: {
|
||||
this.colorClass = 'yellow-snackbar';
|
||||
}
|
||||
break;
|
||||
case NotifyColor.Danger: {
|
||||
this.colorClass = 'red-snackbar';
|
||||
}
|
||||
break;
|
||||
case NotifyColor.Success: {
|
||||
this.colorClass = 'green-snackbar';
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
this.colorClass = 'snackbar';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
open(message: string, color: NotifyColor = NotifyColor.Basic, duration: number = 5000) {
|
||||
this.setColorClass = color;
|
||||
this._snackBar.openFromComponent(NotificationComponent, {
|
||||
data: {
|
||||
message: message,
|
||||
duration: duration,
|
||||
className: this.colorClass,
|
||||
color: color === NotifyColor.Danger ? "accent" : "primary"
|
||||
},
|
||||
duration: duration,
|
||||
verticalPosition: 'top',
|
||||
horizontalPosition: 'center',
|
||||
panelClass: [this.colorClass]
|
||||
})
|
||||
;
|
||||
}
|
||||
}
|
200
src/styles.css
200
src/styles.css
@ -10,22 +10,194 @@ body {
|
||||
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
.green-snackbar {
|
||||
--mdc-snackbar-container-color: #8CBA51;
|
||||
color: black;
|
||||
/* based on angular-toastr css https://github.com/Foxandxss/angular-toastr/blob/cb508fe6801d6b288d3afc525bb40fee1b101650/dist/angular-toastr.css */
|
||||
/* position */
|
||||
.toast-center-center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.toast-top-center {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-center {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-full-width {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-bottom-full-width {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.toast-top-left {
|
||||
top: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
.toast-top-right {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.toast-bottom-right {
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
}
|
||||
.toast-bottom-left {
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.red-snackbar {
|
||||
--mdc-snackbar-container-color: #E20338;
|
||||
color: white;
|
||||
/* toast styles */
|
||||
.toast-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.yellow-snackbar {
|
||||
--mdc-snackbar-container-color: #FFD600;
|
||||
color: black;
|
||||
.toast-message {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.toast-message a,
|
||||
.toast-message label {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.toast-message a:hover {
|
||||
color: #CCCCCC;
|
||||
text-decoration: none;
|
||||
}
|
||||
.toast-close-button {
|
||||
position: relative;
|
||||
right: -0.3em;
|
||||
top: -0.3em;
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0 1px 0 #ffffff;
|
||||
/* opacity: 0.8; */
|
||||
}
|
||||
.toast-close-button:hover,
|
||||
.toast-close-button:focus {
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
opacity: 0.4;
|
||||
}
|
||||
/*Additional properties for button version
|
||||
iOS requires the button element instead of an anchor tag.
|
||||
If you want the anchor version, it requires `href="#"`.*/
|
||||
button.toast-close-button {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.toast-container {
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
}
|
||||
.toast-container * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.toast-container .ngx-toastr {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0 0 6px;
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 300px;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
background-position: 15px center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 24px;
|
||||
box-shadow: 0 0 12px #999999;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
.toast-container .ngx-toastr:hover {
|
||||
box-shadow: 0 0 12px #000000;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/info-circle.svg */
|
||||
.toast-info {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOS4wNDMgOCA4IDExOS4wODMgOCAyNTZjMCAxMzYuOTk3IDExMS4wNDMgMjQ4IDI0OCAyNDhzMjQ4LTExMS4wMDMgMjQ4LTI0OEM1MDQgMTE5LjA4MyAzOTIuOTU3IDggMjU2IDh6bTAgMTEwYzIzLjE5NiAwIDQyIDE4LjgwNCA0MiA0MnMtMTguODA0IDQyLTQyIDQyLTQyLTE4LjgwNC00Mi00MiAxOC44MDQtNDIgNDItNDJ6bTU2IDI1NGMwIDYuNjI3LTUuMzczIDEyLTEyIDEyaC04OGMtNi42MjcgMC0xMi01LjM3My0xMi0xMnYtMjRjMC02LjYyNyA1LjM3My0xMiAxMi0xMmgxMnYtNjRoLTEyYy02LjYyNyAwLTEyLTUuMzczLTEyLTEydi0yNGMwLTYuNjI3IDUuMzczLTEyIDEyLTEyaDY0YzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MTAwaDEyYzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MjR6Jy8+PC9zdmc+");
|
||||
}
|
||||
/* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/times-circle.svg */
|
||||
.toast-error {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOSA4IDggMTE5IDggMjU2czExMSAyNDggMjQ4IDI0OCAyNDgtMTExIDI0OC0yNDhTMzkzIDggMjU2IDh6bTEyMS42IDMxMy4xYzQuNyA0LjcgNC43IDEyLjMgMCAxN0wzMzggMzc3LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwyNTYgMzEybC02NS4xIDY1LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwxMzQuNCAzMzhjLTQuNy00LjctNC43LTEyLjMgMC0xN2w2NS42LTY1LTY1LjYtNjUuMWMtNC43LTQuNy00LjctMTIuMyAwLTE3bDM5LjYtMzkuNmM0LjctNC43IDEyLjMtNC43IDE3IDBsNjUgNjUuNyA2NS4xLTY1LjZjNC43LTQuNyAxMi4zLTQuNyAxNyAwbDM5LjYgMzkuNmM0LjcgNC43IDQuNyAxMi4zIDAgMTdMMzEyIDI1Nmw2NS42IDY1LjF6Jy8+PC9zdmc+");
|
||||
}
|
||||
/* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/check.svg */
|
||||
.toast-success {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTE3My44OTggNDM5LjQwNGwtMTY2LjQtMTY2LjRjLTkuOTk3LTkuOTk3LTkuOTk3LTI2LjIwNiAwLTM2LjIwNGwzNi4yMDMtMzYuMjA0YzkuOTk3LTkuOTk4IDI2LjIwNy05Ljk5OCAzNi4yMDQgMEwxOTIgMzEyLjY5IDQzMi4wOTUgNzIuNTk2YzkuOTk3LTkuOTk3IDI2LjIwNy05Ljk5NyAzNi4yMDQgMGwzNi4yMDMgMzYuMjA0YzkuOTk3IDkuOTk3IDkuOTk3IDI2LjIwNiAwIDM2LjIwNGwtMjk0LjQgMjk0LjQwMWMtOS45OTggOS45OTctMjYuMjA3IDkuOTk3LTM2LjIwNC0uMDAxeicvPjwvc3ZnPg==");
|
||||
}
|
||||
/* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/exclamation-triangle.svg */
|
||||
.toast-warning {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1NzYgNTEyJyB3aWR0aD0nNTc2JyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTU2OS41MTcgNDQwLjAxM0M1ODcuOTc1IDQ3Mi4wMDcgNTY0LjgwNiA1MTIgNTI3Ljk0IDUxMkg0OC4wNTRjLTM2LjkzNyAwLTU5Ljk5OS00MC4wNTUtNDEuNTc3LTcxLjk4N0wyNDYuNDIzIDIzLjk4NWMxOC40NjctMzIuMDA5IDY0LjcyLTMxLjk1MSA4My4xNTQgMGwyMzkuOTQgNDE2LjAyOHpNMjg4IDM1NGMtMjUuNDA1IDAtNDYgMjAuNTk1LTQ2IDQ2czIwLjU5NSA0NiA0NiA0NiA0Ni0yMC41OTUgNDYtNDYtMjAuNTk1LTQ2LTQ2LTQ2em0tNDMuNjczLTE2NS4zNDZsNy40MTggMTM2Yy4zNDcgNi4zNjQgNS42MDkgMTEuMzQ2IDExLjk4MiAxMS4zNDZoNDguNTQ2YzYuMzczIDAgMTEuNjM1LTQuOTgyIDExLjk4Mi0xMS4zNDZsNy40MTgtMTM2Yy4zNzUtNi44NzQtNS4wOTgtMTIuNjU0LTExLjk4Mi0xMi42NTRoLTYzLjM4M2MtNi44ODQgMC0xMi4zNTYgNS43OC0xMS45ODEgMTIuNjU0eicvPjwvc3ZnPg==");
|
||||
}
|
||||
.toast-container.toast-top-center .ngx-toastr,
|
||||
.toast-container.toast-bottom-center .ngx-toastr {
|
||||
width: 300px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.toast-container.toast-top-full-width .ngx-toastr,
|
||||
.toast-container.toast-bottom-full-width .ngx-toastr {
|
||||
width: 96%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.ngx-toastr {
|
||||
background-color: #030303;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.toast-success {
|
||||
background-color: #51A351;
|
||||
}
|
||||
.toast-error {
|
||||
background-color: #BD362F;
|
||||
}
|
||||
.toast-info {
|
||||
background-color: #2F96B4;
|
||||
}
|
||||
.toast-warning {
|
||||
background-color: #F89406;
|
||||
}
|
||||
.toast-progress {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 4px;
|
||||
background-color: #000000;
|
||||
opacity: 0.4;
|
||||
}
|
||||
/* Responsive Design */
|
||||
@media all and (max-width: 240px) {
|
||||
.toast-container .ngx-toastr.div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 11em;
|
||||
}
|
||||
.toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 241px) and (max-width: 480px) {
|
||||
.toast-container .ngx-toastr.div {
|
||||
padding: 8px 8px 8px 50px;
|
||||
width: 18em;
|
||||
}
|
||||
.toast-container .toast-close-button {
|
||||
right: -0.2em;
|
||||
top: -0.2em;
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 481px) and (max-width: 768px) {
|
||||
.toast-container .ngx-toastr.div {
|
||||
padding: 15px 15px 15px 50px;
|
||||
width: 25em;
|
||||
}
|
||||
|
||||
.snackbar {
|
||||
--mdc-snackbar-container-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user