Skip to content

Commit

Permalink
Merge pull request #90 from EBISPOT/06/07/22_release
Browse files Browse the repository at this point in the history
06/07/22 release
  • Loading branch information
ala-ebi authored Jul 7, 2022
2 parents dc84c33 + 12bc399 commit 02df2aa
Show file tree
Hide file tree
Showing 27 changed files with 698 additions and 127 deletions.
5 changes: 3 additions & 2 deletions src/app/core/guards/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { TokenStorageService } from '../services/token-storage.service';

@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {

constructor(private authService: AuthService, private router: Router) {
constructor(private authService: AuthService, private tss: TokenStorageService) {
}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.authService.loggedIn() && this.authService.isCurator()) {
return true;
} else {
this.router.navigateByUrl('/login').then();
this.tss.signOut(state.url);
return false;
}
}
Expand Down
16 changes: 15 additions & 1 deletion src/app/core/interceptors/auth.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';

import { TokenStorageService } from '../services/token-storage.service';
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';

const TOKEN_HEADER_KEY = 'Authorization';

Expand All @@ -17,7 +21,17 @@ export class AuthInterceptor implements HttpInterceptor {
if (token != null) {
authReq = req.clone({headers: req.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token)});
}
return next.handle(authReq);
return next.handle(authReq).pipe(
catchError(
(err, caught) => {
if (err.status === 401) {
this.tokenStorageService.signOut();
return of(err);
}
throw err;
}
)
);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/app/core/models/sample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Sample {
GCST: string;
initialSampleDescription: string;
replicateSampleDescription: string;
studyTag: string;
}
6 changes: 5 additions & 1 deletion src/app/core/models/study.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@ export interface Study {
agreedToCc0: boolean;
diseaseTrait: ReportedTrait;
efoTraits: EfoTrait[];
}
backgroundEfoTraits: EfoTrait[];
sumstats_flag: boolean;
pooled_flag: boolean;
gxe_flag: boolean;
}
2 changes: 2 additions & 0 deletions src/app/core/models/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@ export interface Submission {
editTemplate: Provenance;
lockDetails: {lockedBy: Provenance, status: string};
agreedToCc0: boolean;
opentargets_flag: boolean;
userrequested_flag: boolean;
}
9 changes: 3 additions & 6 deletions src/app/core/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@ export class AuthService {
}

isCurator() {
return this.getDecodedToken().domains.indexOf('self.GWAS_Curator') > -1;
return this.getDecodedToken()?.domains?.indexOf('self.GWAS_Curator') > -1;
}

getDecodedToken() {
const jwtToken = this.tokenStorageService.getToken();
let decoded = jwt_decode(jwtToken);
const decoded = jwt_decode(jwtToken);
if (Date.now() > decoded.exp * 1000) {
decoded = 'SESSION TIMEOUT';
alert(decoded);
this.tokenStorageService.signOut();
this.router.navigateByUrl('/login').then();
}
return decoded;
}
Expand Down Expand Up @@ -82,6 +79,6 @@ export class AuthService {
}

logout() {
this.tokenStorageService.signOut();
window.localStorage.removeItem('id_token');
}
}
8 changes: 8 additions & 0 deletions src/app/core/services/curation-http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ export class CurationHttpService {
).pipe(catchError(CurationHttpService.formatErrors));
}

patch(path: string, body: any = {}, params: HttpParams = new HttpParams()): Observable<any> {
return this.http.patch(
`${environment.CURATION_API_URL}${path}`,
body,
{params}
).pipe(catchError(CurationHttpService.formatErrors));
}

download(path: string, params: HttpParams = new HttpParams()): Observable<any> {
return this.http.get(`${environment.CURATION_API_URL}${path}`, {params, responseType: 'blob'})
.pipe(catchError(CurationHttpService.formatErrors));
Expand Down
38 changes: 38 additions & 0 deletions src/app/core/services/submission.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SubmissionHistory } from '../models/submissionHistory';
import { CurationHttpService } from './curation-http.service';
import { ReportedTrait } from '../models/reportedTrait';
import { Study } from '../models/study';
import { EfoTrait } from '../models/efoTrait';

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -115,6 +116,11 @@ export class SubmissionService {
return this.curationHttp.get('/submissions/' + submissionId + '/studies/' + studyId);
}

downloadBulkStudyMultiTraitUploadTemplate() {

return this.curationHttp.download('/reported-traits/templates?file=study-multi-trait');
}

