diff --git a/karma.globals.js b/karma.globals.js index f2903c3..11251d5 100644 --- a/karma.globals.js +++ b/karma.globals.js @@ -2,4 +2,5 @@ var ENV = { production: 'false', api: 'apiRoot', irbUrl: 'irbUrl', + homeRoute: 'home', }; diff --git a/package-lock.json b/package-lock.json index 2854c01..d9d7249 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12291,9 +12291,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sartography-workflow-lib": { - "version": "0.0.167", - "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.167.tgz", - "integrity": "sha512-Ju6VehVOj6yjAYOTEN2PtFbWUXB6LTldaf5GO8iW2lx20Z+TGnrK0Lvgh1hv3/F+7yUqpcZjJvO+ppYahpURRA==" + "version": "0.0.170", + "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.170.tgz", + "integrity": "sha512-bLj7scU+z2lafzPmbpAAqLoGJZX0e2t1PZq5C4sqWIU/vuq3xf5dQGFL7nOyWpfxGchxWjszi1+9LqC2PhSJtw==" }, "sass": { "version": "1.23.3", diff --git a/package.json b/package.json index 7e1abb2..3c161b1 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "ngx-file-drop": "^8.0.8", "ngx-markdown": "^9.0.0", "rxjs": "~6.5.4", - "sartography-workflow-lib": "^0.0.167", + "sartography-workflow-lib": "^0.0.170", "tslib": "^1.11.1", "uuid": "^7.0.2", "zone.js": "^0.10.3" diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index a2848ec..c39c157 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -4,6 +4,8 @@ import {SessionRedirectComponent} from 'sartography-workflow-lib'; import {environment} from '../environments/environment.runtime'; import {HomeComponent} from './home/home.component'; import {ModelerComponent} from './modeler/modeler.component'; +import {ProtocolBuilderComponent} from './protocol-builder/protocol-builder.component'; +import {ReferenceFilesComponent} from './reference-files/reference-files.component'; import {SignInComponent} from './sign-in/sign-in.component'; import {SignOutComponent} from './sign-out/sign-out.component'; @@ -18,6 +20,14 @@ const routes: Routes = [ path: 'home', component: HomeComponent }, + { + path: 'pb', + component: ProtocolBuilderComponent + }, + { + path: 'reffiles', + component: ReferenceFilesComponent + }, { path: 'modeler/:workflowSpecId', component: ModelerComponent diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c70a131..aaeeb30 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -49,6 +49,8 @@ import {SignInComponent} from './sign-in/sign-in.component'; import {SignOutComponent} from './sign-out/sign-out.component'; import {WorkflowSpecCardComponent} from './workflow-spec-card/workflow-spec-card.component'; import {WorkflowSpecListComponent} from './workflow-spec-list/workflow-spec-list.component'; +import { ProtocolBuilderComponent } from './protocol-builder/protocol-builder.component'; +import { ReferenceFilesComponent } from './reference-files/reference-files.component'; @Injectable() export class ThisEnvironment implements AppEnvironment { @@ -81,6 +83,8 @@ export class ThisEnvironment implements AppEnvironment { HomeComponent, WorkflowSpecCardComponent, ApiErrorsComponent, + ProtocolBuilderComponent, + ReferenceFilesComponent, ], imports: [ BrowserAnimationsModule, diff --git a/src/app/navbar/navbar.component.ts b/src/app/navbar/navbar.component.ts index d91f047..20afb95 100644 --- a/src/app/navbar/navbar.component.ts +++ b/src/app/navbar/navbar.component.ts @@ -47,8 +47,9 @@ export class NavbarComponent { private _loadNavLinks() { const displayName = this.user.display_name || this.user.first_name || this.user.last_name; this.navLinks = [ - {path: '/', id: 'nav_home', label: 'Home'}, - {path: '/inbox', id: 'nav_inbox', label: 'Inbox'}, + {path: '/home', id: 'nav_home', label: 'Configurator'}, + {path: '/pb', id: 'nav_pb', label: 'Protocol Builder Tester'}, + {path: '/reffiles', id: 'nav_reffiles', label: 'Reference Files'}, {path: '/help', id: 'nav_help', label: 'Help'}, { id: 'nav_account', label: `${displayName} (${this.user.email_address})`, diff --git a/src/app/protocol-builder/protocol-builder.component.html b/src/app/protocol-builder/protocol-builder.component.html new file mode 100644 index 0000000..8887424 --- /dev/null +++ b/src/app/protocol-builder/protocol-builder.component.html @@ -0,0 +1,4 @@ +
+

