refactor: clean code

This commit is contained in:
Polianin Nikita 2024-12-18 06:57:27 +03:00
parent 3af8c43cd9
commit a2d4151cc3
47 changed files with 181 additions and 150 deletions

View File

@ -15,7 +15,7 @@ import {Router} from "@angular/router";
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {RequestBuilder, RequestData} from "@api/RequestBuilder"; import {RequestBuilder, RequestData} from "@api/RequestBuilder";
import {ToastrService} from "ngx-toastr"; import {ToastrService} from "ngx-toastr";
import {AuthRoles} from "@model/AuthRoles"; import {AuthRoles} from "@model/authRoles";
export enum AvailableVersion { export enum AvailableVersion {
v1 v1
@ -69,7 +69,7 @@ export default abstract class ApiService {
}).pipe( }).pipe(
catchError(error => { catchError(error => {
if (!secondTry && error.status === 401) if (!secondTry && error.status === 401)
return this.handle401Error().pipe( return this.handle401Error(error).pipe(
switchMap(() => this.sendHttpRequest<Type>(method, request, true)) switchMap(() => this.sendHttpRequest<Type>(method, request, true))
); );
else { else {
@ -88,7 +88,7 @@ export default abstract class ApiService {
}); });
} }
private handle401Error(): Observable<any> { private handle401Error(error: any): Observable<any> {
if (ApiService.isRefreshingToken.value) if (ApiService.isRefreshingToken.value)
return ApiService.refreshTokenSubject.asObservable(); return ApiService.refreshTokenSubject.asObservable();
@ -103,7 +103,7 @@ export default abstract class ApiService {
ApiService.isRefreshingToken.next(false); ApiService.isRefreshingToken.next(false);
ApiService.refreshTokenSubject.error(err); ApiService.refreshTokenSubject.error(err);
ApiService.refreshTokenSubject = new ReplaySubject(1); ApiService.refreshTokenSubject = new ReplaySubject(1);
throw err; throw error;
}) })
); );
} }

View File