downloadBulkStudyTraitUploadTemplate() {

return this.curationHttp.download('/reported-traits/templates?file=study-trait');
Expand All @@ -125,14 +131,46 @@ export class SubmissionService {
return this.curationHttp.download('/reported-traits/templates?file=study-efo-trait');
}

downloadSamplesPrefilledTemplate(submissionId: string) {

return this.curationHttp.download('/submissions/' + submissionId + '/studies/sampledescription/files');
}

editReportedTraits(trait: ReportedTrait, submissionId, study: Study) {

return this.curationHttp.put('/submissions/' + submissionId + '/studies/' + study.studyId,
{diseaseTrait: trait, study_tag: study.study_tag});
}

editEfoTraits(efoTraits: EfoTrait[], submissionId, study: Study) {

return this.curationHttp.put('/submissions/' + submissionId + '/studies/' + study.studyId,
{efoTraits, study_tag: study.study_tag});
}

editBgEfoTraits(backgroundEfoTraits: EfoTrait[], submissionId, study: Study) {

return this.curationHttp.put('/submissions/' + submissionId + '/studies/' + study.studyId,
{backgroundEfoTraits, study_tag: study.study_tag});
}

filterSubmissions(filtersString: string, size: number, page: number, sort: string, order: string) {
const params = filtersString + '&size=' + String(size) + '&sort=' + sort + ',' + order;
return this.curationHttp.get('/submissions?' + params);
}

patchSubmission(submission: Submission) {

return this.curationHttp.patch('/submissions/' + submission.submissionId, submission);
}

getSubmissionSamples(size: number, page: number, sort: string, order: string, submissionId: string) {

let params: HttpParams = new HttpParams();
params = params
.set('size', String(size))
.set('page', String(page))
.set('sort', sort + ',' + order);
return this.curationHttp.get('/submissions/' + submissionId + '/studies/sampledescription', params);
}
}
11 changes: 8 additions & 3 deletions src/app/core/services/token-storage.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Injectable } from '@angular/core';
import { Router, RouterStateSnapshot } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';

const TOKEN_KEY = 'id_token';