Protocol Builder Tester

+

(Coming soon)

+
diff --git a/src/app/protocol-builder/protocol-builder.component.scss b/src/app/protocol-builder/protocol-builder.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/protocol-builder/protocol-builder.component.spec.ts b/src/app/protocol-builder/protocol-builder.component.spec.ts new file mode 100644 index 0000000..18c570b --- /dev/null +++ b/src/app/protocol-builder/protocol-builder.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProtocolBuilderComponent } from './protocol-builder.component'; + +describe('ProtocolBuilderComponentComponent', () => { + let component: ProtocolBuilderComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ProtocolBuilderComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProtocolBuilderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/protocol-builder/protocol-builder.component.ts b/src/app/protocol-builder/protocol-builder.component.ts new file mode 100644 index 0000000..770a186 --- /dev/null +++ b/src/app/protocol-builder/protocol-builder.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-protocol-builder', + templateUrl: './protocol-builder.component.html', + styleUrls: ['./protocol-builder.component.scss'] +}) +export class ProtocolBuilderComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/reference-files/reference-files.component.html b/src/app/reference-files/reference-files.component.html new file mode 100644 index 0000000..1fd2583 --- /dev/null +++ b/src/app/reference-files/reference-files.component.html @@ -0,0 +1,12 @@ +
+

Reference Files

+ +
+

{{refFile.name}}

+
+ + +
+
+
+ diff --git a/src/app/reference-files/reference-files.component.scss b/src/app/reference-files/reference-files.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/reference-files/reference-files.component.spec.ts b/src/app/reference-files/reference-files.component.spec.ts new file mode 100644 index 0000000..086f86e --- /dev/null +++ b/src/app/reference-files/reference-files.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ReferenceFilesComponent } from './reference-files.component'; + +describe('ReferenceFilesComponent', () => { + let component: ReferenceFilesComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ReferenceFilesComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ReferenceFilesComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/reference-files/reference-files.component.ts b/src/app/reference-files/reference-files.component.ts new file mode 100644 index 0000000..5304b38 --- /dev/null +++ b/src/app/reference-files/reference-files.component.ts @@ -0,0 +1,63 @@ +import {Component, OnInit} from '@angular/core'; +import {MatDialog} from '@angular/material/dialog'; +import {MatSnackBar} from '@angular/material/snack-bar'; +import * as fileSaver from 'file-saver'; +import {ApiService, FileMeta, FileType} from 'sartography-workflow-lib'; +import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component'; +import {OpenFileDialogData} from '../_interfaces/dialog-data'; + +@Component({ + selector: 'app-reference-files', + templateUrl: './reference-files.component.html', + styleUrls: ['./reference-files.component.scss'] +}) +export class ReferenceFilesComponent implements OnInit { + referenceFiles: FileMeta[]; + + constructor( + private apiService: ApiService, + public dialog: MatDialog, + private snackBar: MatSnackBar, + ) { + this._loadReferenceFiles(); + } + + ngOnInit(): void { + } + + _loadReferenceFiles() { + this.apiService.listReferenceFiles().subscribe(f => this.referenceFiles = f); + } + + openFileDialog(fm: FileMeta) { + this.apiService.getReferenceFile(fm.name).subscribe(oldFile => { + const dialogData: OpenFileDialogData = { + fileMetaId: fm.id, + file: new File([oldFile.body], fm.name, { + type: fm.content_type, + lastModified: parseInt(oldFile.headers.get('last-modified'), 10) + }), + mode: 'local', + fileTypes: [FileType.XLSX, FileType.XLS], + }; + const dialogRef = this.dialog.open(OpenFileDialogComponent, {data: dialogData}); + + dialogRef.afterClosed().subscribe((data: OpenFileDialogData) => { + if (data && data.file) { + console.log('data', data); + this.apiService.updateReferenceFile(fm.name, data.file).subscribe(() => { + this._loadReferenceFiles(); + }); + } + }); + + }); + } + + downloadFile(fm: FileMeta) { + this.apiService.getReferenceFile(fm.name).subscribe(response => { + const blob = new Blob([response.body], {type: fm.content_type}); + fileSaver.saveAs(blob, fm.name); + }); + } +} diff --git a/src/environments/environment.runtime.ts b/src/environments/environment.runtime.ts index 9166476..17a3a9f 100644 --- a/src/environments/environment.runtime.ts +++ b/src/environments/environment.runtime.ts @@ -2,14 +2,11 @@ import {AppEnvironment} from 'sartography-workflow-lib'; declare var ENV; -const envHas = (key, temp): boolean => (ENV && (ENV[key] !== null) && (ENV[key] !== undefined) && (ENV[key] !== temp)); +export const _has = (env, key, temp): boolean => env && ![null, undefined, temp, ''].includes(env[key]); export const environment: AppEnvironment = { - homeRoute: envHas('homeRoute', '$HOME_ROUTE') ? ENV.homeRoute : 'home', - production: envHas('production', '$PRODUCTION') ? (ENV.production === 'true') : false, - api: envHas('api', '$API_URL') ? ENV.api : 'http://localhost:5000/v1.0', - irbUrl: envHas('irbUrl', '$IRB_URL') ? ENV.irbUrl : 'http://localhost:5001', + homeRoute: _has(ENV, 'homeRoute', '$HOME_ROUTE') ? ENV.homeRoute : 'home', + production: _has(ENV, 'production', '$PRODUCTION') ? (ENV.production === 'true') : false, + api: _has(ENV, 'api', '$API_URL') ? ENV.api : 'http://localhost:5000/v1.0', + irbUrl: _has(ENV, 'irbUrl', '$IRB_URL') ? ENV.irbUrl : 'http://localhost:5001', }; - - - diff --git a/src/environments/environment.spec.ts b/src/environments/environment.spec.ts index 0741512..5d59b5b 100644 --- a/src/environments/environment.spec.ts +++ b/src/environments/environment.spec.ts @@ -1,5 +1,6 @@ -import {environment} from './environment.runtime'; +import {_has, environment} from './environment.runtime'; +declare var ENV; describe('Environments', () => { it('should have settings for all the environments', () => { @@ -7,5 +8,40 @@ describe('Environments', () => { expect(environment.production).toEqual(false); expect(environment.api).toEqual('apiRoot'); expect(environment.irbUrl).toEqual('irbUrl'); + expect(environment.homeRoute).toEqual('home'); + }); + + it('should check if environment variables are defined', () => { + const env = { + homeRoute: '$HOME_ROUTE', + production: '$PRODUCTION', + api: '$API_URL', + irbUrl: '$IRB_URL', + }; + + expect(_has(env, 'homeRoute', '$HOME_ROUTE')).toBeFalse(); + expect(_has(env, 'production', '$PRODUCTION')).toBeFalse(); + expect(_has(env, 'api', '$API_URL')).toBeFalse(); + expect(_has(env, 'irbUrl', '$IRB_URL')).toBeFalse(); + + env.homeRoute = undefined; + env.production = undefined; + env.api = undefined; + env.irbUrl = undefined; + + expect(_has(env, 'homeRoute', '$HOME_ROUTE')).toBeFalse(); + expect(_has(env, 'production', '$PRODUCTION')).toBeFalse(); + expect(_has(env, 'api', '$API_URL')).toBeFalse(); + expect(_has(env, 'irbUrl', '$IRB_URL')).toBeFalse(); + + env.homeRoute = 'something'; + env.production = 'something'; + env.api = 'something'; + env.irbUrl = 'something'; + + expect(_has(env, 'homeRoute', '$HOME_ROUTE')).toBeTrue(); + expect(_has(env, 'production', '$PRODUCTION')).toBeTrue(); + expect(_has(env, 'api', '$API_URL')).toBeTrue(); + expect(_has(env, 'irbUrl', '$IRB_URL')).toBeTrue(); }); });