@ -19,7 +19,7 @@ export default class AuthApiService extends ApiService {
return this.post<AuthRoles>(request); return this.post<AuthRoles>(request);
} }
public reLogin(){ public reLogin() {
let request = this.createRequestBuilder() let request = this.createRequestBuilder()
.setEndpoint('ReLogin') .setEndpoint('ReLogin')
.setWithCredentials() .setWithCredentials()

View File

@ -1,7 +1,7 @@
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import ApiService, {AvailableVersion} from "@api/api.service"; import ApiService, {AvailableVersion} from "@api/api.service";
import {DateOnly} from "@model/DateOnly"; import {DateOnly} from "@model/dateOnly";
import {PeriodTimes} from "@model/pairPeriodTime"; import {PairPeriodTime} from "@model/pairPeriodTime";
import {ScheduleRequest} from "@api/v1/scheduleRequest"; import {ScheduleRequest} from "@api/v1/scheduleRequest";
import {ScheduleResponse} from "@api/v1/scheduleResponse"; import {ScheduleResponse} from "@api/v1/scheduleResponse";
import {map} from "rxjs"; import {map} from "rxjs";
@ -16,7 +16,7 @@ export class ScheduleService extends ApiService {
} }
public pairPeriod() { public pairPeriod() {
return this.get<PeriodTimes>('PairPeriod'); return this.get<PairPeriodTime>('PairPeriod');
} }
public postSchedule(data: ScheduleRequest) { public postSchedule(data: ScheduleRequest) {

View File

@ -1 +1 @@
<mat-progress-spinner [color]="color" mode="indeterminate" [diameter]="scale" /> <mat-progress-spinner [color]="color" mode="indeterminate" [diameter]="scale"/>

View File

@ -1,13 +1,11 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {MatProgressSpinner} from "@angular/material/progress-spinner"; import {MatProgressSpinner} from "@angular/material/progress-spinner";
import {NgStyle} from "@angular/common";
@Component({ @Component({
selector: 'app-data-spinner', selector: 'app-data-spinner',
standalone: true, standalone: true,
imports: [ imports: [
MatProgressSpinner, MatProgressSpinner,
NgStyle
], ],
templateUrl: './data-spinner.component.html' templateUrl: './data-spinner.component.html'
}) })

View File

@ -1,16 +1,13 @@
import { Component } from '@angular/core'; import {Component} from '@angular/core';
import {MatToolbar} from "@angular/material/toolbar"; import {MatToolbar} from "@angular/material/toolbar";
import {MatAnchor, MatButton} from "@angular/material/button";
import {HasRoleDirective} from "@/directives/has-role.directive"; import {HasRoleDirective} from "@/directives/has-role.directive";
import {AuthRoles} from "@model/AuthRoles"; import {AuthRoles} from "@model/authRoles";
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
standalone: true, standalone: true,
imports: [ imports: [
MatToolbar, MatToolbar,
MatButton,
MatAnchor,
HasRoleDirective HasRoleDirective
], ],
templateUrl: './header.component.html', templateUrl: './header.component.html',

View File

@ -1,14 +1,13 @@
import {Component, EventEmitter, Input, Output} from '@angular/core'; import {Component, EventEmitter, Input, Output} from '@angular/core';
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component"; import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
import {MatIcon} from "@angular/material/icon"; import {MatIcon} from "@angular/material/icon";
import {MatButton, MatFabButton} from "@angular/material/button"; import {MatFabButton} from "@angular/material/button";
@Component({ @Component({
selector: 'app-loading-indicator', selector: 'app-loading-indicator',
standalone: true, standalone: true,
imports: [ imports: [
DataSpinnerComponent, DataSpinnerComponent,
MatButton,
MatIcon, MatIcon,
MatFabButton MatFabButton
], ],

View File

@ -3,7 +3,6 @@ import {MatTableDataSource, MatTableModule} from "@angular/material/table";
import {MatIcon} from "@angular/material/icon"; import {MatIcon} from "@angular/material/icon";
import {DatePipe} from "@angular/common"; import {DatePipe} from "@angular/common";
import {addDays} from "@progress/kendo-date-math"; import {addDays} from "@progress/kendo-date-math";
import {MatDivider} from "@angular/material/divider";
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component"; import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
import {ScheduleResponse} from "@api/v1/scheduleResponse"; import {ScheduleResponse} from "@api/v1/scheduleResponse";
@ -23,7 +22,6 @@ interface Dictionary {
MatTableModule, MatTableModule,
MatIcon, MatIcon,
DatePipe, DatePipe,
MatDivider,
DataSpinnerComponent DataSpinnerComponent
], ],
templateUrl: './table.component.html', templateUrl: './table.component.html',

View File

@ -23,7 +23,8 @@
Кабинет Кабинет
</mat-panel-title> </mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<mat-chip-listbox hideSingleSelectionIndicator (change)="onLectureHallSelected($event.value)" [formControl]="formLectureHalls" #lectureChip> <mat-chip-listbox hideSingleSelectionIndicator (change)="onLectureHallSelected($event.value)"
[formControl]="formLectureHalls" #lectureChip>
@for (lectureHall of lectureHallsFiltered; track $index) { @for (lectureHall of lectureHallsFiltered; track $index) {
<mat-chip-option [value]="lectureHall.id" color="accent"> <mat-chip-option [value]="lectureHall.id" color="accent">
{{ lectureHall.name }} {{ lectureHall.name }}

View File

@ -1,5 +1,4 @@
import {Component, EventEmitter, ViewChild} from '@angular/core'; import {Component, EventEmitter, ViewChild} from '@angular/core';
import {AsyncPipe} from "@angular/common";
import {MatAccordion, MatExpansionModule, MatExpansionPanel} from "@angular/material/expansion"; import {MatAccordion, MatExpansionModule, MatExpansionPanel} from "@angular/material/expansion";
import {MatChipListbox, MatChipsModule} from "@angular/material/chips"; import {MatChipListbox, MatChipsModule} from "@angular/material/chips";
import {catchError} from "rxjs"; import {catchError} from "rxjs";
@ -22,7 +21,6 @@ enum Enclosure {
imports: [ imports: [
MatChipsModule, MatChipsModule,
MatExpansionModule, MatExpansionModule,
AsyncPipe,
ReactiveFormsModule, ReactiveFormsModule,
MatAccordion, MatAccordion,
LoadingIndicatorComponent LoadingIndicatorComponent

View File

@ -1,11 +1,14 @@
<!--suppress CssInvalidPropertyValue --> <!--suppress CssInvalidPropertyValue -->
<button mat-button [matMenuTriggerFor]="menu" #menuTrigger="matMenuTrigger" [id]="idButton" style="margin-bottom: 10px;">{{ textButton }}</button> <button mat-button [matMenuTriggerFor]="menu" #menuTrigger="matMenuTrigger" [id]="idButton"
style="margin-bottom: 10px;">{{ textButton }}
</button>
<mat-menu #menu="matMenu" [hasBackdrop]="false" class="menu-options"> <mat-menu #menu="matMenu" [hasBackdrop]="false" class="menu-options">
<div (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" style="padding: 0 15px 15px"> <div (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" style="padding: 0 15px 15px">
<div class="header-menu"> <div class="header-menu">
<mat-form-field appearance="outline" color="accent" style="display:flex;"> <mat-form-field appearance="outline" color="accent" style="display:flex;">
<input matInput placeholder="Поиск..." [(ngModel)]="searchQuery" [disabled]="data === null || data.length === 0"> <input matInput placeholder="Поиск..." [(ngModel)]="searchQuery"
[disabled]="data === null || data.length === 0">
<button mat-icon-button matSuffix (click)="clearSearchQuery()" [disabled]="data === null || data.length === 0"> <button mat-icon-button matSuffix (click)="clearSearchQuery()" [disabled]="data === null || data.length === 0">
<mat-icon style="color: var(--mdc-filled-button-label-text-color);">close</mat-icon> <mat-icon style="color: var(--mdc-filled-button-label-text-color);">close</mat-icon>
</button> </button>

View File

@ -4,7 +4,6 @@ import {MatTab, MatTabGroup} from "@angular/material/tabs";
import {Observable} from "rxjs"; import {Observable} from "rxjs";
import {FormsModule, ReactiveFormsModule} from "@angular/forms"; import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {MatButton} from "@angular/material/button"; import {MatButton} from "@angular/material/button";
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
import {GroupComponent} from "@component/schedule/tabs/group/group.component"; import {GroupComponent} from "@component/schedule/tabs/group/group.component";
import {ProfessorComponent} from "@component/schedule/tabs/professor/professor.component"; import {ProfessorComponent} from "@component/schedule/tabs/professor/professor.component";
import {LectureHallComponent} from "@component/schedule/tabs/lecture-hall/lecture-hall.component"; import {LectureHallComponent} from "@component/schedule/tabs/lecture-hall/lecture-hall.component";
@ -15,7 +14,7 @@ import {DisciplineService} from "@api/v1/discipline.service";
import {LectureHallService} from "@api/v1/lectureHall.service"; import {LectureHallService} from "@api/v1/lectureHall.service";
import {GroupService} from "@api/v1/group.service"; import {GroupService} from "@api/v1/group.service";
import {ProfessorService} from "@api/v1/professor.service"; import {ProfessorService} from "@api/v1/professor.service";
import {AuthRoles} from "@model/AuthRoles"; import {AuthRoles} from "@model/authRoles";
import {HasRoleDirective} from "@/directives/has-role.directive"; import {HasRoleDirective} from "@/directives/has-role.directive";
import {TabSelectType, TabStorageService} from "@service/tab-storage.service"; import {TabSelectType, TabStorageService} from "@service/tab-storage.service";
import {ScheduleRequest} from "@api/v1/scheduleRequest"; import {ScheduleRequest} from "@api/v1/scheduleRequest";
@ -36,7 +35,6 @@ export enum TabsSelect {
MatTab, MatTab,
ReactiveFormsModule, ReactiveFormsModule,
MatButton, MatButton,
DataSpinnerComponent,
GroupComponent, GroupComponent,
ProfessorComponent, ProfessorComponent,
LectureHallComponent, LectureHallComponent,

View File

@ -1,6 +1,6 @@
import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core'; import {Directive, Input, TemplateRef, ViewContainerRef} from '@angular/core';
import AuthApiService from "@api/v1/authApiService"; import AuthApiService from "@api/v1/authApiService";
import {AuthRoles} from "@model/AuthRoles"; import {AuthRoles} from "@model/authRoles";
import {catchError, of} from "rxjs"; import {catchError, of} from "rxjs";
@Directive({ @Directive({
@ -13,7 +13,8 @@ export class HasRoleDirective {
private templateRef: TemplateRef<any>, private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef, private viewContainer: ViewContainerRef,
private authService: AuthApiService private authService: AuthApiService
) {} ) {
}
@Input() set appHasRole(role: AuthRoles) { @Input() set appHasRole(role: AuthRoles) {
this.viewContainer.clear(); this.viewContainer.clear();
@ -29,6 +30,6 @@ export class HasRoleDirective {
this.viewContainer.createEmbeddedView(this.templateRef); this.viewContainer.createEmbeddedView(this.templateRef);
else else
this.viewContainer.clear(); this.viewContainer.clear();
}) });
} }
} }

View File

@ -8,10 +8,12 @@
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet"> <link
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head> </head>
<body class="mat-typography"> <body class="mat-typography">
<app-root></app-root> <app-root></app-root>
</body> </body>
</html> </html>

View File

@ -1,6 +1,6 @@
import { bootstrapApplication } from '@angular/platform-browser'; import {bootstrapApplication} from '@angular/platform-browser';
import { appConfig } from './app/app.config'; import {appConfig} from './app/app.config';
import { AppComponent } from './app/app.component'; import {AppComponent} from './app/app.component';
bootstrapApplication(AppComponent, appConfig) bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err)); .catch((err) => console.error(err));

View File

@ -17,7 +17,7 @@
.formLogin form { .formLogin form {
display: flex; display: flex;
flex-direction:column; flex-direction: column;
} }
.formLoginButton { .formLoginButton {

View File

@ -57,7 +57,7 @@
</form> </form>
<mat-error> <mat-error>
{{errorText}} {{ errorText }}
</mat-error> </mat-error>
<div class="formLoginButton"> <div class="formLoginButton">

View File

@ -1,4 +1,4 @@
import { Component } from '@angular/core'; import {Component} from '@angular/core';
import {MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle} from '@angular/material/dialog'; import {MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle} from '@angular/material/dialog';
import {MatButton} from "@angular/material/button"; import {MatButton} from "@angular/material/button";
@ -15,7 +15,8 @@ import {MatButton} from "@angular/material/button";
}) })
export class ConfirmDialogComponent { export class ConfirmDialogComponent {
constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) { } constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) {
}
protected onConfirm(): void { protected onConfirm(): void {
this.dialogRef.close(true); this.dialogRef.close(true);

View File

@ -9,10 +9,10 @@ export class TimeOnly {
if (hourOrTime instanceof Date) { if (hourOrTime instanceof Date) {
this._ticks = hourOrTime.getTime(); this._ticks = hourOrTime.getTime();
} else if (typeof hourOrTime === 'number' && minute !== undefined && second !== undefined) { } else if (typeof hourOrTime === 'number' && minute !== undefined && second !== undefined) {
this._ticks = new Date(2000, 0, 1, hourOrTime, minute, second, 0).getTime() this._ticks = new Date(2000, 0, 1, hourOrTime, minute, second, 0).getTime();
} else if (typeof hourOrTime === 'string') { } else if (typeof hourOrTime === 'string') {
const [h, m, s] = hourOrTime.split(':').map(Number); const [h, m, s] = hourOrTime.split(':').map(Number);
this._ticks = new Date(2000, 0, 1, h, m, s, 0).getTime() this._ticks = new Date(2000, 0, 1, h, m, s, 0).getTime();
} else { } else {
throw new Error('Invalid constructor arguments'); throw new Error('Invalid constructor arguments');
} }
@ -35,7 +35,7 @@ export class TimeOnly {
} }
toTimeWithoutSeconds(): string { toTimeWithoutSeconds(): string {
return `${String(this.hour).padStart(2, '0')}:${String(this.minute).padStart(2, '0')}` return `${String(this.hour).padStart(2, '0')}:${String(this.minute).padStart(2, '0')}`;
} }
toString(): string { toString(): string {

View File

@ -17,38 +17,46 @@ body {
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
} }
.toast-top-center { .toast-top-center {
top: 0; top: 0;
right: 0; right: 0;
width: 100%; width: 100%;
} }
.toast-bottom-center { .toast-bottom-center {
bottom: 0; bottom: 0;
right: 0; right: 0;
width: 100%; width: 100%;
} }
.toast-top-full-width { .toast-top-full-width {
top: 0; top: 0;
right: 0; right: 0;
width: 100%; width: 100%;
} }
.toast-bottom-full-width { .toast-bottom-full-width {
bottom: 0; bottom: 0;
right: 0; right: 0;
width: 100%; width: 100%;
} }
.toast-top-left { .toast-top-left {
top: 12px; top: 12px;
left: 12px; left: 12px;
} }
.toast-top-right { .toast-top-right {
top: 12px; top: 12px;
right: 12px; right: 12px;
} }
.toast-bottom-right { .toast-bottom-right {
right: 12px; right: 12px;
bottom: 12px; bottom: 12px;
} }
.toast-bottom-left { .toast-bottom-left {
bottom: 12px; bottom: 12px;
left: 12px; left: 12px;
@ -58,17 +66,21 @@ body {
.toast-title { .toast-title {
font-weight: bold; font-weight: bold;
} }
.toast-message { .toast-message {
word-wrap: break-word; word-wrap: break-word;
} }
.toast-message a, .toast-message a,
.toast-message label { .toast-message label {
color: #FFFFFF; color: #FFFFFF;
} }
.toast-message a:hover { .toast-message a:hover {
color: #CCCCCC; color: #CCCCCC;
text-decoration: none; text-decoration: none;
} }
.toast-close-button { .toast-close-button {
position: relative; position: relative;
right: -0.3em; right: -0.3em;
@ -80,6 +92,7 @@ body {
text-shadow: 0 1px 0 #ffffff; text-shadow: 0 1px 0 #ffffff;
/* opacity: 0.8; */ /* opacity: 0.8; */
} }
.toast-close-button:hover, .toast-close-button:hover,
.toast-close-button:focus { .toast-close-button:focus {
color: #000000; color: #000000;
@ -87,6 +100,7 @@ body {
cursor: pointer; cursor: pointer;
opacity: 0.4; opacity: 0.4;
} }
/*Additional properties for button version /*Additional properties for button version
iOS requires the button element instead of an anchor tag. iOS requires the button element instead of an anchor tag.
If you want the anchor version, it requires `href="#"`.*/ If you want the anchor version, it requires `href="#"`.*/
@ -96,14 +110,17 @@ button.toast-close-button {
background: transparent; background: transparent;
border: 0; border: 0;
} }
.toast-container { .toast-container {
pointer-events: none; pointer-events: none;
position: fixed; position: fixed;
z-index: 999999; z-index: 999999;
} }
.toast-container * { .toast-container * {
box-sizing: border-box; box-sizing: border-box;
} }
.toast-container .ngx-toastr { .toast-container .ngx-toastr {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -117,55 +134,68 @@ button.toast-close-button {
box-shadow: 0 0 12px #999999; box-shadow: 0 0 12px #999999;
color: #FFFFFF; color: #FFFFFF;
} }
.toast-container .ngx-toastr:hover { .toast-container .ngx-toastr:hover {
box-shadow: 0 0 12px #000000; box-shadow: 0 0 12px #000000;
opacity: 1; opacity: 1;
cursor: pointer; cursor: pointer;
} }
/* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/info-circle.svg */ /* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/info-circle.svg */
.toast-info { .toast-info {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOS4wNDMgOCA4IDExOS4wODMgOCAyNTZjMCAxMzYuOTk3IDExMS4wNDMgMjQ4IDI0OCAyNDhzMjQ4LTExMS4wMDMgMjQ4LTI0OEM1MDQgMTE5LjA4MyAzOTIuOTU3IDggMjU2IDh6bTAgMTEwYzIzLjE5NiAwIDQyIDE4LjgwNCA0MiA0MnMtMTguODA0IDQyLTQyIDQyLTQyLTE4LjgwNC00Mi00MiAxOC44MDQtNDIgNDItNDJ6bTU2IDI1NGMwIDYuNjI3LTUuMzczIDEyLTEyIDEyaC04OGMtNi42MjcgMC0xMi01LjM3My0xMi0xMnYtMjRjMC02LjYyNyA1LjM3My0xMiAxMi0xMmgxMnYtNjRoLTEyYy02LjYyNyAwLTEyLTUuMzczLTEyLTEydi0yNGMwLTYuNjI3IDUuMzczLTEyIDEyLTEyaDY0YzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MTAwaDEyYzYuNjI3IDAgMTIgNS4zNzMgMTIgMTJ2MjR6Jy8+PC9zdmc+"); 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 */ /* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/times-circle.svg */
.toast-error { .toast-error {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTI1NiA4QzExOSA4IDggMTE5IDggMjU2czExMSAyNDggMjQ4IDI0OCAyNDgtMTExIDI0OC0yNDhTMzkzIDggMjU2IDh6bTEyMS42IDMxMy4xYzQuNyA0LjcgNC43IDEyLjMgMCAxN0wzMzggMzc3LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwyNTYgMzEybC02NS4xIDY1LjZjLTQuNyA0LjctMTIuMyA0LjctMTcgMEwxMzQuNCAzMzhjLTQuNy00LjctNC43LTEyLjMgMC0xN2w2NS42LTY1LTY1LjYtNjUuMWMtNC43LTQuNy00LjctMTIuMyAwLTE3bDM5LjYtMzkuNmM0LjctNC43IDEyLjMtNC43IDE3IDBsNjUgNjUuNyA2NS4xLTY1LjZjNC43LTQuNyAxMi4zLTQuNyAxNyAwbDM5LjYgMzkuNmM0LjcgNC43IDQuNyAxMi4zIDAgMTdMMzEyIDI1Nmw2NS42IDY1LjF6Jy8+PC9zdmc+"); 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 */ /* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/check.svg */
.toast-success { .toast-success {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1MTIgNTEyJyB3aWR0aD0nNTEyJyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTE3My44OTggNDM5LjQwNGwtMTY2LjQtMTY2LjRjLTkuOTk3LTkuOTk3LTkuOTk3LTI2LjIwNiAwLTM2LjIwNGwzNi4yMDMtMzYuMjA0YzkuOTk3LTkuOTk4IDI2LjIwNy05Ljk5OCAzNi4yMDQgMEwxOTIgMzEyLjY5IDQzMi4wOTUgNzIuNTk2YzkuOTk3LTkuOTk3IDI2LjIwNy05Ljk5NyAzNi4yMDQgMGwzNi4yMDMgMzYuMjA0YzkuOTk3IDkuOTk3IDkuOTk3IDI2LjIwNiAwIDM2LjIwNGwtMjk0LjQgMjk0LjQwMWMtOS45OTggOS45OTctMjYuMjA3IDkuOTk3LTM2LjIwNC0uMDAxeicvPjwvc3ZnPg=="); 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 */ /* https://github.com/FortAwesome/Font-Awesome-Pro/blob/master/advanced-options/raw-svg/regular/exclamation-triangle.svg */
.toast-warning { .toast-warning {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1NzYgNTEyJyB3aWR0aD0nNTc2JyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTU2OS41MTcgNDQwLjAxM0M1ODcuOTc1IDQ3Mi4wMDcgNTY0LjgwNiA1MTIgNTI3Ljk0IDUxMkg0OC4wNTRjLTM2LjkzNyAwLTU5Ljk5OS00MC4wNTUtNDEuNTc3LTcxLjk4N0wyNDYuNDIzIDIzLjk4NWMxOC40NjctMzIuMDA5IDY0LjcyLTMxLjk1MSA4My4xNTQgMGwyMzkuOTQgNDE2LjAyOHpNMjg4IDM1NGMtMjUuNDA1IDAtNDYgMjAuNTk1LTQ2IDQ2czIwLjU5NSA0NiA0NiA0NiA0Ni0yMC41OTUgNDYtNDYtMjAuNTk1LTQ2LTQ2LTQ2em0tNDMuNjczLTE2NS4zNDZsNy40MTggMTM2Yy4zNDcgNi4zNjQgNS42MDkgMTEuMzQ2IDExLjk4MiAxMS4zNDZoNDguNTQ2YzYuMzczIDAgMTEuNjM1LTQuOTgyIDExLjk4Mi0xMS4zNDZsNy40MTgtMTM2Yy4zNzUtNi44NzQtNS4wOTgtMTIuNjU0LTExLjk4Mi0xMi42NTRoLTYzLjM4M2MtNi44ODQgMC0xMi4zNTYgNS43OC0xMS45ODEgMTIuNjU0eicvPjwvc3ZnPg=="); background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCA1NzYgNTEyJyB3aWR0aD0nNTc2JyBoZWlnaHQ9JzUxMic+PHBhdGggZmlsbD0ncmdiKDI1NSwyNTUsMjU1KScgZD0nTTU2OS41MTcgNDQwLjAxM0M1ODcuOTc1IDQ3Mi4wMDcgNTY0LjgwNiA1MTIgNTI3Ljk0IDUxMkg0OC4wNTRjLTM2LjkzNyAwLTU5Ljk5OS00MC4wNTUtNDEuNTc3LTcxLjk4N0wyNDYuNDIzIDIzLjk4NWMxOC40NjctMzIuMDA5IDY0LjcyLTMxLjk1MSA4My4xNTQgMGwyMzkuOTQgNDE2LjAyOHpNMjg4IDM1NGMtMjUuNDA1IDAtNDYgMjAuNTk1LTQ2IDQ2czIwLjU5NSA0NiA0NiA0NiA0Ni0yMC41OTUgNDYtNDYtMjAuNTk1LTQ2LTQ2LTQ2em0tNDMuNjczLTE2NS4zNDZsNy40MTggMTM2Yy4zNDcgNi4zNjQgNS42MDkgMTEuMzQ2IDExLjk4MiAxMS4zNDZoNDguNTQ2YzYuMzczIDAgMTEuNjM1LTQuOTgyIDExLjk4Mi0xMS4zNDZsNy40MTgtMTM2Yy4zNzUtNi44NzQtNS4wOTgtMTIuNjU0LTExLjk4Mi0xMi42NTRoLTYzLjM4M2MtNi44ODQgMC0xMi4zNTYgNS43OC0xMS45ODEgMTIuNjU0eicvPjwvc3ZnPg==");
} }
.toast-container.toast-top-center .ngx-toastr, .toast-container.toast-top-center .ngx-toastr,
.toast-container.toast-bottom-center .ngx-toastr { .toast-container.toast-bottom-center .ngx-toastr {
width: 300px; width: 300px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.toast-container.toast-top-full-width .ngx-toastr, .toast-container.toast-top-full-width .ngx-toastr,
.toast-container.toast-bottom-full-width .ngx-toastr { .toast-container.toast-bottom-full-width .ngx-toastr {
width: 96%; width: 96%;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.ngx-toastr { .ngx-toastr {
background-color: #030303; background-color: #030303;
pointer-events: auto; pointer-events: auto;
} }
.toast-success { .toast-success {
background-color: #51A351; background-color: #51A351;
} }
.toast-error { .toast-error {
background-color: #BD362F; background-color: #BD362F;
} }
.toast-info { .toast-info {
background-color: #2F96B4; background-color: #2F96B4;
} }
.toast-warning { .toast-warning {
background-color: #F89406; background-color: #F89406;
} }
.toast-progress { .toast-progress {
position: absolute; position: absolute;
left: 0; left: 0;
@ -174,27 +204,32 @@ button.toast-close-button {
background-color: #000000; background-color: #000000;
opacity: 0.4; opacity: 0.4;
} }
/* Responsive Design */ /* Responsive Design */
@media all and (max-width: 240px) { @media all and (max-width: 240px) {
.toast-container .ngx-toastr.div { .toast-container .ngx-toastr.div {
padding: 8px 8px 8px 50px; padding: 8px 8px 8px 50px;
width: 11em; width: 11em;
} }
.toast-container .toast-close-button { .toast-container .toast-close-button {
right: -0.2em; right: -0.2em;
top: -0.2em; top: -0.2em;
} }
} }
@media all and (min-width: 241px) and (max-width: 480px) { @media all and (min-width: 241px) and (max-width: 480px) {
.toast-container .ngx-toastr.div { .toast-container .ngx-toastr.div {
padding: 8px 8px 8px 50px; padding: 8px 8px 8px 50px;
width: 18em; width: 18em;
} }
.toast-container .toast-close-button { .toast-container .toast-close-button {
right: -0.2em; right: -0.2em;
top: -0.2em; top: -0.2em;
} }
} }
@media all and (min-width: 481px) and (max-width: 768px) { @media all and (min-width: 481px) and (max-width: 768px) {
.toast-container .ngx-toastr.div { .toast-container .ngx-toastr.div {
padding: 15px 15px 15px 50px; padding: 15px 15px 15px 50px;