Skip to content

Commit

Permalink
Merge pull request #300 from TheJacksonLaboratory/feature/maxolyzer
Browse files Browse the repository at this point in the history
Feature/maxolyzer
  • Loading branch information
iimpulse committed Sep 18, 2024
2 parents c63f741 + a97bddc commit 0c86c3e
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 91 deletions.
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Modules
import {NgModule} from '@angular/core';
import { MAT_TABS_CONFIG } from '@angular/material/tabs';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {RoutingModule} from './app-routing.module';
Expand Down Expand Up @@ -36,7 +37,7 @@ import {SafeHtmlPipe} from './shared/pipes/sanitize.pipe';
RoutingModule,
SearchModule
],
providers: [SearchService, NewsService],
providers: [SearchService, NewsService, { provide: MAT_TABS_CONFIG, useValue: { animationDuration: '0ms' } }],
bootstrap: [AppComponent]
})
export class AppModule {
Expand Down
3 changes: 1 addition & 2 deletions src/app/browser/browser.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {GlobalMaterialModules} from '../shared/modules/global.module';
// Services
import {SearchService} from '../shared/search/service/search.service';
import { AnnotationService } from './services/annotation/annotation.service';
import {TermService} from './services/term/term.service';
import {GeneService} from './services/gene/gene.service';
import {OntologyService} from './services/ontology/ontology.service';
// Components
Expand All @@ -32,7 +31,7 @@ import {ProfileSearchComponent} from './pages/profile-search/profile-search.comp
GlobalMaterialModules,
ExtrasModule
],
providers: [SearchService, TermService, GeneService, DialogService,
providers: [SearchService, GeneService, DialogService,
OntologyService, AnnotationService],
declarations: [TermComponent, DiseaseComponent,
GeneComponent,
Expand Down
12 changes: 12 additions & 0 deletions src/app/browser/models/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export interface PhenotypeAssociation {
diseases: any[];
genes: any[];
assays: any[];
medicalActions: any[];
}

export interface GeneAssociation {
Expand All @@ -148,10 +149,21 @@ export interface DiseaseAssociation {
disease: Disease;
categories: {};
genes: any[];
medicalActions: MedicalActionSourceExtended[];
}

export enum EntityType {
PHENOTYPE,
DISEASE,
GENE
}

export interface MedicalActionSourceExtended extends SimpleTerm{
relations: string[];
sources: string[];
}

export interface MedicalActionTargetExtended extends SimpleTerm {
targets: string[];
sources: string[];
}
5 changes: 0 additions & 5 deletions src/app/browser/pages/disease/disease.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,3 @@
.mat-row {
border-bottom-color: rgba(0, 0, 0, 0.25) !important;
}


.source .material-icons,.material-icons-outlined {
font-size: 12px;
}
85 changes: 74 additions & 11 deletions src/app/browser/pages/disease/disease.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
<mat-card class="item-summary mat-elevation-z6">
<mat-card-content>
<span class="item-title">{{disease.name}}&nbsp;</span>
<a *ngIf="disease.mondoId" class="item-id" [href]="getExternalTermIdUrlFromId(disease.mondoId)" target="_blank">
<a *ngIf="disease.mondoId" class="item-id" [href]="utilityService.getExternalTermIdUrlFromId(disease.mondoId)" target="_blank">
{{disease.mondoId}}
<mat-icon>open_in_new</mat-icon>
</a>
<a class="item-id" [href]="getExternalTermIdUrlFromId(disease.id)" target="_blank">
<a class="item-id" [href]="utilityService.getExternalTermIdUrlFromId(disease.id)" target="_blank">
{{disease.id}}
<mat-icon>open_in_new</mat-icon>
</a>
Expand Down Expand Up @@ -74,19 +74,19 @@ <h3 class="category-title">{{catTermSource.catLabel}}
<mat-header-cell *matHeaderCellDef>Source(s)</mat-header-cell>
<mat-cell [ngClass]="{'source-cell': row.metadata.sources.length > 1}" *matCellDef="let row">
<ng-container *ngFor="let source of row.metadata.sources">
<div class="source" *ngIf="isTermIdExpected(source,'PMID')">
<a [href]="getExternalTermIdUrlFromId(source)" target="_blank">
<div class="source" *ngIf="utilityService.isTermIdExpected(source,'PMID')">
<a [href]="utilityService.getExternalTermIdUrlFromId(source)" target="_blank">
PubMed <i class="material-icons-outlined">library_books</i>
</a>
</div>
<div class="source" *ngIf="isTermIdExpected(source, 'BOOKSHELF')">
<div class="source" *ngIf="utilityService.isTermIdExpected(source, 'BOOKSHELF')">
<a [href]="source" target="_blank">
Gene Review <i class="material-icons-outlined">library_books</i>
</a>
</div>
<div class="source" *ngIf="!isTermIdExpected(source, 'PMID') && !isTermIdExpected(source, 'BOOKSHELF')">
<a [href]="getExternalTermIdUrlFromId(source)" target="_blank">
<span>{{getDiseaseDatabaseName(source)}} &nbsp;</span>
<div class="source" *ngIf="!utilityService.isTermIdExpected(source, 'PMID') && !utilityService.isTermIdExpected(source, 'BOOKSHELF')">
<a [href]="utilityService.getExternalTermIdUrlFromId(source)" target="_blank">
<span>{{utilityService.getDiseaseDatabaseName(source)}} &nbsp;</span>
<i class="material-icons">open_in_new</i>
</a>
</div>
Expand Down Expand Up @@ -130,15 +130,78 @@ <h3 class="category-title">{{catTermSource.catLabel}}
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
</ng-container>
</mat-table>

<mat-paginator #genePaginator [pageSizeOptions]="[50, 100, 500]"></mat-paginator>
<div class="associationsPaging">
<p>{{geneDataSource.data.length}} gene associations.
</p>
</div>
</div>
</div>
</div>

<!-- no results found -->
<div class="container center" [hidden]="geneDataSource?.data.length !== 0">
<h4>No gene results found for "{{query}}"</h4>
<h4>No gene results found for {{query}}</h4>
</div>

</mat-tab>
<!-- Medical Actions Tab -->
<mat-tab label="Medical Actions">
<!--<div class="tab-content">-->
<div [hidden]="medicalActionsDataSource?.data.length === 0">
<div class="tab-output-container">
<!-- Gene Association Table -->
<div class="associations gene-association">
<mat-table [dataSource]="medicalActionsDataSource" matSort>
<mat-header-row *matHeaderRowDef="medicalActionColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let row; columns: medicalActionColumns;"></mat-row>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef>MaXo Id</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.id}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>MaXo Name</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
</ng-container>
<ng-container matColumnDef="relations">
<mat-header-cell *matHeaderCellDef>Relation</mat-header-cell>
<mat-cell *matCellDef="let row">
<ng-container *ngIf="row.relations.length == 1">

Check failure on line 170 in src/app/browser/pages/disease/disease.component.html

View workflow job for this annotation

GitHub Actions / load

Expected `===` but received `==`
{{row.relations[0]}}
</ng-container>
<ng-container *ngIf="row.relations.length > 1">
{{row.relations.join(" and ")}}
</ng-container>
</mat-cell>
</ng-container>
<ng-container matColumnDef="targets">
<mat-header-cell *matHeaderCellDef>Target</mat-header-cell>
<mat-cell *matCellDef="let row">
<ng-container *ngIf="row.targets.length > 0">
<div *ngFor="let target of row.targets">
<div *ngIf="utilityService.isTermIdExpected(target.id,'HP')">
<a routerLink="/browse/term/{{target.id}}">{{target.id}}</a>
</div>
<div *ngIf="utilityService.isTermIdExpected(target.id,'OMIM')">
{{target.id}}
</div>
</div>
</ng-container>
</mat-cell>
</ng-container>
</mat-table>
<div class="associationsPaging">
<p>{{medicalActionsDataSource.data.length}} medical actions.
</p>
</div>
</div>
</div>
</div>

<!-- no results found -->
<div class="container center" [hidden]="medicalActionsDataSource?.data.length !== 0">
<h4>No medical action results found for {{query}}</h4>
</div>

</mat-tab>
Expand Down
34 changes: 7 additions & 27 deletions src/app/browser/pages/disease/disease.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {ActivatedRoute, Router} from '@angular/router';
import {MatTableDataSource} from '@angular/material/table';
import {MatSort} from '@angular/material/sort';
import {MatPaginator} from '@angular/material/paginator';
import { Disease, SimpleTerm, Term, TermCategory } from '../../models/models';
import { UtilityService } from '../../../shared/utility/utility.service';
import { Disease, MedicalActionSourceExtended, SimpleTerm, Term, TermCategory } from '../../models/models';
import { AnnotationService } from '../../services/annotation/annotation.service';
import {DialogService} from '../../../shared/dialog-excel-download/dialog.service';

Expand All @@ -19,8 +20,10 @@ export class DiseaseComponent {
termColumns = ['id', 'name', 'metadata.onset', 'metadata.frequency', 'metadata.sources'];
hasTerms = false;
geneColumns = ['id', 'name'];
termDataSource: MatTableDataSource<Term>;
medicalActionColumns = ['id', 'name', 'relations', 'targets']
medicalActionsDataSource: MatTableDataSource<MedicalActionSourceExtended>;
geneDataSource: MatTableDataSource<SimpleTerm>;

isLoading = true;
catTermSources: TermCategory[] = [];
@ViewChild(MatSort) sort: MatSort;
Expand All @@ -29,6 +32,7 @@ export class DiseaseComponent {

constructor(private route: ActivatedRoute,
public dialogService: DialogService, public annotationService: AnnotationService,
public utilityService: UtilityService,
private router: Router) {
this.route.params.subscribe((params) => {
this.query = params.id;
Expand All @@ -44,6 +48,7 @@ export class DiseaseComponent {
this.setCatTermsDBSource(data.categories);
this.geneDataSource = new MatTableDataSource(data.genes);
this.geneDataSource.paginator = this.genePaginator;
this.medicalActionsDataSource = new MatTableDataSource(data.medicalActions);
this.isLoading = false;
}, (error) => {
const errorString = 'Could not find requested disease id.';
Expand Down Expand Up @@ -88,31 +93,6 @@ export class DiseaseComponent {
});
}

getExternalTermIdUrlFromId(termId?: string) {
if(!termId){
return '';
}
const sourceParts = termId.split(':');
if (this.isTermIdExpected(termId, "OMIM")) {
return `https://omim.org/entry/${sourceParts[1]}`;
} else if (this.isTermIdExpected(termId, "ORPHA")) {
return `https://www.orpha.net/consor/cgi-bin/OC_Exp.php?Lng=EN&Expert=${sourceParts[1]}`
} else if (this.isTermIdExpected(termId, "MONDO")){
return `https://monarchinitiative.org/disease/${termId}`;
} else if(this.isTermIdExpected(termId, "PMID")){
return `https://www.ncbi.nlm.nih.gov/pubmed/${sourceParts[1]}`;
}
}

isTermIdExpected(diseaseId: string, expected: string) {
return diseaseId != "" && diseaseId != null && expected != "" && expected != null
? diseaseId.toUpperCase().includes(expected) : false;
}

getDiseaseDatabaseName(diseaseId){
return diseaseId != "" && diseaseId != null ? diseaseId.split(':')[0] : '';
}

applyGeneFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { async, ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import {ProfileSearchComponent} from './profile-search.component';
import {SearchService} from "../../../shared/search/service/search.service";
Expand All @@ -11,10 +11,10 @@ describe('ProfileSearchComponent', () => {
let component: ProfileSearchComponent;
let fixture: ComponentFixture<ProfileSearchComponent>;

beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProfileSearchComponent],
providers: [SearchService, TermService],
providers: [SearchService],
imports: [HttpClientTestingModule, GlobalMaterialModules, NoopAnimationsModule]
})
.compileComponents();
Expand Down
4 changes: 4 additions & 0 deletions src/app/browser/pages/term/term.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,7 @@ img.mat-chip-avatar::before {
.translate-btn .material-icons {
font-size: 18px;
}

.source-hover {
text-decoration: none;
}
69 changes: 67 additions & 2 deletions src/app/browser/pages/term/term.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ <h3 class="card-title">Hierarchy</h3>
<!-- TABS -->
<div class="hpo-group-tab" *ngIf="term">
<mat-tab-group selectedIndex="0" class="term-details-tab-group mat-elevation-z6">
<!-- Disease association -->
<!-- Disease Association -->
<mat-tab label="Disease Associations">
<div [hidden]="diseaseAssocCount === 0">
<div class="tab-output-container">
Expand Down Expand Up @@ -174,7 +174,7 @@ <h4>Ontology Annotation Network Error. <a href="https://github.com/TheJacksonLab
</mat-tab>

<!-- Gene Association -->
<mat-tab label="Gene Associations">
<mat-tab label="Gene Associations [Inferred]">
<div [hidden]="geneAssocCount === 0">
<div class="tab-output-container">
<div class="filter-container">
Expand Down Expand Up @@ -223,6 +223,71 @@ <h4>Ontology Annotation Network Error. <a href="https://github.com/TheJacksonLab
</div>
</mat-tab>

<!-- Medical Action Association -->
<mat-tab label="Medical Actions">
<div [hidden]="medicalActionDisplayCount === 0">
<div class="tab-output-container">
<mat-progress-bar *ngIf="assocLoading" class="loading-result-details" color="primary"
mode="indeterminate">
</mat-progress-bar>

<div [hidden]="assocLoading" class="associations medical-actions-association">
<mat-table [dataSource]="medicalActionSource">
<mat-header-row *matHeaderRowDef="medicalActionColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let row; columns: medicalActionColumns;"></mat-row>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef>MaXo Id</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.id}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> MaXo Name</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.name}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="relation">
<mat-header-cell *matHeaderCellDef> Relation</mat-header-cell>
<mat-cell *matCellDef="let row">
<ng-container *ngIf="row.relations.length == 1">

Check failure on line 253 in src/app/browser/pages/term/term.component.html

View workflow job for this annotation

GitHub Actions / load

Expected `===` but received `==`
{{row.relations[0]}}
</ng-container>
<ng-container *ngIf="row.relations.length > 1">
{{row.relations.join(" and ")}}
</ng-container>
</mat-cell>
</ng-container>
<ng-container matColumnDef="source">
<mat-header-cell *matHeaderCellDef> Sources</mat-header-cell>
<mat-cell *matCellDef="let row; let i = index">
<div *ngFor="let source of row.sources">
<div class="source" *ngIf="utilityService.isTermIdExpected(source,'PMID')">
<a class="source-hover" [href]="utilityService.getExternalTermIdUrlFromId(source)" target="_blank">
PubMed <i class="material-icons-outlined">library_books</i>&nbsp;&nbsp;
</a>
<a *ngIf="row.sources.length > 4">
({{row.sources.length - 4}} more).
</a>
</div>
</div>
</mat-cell>
</ng-container>
</mat-table>

<!-- paging: associations subset count -->
<div *ngIf="!assocLoading" class="associationsPaging">
<p>{{medicalActionDisplayCount}} medical actions.
</p>
</div>
</div>
</div>
</div>
<div class="container center" [hidden]="medicalActionDisplayCount !== 0">
<h4>No medical actions found for <strong>{{term.id}}</strong></h4>
</div>
</mat-tab>

<!-- Loinc Association -->
<div>
<mat-tab label="LOINC Associations">
Expand Down
Loading

0 comments on commit 0c86c3e

Please sign in to comment.