Commit ff6791a4 authored by Rasko Leinonen's avatar Rasko Leinonen
Browse files

Added sample-checklist and sequence-checklist endpoints.

parent c37f75ce
......@@ -62,3 +62,11 @@ fabric.properties
.idea/httpRequests
/.idea/modules/
.gradle/
.idea/modules.xml
.idea/vcs.xml
.idea/misc.xml
.idea/google-java-format.xml
.idea/encodings.xml
frontend/.vscode/settings.json
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel>
<module name="uk.ac.ebi.ena.webin-portal.webin-portal.main" target="1.8" />
<module name="uk.ac.ebi.ena.webin-portal.webin-portal.test" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>
\ No newline at end of file
......@@ -2,7 +2,9 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2dd3617875b940c2a4963a7d740250ff)](https://app.codacy.com/app/enasequence/webin-portal?utm_source=github.com&utm_medium=referral&utm_content=enasequence/webin-portal&utm_campaign=badger)
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.5.0 and has been later upgraded to version 1.6.8.
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.5.0 and has been later upgraded to
version 1.6.8
version 7.3.8
## Development server
......
This diff is collapsed.
......@@ -16,31 +16,32 @@
},
"private": true,
"dependencies": {
"@angular/animations": "7.0.1",
"@angular/animations": "7.2.13",
"@angular/cdk": "^7.0.2",
"@angular/common": "7.0.1",
"@angular/compiler": "7.0.1",
"@angular/core": "7.0.1",
"@angular/common": "7.2.13",
"@angular/compiler": "7.2.13",
"@angular/core": "7.2.13",
"@angular/flex-layout": "^7.0.0-beta.19",
"@angular/forms": "7.0.1",
"@angular/http": "7.0.1",
"@angular/forms": "7.2.13",
"@angular/http": "7.2.13",
"@angular/material": "^7.0.2",
"@angular/platform-browser": "7.0.1",
"@angular/platform-browser-dynamic": "7.0.1",
"@angular/router": "7.0.1",
"@angular/platform-browser": "7.2.13",
"@angular/platform-browser-dynamic": "7.2.13",
"@angular/router": "7.2.13",
"@types/file-saver": "^1.3.1",
"core-js": "^2.5.7",
"enum": "^2.5.0",
"file-saver": "^2.0.0-rc.4",
"hammerjs": "^2.0.8",
"rxjs": "^6.3.3",
"tslib": "^1.9.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.10.3",
"@angular/cli": "7.0.3",
"@angular/compiler-cli": "7.0.1",
"@angular/language-service": "7.0.1",
"@angular-devkit/build-angular": "~0.13.0",
"@angular/cli": "7.3.8",
"@angular/compiler-cli": "7.2.13",
"@angular/language-service": "7.2.13",
"@types/jasmine": "~2.8.9",
"@types/jasminewd2": "~2.0.5",
"@types/node": "~10.12.0",
......@@ -52,10 +53,10 @@
"karma-coverage-istanbul-reporter": "^2.0.4",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^1.4.0",
"node-sass": "^4.9.4",
"node-sass": "^4.11.0",
"protractor": "^5.4.1",
"ts-node": "~7.0.1",
"tslint": "~5.11.0",
"typescript": "3.1.3"
"typescript": "3.2.4"
}
}
......@@ -13,8 +13,8 @@ import { BrowserModule } from '@angular/platform-browser';
import { UiModule } from './ui/ui.module';
import {HttpClientModule} from '@angular/common/http';
import {HTTP_INTERCEPTORS} from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
......@@ -43,7 +43,6 @@ import { WebinAuthenticationInterceptor } from './webin-authentication.intercept
import { RouterModule, Routes } from '@angular/router';
const appRoutes: Routes = [
{
path: 'login',
......@@ -53,6 +52,16 @@ const appRoutes: Routes = [
path: 'logout',
component: LogoutComponent,
},
{
path: 'sample-checklist',
component: ChecklistComponent,
data: { checklistType: 'sample' }
},
{
path: 'sequence-checklist',
component: ChecklistComponent,
data: { checklistType: 'sequence' }
},
{
path: 'consent',
component: GdprComponent,
......@@ -67,14 +76,14 @@ const appRoutes: Routes = [
@NgModule({
imports: [
BrowserModule,
UiModule,
HttpClientModule,
// Router
RouterModule.forRoot(
appRoutes,
{ enableTracing: false } // <-- debugging purposes only
),
BrowserModule,
UiModule,
HttpClientModule,
// Router
RouterModule.forRoot(
appRoutes,
{ enableTracing: false } // <-- debugging purposes only
),
],
declarations: [
AppComponent,
......@@ -93,9 +102,9 @@ const appRoutes: Routes = [
ChecklistComponent,
],
bootstrap: [
AppComponent,
HeaderComponent,
FooterComponent,
AppComponent,
HeaderComponent,
FooterComponent,
],
providers: [
WebinRestService,
......@@ -107,9 +116,9 @@ const appRoutes: Routes = [
WebinGdprGuardService,
{
provide: HTTP_INTERCEPTORS,
useClass: WebinAuthenticationInterceptor,
multi: true,
provide: HTTP_INTERCEPTORS,
useClass: WebinAuthenticationInterceptor,
multi: true,
}
],
entryComponents: [
......
<div *ngIf="!checklistGroupDataSource" >
<mat-expansion-panel [expanded]="init">
<mat-expansion-panel-header>
<mat-panel-title>
<b>Download spreadsheet template for annotated sequences</b>
</mat-panel-title>
</mat-expansion-panel-header>
<p *ngIf="checklistType === ChecklistType.sample">
Use this submission option to create and download a spreadsheet template for samples.
</p>
<div *ngIf="!checklistGroupDataSource && !init">
<p *ngIf="checklistType === ChecklistType.sequence">
Use this submission option to create and download a spreadsheet template for sequences.
</p>
<p *ngIf="checklistType === ChecklistType.sample">
Use this submission option to create and download a spreadsheet template for samples.
</p>
<button mat-raised-button color="accent" (click)="initChecklists()">Start</button>
</div>
<p *ngIf="checklistType === ChecklistType.sequence">
Use this submission option to create and download a spreadsheet template for sequences.
</p>
<div *ngIf="checklistGroupDataSource" >
<p *ngIf="checklistType === ChecklistType.sample">
Please select the most appropriate checklist group, checklist and checklist fields.
Download an empty spreadsheet template, fill in the spreadsheet and submit the spreadsheet
using Webin.
</p>
<button mat-raised-button color="accent" (click)="initChecklists()">Start</button>
</div>
<p *ngIf="checklistType === ChecklistType.sequence">
Please select the most appropriate checklist group, checklist and checklist fields.
Download an empty spreadsheet template, Fill in the spreadsheet
and submit the spreadsheet using
<a href="http://ena-docs.readthedocs.io/en/latest/cli_04.html" target="_blank">Webin command line interface</a>.
</p>
<div *ngIf="checklistGroupDataSource">
</div>
<p *ngIf="checklistType === ChecklistType.sample">
Please select the most appropriate checklist group, checklist and checklist fields.
Download an empty spreadsheet template, fill in the spreadsheet and submit the spreadsheet
using Webin.
</p>
<div *ngIf="active" style="height:70px;">
<mat-spinner [diameter]="50" [strokeWidth]="5" style="margin:0 auto;">
</mat-spinner>
</div>
<p *ngIf="checklistType === ChecklistType.sequence">
Please select the most appropriate checklist group, checklist and checklist fields.
Download an empty spreadsheet template, Fill in the spreadsheet
and submit the spreadsheet using
<a href="http://ena-docs.readthedocs.io/en/latest/cli_04.html" target="_blank">Webin command line interface</a>.
</p>
<div *ngIf="dataError">
<div class="app-error">
<i class="material-icons">error</i>
{{dataError}}
</div>
</div>
<mat-vertical-stepper #stepper *ngIf="checklistGroupDataSource">
<mat-step label="Select checklist group">
<p>Please select a checklist group first.</p>
<div class="mat-elevation-z8">
<mat-table [dataSource]="checklistGroupDataSource">
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
<mat-cell *matCellDef="let checklistGroup">
<p style="font-weight:bold;"> {{ checklistGroup.name }} </p>
<p style="margin-left:10px;"> {{ checklistGroup.description }} </p>
</mat-cell>
</ng-container>
<mat-row *matRowDef="let row; columns: checklistGroupDisplayedColumns;" (click)="setChecklistGroup(row, stepper)"></mat-row>
</mat-table>
</div>
<div *ngIf="active" style="height:70px;">
<mat-spinner [diameter]="50" [strokeWidth]="5" style="margin:0 auto;">
</mat-spinner>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext [disabled]="!this.selectedChecklistGroup">Next</button>
<div *ngIf="dataError">
<div class="app-error">
<i class="material-icons">error</i>
{{dataError}}
</div>
</div>
</mat-step>
<mat-step label="Select checklist">
<div *ngIf="!selectedChecklistGroup">
<mat-vertical-stepper #stepper *ngIf="checklistGroupDataSource">
<mat-step label="Select checklist group">
<p>Please select a checklist group first.</p>
</div>
<div *ngIf="selectedChecklistGroup">
<p>You have selected <b>{{selectedChecklistGroup.name}}</b>. Please select the most appropriate checklist from the list below.</p>
<div class="mat-elevation-z8">
<table cdk-table [dataSource]="checklistDataSource">
<ng-container cdkColumnDef="name">
<th cdk-header-cell *cdkHeaderCellDef>Name</th>
<td cdk-cell *cdkCellDef="let checklist">
<p style="font-weight:bold">{{ checklist.name }}</p>
<p>{{ checklist.description }}</p>
</td>
<mat-table [dataSource]="checklistGroupDataSource">
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
<mat-cell *matCellDef="let checklistGroup">
<p style="font-weight:bold;"> {{ checklistGroup.name }} </p>
<p style="margin-left:10px;"> {{ checklistGroup.description }} </p>
</mat-cell>
</ng-container>
<tr cdk-row *cdkRowDef="let row; columns: checklistDisplayedColumns;" (click)="setChecklist(row, stepper)"></tr>
</table>
<mat-row *matRowDef="let row; columns: checklistGroupDisplayedColumns;"
(click)="setChecklistGroup(row, stepper)"></mat-row>
</mat-table>
</div>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext [disabled]="!this.selectedChecklist">Next</button>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext [disabled]="!this.selectedChecklistGroup">Next</button>
</div>
</mat-step>
<mat-step label="Select checklist fields">
<div *ngIf="!selectedChecklist">
<p>Please select a checklist first.</p>
</div>
</mat-step>
<mat-step label="Select checklist">
<div *ngIf="!selectedChecklistGroup">
<p>Please select a checklist group first.</p>
</div>
<div *ngIf="selectedChecklist">
<p>You have selected <b>{{selectedChecklist.name}}</b>. Please select the checklist fields below.</p>
<div *ngIf="selectedChecklistGroup">
<p>You have selected <b>{{selectedChecklistGroup.name}}</b>. Please select the most appropriate checklist from
the list below.</p>
<div class="mat-elevation-z8">
<table cdk-table [dataSource]="checklistDataSource">
<ng-container cdkColumnDef="name">
<th cdk-header-cell *cdkHeaderCellDef>Name</th>
<td cdk-cell *cdkCellDef="let checklist">
<p style="font-weight:bold">{{ checklist.name }}</p>
<p>{{ checklist.description }}</p>
</td>
</ng-container>
<tr cdk-row *cdkRowDef="let row; columns: checklistDisplayedColumns;" (click)="setChecklist(row, stepper)">
</tr>
</table>
</div>
</div>
<div class="mat-elevation-z8">
<mat-accordion>
<mat-expansion-panel *ngFor="let fieldGroup of selectedChecklist.fieldGroups">
<mat-expansion-panel-header>
<mat-panel-title>
{{fieldGroup.name}}<span fxHide fxShow.gt-sm> {{getSelectedFieldsDisplayText(fieldGroup)}}</span>
</mat-panel-title>
</mat-expansion-panel-header>
<div *ngFor="let field of fieldGroup.fields">
<mat-checkbox class="checklist-checked-field" [(ngModel)]="selectedFields[field.label]" [disabled]="mandatoryFields[field.label]"><b class="checklist-checked-field">{{field.label}}</b></mat-checkbox>
<p fxHide fxShow.gt-sm><i>{{field.mandatory}} {{getFieldTypeDisplayText(field)}}</i></p>
<!--
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext [disabled]="!this.selectedChecklist">Next</button>
</div>
</mat-step>
<mat-step label="Select checklist fields">
<div *ngIf="!selectedChecklist">
<p>Please select a checklist first.</p>
</div>
<div *ngIf="selectedChecklist">
<p>You have selected <b>{{selectedChecklist.name}}</b>. Please select the checklist fields below.</p>
<div class="mat-elevation-z8">
<mat-accordion>
<mat-expansion-panel *ngFor="let fieldGroup of selectedChecklist.fieldGroups">
<mat-expansion-panel-header>
<mat-panel-title>
{{fieldGroup.name}}<span fxHide fxShow.gt-sm> {{getSelectedFieldsDisplayText(fieldGroup)}}</span>
</mat-panel-title>
</mat-expansion-panel-header>
<div *ngFor="let field of fieldGroup.fields">
<mat-checkbox class="checklist-checked-field" [(ngModel)]="selectedFields[field.label]"
[disabled]="mandatoryFields[field.label]"><b class="checklist-checked-field">{{field.label}}</b>
</mat-checkbox>
<p fxHide fxShow.gt-sm><i>{{field.mandatory}} {{getFieldTypeDisplayText(field)}}</i></p>
<!--
<p *ngIf="checklistType === ChecklistType.sequence">
{{field.name}}
</p>
-->
<p>
{{field.description}}
</p>
<div fxLayout="row">
<div fxFlex = "200px">
<p *ngIf="field.units.length > 0">
<mat-select class="checklist-restriction" placeholder="Permitted units">
<mat-option *ngFor="let unit of field.units" [value]="unit" disabled>
{{ unit }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.regexValue" class="checklist-restriction">
<mat-select class="checklist-restriction" placeholder="Regular expression">
<mat-option disabled>
{{ field.regexValue }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.textChoice && field.textChoice.length > 0">
<mat-select class="checklist-restriction" placeholder="Permitted values">
<mat-option *ngFor="let textChoice of field.textChoice" [value]="textChoice" disabled>
{{ textChoice }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.ontologyId" class="checklist-restriction">
Permitted ontology: {{ field.ontologyId }}
</p>
<p>
{{field.description}}
</p>
<div fxLayout="row">
<div fxFlex="200px">
<p *ngIf="field.units.length > 0">
<mat-select class="checklist-restriction" placeholder="Permitted units">
<mat-option *ngFor="let unit of field.units" [value]="unit" disabled>
{{ unit }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.regexValue" class="checklist-restriction">
<mat-select class="checklist-restriction" placeholder="Regular expression">
<mat-option disabled>
{{ field.regexValue }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.textChoice && field.textChoice.length > 0">
<mat-select class="checklist-restriction" placeholder="Permitted values">
<mat-option *ngFor="let textChoice of field.textChoice" [value]="textChoice" disabled>
{{ textChoice }}
</mat-option>
</mat-select>
</p>
<p *ngIf="field.ontologyId" class="checklist-restriction">
Permitted ontology: {{ field.ontologyId }}
</p>
</div>
<div fxFlex>
</div>
</div>
<div fxFlex>
</div>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
<mat-step label="Download spreadsheet template">
<div *ngIf="!selectedChecklist">
<p>Please select a checklist first.</p>
</div>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
<mat-step label="Download spreadsheet template">
<div *ngIf="!selectedChecklist">
<p>Please select a checklist first.</p>
</div>
<div *ngIf="selectedChecklist">
<p>
Please download the spreadsheet template containing the fields you have selected by using the 'Download' button below.
</p>
<div *ngIf="selectedChecklist">
<div *ngIf="checklistType === ChecklistType.sequence">
<p>
Please do not modify the first two lines of the spreadsheet. The first line contains the checklist name and
the second line contains the field names in separate columns. The first column in the spreadsheet,
the ENTRYNUMBER, starts with 1 and is incremented by 1 for each sequence. For example, if the spreadsheet
has 10 sequences the first ENTRYNUMBER should be 1 and the last should be 10. The other columns in the
spreadsheet correspond to the checklist fields you have selected. You can find more information about
permitted values for each column from the 'Select checklist fields' page.
Please download the spreadsheet template containing the fields you have selected by using the 'Download'
button below.
</p>
</div>
<div *ngIf="checklistType === ChecklistType.sequence">
<p>
Please do not modify the first two lines of the spreadsheet. The first line contains the checklist name and
the second line contains the field names in separate columns. The first column in the spreadsheet,
the ENTRYNUMBER, starts with 1 and is incremented by 1 for each sequence. For example, if the spreadsheet
has 10 sequences the first ENTRYNUMBER should be 1 and the last should be 10. The other columns in the
spreadsheet correspond to the checklist fields you have selected. You can find more information about
permitted values for each column from the 'Select checklist fields' page.
</p>
<button mat-raised-button color="accent" (click)="download()">Download</button>
</div>
</div>
<button mat-raised-button color="accent" (click)="download()">Download</button>
<div>
<button mat-button matStepperPrevious>Back</button>
<!-- <button mat-button matStepperNext (click)="">Done</button> -->
</div>
</div>
<div>
<button mat-button matStepperPrevious>Back</button>
<!-- <button mat-button matStepperNext (click)="">Done</button> -->
</div>
</mat-step>
</mat-vertical-stepper>
</mat-step>
</mat-vertical-stepper>
</mat-expansion-panel>
......@@ -18,6 +18,7 @@ import { WebinReportService } from '../webin-report.service';
import { MockWebinReportService } from '../mock/mock-webin-report.service';
import { ChecklistComponent } from './checklist.component';
import { RouterModule } from '@angular/router';
describe('ChecklistComponent', () => {
let component: ChecklistComponent;
......@@ -25,8 +26,8 @@ describe('ChecklistComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ChecklistComponent ],
imports: [ UiModule ],
declarations: [ChecklistComponent],
imports: [UiModule, RouterModule.forRoot([])],
providers: [
{
provide: WebinAuthenticationService,
......@@ -38,7 +39,7 @@ describe('ChecklistComponent', () => {
},
]
})
.compileComponents();
.compileComponents();
}));
beforeEach(() => {
......
......@@ -9,11 +9,11 @@
* specific language governing permissions and limitations under the License.
*/
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { Component, Input, ViewEncapsulation, OnInit } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { MatTableDataSource } from '@angular/material';
import { saveAs } from 'file-saver';
import { retry, mergeMap } from 'rxjs/operators';
import { retry, mergeMap, map } from 'rxjs/operators';
import { ChecklistType } from '../checklist-type.enum';
import { ChecklistInterface } from '../checklist.interface';
import { ChecklistGroupInterface } from '../checklist-group.interface';
......@@ -21,6 +21,7 @@ import { ChecklistFieldGroupInterface } from '../checklist-field-group.interface
import { ChecklistFieldInterface } from '../checklist-field.interface';
import { WebinAuthenticationService } from '../webin-authentication.service';
import { WebinReportService } from '../webin-report.service';
import { ActivatedRoute } from '@angular/router';
interface BooleanFieldInterface {
[key: string]: boolean;
......@@ -32,9 +33,9 @@ interface BooleanFieldInterface {
styleUrls: ['./checklist.component.css'],
encapsulation: ViewEncapsulation.None
})
export class ChecklistComponent {
@Input() checklistType: ChecklistType = ChecklistType.sample;