Expand All @@ -7,11 +9,14 @@ const TOKEN_KEY = 'id_token';
})
export class TokenStorageService {

constructor() {
constructor(private router: Router, private dialog: MatDialog) {
}

signOut() {
window.localStorage.clear();
signOut(guardReturnUri?: string) {
setTimeout('alert("SESSION EXPIRED")', 1);
this.dialog.closeAll();
this.router.navigate(['/login'], {queryParams: {returnUrl: guardReturnUri ? guardReturnUri : 'home'}}).then();
window.localStorage.removeItem(TOKEN_KEY);
}

public saveToken(token: string) {
Expand Down
8 changes: 5 additions & 3 deletions src/app/feature/authentication/pages/login/login.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, HostListener, OnInit } from '@angular/core';
import { AuthService } from '../../../../core/services/auth.service';
import { Router } from '@angular/router';
import { ActivatedRoute, Router } from '@angular/router';
import { environment } from '../../../../../environments/environment';

@Component({
Expand All @@ -11,11 +11,13 @@ import { environment } from '../../../../../environments/environment';
export class LoginComponent implements OnInit {
window: any;
bgImage: string;
constructor(private authService: AuthService, private router: Router) {}
private returnUrl: string;
constructor(private authService: AuthService, private router: Router, private route: ActivatedRoute) {}

ngOnInit(): void {
if (this.authService.loggedIn()) { this.router.navigateByUrl('/').then(); }
this.randomBgImage();
this.returnUrl = this.route.snapshot.queryParams.returnUrl || '/';
}

login() {
Expand All @@ -27,7 +29,7 @@ export class LoginComponent implements OnInit {
if (event.origin === environment.AAPURL) {
this.authService.saveToken(event.data);
this.window.close();
this.router.navigateByUrl('/').then();
this.router.navigateByUrl(this.returnUrl).then();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ <h3 class="hidden sm:block mt-2">OR</h3>
<div class="flex justify-center" *ngIf="report">
<button mat-raised-button color="warn" (click)="downloadBulkUploadReport()">Download report</button>
</div>
<div class="flex justify-center" *ngIf="report && report.hasErrors == true">
<h4 class="color-warn">Report may contain errors, please download and have a look.</h4>
</div>
<div class="flex justify-center" *ngIf="uploadError">
<h4 class="color-warn">{{uploadError}}</h4>
</div>
<div class="flex justify-center" *ngIf="traitUploader.queue.length > 0">
<mat-progress-bar mode="determinate" [value]="traitUploader.progress"></mat-progress-bar>
</div>
Expand All @@ -129,7 +135,7 @@ <h3 class="hidden sm:block mt-2">OR</h3>
Upload
</button>
<button [disabled]="traitUploader.queue.length == 0" mat-raised-button color="primary"
(click)="traitUploader.isUploading ? traitUploader.cancelAll() : traitUploader.clearQueue(); fileInput.value = '';">
(click)="traitUploader.isUploading ? traitUploader.cancelAll() : traitUploader.clearQueue(); fileInput.value = ''; uploadError = null;">
<span *ngIf="traitUploader.isUploading">Cancel</span>
<span *ngIf="!traitUploader.isUploading">Reset</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class EfoTraitsComponent implements OnInit, AfterViewInit {
editFormInitialValue: any;
isEditFormDirty = false;
menuShow = false;
uploadError: any;

constructor(private tokenService: TokenStorageService, private dialog: MatDialog,
private snackBar: MatSnackBar, private efoTraitService: EfoTraitService) {
Expand All @@ -74,6 +75,7 @@ export class EfoTraitsComponent implements OnInit, AfterViewInit {
});

this.traitUploader.onAfterAddingFile = (file) => {
this.uploadError = null;
file.withCredentials = false;
this.report = null;
if (this.traitUploader.queue.length > 1) {
Expand All @@ -82,13 +84,17 @@ export class EfoTraitsComponent implements OnInit, AfterViewInit {
}
};
this.traitUploader.onSuccessItem = (item, response) => {
this.uploadError = null;
this.snackBar.open('Traits file was uploaded successfully.', '', {duration: 2500});
this.report = response;
this.report = JSON.parse(response);
this.traitUploader.clearQueue();
this.fileInput.nativeElement.value = '';
this.reloadTraits();
};
this.traitUploader.onErrorItem = () => {
this.traitUploader.onErrorItem = (item, response) => {
const prefix = 'FileProcessingException:';
const message = JSON.parse(response).message;
this.uploadError = message.slice(message.indexOf(prefix) + prefix.length);
this.snackBar.open('An unexpected error occurred while uploading traits.', '', {duration: 2500});
};
}
Expand Down Expand Up @@ -286,7 +292,7 @@ export class EfoTraitsComponent implements OnInit, AfterViewInit {
downloadBulkUploadReport() {

const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([this.report]));
link.href = window.URL.createObjectURL(new Blob([atob(this.report.uploadReport)]));
link.setAttribute('download', 'efo-traits-bulk-report.tsv');
document.body.appendChild(link);
link.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ <h3 class="hidden sm:block mt-2">OR</h3>
<div class="flex justify-center" *ngIf="report">
<button mat-raised-button color="warn" (click)="downloadBulkUploadReport()">Download report</button>
</div>
<div class="flex justify-center" *ngIf="report && report.hasErrors == true">
<h4 class="color-warn">Report may contain errors, please download and have a look.</h4>
</div>
<div class="flex justify-center" *ngIf="uploadError">
<h4 class="color-warn">{{uploadError}}</h4>
</div>
<div class="flex justify-center" *ngIf="traitUploader.queue.length > 0">
<mat-progress-bar mode="determinate" [value]="traitUploader.progress"></mat-progress-bar>
</div>
Expand All @@ -115,7 +121,7 @@ <h3 class="hidden sm:block mt-2">OR</h3>
Upload
</button>
<button [disabled]="traitUploader.queue.length == 0" mat-raised-button color="primary"
(click)="traitUploader.isUploading ? traitUploader.cancelAll() : traitUploader.clearQueue(); fileInput.value = '';">
(click)="traitUploader.isUploading ? traitUploader.cancelAll() : traitUploader.clearQueue(); fileInput.value = ''; uploadError = false;">
<span *ngIf="traitUploader.isUploading">Cancel</span>
<span *ngIf="!traitUploader.isUploading">Reset</span>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { FileUploader } from 'ng2-file-upload';
import { environment } from '../../../../../environments/environment';
import { TokenStorageService } from '../../../../core/services/token-storage.service';
import { TraitUploadApiResponse } from '../../../../core/models/rest/api-responses/traitUploadApiResponse';

@Component({
selector: 'app-reported-trait',
Expand Down Expand Up @@ -50,6 +49,7 @@ export class ReportedTraitComponent implements OnInit, AfterViewInit {
analysisId = '';
menuShow = false;
report: any;
uploadError: any;

constructor(private reportedTraitService: ReportedTraitService, private tokenService: TokenStorageService,
private dialog: MatDialog, private snackBar: MatSnackBar) {
Expand All @@ -75,13 +75,17 @@ export class ReportedTraitComponent implements OnInit, AfterViewInit {
}
};
this.traitUploader.onSuccessItem = (item, response) => {
this.uploadError = null;
this.snackBar.open('Traits file was uploaded successfully.', '', {duration: 2500});
this.report = response;
this.report = JSON.parse(response);
this.traitUploader.clearQueue();
this.fileInput.nativeElement.value = '';
this.reloadTraits();
};
this.traitUploader.onErrorItem = () => {
this.traitUploader.onErrorItem = (item, response) => {
const prefix = 'FileProcessingException:';
const message = JSON.parse(response).message;
this.uploadError = message.slice(message.indexOf(prefix) + prefix.length);
this.snackBar.open('An unexpected error occurred while uploading traits.', '', {duration: 2500});
};

Expand Down Expand Up @@ -283,13 +287,11 @@ export class ReportedTraitComponent implements OnInit, AfterViewInit {
this.dataSource = new MatTableDataSource<ReportedTrait>(value?._embedded?.diseaseTraits ? value._embedded.diseaseTraits : null);
this.resultsLength = value.page.totalElements;
});

}

downloadBulkUploadReport() {

const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([this.report]));
link.href = window.URL.createObjectURL(new Blob([atob(this.report.uploadReport)]));
link.setAttribute('download', 'reported-traits-bulk-report.tsv');
document.body.appendChild(link);
link.click();
Expand Down
Loading

0 comments on commit 02df2aa

Please sign in to comment.