Skip to content
Snippets Groups Projects
Commit 992cca8f authored by Hartung, Michael's avatar Hartung, Michael
Browse files

custom toast

parent b25e7446
Branches
Tags
No related merge requests found
Showing
with 214 additions and 35 deletions
......@@ -48,6 +48,7 @@ import { CenterViewInverseComponent } from './components/network/network-menu-le
import { LicenseAgreementComponent } from './components/license-agreement/license-agreement.component';
import { QuickDrugTargetComponent } from './components/quick-drug-target/quick-drug-target.component';
import { QuickDrugComponent } from './components/quick-drug/quick-drug.component';
import { ToastComponent } from './components/toast/toast.component';
@NgModule({
......@@ -77,6 +78,7 @@ import { QuickDrugComponent } from './components/quick-drug/quick-drug.component
LicenseAgreementComponent,
QuickDrugTargetComponent,
QuickDrugComponent,
ToastComponent,
],
imports: [
BrowserModule,
......
......@@ -20,7 +20,7 @@
<a (click)="close()" class="card-header-icon" aria-label="close">
<span class="icon" title="Close analysis">
<i class="fas fa-times" aria-hidden="true"></i>
<i class="fas fa-times color-danger" aria-hidden="true"></i>
</span>
</a>
</header>
......@@ -132,7 +132,7 @@
></i>
<i
*ngIf="!task.info.parameters.includeIndirectDrugs"
class="fa fa-times"
class="fa fa-times color-danger"
></i>
</td>
</tr>
......@@ -150,7 +150,7 @@
></i>
<i
*ngIf="!task.info.parameters.includeNonApprovedDrugs"
class="fa fa-times"
class="fa fa-times color-danger"
></i>
</td>
</tr>
......@@ -190,7 +190,7 @@
<tr>
<td>Include indirect drugs</td>
<td>
<i class="fa fa-times"></i>
<i class="fa fa-times color-danger"></i>
</td>
</tr>
<tr>
......
<div class="toast-holder">
<div *ngFor="let toast of toasts | keyvalue" id="{{toastIdPrefix + toast.key}}">
<div class="toast {{toast.value.type}}" [class.fade-in]="isSeen(toast.key)">
<a (click)="close(toast.key)" aria-label="close" class="close">
<span class="icon" title="Close analysis">
<i class="fas fa-times" aria-hidden="true"></i>
</span>
</a>
<p>{{toast.value.message}}</p>
</div>
</div>
</div>
@import "src/stylesheets/variables";
.toast-holder {
z-index: $toast-z;
top: 3rem;
position: fixed;
left: 0;
right: 0;
}
.toast {
position: relative;
max-width: 60vw;
padding: 10px 15px;
border-radius: 0.25rem;
box-shadow: 0 0.5em 1em -0.125em hsla(0, 0%, 4%, 0.1),
0 0 0 1px hsla(0, 0%, 4%, 0.02);
margin: 0 auto;
&.danger {
color: var(--drgstn-text-secondary);
background-color: var(--drgstn-danger);
}
&.success {
color: var(--drgstn-text-secondary) !important;
background-color: var(--drgstn-success);
}
&.warning {
color: var(--drgstn-text-secondary);
background-color: var(--drgstn-warning);
}
&.info {
color: var(--drgstn-text-secondary);
background-color: var(--drgstn-info);
}
.close {
display: inline;
float: right;
}
}
.fa-times {
color: white;
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ToastComponent } from './toast.component';
describe('ToastComponent', () => {
let component: ToastComponent;
let fixture: ComponentFixture<ToastComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ToastComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ToastComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { LiveToasts } from 'src/app/interfaces';
import { ToastService } from 'src/app/services/toast/toast.service';
@Component({
selector: 'app-toast',
templateUrl: './toast.component.html',
styleUrls: ['./toast.component.scss']
})
export class ToastComponent implements OnInit {
public toasts: LiveToasts = {};
public seen: any = new Set();
public toastIdPrefix = 'drugstone-toast-id-';
constructor(public toast: ToastService) { }
ngOnInit(): void {
this.toast.getToasts$.forEach(data => {
this.toasts = data;
})
}
public isSeen(id) {
console.log(this.seen.has(id))
if (this.seen.has(id)) {
return true
} else {
this.seen.add(id);
return false
}
}
public close(id: number) {
this.toast.deleteToast(id);
document.getElementById(`${this.toastIdPrefix}` + id).remove();
}
}
......@@ -257,3 +257,12 @@ export interface Algorithm {
slug: AlgorithmType | QuickAlgorithmType;
name: string;
}
export interface Toast {
message: string;
type: 'success' | 'info' | 'warning' | 'danger'
}
export interface LiveToasts {
[id: number]: Toast
}
......@@ -525,4 +525,6 @@
</div>
</div>
</div>
<app-toast></app-toast>
</div>
......@@ -7,6 +7,7 @@ import {Injectable} from '@angular/core';
import {NetexControllerService} from '../netex-controller/netex-controller.service';
import {DrugstoneConfigService} from "../drugstone-config/drugstone-config.service";
import {NetworkHandlerService} from "../network-handler/network-handler.service";
import { ToastService } from '../toast/toast.service';
export type AlgorithmType =
'trustrank'
......@@ -72,7 +73,9 @@ export class AnalysisService {
private tissues: Tissue[] = [];
constructor(private http: HttpClient,
constructor(
public toast: ToastService,
private http: HttpClient,
public netex: NetexControllerService,
public drugstoneConfig: DrugstoneConfigService,
public networkHandler: NetworkHandlerService
......@@ -217,14 +220,9 @@ export class AnalysisService {
async startQuickAnalysis(isSuper: boolean, algorithm: QuickAlgorithmType) {
if (!this.canLaunchTask()) {
toast({
this.toast.setNewToast({
message: `You can only run ${MAX_TASKS} tasks at once. Please wait for one of them to finish or delete it from the task list.`,
duration: 5000,
dismissible: true,
pauseOnHover: true,
type: 'is-danger',
position: 'top-center',
animate: {in: 'fadeIn', out: 'fadeOut'}
type: 'danger'
});
return;
}
......@@ -264,29 +262,19 @@ export class AnalysisService {
localStorage.setItem(this.tokensCookieKey, JSON.stringify(this.tokens));
this.startWatching();
toast({
this.toast.setNewToast({
message: 'Quick analysis started. This may take a while.' +
' Once the computation finished you can view the results in the task list to the right.',
duration: 10000,
dismissible: true,
pauseOnHover: true,
type: 'is-success',
position: 'top-center',
animate: {in: 'fadeIn', out: 'fadeOut'}
type: 'success'
});
return { taskId: resp.token, algorithm: algorithm, target: target, params: parameters }
}
async startAnalysis(algorithm, target: 'drug' | 'drug-target', parameters) {
if (!this.canLaunchTask()) {
toast({
this.toast.setNewToast({
message: `You can only run ${MAX_TASKS} tasks at once. Please wait for one of them to finish or delete it from the task list.`,
duration: 5000,
dismissible: true,
pauseOnHover: true,
type: 'is-danger',
position: 'top-center',
animate: {in: 'fadeIn', out: 'fadeOut'}
type: 'danger',
});
return '';
}
......@@ -311,20 +299,15 @@ export class AnalysisService {
let toastType;
if (status === 'DONE') {
toastMessage = 'Computation finished successfully. Click the task in the task list to view the results.';
toastType = 'is-success';
toastType = 'success';
} else if (status === 'FAILED') {
toastMessage = 'Computation failed.';
toastType = 'is-danger';
toastType = 'danger';
}
toast({
this.toast.setNewToast({
message: toastMessage,
duration: 5000,
dismissible: true,
pauseOnHover: true,
type: toastType,
position: 'top-center',
animate: {in: 'fadeIn', out: 'fadeOut'}
});
}
......
import { TestBed } from '@angular/core/testing';
import { ToastService } from './toast.service';
describe('ToastService', () => {
let service: ToastService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ToastService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { LiveToasts, Toast } from 'src/app/interfaces';
@Injectable({
providedIn: 'root'
})
export class ToastService {
constructor() { }
public toasts: Toast[] = [];
// id of toasts will be counted up
private id = 0;
public liveToasts: LiveToasts = {};
private getToasts = new Subject<LiveToasts>();
public setNewToast(toast: Toast) {
this.liveToasts[this.id] = toast;
this.getToasts.next(this.liveToasts);
this.setTimer(this.id);
this.id ++;
}
public setTimer(id: number) {
setTimeout(() => {
this.deleteToast(id);
}, 10000);
}
public deleteToast(id: number) {
if (this.liveToasts.hasOwnProperty(id)) {
delete this.liveToasts[id];
}
}
get getToasts$ () {
return this.getToasts.asObservable();
}
}
......@@ -200,7 +200,7 @@
}
.fa-exclamation-triangle, .fa-times, .help, .delete:after, .delete:before, .modal-close:after, .modal-close:before {
.fa-exclamation-triangle, .color-danger, .help, .delete:after, .delete:before, .modal-close:after, .modal-close:before {
color: var(--drgstn-danger) !important;
}
......
......@@ -62,3 +62,5 @@ $b-text-small-font-size: 14px;
$b-text-smaller-font-size: 12px;
$text-normal-font-size: 12px;
$text-small-font-size: 11px;
$toast-z: 100;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment