diff --git a/src/app/components/analysis-window/analysis-window.component.ts b/src/app/components/analysis-window/analysis-window.component.ts index d5871bf809c1f9cfd4b1a5f5fb3ed81417dbc246..0834b6de706a7586c9f8fe36e55c9685e28ca91b 100644 --- a/src/app/components/analysis-window/analysis-window.component.ts +++ b/src/app/components/analysis-window/analysis-window.component.ts @@ -9,7 +9,7 @@ import { SimpleChanges, ViewChild } from '@angular/core'; -import {HttpClient} from '@angular/common/http'; +import {HttpClient, HttpErrorResponse} from '@angular/common/http'; import {environment} from '../../../environments/environment'; import {AnalysisService} from '../../analysis.service'; import {Protein, Task, NodeType, ViralProtein, Drug} from '../../interfaces'; @@ -150,7 +150,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { selectedStatus = null; selectedItem = {name: selectedNodes[0].id, type: 'Host Protein', data: protein}; // TODO use gene name here - selectedName = protein.proteinAc; + selectedName = protein.name; selectedId = protein.proteinAc; selectedType = 'Host Protein'; if (properties.event.srcEvent.ctrlKey) { @@ -351,9 +351,15 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { private mapNode(nodeId: any, nodeType?: NodeType, isSeed?: boolean, score?: number, details?): any { const {shape, color, size, font, shadow} = this.getNodeLooks(nodeId, nodeType, isSeed); + let nodeLabel = nodeId; + if (nodeType === 'host') { + nodeLabel = details.name; + } else if (nodeType === 'drug') { + nodeLabel = details.name; + } return { id: nodeId, - label: nodeId, + label: nodeLabel, size, color, shape, font, shadow, nodeType, isSeed, details }; @@ -376,7 +382,21 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { if (this.showDrugs) { const proteinAcs = this.proteins.map((protein) => protein.proteinAc); // tslint:disable-next-line:max-line-length - const result = await this.http.get<any>(`${environment.backend}drug_interactions/?proteins=${JSON.stringify(proteinAcs)}`).toPromise(); + const result = await this.http.get<any>(`${environment.backend}drug_interactions/?proteins=${JSON.stringify(proteinAcs)}`).toPromise().catch((err: HttpErrorResponse) => { + // simple logging, but you can do a lot more, see below + toast({ + message: 'An error occured while fetching the drugs.', + duration: 5000, + dismissible: true, + pauseOnHover: true, + type: 'is-danger', + position: 'top-center', + animate: {in: 'fadeIn', out: 'fadeOut'} + }); + this.showDrugs = false; + return; + }); + const drugs = result.drugs; const edges = result.edges; diff --git a/src/app/components/query/query.component.html b/src/app/components/query/query.component.html index 03a4f2d33781a98a0d82904dae9e00fe20d7bde6..c36f4aa6c1f3872edf67c24290f5656e3a95b00f 100644 --- a/src/app/components/query/query.component.html +++ b/src/app/components/query/query.component.html @@ -1,11 +1,12 @@ <div class="content"> <ng-select [items]="queryItems" bindLabel="name" bindValue="data" [virtualScroll]="true" class="custom" - placeholder="Search..." (change)="select($event)"> + placeholder="Search..." [hideSelected]="true" [searchFn]="querySearch" (change)="select($event)"> <ng-template ng-option-tmp let-item="item"> - <b>{{item.name}}</b> <br/> - <span *ngIf="item.type == 'Host Protein'"><small>{{item.type}}</small></span> - <span *ngIf="item.type == 'Viral Protein'"><small>{{item.data.virusName}}</small> | </span> - <span *ngIf="item.type == 'Viral Protein'"><small>{{item.data.datasetName}}</small> </span> + <b *ngIf="item.type == 'Host Protein'"> {{item.data.name}}</b> + <b *ngIf="item.type == 'Viral Protein'"> {{item.data.effectName}}</b> <br/> + <span><small>{{item.type}}</small> | </span> + <span *ngIf="item.type == 'Host Protein'"><small>AC: <b>{{item.data.proteinAc}}</b></small> </span> + <span *ngIf="item.type == 'Viral Protein'"><small><b>{{item.data.virusName}}</b></small></span> </ng-template> </ng-select> </div> diff --git a/src/app/components/query/query.component.ts b/src/app/components/query/query.component.ts index ee71a44d1bc4a29ec306ebab1ff278448de6bc42..56b4bf375f07eaef801ca17a9924676a06dc3560 100644 --- a/src/app/components/query/query.component.ts +++ b/src/app/components/query/query.component.ts @@ -1,5 +1,5 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; -import {QueryItem} from '../../interfaces'; +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Protein, QueryItem, ViralProtein} from '../../interfaces'; @Component({ selector: 'app-query-component', @@ -12,6 +12,19 @@ export class QueryComponent { @Output() selectItem: EventEmitter<any> = new EventEmitter(); @Input() queryItems: QueryItem[]; + querySearch(term: string, item: QueryItem) { + term = term.toLowerCase(); + if (item.type === 'Host Protein') { + const data = item.data as Protein; + return data.name.toLowerCase().indexOf(term) > -1 || data.proteinAc.toLowerCase().indexOf(term) > -1 || + item.type.toLowerCase().indexOf(term) > -1; + } else { + const data = item.data as ViralProtein; + return data.effectName.toLowerCase().indexOf(term) > -1 || data.virusName.toLowerCase().indexOf(term) > -1 || + item.type.toLowerCase().indexOf(term) > -1; + } + } + select(item) { this.selectItem.emit(item); } diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html index e3badb796f0aaea1a351527cc8ed829a4faf7828..0b6a937ce8a288a2ec60bcd5fab929bf7da27eea 100644 --- a/src/app/pages/explorer-page/explorer-page.component.html +++ b/src/app/pages/explorer-page/explorer-page.component.html @@ -77,7 +77,7 @@ <p class="card-header-title"> <span class="icon"> <i class="fas fa-search" aria-hidden="true"></i> - </span> Query Protein + </span> Query Protein/Gene </p> <a (click)="collabsQuery = !collabsQuery" data-action="collapse" class="card-header-icon is-hidden-fullscreen" aria-label="more options"> @@ -386,7 +386,8 @@ <i class="fa fa-virus" *ngIf="p.type =='Viral Protein'"></i> </span> </td> - <td>{{p.name}}</td> + <td *ngIf="p.type == 'Viral Protein'">{{p.name}}</td> + <td *ngIf="p.type == 'Host Protein'">{{p.data.name}}</td> <td> <button (click)="analysis.removeItem(p.name)" class="button is-small is-danger is-outlined"> <i class="fa fa-trash"></i> diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts index ef2e61300a66acc6c6decb51ab856fcf81834e72..9bf8573ada72d14a399f8e6cd2567b3a8007409a 100644 --- a/src/app/pages/explorer-page/explorer-page.component.ts +++ b/src/app/pages/explorer-page/explorer-page.component.ts @@ -175,9 +175,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.selectedItem = item; this.selectedType = item.type; this.selectedName = item.name; + if (this.selectedType === 'Host Protein') { const hostProtein = item.data as Protein; this.selectedId = hostProtein.proteinAc; + this.selectedName = hostProtein.name; + if (zoom) { this.zoomToNode(`p_${item.name}`); } @@ -312,7 +315,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { this.queryItems = []; hostProteins.forEach((protein) => { this.queryItems.push({ - name: protein.proteinAc, + name: protein.name, type: 'Host Protein', data: protein }); @@ -409,12 +412,12 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { private mapHostProteinToNode(hostProtein: Protein): any { let color = '#e2b600'; - if (this.analysis.inSelection(hostProtein.proteinAc)) { + if (this.analysis.inSelection(hostProtein.name)) { color = '#48C774'; } return { id: `p_${hostProtein.proteinAc}`, - label: `${hostProtein.proteinAc}`, + label: `${hostProtein.name}`, size: 10, font: '5px', color, shape: 'ellipse', shadow: false, x: hostProtein.x, y: hostProtein.y,