Fix bugs affecting docker/prod build and tests.

This commit is contained in:
Laura Glendenning
2020-11-04 13:40:44 -05:00
parent b77919c399
commit a939fb406e
22 changed files with 4 additions and 509 deletions

View File

@@ -71,9 +71,6 @@ import { AddCollectionComponent } from "./component/add-collection/add-collectio
import { CollectionDetailsComponent, AddLabelDialog, AddViewerDialog, AddAnnotatorDialog} from "./component/collection-details/collection-details.component";
import { AddDocumentComponent } from "./component/add-document/add-document.component";
import { ViewCollectionsComponent } from "./component/view-collections/view-collections.component";
import { NavMyCollectionsComponent } from "./component/nav-my-collections/nav-my-collections.component";
import { NavCollectionMenuComponent } from "./component/nav-collection-menu/nav-collection-menu.component";
import { NavigationComponent } from "./component/navigation/navigation.component";
import { UserChooserComponent } from "./component/user-chooser/user-chooser.component";
import { LabelChooserComponent } from "./component/label-chooser/label-chooser.component";
import { AdminComponent } from "./component/admin/admin.component";
@@ -102,7 +99,6 @@ import { ImageCollectionUploaderComponent, ImageCollectionUploaderDialog } from
import { StatusBarComponent } from './component/status-bar/status-bar.component';
import { StatusBarService } from "./service/status-bar/status-bar.service";
import { AboutComponent } from './component/about/about.component';
import { ToolbarComponent } from './component/toolbar';
import { ToolbarNavComponent } from './component/toolbar/toolbar-nav/toolbar-nav.component';
import { ToolbarNavButtonComponent } from './component/toolbar/toolbar-nav-button/toolbar-nav-button.component';
import { UserCardComponent } from './component/user-card/user-card.component';
@@ -119,9 +115,6 @@ export function initializeApp(appConfig: AppConfig) {
CollectionDetailsComponent,
AddDocumentComponent,
ViewCollectionsComponent,
NavMyCollectionsComponent,
NavCollectionMenuComponent,
NavigationComponent,
UserChooserComponent,
LabelChooserComponent,
AdminComponent,
@@ -153,7 +146,6 @@ export function initializeApp(appConfig: AppConfig) {
ImageCollectionUploaderDialog,
StatusBarComponent,
AboutComponent,
ToolbarComponent,
ToolbarNavComponent,
ToolbarNavButtonComponent,
UserCardComponent

View File

@@ -1,16 +1,14 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { Component, OnInit, ViewChild, AfterViewInit, Inject } from "@angular/core";
import { Component, OnInit, ViewChild, Inject } from "@angular/core";
import { MatPaginator, MatTableDataSource, MatSort, MatDialog, MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
import { ActivatedRoute, Router } from "@angular/router";
import { HttpErrorResponse } from "@angular/common/http";
import * as _ from "lodash";
import * as moment from "moment";
import { take } from "rxjs/operators";
import { PATHS, PARAMS } from "../../app.paths";
import { AnnotationService } from "../../service/annotation/annotation.service";
import { AuthService } from "../../service/auth/auth.service";
import { BackendService } from "../../service/backend/backend.service"
import { CollectionRepositoryService } from "../../service/collection-repository/collection-repository.service";
@@ -19,13 +17,10 @@ import { EventService } from "../../service/event/event.service";
import { PipelineService } from "../../service/pipeline/pipeline.service";
import { MetricsService } from "../../service/metrics/metrics.service";
import { Annotation } from "../../model/annotation";
import { Document } from "../../model/document";
import { Classifier } from "../../model/classifier";
import { Collection, DownloadCollectionData, METADATA_TITLE } from "../../model/collection";
import { Pipeline } from "../../model/pipeline";
import { DocumentMenuItem } from "../nav-collection-menu/nav-collection-menu.component";
import { Metric } from "../../model/metrics";
import { IaaReportingService } from '../../service/iaa-reporting/iaa-reporting.service';
import { IAAReport } from '../../model/iaareport';
import { DownloadCollectionDataDialogComponent } from '../download-collection-data.dialog/download-collection-data.dialog.component';
@@ -93,7 +88,6 @@ export class CollectionDetailsComponent implements OnInit {
constructor(private router: Router,
private route: ActivatedRoute,
private annotationService: AnnotationService,
private collectionService: CollectionRepositoryService,
private documentsService: DocumentRepositoryService,
private pipelineService: PipelineService,

View File

@@ -1,13 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
.loading {
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
}
.annotated-icon {
vertical-align: middle;
margin-right: 5px;
}

View File

@@ -1,24 +0,0 @@
<!-- (C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC.-->
<button mat-menu-item [matMenuTriggerFor]="documentMenu">
{{ collection_title }}
</button>
<mat-menu #documentMenu="matMenu">
<ng-template matMenuContent>
<button mat-menu-item [routerLink]="['/' + PATHS.collection.details, collection_id]">
Collection Details
</button>
<button mat-menu-item [routerLink]="['/' + PATHS.document.add, collection_id]">
Add Document
</button>
<mat-divider></mat-divider>
<div *ngIf="loading" class="loading"><mat-spinner></mat-spinner></div>
<button mat-menu-item *ngFor="let doc of documents" [routerLink]="['/' + PATHS.document.annotate, doc.id]" style="align-items: center; justify-content: space-between">
<!--<div [ngStyle]="{'color':doc.has_annotations ? 'green' : 'red'}" >{{ doc.text_start }}</div>-->
<div>
<span *ngIf="doc.has_annotations" class="material-icons annotated-icon" style="color: green">done</span>
<span *ngIf="!doc.has_annotations" class="material-icons annotated-icon" style="color: red">clear</span>
<span>{{ doc.text_start }}</span>
</div>
</button>
</ng-template>
</mat-menu>

View File

@@ -1,27 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavCollectionMenuComponent } from './nav-collection-menu.component';
describe('NavCollectionMenuComponent', () => {
let component: NavCollectionMenuComponent;
let fixture: ComponentFixture<NavCollectionMenuComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NavCollectionMenuComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavCollectionMenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,95 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { Component, OnInit, Input, OnDestroy } from "@angular/core";
import * as _ from "lodash";
import { Observable, Subscription, of } from 'rxjs';
import { filter, map, tap, take } from 'rxjs/operators';
import { PATHS } from "../../app.paths";
import { DocumentRepositoryService } from "../../service/document-repository/document-repository.service";
import { Document } from "../../model/document";
import { AnnotatedService } from 'src/app/service/annotated/annotated.service';
import { AuthService } from 'src/app/service/auth/auth.service';
export interface DocumentMenuItem {
id: string;
text_start: string;
has_annotations: boolean
};
@Component({
selector: "app-nav-collection-menu",
templateUrl: "./nav-collection-menu.component.html",
styleUrls: ["./nav-collection-menu.component.css"]
})
export class NavCollectionMenuComponent implements OnInit, OnDestroy {
@Input() public collection_title: string;
@Input() public collection_id: string;
public readonly PATHS = PATHS;
public loading = true;
private _documents: DocumentMenuItem[];
private annotationChangesSubscription : Subscription;
constructor(private documentService: DocumentRepositoryService,
private annotatedService: AnnotatedService,
private auth :AuthService) { }
ngOnInit() {
this.listenForAnnotationChanges();
}
listenForAnnotationChanges() {
this.annotationChangesSubscription = this.annotatedService.documentAnnotated.pipe(
filter((newAnnotation:any)=> newAnnotation.collection_id == this.collection_id))
.subscribe((newAnnotation)=> {
this.documents$.pipe(take(1)).subscribe((documents: DocumentMenuItem[]) => {
documents.find(doc => doc.id == newAnnotation.doc_id).has_annotations = true;
});
});
}
public get documents(): DocumentMenuItem[] {
if(this._documents === undefined) {
this.reloadAsync();
}
return this._documents;
}
public get documents$(): Observable<DocumentMenuItem[]> {
if(this._documents !== undefined) {
return of(this._documents);
} else {
return this.reload();
}
}
public reloadAsync() {
this.reload().pipe(take(1)).subscribe();
}
public reload(): Observable<DocumentMenuItem[]> {
this.loading = true;
return this.documentService.getDocumentsByCollectionID(this.collection_id, true).pipe(
map((documents: Document[]) => documents.map(doc => <DocumentMenuItem>{
id: doc._id,
text_start: doc.getTextPreview(),
has_annotations: doc.has_annotated ? doc.has_annotated[this.auth.loggedInUser.id] : undefined
})),
tap((documents: DocumentMenuItem[]) => {
this._documents = documents;
this.loading = false;
}));
}
ngOnDestroy(){
this.annotationChangesSubscription.unsubscribe();
}
}

View File

@@ -1,8 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
.loading {
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
}

View File

@@ -1,11 +0,0 @@
<!-- (C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC.-->
<div *ngIf="loading" class="loading">
<mat-spinner></mat-spinner>
</div>
<ng-container *ngIf="!loading">
<app-nav-collection-menu *ngFor="let collection of collections"
[collection_title]="collection.title"
[collection_id]="collection.id">
</app-nav-collection-menu>
</ng-container>

View File

@@ -1,27 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavMyCollectionsComponent } from './nav-my-collections.component';
describe('NavMyCollectionsComponent', () => {
let component: NavMyCollectionsComponent;
let fixture: ComponentFixture<NavMyCollectionsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NavMyCollectionsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavMyCollectionsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,74 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { Component, OnInit, ViewChildren, QueryList } from "@angular/core";
import { Observable } from "rxjs";
import { map, toArray, tap, take } from "rxjs/operators";
import { NavCollectionMenuComponent } from "../nav-collection-menu/nav-collection-menu.component";
import { CollectionRepositoryService } from "../../service/collection-repository/collection-repository.service";
import { EventService, AddedDocumentIds } from "../../service/event/event.service";
import { Collection } from "../../model/collection";
export interface CollectionData {
id: string;
title: string;
}
@Component({
selector: "app-nav-my-collections",
templateUrl: "./nav-my-collections.component.html",
styleUrls: ["./nav-my-collections.component.css"]
})
export class NavMyCollectionsComponent implements OnInit {
public loading = true;
public collections: CollectionData[];
@ViewChildren(NavCollectionMenuComponent)
public menus: QueryList<NavCollectionMenuComponent>;
constructor(private collectionsService: CollectionRepositoryService,
private event: EventService) { }
ngOnInit() {
this.refreshCollectionsAsync();
this.event.collectionAddedOrArchived.subscribe((_: Collection) => {
this.refreshCollectionsAsync();
});
this.event.systemDataImported.subscribe(() => {
this.refreshCollectionsAsync();
});
this.event.documentAddedById.subscribe((ids: AddedDocumentIds) => {
this.refreshCollectionAsync(ids.collectionId);
});
}
private refreshCollectionsAsync() {
this.loading = true;
this.refreshCollections$().pipe(take(1)).subscribe(() => this.loading = false);
}
private refreshCollections$(): Observable<CollectionData[]> {
return this.collectionsService.getMyUnarchivedCollectionsPaginated().pipe(
map((collection: Collection) => <CollectionData>{
id: collection._id,
title: collection.getTitleOrId()
}),
toArray(),
tap((collections: CollectionData[]) => this.collections = collections)
);
}
private refreshCollectionAsync(collectionId: string) {
this.refreshCollection$(collectionId).pipe(take(1)).subscribe();
}
private refreshCollection$(collectionId: string): Observable<void> {
return this.menus.find((_, index) => this.collections[index].id === collectionId)
.reload().pipe(map(() => undefined));
}
}

View File

@@ -1,2 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */

View File

@@ -1,43 +0,0 @@
<!-- (C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC.-->
<mat-nav-list id="nav-list">
<mat-list-item (click)="isExpanded = !isExpanded">
<button mat-icon-button>
<span class="material-icons">{{ isExpanded ? "chevron_left" : "menu" }}</span>
</button>
</mat-list-item>
<mat-list-item [routerLink]="[appConfig.landingPage]">
<span class="material-icons" mat-list-icon>home</span>
<p matLine *ngIf="isExpanded">Home</p>
</mat-list-item>
<mat-list-item [matMenuTriggerFor]="myCollections" dir="right" id="pineNavMyCollections">
<span class="material-icons" mat-list-icon>library_books</span>
<p matLine *ngIf="isExpanded">My Collections</p>
<p><span class="material-icons" style="margin-top: 6px">chevron_right</span></p>
</mat-list-item>
<!-- https://github.com/angular/components/issues/14621 -->
<mat-menu id="myCollectionsMenu" #myCollections="matMenu" xPosition="after" overlapTrigger="false" direction="right">
<button id="pineNavViewAllCollections" mat-menu-item [routerLink]="['/' + PATHS.collection.view]">View All Collections</button>
<mat-divider></mat-divider>
<app-nav-my-collections></app-nav-my-collections>
</mat-menu>
<mat-list-item [routerLink]="['/' + PATHS.collection.add]">
<span class="material-icons" mat-list-icon>library_add</span>
<p matLine *ngIf="isExpanded">Add Collection</p>
</mat-list-item>
<mat-list-item *ngIf="userIsAdmin()" [routerLink]="['/' + PATHS.admin.dashboard]">
<span class="material-icons" mat-list-icon>whatshot</span>
<p matLine *ngIf="isExpanded">Admin Dashboard</p>
</mat-list-item>
<mat-list-item *ngIf="authService.canManageUsers" [routerLink]="['/' + PATHS.user.account]">
<span class="material-icons" mat-list-icon>account_circle</span>
<p matLine *ngIf="isExpanded">Manage Account</p>
</mat-list-item>
<mat-list-item (click)="doAbout()">
<span class="material-icons" mat-list-icon>help</span>
<p matLine *ngIf="isExpanded">About</p>
</mat-list-item>
<mat-list-item (click)="doLogout()" id="pineNavLogout">
<span class="material-icons" mat-list-icon>exit_to_app</span>
<p matLine *ngIf="isExpanded">Logout</p>
</mat-list-item>
</mat-nav-list>

View File

@@ -1,27 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavigationComponent } from './navigation.component';
describe('NavigationComponent', () => {
let component: NavigationComponent;
let fixture: ComponentFixture<NavigationComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NavigationComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavigationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,45 +0,0 @@
/*(C) 2019 The Johns Hopkins University Applied Physics Laboratory LLC. */
import { Component, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material";
import { PATHS } from "../../app.paths";
import { AppConfig } from "../../app.config";
import { AuthService } from "../../service/auth/auth.service";
import { EventService } from "../../service/event/event.service";
import { show } from "../about/about.component";
@Component({
selector: "app-navigation",
templateUrl: "./navigation.component.html",
styleUrls: ["./navigation.component.css"]
})
export class NavigationComponent implements OnInit {
public readonly PATHS = PATHS;
public isExpanded = true;
constructor(public appConfig: AppConfig,
public authService: AuthService,
private events: EventService,
private dialog: MatDialog) { }
ngOnInit() {
}
public doAbout() {
show(this.dialog);
}
public doLogout() {
this.events.logout.emit(null);
}
public userIsAdmin() {
return this.authService.loggedInUser.is_admin;
}
}

View File

@@ -1 +0,0 @@
export * from './toolbar/toolbar.component';

View File

@@ -1,5 +1,5 @@
<ng-container>
<app-toolbar-nav-button class="doc-collections-btn" [icon]="eco" link="/collection">Document Collections</app-toolbar-nav-button>
<app-toolbar-nav-button class="doc-collections-btn" link="/collection">Document Collections</app-toolbar-nav-button>
<button class="info-btn" mat-icon-button matTooltip="About" (click)="doAbout()">
<mat-icon>info</mat-icon>
</button>

View File

@@ -1,23 +0,0 @@
<mat-toolbar class="app-toolbar" color="primary" fxFlex="nogrow" fxLayout="row">
<div></div>
<div fxLayout="row" style="cursor: pointer" [routerLink]=" ['/home'] " routerLinkActive="active">
<img class="logo-img" src="assets/PMAP_data_catalog_logo_crop@4x.png" alt="PMAP Data Catalog Logo"/>
<h1>{{title}}</h1>
</div>
<ng-container *ngIf="user">
<app-toolbar-nav></app-toolbar-nav>
<span fxFlex></span>
<button mat-flat-button color="primary" [matMenuTriggerFor]="userMenu" aria-label="User Profile">
<mat-icon class="account-icon">account_circle</mat-icon>
<span id="toolbar-user-name">{{user.details.givenName}} {{user.details.sn}}</span>
<mat-icon>keyboard_arrow_down</mat-icon>
</button>
<mat-menu #userMenu="matMenu" yPosition="below" overlapTrigger="false">
<!-- <app-user-card></app-user-card> -->
</mat-menu>
</ng-container>
</mat-toolbar>

View File

@@ -1,21 +0,0 @@
.app-toolbar {
padding-right: 4px;
}
.app-icon {
margin-right: 10px;
}
app-toolbar-nav {
margin-left: 24px;
}
.account-icon {
margin-right: 4px;
}
.logo-img {
height: 36px;
margin-right: 12px;
margin-top: -4px;
}

View File

@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ToolbarComponent } from './toolbar.component';
describe('ToolbarComponent', () => {
let component: ToolbarComponent;
let fixture: ComponentFixture<ToolbarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ToolbarComponent ]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ToolbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,27 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/service/auth/auth.service';
@Component({
selector: 'app-toolbar',
templateUrl: './toolbar.component.html',
styleUrls: ['./toolbar.component.scss']
})
export class ToolbarComponent implements OnInit {
title = "PMAP Data Catalog"
//user: AuthUser;
//faBookOpen = faBookOpen;
constructor(private authService: AuthService) { }
ngOnInit() {
/* this.authService.currentUser$.subscribe((user) =>{
this.user = user;
}); */
}
logout(): void {
this.authService.logout();
}
}

View File

@@ -32,6 +32,7 @@ else
docker run -it \
--name pine-cypress \
--network nlp_webapp_default \
--ipc=host \
--env AUTH_MODULE="${AUTH_MODULE}" \
--env CYPRESS_BASE_URL="https://frontend_annotation" \
--env CYPRESS_API_URL="https://frontend_annotation/api" \

View File

@@ -86,7 +86,7 @@ describe("Sanity Tests", function() {
.find("#content")
.should("be.visible")
.within(() => {
cy.contains("PINE")
cy.contains("PINE", {timeout: 20 * 1000})
.should("be.visible", {timeout: 20 * 1000});
cy.contains("database")
.should("be.visible");