Skip to content
Snippets Groups Projects
Commit b0b3f1ab authored by Julian Matschinske's avatar Julian Matschinske
Browse files

Add custom proteins

parent 4dc82cec
No related branches found
No related tags found
No related merge requests found
......@@ -103,7 +103,7 @@ export class AnalysisService {
this.selectListSubject.next({items: removedWrappers, selected: false});
}
public addAllHostProteins(nodes, proteins) {
public addVisibleHostProteins(nodes, proteins) {
const items: Wrapper[] = [];
const visibleIds = new Set<string>(nodes.getIds());
for (const protein of proteins) {
......@@ -117,7 +117,7 @@ export class AnalysisService {
this.selectListSubject.next({items, selected: true});
}
public addAllViralProteins(nodes, viralProteins) {
public addVisibleViralProteins(nodes, viralProteins) {
const items: Wrapper[] = [];
const visibleIds = new Set<string>(nodes.getIds());
for (const viralProtein of viralProteins) {
......@@ -131,6 +131,22 @@ export class AnalysisService {
this.selectListSubject.next({items, selected: true});
}
public removeAllHostProteins() {
const items: Wrapper[] = Array.from(this.selectedItems.values()).filter(p => p.type === 'host');
for (const wrapper of items) {
this.selectedItems.delete(wrapper.nodeId);
}
this.selectListSubject.next({items, selected: false});
}
public removeAllViralProteins() {
const items: Wrapper[] = Array.from(this.selectedItems.values()).filter(p => p.type === 'virus');
for (const wrapper of items) {
this.selectedItems.delete(wrapper.nodeId);
}
this.selectListSubject.next({items, selected: false});
}
resetSelection() {
this.selectListSubject.next({items: [], selected: null});
this.selectedItems.clear();
......
......@@ -19,6 +19,7 @@ import {AnalysisWindowComponent} from './components/analysis-window/analysis-win
import {TaskListComponent} from './components/task-list/task-list.component';
import {ToggleComponent} from './components/toggle/toggle.component';
import {InfoBoxComponent} from './components/info-box/info-box.component';
import {CustomProteinsComponent} from './components/custom-proteins/custom-proteins.component';
import {AnalysisService} from './analysis.service';
......@@ -36,6 +37,7 @@ import {AnalysisService} from './analysis.service';
TaskListComponent,
ToggleComponent,
InfoBoxComponent,
CustomProteinsComponent,
],
imports: [
BrowserModule,
......
<div class="modal" [class.is-active]="show">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">
<span class="icon"><i class="fa fa-dna"></i></span>
Add Custom Proteins
</p>
<button (click)="close()" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="notification is-success" *ngIf="itemsAdded.length > 0">
{{itemsAdded.length}} host proteins have been added to the selection.
</div>
<div class="notification is-warning" *ngIf="notFound.length > 0">
The following {{notFound.length}} Uniprot IDs could not be found and have been ignored:
<ul><li class="not-found" *ngFor="let nf of notFound">{{nf}}</li></ul>
</div>
<div class="field">
<label class="label" for="protein-list">List of Uniprot IDs</label>
<div class="control">
<textarea class="input" [ngModel]="textList" (ngModelChange)="changeTextList($event)" id="protein-list"></textarea>
</div>
</div>
<p *ngIf="proteins">
Proteins parsed: {{proteins.length}}
</p>
</section>
<footer class="modal-card-foot">
<button (click)="addProteins();" class="button is-success is-rounded has-tooltip"
data-tooltip="Add list of proteins to the selection."
[disabled]="proteins.length === 0">
<span class="icon">
<i class="fa fa-plus"></i>
</span>
<span>
Add
</span>
</button>
<button (click)="close()" class="button is-rounded has-tooltip" data-tooltip="Close the current window.">Close
</button>
</footer>
</div>
</div>
#protein-list {
height: 150px;
}
.not-found {
padding: 4px;
margin: 4px;
border-radius: 3px;
background-color: rgba(255, 255, 255, 0.33);
}
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {CustomProteinsComponent} from './custom-proteins.component';
import {HttpClientModule} from '@angular/common/http';
describe('CustomProteinsComponent', () => {
let component: CustomProteinsComponent;
let fixture: ComponentFixture<CustomProteinsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CustomProteinsComponent],
imports: [HttpClientModule],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CustomProteinsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../../../environments/environment';
import {getWrapperFromProtein, Wrapper} from '../../interfaces';
import {AnalysisService} from '../../analysis.service';
@Component({
selector: 'app-custom-proteins',
templateUrl: './custom-proteins.component.html',
styleUrls: ['./custom-proteins.component.scss']
})
export class CustomProteinsComponent implements OnInit {
@Input()
public show = false;
@Output()
public showChange = new EventEmitter<boolean>();
public textList = '';
public proteins: Array<string> = [];
public notFound: Array<string> = [];
public itemsAdded: Array<Wrapper> = [];
constructor(private http: HttpClient, private analysis: AnalysisService) { }
ngOnInit(): void {
}
public close() {
this.show = false;
this.showChange.emit(this.show);
}
public async addProteins() {
this.notFound = [];
this.itemsAdded = [];
const proteins = this.proteins;
this.changeTextList('');
const result = await this.http.post<any>(`${environment.backend}query_proteins/`, proteins).toPromise();
this.notFound = result.notFound;
const details = result.details;
const items = [];
for (const detail of details) {
items.push(getWrapperFromProtein(detail));
}
this.itemsAdded = items;
this.analysis.addItems(items);
}
public changeTextList(textList) {
this.textList = textList;
if (!textList) {
this.proteins = [];
return;
}
const separators = ['\n', ',', ';', ' '];
let proteins;
for (const sep of separators) {
if (textList.indexOf(sep) === -1) {
continue;
}
proteins = textList.split(sep).map(ac => ac.trim()).filter(ac => !!ac);
break;
}
if (!proteins) {
proteins = [textList];
}
this.proteins = proteins;
}
}
......@@ -4,6 +4,9 @@
[dataset]="selectedDataset.backendId">
</app-launch-analysis>
<app-custom-proteins [(show)]="showCustomProteinsDialog">
</app-custom-proteins>
<div class="covex explorer">
<div class="covex left-window">
......@@ -387,7 +390,7 @@
</span>
</a>
</header>
<div *ngIf="collapseSelection">
<div *ngIf="collapseSelection" class="seed-selection">
<div class="card-content overflow">
<table class="table selection-table" *ngIf="analysis.getCount() > 0">
<thead>
......@@ -421,25 +424,56 @@
</i>
</div>
<footer class="card-footer">
<a (click)="analysis.addAllHostProteins(currentViewNodes, currentViewProteins)"
<a (click)="analysis.addVisibleHostProteins(currentViewNodes, currentViewProteins)"
class="card-footer-item has-text-success" data-tooltip="Add all visible host proteins.">
<span class="icon">
<i class="fa fa-plus"></i>
<i class="fa fa-eye"></i>
</span>
<span>
Host Proteins
</span>
</a>
<a (click)="analysis.addAllViralProteins(currentViewNodes, currentViewEffects)"
<a (click)="analysis.addVisibleViralProteins(currentViewNodes, currentViewEffects)"
class="card-footer-item has-text-success" data-tooltip="Add all visible viral proteins.">
<span class="icon">
<i class="fa fa-plus"></i>
<i class="fa fa-eye"></i>
</span>
<span>
Viral Proteins
</span>
</a>
</footer>
<footer class="card-footer">
<a (click)="analysis.removeAllHostProteins()"
class="card-footer-item has-text-danger" data-tooltip="Remove all host proteins.">
<span class="icon">
<i class="fa fa-minus"></i>
</span>
<span>
Host Proteins
</span>
</a>
<a (click)="analysis.removeAllViralProteins()"
class="card-footer-item has-text-danger" data-tooltip="Remove all viral proteins.">
<span class="icon">
<i class="fa fa-minus"></i>
</span>
<span>
Viral Proteins
</span>
</a>
</footer>
<footer class="card-footer">
<a (click)="showCustomProteinsDialog = true" class="card-footer-item has-text-primary"
data-tooltip="Add a custom list of proteins.">
<span class="icon">
<i class="fa fa-upload"></i>
</span>
<span>
Custom Proteins
</span>
</a>
</footer>
<footer class="card-footer">
<a (click)="analysis.resetSelection()" class="card-footer-item has-text-danger"
data-tooltip="Remove all entries of the selection.">
......
......@@ -41,3 +41,12 @@
padding: 15px;
font-weight: bold;
}
.seed-selection {
.card-footer {
font-size: 12px;
a {
padding: 3px;
}
}
}
......@@ -60,6 +60,8 @@ export class ExplorerPageComponent implements OnInit, AfterViewInit {
public showAnalysisDialog = false;
public analysisDialogTarget: 'drug' | 'drug-target';
public showCustomProteinsDialog = false;
public selectedAnalysisToken: string | null = null;
public currentDataset = [];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment