From 948bbdc85a33523682dee1871f2b17ebafabc60a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Sp=C3=A4th?= <julian.spaeth@wzw.tum.de> Date: Mon, 6 Apr 2020 13:03:58 +0200 Subject: [PATCH] Beautify site --- src/app/analysis.service.ts | 12 ++ .../analysis-window.component.html | 62 +++--- .../analysis-window.component.ts | 6 +- .../task-list/task-list.component.html | 20 +- .../explorer-page.component.html | 201 +++++++++--------- .../explorer-page/explorer-page.component.ts | 7 +- src/styles.scss | 24 ++- 7 files changed, 198 insertions(+), 134 deletions(-) diff --git a/src/app/analysis.service.ts b/src/app/analysis.service.ts index 9bf57b53..e90aade5 100644 --- a/src/app/analysis.service.ts +++ b/src/app/analysis.service.ts @@ -26,6 +26,18 @@ export class AnalysisService { this.startWatching(); } + removeTask(token) { + this.tokens = this.tokens.filter((item) => item !== token); + this.tasks = this.tasks.filter((item) => item.token !== (token)); + localStorage.setItem('tokens', JSON.stringify(this.tokens)); + } + + removeAllTasks() { + this.tasks.forEach((task) => { + this.removeTask(task.token); + }); + } + async getTasks() { return await this.http.get<any>(`${environment.backend}tasks/?tokens=${JSON.stringify(this.tokens)}`).toPromise().catch((e) => { clearInterval(this.intervalId); diff --git a/src/app/components/analysis-window/analysis-window.component.html b/src/app/components/analysis-window/analysis-window.component.html index 52283666..d2319eb2 100644 --- a/src/app/components/analysis-window/analysis-window.component.html +++ b/src/app/components/analysis-window/analysis-window.component.html @@ -16,49 +16,59 @@ <div class="card-content"> <div class="content"> - <div class="network center" #network> - <button class="button is-loading center">Loading</button> + <div class="card-image"> + <div class="network center" #network> + <button class="button is-loading center">Loading</button> + </div> </div> <footer class="card-footer"> <div class="field has-addons"> <p class="control"> - <button class="button is-rounded" [class.is-primary]="showDrugs" (click)="toggleDrugs(true)"> - <span class="icon is-small"> - <i class="fas fa-capsules"></i> - </span> - <span>Drugs On</span> - </button> - </p> - <p class="control"> - <button class="button is-rounded" [class.is-primary]="!showDrugs" (click)="toggleDrugs(false)"> - <span>Off</span> - </button> - </p> - </div> - <button class="card-footer-item button is-primary" [disabled]="true"> + <button class="button is-rounded is-success" [disabled]="true"> <span class="icon"> <i class="fas fa-cloud-download-alt" aria-hidden="true"></i> </span> - <span> + <span> Export Results </span> - </button> - <button class="card-footer-item button" [disabled]="true"> + </button> + </p> + <p class="control"> + <button class="button is-primary" [disabled]="true"> <span class="icon"> - <i class="fas fa-cloud-download-alt" aria-hidden="true"></i> + <i class="fas fa-camera" aria-hidden="true"></i> </span> - <span> - Save as PNG + <span> + Screenshot </span> - </button> - <button class="card-footer-item button is-danger" [disabled]="true"> + </button> + </p> + <p class="control"> + <button class="button is-danger is-rounded" (click)="analysis.removeTask(token)"> <span class="icon"> <i class="fas fa-trash" aria-hidden="true"></i> </span> - <span> + <span> Delete Analysis </span> - </button> + </button> + </p> + </div> + <div class="field has-addons footer-toggle-buttons"> + <p class="control"> + <button class="button is-rounded" [class.is-primary]="showDrugs" (click)="toggleDrugs(true)"> + <span class="icon is-small"> + <i class="fas fa-capsules"></i> + </span> + <span>Drugs On</span> + </button> + </p> + <p class="control"> + <button class="button is-rounded" [class.is-primary]="!showDrugs" (click)="toggleDrugs(false)"> + <span>Off</span> + </button> + </p> + </div> </footer> </div> </div> diff --git a/src/app/components/analysis-window/analysis-window.component.ts b/src/app/components/analysis-window/analysis-window.component.ts index e8d4e231..e89bce3a 100644 --- a/src/app/components/analysis-window/analysis-window.component.ts +++ b/src/app/components/analysis-window/analysis-window.component.ts @@ -36,7 +36,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { public showDrugs = false; private result: any; - constructor(private http: HttpClient, private analysis: AnalysisService) { + constructor(private http: HttpClient, public analysis: AnalysisService) { } async ngOnInit() { @@ -119,7 +119,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { node.x = pos[nodeId].x; node.y = pos[nodeId].y; if (selected) { - node.color = '#c42eff'; + node.color = '#48C774'; this.nodeData.nodes.update(node); } else { node.color = '#e2b600'; @@ -169,7 +169,7 @@ export class AnalysisWindowComponent implements OnInit, OnChanges { private mapProteinToNode(protein: any): any { let color = '#e2b600'; if (this.analysis.inSelection(protein)) { - color = '#c42eff'; + color = '#48C774'; } return { id: `p_${protein.proteinAc}`, diff --git a/src/app/components/task-list/task-list.component.html b/src/app/components/task-list/task-list.component.html index a7762379..7dfbe838 100644 --- a/src/app/components/task-list/task-list.component.html +++ b/src/app/components/task-list/task-list.component.html @@ -2,17 +2,25 @@ <div class="list is-hoverable"> <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)"> - <b>Algorithm: {{task.info.algorithm}}</b><br> + <span><b>{{task.info.algorithm}} (Queued)</b></span> + <span class="icon"><i class="fas fa-pause" aria-hidden="true"></i></span><br> Queue Length: {{task.stats.queueLength}}<br> Queue Position:{{task.stats.queuePosition}} </div> - <div *ngIf="task.info.startedAt && !task.info.done" (click)="open(task.token)"> - <a>Algorithm: {{task.info.algorithm}}</a><br> + <div *ngIf="task.info.startedAt && !task.info.done && !task.info.failed" (click)="open(task.token)"> + <span><b>{{task.info.algorithm}} ({{task.info.startedAt | date :'short'}})</b></span> + <span class="icon"><i class="fas fa-spinner" aria-hidden="true"></i></span> + <br> <progress class="progress is-primary" [value]="task.info.progress * 100" max="100"></progress> </div> - <div *ngIf="task.info.done" (click)="open(task.token)"> - <span>Algorithm: {{task.info.algorithm}}</span> - <span class="icon is-success"><i class="fas fa-check is-success" aria-hidden="true"></i> + <div *ngIf="task.info.failed && task.info.finishedAt == null"> + <span><b>{{task.info.algorithm}} ({{task.info.startedAt | date :'short'}})</b></span> + <span class="icon"><i class="fas fa-exclamation-triangle" aria-hidden="true"></i> + </span> + </div> + <div *ngIf="task.info.done && !task.info.failed" (click)="open(task.token)"> + <span><b>{{task.info.algorithm}} ({{task.info.startedAt | date :'short'}})</b></span> + <span class="icon"><i class="fas fa-check" aria-hidden="true"></i> </span> </div> </a> diff --git a/src/app/pages/explorer-page/explorer-page.component.html b/src/app/pages/explorer-page/explorer-page.component.html index 28279da8..6e0d1b34 100644 --- a/src/app/pages/explorer-page/explorer-page.component.html +++ b/src/app/pages/explorer-page/explorer-page.component.html @@ -90,9 +90,14 @@ </div> </div> <footer class="card-footer"> - <button (click)="reset($event);" class="card-footer-item button is-danger"> + <a (click)="reset($event);" class="card-footer-item has-text-danger"> + <span class="icon"> + <i class="fa fa-refresh"></i> + </span> + <span> Reset - </button> + </span> + </a> </footer> </div> </div> @@ -111,26 +116,25 @@ </div> </div> <footer class="card-footer"> - <button (click)="toCanvas()" class="card-footer-item button is-primary"> + <button (click)="toCanvas()" class="button is-primary"> <span class="icon"> - <i class="fas fa-cloud-download-alt" aria-hidden="true"></i> - </span> <span>Save as PNG</span> + <i class="fas fa-camera" aria-hidden="true"></i> + </span> <span>Screenshot</span> </button> - <div class="field has-addons"> + <div class="field has-addons footer-toggle-buttons"> <p class="control"> - <button class="button is-rounded" (click)="updatePhysicsEnabled(true)"> - <span class="icon is-small"> - <i class="fas fa-wind"></i> - </span> + <button class="button is-rounded" [class.is-primary]="physicsEnabled" + (click)="updatePhysicsEnabled(true)"> + <span class="icon is-small"> + <i class="fas fa-wind"></i> + </span> <span>Animation On</span> </button> </p> <p class="control"> - <button class="button is-rounded" (click)="updatePhysicsEnabled(false)"> - <span class="icon is-small"> - <i class="fas fa-times"></i> - </span> - <span>Animation Off</span> + <button class="button is-rounded" [class.is-primary]="!physicsEnabled" + (click)="updatePhysicsEnabled(false)"> + <span>Off</span> </button> </p> </div> @@ -147,7 +151,7 @@ <div class="covex bar-right"> - <div class="card bar-medium"> + <div class="card bar-large"> <header class="card-header"> <p class="card-header-title"> <span class="icon"> @@ -157,27 +161,44 @@ </header> <div class="card-content"> <div *ngIf="showDetails"> - <p><b>Protein Name:</b> {{ currentProteinAc }}</p> - <!-- <p><b>Gene Name(s):</b> <span *ngFor="let geneName of geneNames"> {{ geneName }}</span></p>--> - <!-- <p><b>Protein Name(s):</b> <span *ngFor="let proteinName of proteinNames"> {{ proteinName }}</span></p>--> <p><b>Protein AC(s):</b> <a href="https://www.uniprot.org/uniprot/{{proteinAc}}" target="_blank" *ngFor="let proteinAc of proteinAcs"> {{ proteinAc }} </a> </p> + <div class="field has-addons add-remove-toggle"> + <p class="control"> + <button class="button is-rounded" [class.is-success]="!inSelection(currentProteinAc)" + [disabled]="inSelection(currentProteinAc)" + (click)="addToSelection(currentProteinAc)"> + <span class="icon is-small"> + <i class="fas fa-plus"></i> + </span> + <span>Add to Analysis</span> + </button> + </p> + <p class="control"> + <button class="button is-rounded" [class.is-danger]="inSelection(currentProteinAc)" + [disabled]="!inSelection(currentProteinAc)" + (click)="removeFromSelection(currentProteinAc)"> + <span>Remove</span> + <span class="icon is-small"> + <i class="fas fa-trash"></i> + </span> + </button> + </p> + </div> </div> - <div *ngIf="!showDetails"> Please select a node for further information. <!-- <a (click)="selectedAnalysisToken = 'oy4UsXfBDobTucdQBhN9IUzfnpqKwzqx'"> Open Analysis Window </a>--> </div> - </div> </div> - <div class="card bar-medium"> + <div class="card bar-large"> <header class="card-header"> <p class="card-header-title"> <span class="icon"> @@ -186,96 +207,86 @@ </p> </header> <div class="card-content"> - <button class="button is-success" *ngIf="!inSelection(currentProteinAc)" - (click)="addToSelection(currentProteinAc)"> - <span> - <span class="icon"> - <i class="fa fa-plus"></i> - </span> - <span> - Add to Analysis - </span> - </span> - </button> - <button class="button is-danger" *ngIf="inSelection(currentProteinAc)" - (click)="removeFromSelection(currentProteinAc)"> - <span> - <span class="icon"> - <i class="fa fa-minus"></i> - </span> - <span> - Remove from Analysis - </span> - </span> - </button> - <p></p> <button (click)="showAnalysisDialog = true" - class="button is-primary" + class="button is-primary is-fullwidth" [disabled]="analysis.getCount() === 0"> + <span class="icon"> + <i class="fa fa-rocket"></i> + </span> <span> - <span class="icon"> - <i class="fa fa-list"></i> - </span> - <span> - Open Analysis - </span> + Launch Analysis </span> - </button> </div> + </div> - - <div class="card bar-large"> - <header class="card-header"> - <p class="card-header-title"> + <div class="card bar-large"> + <header class="card-header"> + <p class="card-header-title"> <span class="icon"> <i class="fas fa-filter" aria-hidden="true"></i> </span> Tasks - </p> - </header> - <div class="card-content"> - <app-task-list [(token)]="selectedAnalysisToken"></app-task-list> - </div> + </p> + </header> + <div class="card-content overflow"> + <app-task-list [(token)]="selectedAnalysisToken"></app-task-list> </div> + <footer class="card-footer"> + <a (click)="analysis.removeAllTasks();" class="card-footer-item has-text-danger"> + <span class="icon"> + <i class="fa fa-trash"></i> + </span> + <span> + Delete All + </span> + </a> + </footer> + </div> - <div class="card bar-large"> - <header class="card-header"> - <p class="card-header-title"> + <div class="card bar-large"> + <header class="card-header"> + <p class="card-header-title"> <span class="icon"> <i class="fas fa-filter" aria-hidden="true"></i> </span> Selection - </p> - </header> - <div class="card-content overflow"> - <table class="table"> - <thead> - <tr> - <td>AC</td> - <td>Actions</td> - </tr> - </thead> - <tbody> - <tr *ngFor="let p of analysis.getSelection()"> - <td>{{p.proteinAc}}</td> - <td> - <button (click)="analysis.removeProtein(p)" class="button is-small is-danger"> - <i class="fa fa-trash"></i> - </button> - </td> - </tr> - </tbody> - </table> - <footer class="card-footer"> - <button [disabled]="analysis.getSelection().length < 1" (click)="analysis.resetSelection();" - class="card-footer-item button is-danger"> - Reset - </button> - </footer> - </div> + </p> + </header> + <div class="card-content overflow"> + <table class="table" *ngIf="analysis.getCount() > 0"> + <thead> + <tr> + <td>AC</td> + <td>Actions</td> + </tr> + </thead> + <tbody> + <tr *ngFor="let p of analysis.getSelection()"> + <td>{{p.proteinAc}}</td> + <td> + <button (click)="analysis.removeProtein(p)" class="button is-small is-danger is-outlined"> + <i class="fa fa-trash"></i> + </button> + </td> + </tr> + </tbody> + </table> + <i *ngIf="analysis.getCount() === 0"> + To select proteins, click them while pressing CTRL. + </i> </div> - - + <footer class="card-footer"> + <a (click)="analysis.resetSelection()" class="card-footer-item has-text-danger"> + <span class="icon"> + <i class="fa fa-refresh"></i> + </span> + <span> + Reset + </span> + </a> + </footer> </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 60195ced..fddd254e 100644 --- a/src/app/pages/explorer-page/explorer-page.component.ts +++ b/src/app/pages/explorer-page/explorer-page.component.ts @@ -48,7 +48,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { public selectedAnalysisToken: string | null = null; public currentDataset = []; - private array = [0]; + private screenshotArray = [0]; public datasetItems: Array<{ label: string, datasets: string, data: Array<[string, string]> }> = [ {label: 'All', datasets: 'TUM & Krogan', data: [['TUM', 'HCoV'], ['TUM', 'SARS-CoV2'], ['Krogan', 'SARS-CoV2']]}, @@ -348,9 +348,10 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } public updatePhysicsEnabled(bool) { + this.physicsEnabled = bool; this.network.setOptions({ physics: { - enabled: bool, + enabled: this.physicsEnabled, stabilization: { enabled: false, }, @@ -446,7 +447,7 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit { } public toCanvas() { - this.array.forEach((key, index) => { + this.screenshotArray.forEach((key, index) => { const elem = document.getElementById(index.toString()); html2canvas(elem).then((canvas) => { const generatedImage = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream'); diff --git a/src/styles.scss b/src/styles.scss index 443146df..fb5ecf7b 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -139,9 +139,31 @@ div.covex.explorer { margin-top: 0; } -i.fas.is-success { +div.field.has-addons.add-remove-toggle { + margin-top: 20px; +} + +.fa-check { + color: #48C774; +} +.fa-spinner { + color: #e2b600; } +.fa-pause { + color: #e2b600; +} + +.fa-exclamation-triangle { + color: #EF476F; +} + +div.field.has-addons.footer-toggle-buttons { + margin-left: 20px; + margin-right: 10px; +} + + html, body { height: 100%; } body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } -- GitLab