From 08db12b6400750084e5817d2a429b1349be34606 Mon Sep 17 00:00:00 2001
From: Julian Matschinske <ge93nar@mytum.de>
Date: Tue, 7 Apr 2020 14:18:35 +0200
Subject: [PATCH] Extend Analysis Launch and Result View

---
 src/app/analysis.service.ts                   |   3 +-
 .../analysis-window.component.html            | 107 ++++++------------
 .../analysis-window.component.scss            |  12 ++
 .../analysis-window.component.ts              |  56 ++++-----
 .../launch-analysis.component.html            |  25 ++--
 .../launch-analysis.component.ts              |  31 ++++-
 .../task-list/task-list.component.html        |   8 +-
 src/app/interfaces.ts                         |   2 +
 .../explorer-page.component.html              |  40 +++++--
 .../explorer-page/explorer-page.component.ts  |   1 +
 10 files changed, 145 insertions(+), 140 deletions(-)

diff --git a/src/app/analysis.service.ts b/src/app/analysis.service.ts
index a302c42a..d85b8c67 100644
--- a/src/app/analysis.service.ts
+++ b/src/app/analysis.service.ts
@@ -92,9 +92,10 @@ export class AnalysisService {
     });
   }
 
-  async startAnalysis(algorithm, parameters) {
+  async startAnalysis(algorithm, target: 'drug' | 'drug-target', parameters) {
     const resp = await this.http.post<any>(`${environment.backend}task/`, {
       algorithm,
+      target,
       parameters,
     }).toPromise();
     this.tokens.push(resp.token);
diff --git a/src/app/components/analysis-window/analysis-window.component.html b/src/app/components/analysis-window/analysis-window.component.html
index ba091706..b147c55e 100644
--- a/src/app/components/analysis-window/analysis-window.component.html
+++ b/src/app/components/analysis-window/analysis-window.component.html
@@ -1,5 +1,5 @@
 <div *ngIf="token">
-  <div class="card analysis" *ngIf="task && task.info.done">
+  <div class="card analysis">
     <header class="card-header">
       <p class="card-header-title">
         <span class="icon">
@@ -13,9 +13,36 @@
         </span>
       </a>
     </header>
-
     <div class="card-content">
-      <div class="content">
+      <div class="tabs is-centered">
+        <ul>
+          <li [class.is-active]="tab === 'meta'"><a (click)="tab = 'meta'">Meta</a></li>
+          <li [class.is-active]="tab === 'network'"><a (click)="tab = 'network'">Network</a></li>
+          <li [class.is-active]="tab === 'table'"><a (click)="tab = 'table'">Table</a></li>
+        </ul>
+      </div>
+      <div class="content tab-content" *ngIf="task && task.info.done" [class.is-visible]="tab === 'meta'">
+        <div *ngIf="task">
+          <p>
+            Algorithm: {{task.info.algorithm}}
+          </p>
+          <div *ngIf="task.info.algorithm === 'trustrank'">
+            <table class="table is-narrow">
+              <tbody>
+              <tr>
+                <td>Damping Factor</td>
+                <td>{{task.info.parameters.dampingFactor}}</td>
+              </tr>
+              <tr>
+                <td>Result Size</td>
+                <td>{{task.info.parameters.resultSize}}</td>
+              </tr>
+              </tbody>
+            </table>
+          </div>
+        </div>
+      </div>
+      <div class="content tab-content" *ngIf="task && task.info.done" [class.is-visible]="tab === 'network'">
         <div class="card-image">
           <div class="network center" #network>
             <button class="button is-loading center">Loading</button>
@@ -71,79 +98,9 @@
           </div>
         </footer>
       </div>
-    </div>
-
-    <div class="card analysis" *ngIf="task && !task.info.startedAt">
-      <header class="card-header">
-        <p class="card-header-title">
-        <span class="icon">
-          <i class="fas fa-cog" aria-hidden="true"></i>
-        </span>
-          Analysis Queued...
-        </p>
-        <a (click)="close()" class="card-header-icon" aria-label="close">
-        <span class="icon">
-          <i class="fas fa-times" aria-hidden="true"></i>
-        </span>
-        </a>
-      </header>
-      <div class="card-content">
-        <div class="content">
-          The analysis is queued
-          <!--TODO: Display queue information-->
-        </div>
-      </div>
-      <footer class="card-footer">
-      </footer>
-    </div>
-
-    <div class="card analysis" *ngIf="task && task.info.startedAt && !task.info.done">
-      <header class="card-header">
-        <p class="card-header-title">
-        <span class="icon">
-          <i class="fas fa-cog fa-spin" aria-hidden="true"></i>
-        </span>
-          Analysis in Progress...
-        </p>
-        <a (click)="close()" class="card-header-icon" aria-label="close">
-        <span class="icon">
-          <i class="fas fa-times" aria-hidden="true"></i>
-        </span>
-        </a>
-      </header>
-      <div class="card-content">
-        <div class="content">
-          The analysis is in progress
-          <!--TODO: Display analysis progress-->
-        </div>
-      </div>
-      <footer class="card-footer">
-      </footer>
-    </div>
-
-    <div class="card analysis" *ngIf="!task">
-      <header class="card-header">
-        <p class="card-header-title">
-        <span class="icon">
-          <i class="fas fa-question" aria-hidden="true"></i>
-        </span>
-          Analysis not found
-        </p>
-        <a (click)="close()" class="card-header-icon" aria-label="more options">
-        <span class="icon">
-          <i class="fas fa-times" aria-hidden="true"></i>
-        </span>
-        </a>
-      </header>
-      <div class="card-content">
-        <div class="content">
-        <span class="notification is-danger">
-          The analysis you were looking for is either gone or never existed.
-        </span>
-        </div>
+      <div class="content tab-content" *ngIf="task && task.info.done" [class.is-visible]="tab === 'table'">
+        TABLE
       </div>
-      <footer class="card-footer">
-      </footer>
     </div>
   </div>
 </div>
diff --git a/src/app/components/analysis-window/analysis-window.component.scss b/src/app/components/analysis-window/analysis-window.component.scss
index 4888ec89..056832a0 100644
--- a/src/app/components/analysis-window/analysis-window.component.scss
+++ b/src/app/components/analysis-window/analysis-window.component.scss
@@ -3,3 +3,15 @@
   height: 100%;
   width: 100%;
 }
+
+div.network {
+  height: calc(100vh - 210px - 80px);
+}
+
+.tab-content {
+  visibility: hidden;
+
+  &.is-visible {
+    visibility: visible;
+  }
+}
diff --git a/src/app/components/analysis-window/analysis-window.component.ts b/src/app/components/analysis-window/analysis-window.component.ts
index b90fde85..ccc612ef 100644
--- a/src/app/components/analysis-window/analysis-window.component.ts
+++ b/src/app/components/analysis-window/analysis-window.component.ts
@@ -12,7 +12,7 @@ import {
 import {HttpClient} from '@angular/common/http';
 import {environment} from '../../../environments/environment';
 import {AnalysisService} from '../../analysis.service';
-import {Protein, Task, NodeType, ViralProtein, QueryItem} from '../../interfaces';
+import {Protein, Task, NodeType, ViralProtein} from '../../interfaces';
 
 declare var vis: any;
 
@@ -24,12 +24,6 @@ declare var vis: any;
 export class AnalysisWindowComponent implements OnInit, OnChanges {
 
   @Input() token: string | null = null;
-  @Input() selectedProteinName: string;
-  @Input() selectedProteinType: string;
-  @Input() selectedProteinAc: string;
-  @Input() selectedProteinItem: QueryItem;
-  @Input() selectedProteinVirus: string;
-  @Input() selectedProteinDataset: string;
 
   @Output() tokenChange = new EventEmitter<string | null>();
   @Output() showDetailsChange: EventEmitter<any> = new EventEmitter();
@@ -43,6 +37,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
   private nodeData: { nodes: any, edges: any } = {nodes: null, edges: null};
   private drugNodes = [];
   public showDrugs = false;
+  public tab = 'network';
 
   constructor(private http: HttpClient, public analysis: AnalysisService) {
   }
@@ -79,14 +74,20 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
         this.network.on('selectNode', (properties) => {
           const selectedNodes = this.nodeData.nodes.get(properties.nodes);
           if (selectedNodes.length > 0) {
+            let selectedProteinItem;
+            let selectedProteinName;
+            let selectedProteinType;
+            let selectedProteinAc;
+            let selectedProteinDataset;
+            let selectedProteinVirus;
             if (selectedNodes[0].nodeType === 'host') {
               const protein: Protein = {name: '', proteinAc: selectedNodes[0].id};
-              this.selectedProteinName = null;
-              this.selectedProteinDataset = null;
-              this.selectedProteinVirus = null;
-              this.selectedProteinItem = {name: selectedNodes[0].id, type: 'Host Protein', data: protein};
-              this.selectedProteinAc = protein.proteinAc;
-              this.selectedProteinType = 'Host Protein';
+              selectedProteinName = null;
+              selectedProteinDataset = null;
+              selectedProteinVirus = null;
+              selectedProteinItem = {name: selectedNodes[0].id, type: 'Host Protein', data: protein};
+              selectedProteinAc = protein.proteinAc;
+              selectedProteinType = 'Host Protein';
               if (properties.event.srcEvent.ctrlKey) {
                 if (this.analysis.inSelection(protein.proteinAc)) {
                   this.analysis.removeItem(protein.proteinAc);
@@ -96,33 +97,26 @@ export class AnalysisWindowComponent implements OnInit, OnChanges {
                 }
               }
             } else if (selectedNodes[0].nodeType === 'virus') {
-              const virus: ViralProtein = {effectName: selectedNodes[0].id, virusName: null, datasetName: null};
-              this.selectedProteinAc = null;
-              this.selectedProteinDataset = null;
-              this.selectedProteinVirus = null;
-              this.selectedProteinItem = {name: virus.effectName, type: 'Viral Protein', data: virus};
-              this.selectedProteinName = virus.effectName;
-              this.selectedProteinType = 'Viral Protein';
+              const virus: ViralProtein = {viralProteinId: null, effectName: selectedNodes[0].id, virusName: null, datasetName: null};
+              selectedProteinAc = null;
+              selectedProteinDataset = null;
+              selectedProteinVirus = null;
+              selectedProteinItem = {name: virus.effectName, type: 'Viral Protein', data: virus};
+              selectedProteinName = virus.effectName;
+              selectedProteinType = 'Viral Protein';
               if (properties.event.srcEvent.ctrlKey) {
                 if (this.analysis.inSelection(virus.effectName)) {
                   this.analysis.removeItem(virus.effectName);
                 } else {
-                  this.analysis.addItem(this.selectedProteinItem);
+                  this.analysis.addItem(selectedProteinItem);
                   this.analysis.getCount();
                 }
               }
             }
-            this.showDetailsChange.emit([true, [this.selectedProteinItem, this.selectedProteinName,
-              this.selectedProteinType, this.selectedProteinAc, this.selectedProteinDataset, this.selectedProteinVirus]]);
+            this.showDetailsChange.emit([true, [selectedProteinItem, selectedProteinName, selectedProteinType, selectedProteinAc,
+              selectedProteinDataset, selectedProteinVirus]]);
           } else {
-            this.selectedProteinItem = null;
-            this.selectedProteinName = null;
-            this.selectedProteinType = null;
-            this.selectedProteinAc = null;
-            this.selectedProteinDataset = null;
-            this.selectedProteinVirus = null;
-            this.showDetailsChange.emit([false, [this.selectedProteinItem, this.selectedProteinName,
-              this.selectedProteinType, this.selectedProteinAc, this.selectedProteinDataset, this.selectedProteinVirus]]);
+            this.showDetailsChange.emit([false, [null, null, null, null, null, null]]);
           }
         });
 
diff --git a/src/app/components/launch-analysis/launch-analysis.component.html b/src/app/components/launch-analysis/launch-analysis.component.html
index b85a31c9..54a64d53 100644
--- a/src/app/components/launch-analysis/launch-analysis.component.html
+++ b/src/app/components/launch-analysis/launch-analysis.component.html
@@ -2,35 +2,32 @@
   <div class="modal-background"></div>
   <div class="modal-card">
     <header class="modal-card-head">
-      <p class="modal-card-title">Launch Analysis</p>
+      <p class="modal-card-title" *ngIf="target === 'drug'">
+        <span class="icon"><i class="fa fa-capsules"></i></span>
+        Find Drugs
+      </p>
+      <p class="modal-card-title" *ngIf="target === 'drug-target'">
+        <span class="icon"><i class="fa fa-crosshairs"></i></span>
+        Find Drug Targets
+      </p>
       <button (click)="close()" class="delete" aria-label="close"></button>
     </header>
     <section class="modal-card-body">
       <div class="tabs is-toggle is-small is-fullwidth is-rounded">
         <ul>
-          <li [class.is-active]="algorithm === 'dummy'">
-            <a (click)="algorithm = 'dummy'" class="is-boxed is-medium">Dummy</a>
-          </li>
-          <li [class.is-active]="algorithm === 'trustrank'">
-            <a (click)="algorithm = 'trustrank'" class="is-boxed is-medium">Trustrank</a>
-          </li>
-          <li [class.is-active]="algorithm === 'keypathwayminer'">
-            <a (click)="algorithm = 'keypathwayminer'" class="is-boxed is-medium">KeyPathwayMiner</a>
-          </li>
-          <li [class.is-active]="algorithm === 'multisteiner'">
-            <a (click)="algorithm = 'multisteiner'" class="is-boxed is-medium">Multi-Steiner</a>
+          <li [class.is-active]="algorithm === algo.slug" *ngFor="let algo of algorithms">
+            <a (click)="algorithm = algo.slug" class="is-boxed is-medium">{{algo.name}}</a>
           </li>
         </ul>
       </div>
 
       <div *ngIf="algorithm==='trustrank'">
-        <div class="field">
+        <div class="field" *ngIf="target === 'drug-target'">
           <label class="label" for="trustrank-strain">Strain</label>
           <div  class="control">
             <div class="select">
               <select id="trustrank-strain" [(ngModel)]="trustrankStrain">
                 <option [ngValue]="'SARS_CoV2'">SARS Coronavirus 2</option>
-                <option [ngValue]="'drugs'">Drugs</option>
               </select>
             </div>
           </div>
diff --git a/src/app/components/launch-analysis/launch-analysis.component.ts b/src/app/components/launch-analysis/launch-analysis.component.ts
index cb1f46e3..fc743ec7 100644
--- a/src/app/components/launch-analysis/launch-analysis.component.ts
+++ b/src/app/components/launch-analysis/launch-analysis.component.ts
@@ -1,20 +1,34 @@
-import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
 import {AnalysisService} from '../../analysis.service';
 
+interface Algorithm {
+  slug: string;
+  name: string;
+}
+
+const DUMMY: Algorithm = {slug: 'dummy', name: 'Dummy'};
+const TRUSTRANK: Algorithm = {slug: 'trustrank', name: 'Trust-Rank'};
+const KEYPATHWAYMINER: Algorithm = {slug: 'keypathwayminer', name: 'KeyPathwayMiner'};
+const MULTISTEINER: Algorithm = {slug: 'multisteiner', name: 'Multi-Steiner'};
+
 @Component({
   selector: 'app-launch-analysis',
   templateUrl: './launch-analysis.component.html',
   styleUrls: ['./launch-analysis.component.scss']
 })
-export class LaunchAnalysisComponent implements OnInit {
+export class LaunchAnalysisComponent implements OnInit, OnChanges {
 
   @Input()
   public show = false;
+  @Input()
+  public target: 'drug' | 'drug-target';
   @Output()
   public showChange = new EventEmitter<boolean>();
 
   public algorithm: 'dummy' | 'trustrank' | 'keypathwayminer' | 'multisteiner';
 
+  public algorithms: Array<Algorithm> = [];
+
   // Trustrank Parameters
   public trustrankStrain = 'SARS_CoV2';
   public trustrankDampingFactor = 0.85;
@@ -36,6 +50,16 @@ export class LaunchAnalysisComponent implements OnInit {
   ngOnInit(): void {
   }
 
+  ngOnChanges(changes: SimpleChanges): void {
+    if (this.target === 'drug-target') {
+      this.algorithms = [TRUSTRANK, MULTISTEINER, KEYPATHWAYMINER, DUMMY];
+      this.trustrankStrain = 'SARS_CoV2';
+    } else if (this.target === 'drug') {
+      this.algorithms = [TRUSTRANK, DUMMY];
+      this.trustrankStrain = 'drugs';
+    }
+  }
+
   public close() {
     this.show = false;
     this.showChange.emit(this.show);
@@ -60,10 +84,9 @@ export class LaunchAnalysisComponent implements OnInit {
     } else if (this.algorithm === 'multisteiner') {
       parameters.strain = this.multisteinerStrain;
       parameters.num_trees = this.multisteinerNumTrees;
-
     }
 
-    await this.analysis.startAnalysis(this.algorithm, parameters);
+    await this.analysis.startAnalysis(this.algorithm, this.target, parameters);
   }
 
 }
diff --git a/src/app/components/task-list/task-list.component.html b/src/app/components/task-list/task-list.component.html
index 1a9c4881..292d3cc0 100644
--- a/src/app/components/task-list/task-list.component.html
+++ b/src/app/components/task-list/task-list.component.html
@@ -3,7 +3,7 @@
     <a *ngFor="let task of analysis.tasks" class="list-item" [class.is-active]="task.token === token">
       <div *ngIf="!task.info.startedAt" (click)="open(task.token)">
         <p>
-          <span class="is-capitalized">{{task.info.algorithm}}</span>
+          <span class="is-capitalized"><i class="fa" [class.fa-capsules]="task.info.target === 'drug'" [class.fa-crosshairs]="task.info.target === 'drug-target'"></i> {{task.info.algorithm}}</span>
           <span class="icon is-pulled-right"><i class="fas fa-pause" aria-hidden="true"></i></span>
         </p>
         <p>
@@ -12,7 +12,7 @@
       </div>
       <div *ngIf="!task.info.done && !task.info.failed && task.info.startedAt" (click)="open(task.token)">
         <p>
-          <span class="is-capitalized">{{task.info.algorithm}}</span>
+          <span class="is-capitalized"><i class="fa" [class.fa-capsules]="task.info.target === 'drug'" [class.fa-crosshairs]="task.info.target === 'drug-target'"></i> {{task.info.algorithm}}</span>
           <span class="icon is-pulled-right"><i class="fas fa-spinner fa-spin" aria-hidden="true"></i></span>
         </p>
         <p>
@@ -23,7 +23,7 @@
       </div>
       <div *ngIf="task.info.done" (click)="open(task.token)">
         <p>
-          <span class="is-capitalized">{{task.info.algorithm}}</span>
+          <span class="is-capitalized"><i class="fa" [class.fa-capsules]="task.info.target === 'drug'" [class.fa-crosshairs]="task.info.target === 'drug-target'"></i> {{task.info.algorithm}}</span>
           <span class="icon is-pulled-right"><i class="fas fa-check" aria-hidden="true"></i></span>
         </p>
         <p>
@@ -32,7 +32,7 @@
       </div>
       <div *ngIf="task.info.failed && task.info.finishedAt == null">
         <p>
-          <span class="is-capitalized">{{task.info.algorithm}}</span>
+          <span class="is-capitalized"><i class="fa" [class.fa-capsules]="task.info.target === 'drug'" [class.fa-crosshairs]="task.info.target === 'drug-target'"></i> {{task.info.algorithm}}</span>
           <span class="icon is-pulled-right"><i class="fas fa-exclamation-triangle" aria-hidden="true"></i></span>
         </p>
         <p class="has-text-danger">
diff --git a/src/app/interfaces.ts b/src/app/interfaces.ts
index 6a5341ed..5ae4c54a 100644
--- a/src/app/interfaces.ts
+++ b/src/app/interfaces.ts
@@ -9,6 +9,7 @@ export interface Protein {
 }
 
 export interface ViralProtein {
+  viralProteinId: string;
   effectName: string;
   virusName: string;
   datasetName: string;
@@ -27,6 +28,7 @@ export interface ProteinViralInteraction {
 export interface Task {
   token: string;
   info: {
+    target: 'drug' | 'drug-target',
     algorithm: 'trustrank' | 'multisteiner' | 'keypathwayminer';
     parameters?: { [key: string]: any };
 
diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html
index 6cc3172c..99f89360 100644
--- a/src/app/pages/explorer-page/explorer-page.component.html
+++ b/src/app/pages/explorer-page/explorer-page.component.html
@@ -1,4 +1,4 @@
-<app-launch-analysis [(show)]="showAnalysisDialog"></app-launch-analysis>
+<app-launch-analysis [(show)]="showAnalysisDialog" [target]="analysisDialogTarget"></app-launch-analysis>
 
 <div class="covex explorer">
 
@@ -260,16 +260,34 @@
       </header>
       <div *ngIf="collabsAnalysis">
         <div class="card-content">
-          <button (click)="showAnalysisDialog = true"
-                  class="button is-primary is-fullwidth is-rounded"
-                  [disabled]="analysis.getCount() === 0">
-            <span class="icon">
-              <i class="fa fa-rocket"></i>
-            </span>
-            <span>
-              Launch Analysis
-            </span>
-          </button>
+          <div class="field">
+            <div class="control">
+              <button (click)="analysisDialogTarget = 'drug-target'; showAnalysisDialog = true;"
+                      class="button is-primary is-fullwidth is-rounded"
+                      [disabled]="analysis.getCount() === 0">
+              <span class="icon">
+                <i class="fa fa-crosshairs"></i>
+              </span>
+                <span>
+                Find Drug Targets
+              </span>
+              </button>
+            </div>
+          </div>
+          <div class="field">
+            <div class="control">
+              <button (click)="analysisDialogTarget = 'drug'; showAnalysisDialog = true;"
+                      class="button is-primary is-fullwidth is-rounded"
+                      [disabled]="analysis.getCount() === 0">
+              <span class="icon">
+                <i class="fa fa-capsules"></i>
+              </span>
+                <span>
+                Find Drugs
+              </span>
+              </button>
+            </div>
+          </div>
         </div>
       </div>
     </div>
diff --git a/src/app/pages/explorer-page/explorer-page.component.ts b/src/app/pages/explorer-page/explorer-page.component.ts
index 7dd8002b..9d2b19f4 100644
--- a/src/app/pages/explorer-page/explorer-page.component.ts
+++ b/src/app/pages/explorer-page/explorer-page.component.ts
@@ -55,6 +55,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
 
   public queryItems: QueryItem[] = [];
   public showAnalysisDialog = false;
+  public analysisDialogTarget: 'drug' | 'drug-target';
 
   public selectedAnalysisToken: string | null = null;
 
-- 
GitLab