diff --git a/.travis.yml b/.travis.yml index 94f1375..1c52ec4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ env: - API_URL=http://localhost:5000/v1.0 - BASE_HREF=/ - HOME_ROUTE=home - - IRB_URL=http://localhost:5001 + - IRB_URL=http://localhost:5001/ - PORT0=4200 - PRODUCTION=false script: diff --git a/Dockerfile b/Dockerfile index 2b988f3..1cedae5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ADD package-lock.json /crc-bpmn/ COPY . /crc-bpmn/ -ARG build_config=staging +ARG build_config=prod RUN npm install && \ npm run build:$build_config @@ -17,18 +17,21 @@ RUN npm install && \ FROM nginx:alpine RUN set -x && apk add --update --no-cache bash libintl gettext curl -COPY --from=builder /crc-bpmn/dist/* /usr/share/nginx/html/ +COPY --from=builder /crc-bpmn/dist/* /etc/nginx/html/ COPY --from=builder /crc-bpmn/nginx.conf /etc/nginx/conf.d/default.conf # Script for substituting environment variables COPY ./docker/substitute-env-variables.sh ./entrypoint.sh RUN chmod +x ./entrypoint.sh -# Substitute environment variables in nginx configuration and index.html -ENTRYPOINT ["./entrypoint.sh", \ - "/usr/share/nginx/html/index.html,/etc/nginx/conf.d/default.conf", \ - "PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,PORT0", \ - "/usr/share/nginx/html/index.html"] +# Fix for Angular routing +RUN echo "pushstate: enabled" > /etc/nginx/html/Staticfile -### STAGE 3: Profit! ### -CMD ["nginx", "-g", "daemon off;"] +# The entrypoint.sh script will run after the container finishes starting. +# Substitutes environment variables in nginx configuration and index.html, +# then starts/reloads nginx. +ENTRYPOINT ["./entrypoint.sh", \ + "/etc/nginx/html/index.html,/etc/nginx/conf.d/default.conf", \ + "PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,DEPLOY_URL,PORT0", \ + "/etc/nginx/html", \ + "true"] diff --git a/angular.json b/angular.json index 082b463..fe6bfe6 100644 --- a/angular.json +++ b/angular.json @@ -190,5 +190,8 @@ "@schematics/angular:component": { "style": "scss" } + }, + "cli": { + "analytics": false } -} +} \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e832bc4..4fb688f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,58 +2,68 @@ version: "3.3" services: db: container_name: db - image: sartography/cr-connect-db:$E2E_TAG + image: sartography/cr-connect-db:dev ports: - "5432:5432" environment: - - POSTGRES_USER=crc_user - - POSTGRES_PASSWORD=crc_pass - - POSTGRES_MULTIPLE_DATABASES=crc_test,crc_dev,pb_test,pb + - POSTGRES_USER=rrt_user + - POSTGRES_PASSWORD=rrt_pass + - POSTGRES_MULTIPLE_DATABASES=rrt healthcheck: test: ["CMD", "pg_isready"] timeout: 20s retries: 10 - pb: - container_name: pb - depends_on: - - db - image: sartography/protocol-builder-mock:$E2E_TAG - environment: - - FLASK_APP=/protocol-builder-mock/app.py - - UPGRADE_DB=true - - DB_HOST=db - - DB_PORT=5432 - - DB_PASSWORD=crc_pass - - DB_USER=crc_user - - DB_NAME=pb_test - ports: - - "5001:5001" - command: ./wait-for-it.sh db:5432 -t 0 -- ./docker_run.sh - - ldap: - container_name: ldap - image: tuxmonteiro/ldap-mock - ports: - - "3890" backend: container_name: backend depends_on: - db - - pb - - ldap - image: sartography/cr-connect-workflow:$E2E_TAG + image: sartography/cr-connect-workflow:dev environment: - - FLASK_APP=./crc/__init__.py - - UPGRADE_DB=true - - RESET_DB=true - - LDAP_URL=ldap - - PB_BASE_URL=http://pb:5001/pb/ + - APPLICATION_ROOT=/api + - CORS_ALLOW_ORIGINS=localhost:5002,bpmn:5002,localhost:4200,frontend:4200 - DB_HOST=db + - DB_NAME=rrt + - DB_PASSWORD=rrt_pass - DB_PORT=5432 - - DB_PASSWORD=crc_pass - - DB_USER=crc_user - - DB_NAME=crc_test + - DB_USER=rrt_user + - LDAP_URL=ldap.virginia.edu + - PB_ENABLED=false + - PORT0=5000 + - RESET_DB=true + - UPGRADE_DB=true ports: - "5000:5000" - command: ./wait-for-it.sh pb:5001 -t 0 -- ./docker_run.sh + command: ./wait-for-it.sh db:5432 -t 0 -- ./docker_run.sh + + bpmn: + container_name: bpmn + depends_on: + - db + - backend + image: sartography/cr-connect-bpmn:dev + environment: + - API_URL=http://localhost:5000/api/v1.0 + - BASE_HREF=/bpmn/ + - DEPLOY_URL=/bpmn/ + - HOME_ROUTE=home + - PORT0=5002 + - PRODUCTION=false + ports: + - "5002:5002" + + frontend: + container_name: frontend + depends_on: + - db + - backend + image: sartography/cr-connect-frontend:dev + environment: + - API_URL=http://localhost:5000/api/v1.0 + - BASE_HREF=/app/ + - DEPLOY_URL=/app/ + - HOME_ROUTE=home + - PORT0=4200 + - PRODUCTION=false + ports: + - "4200:4200" diff --git a/docker/substitute-env-variables.sh b/docker/substitute-env-variables.sh index 6dd40f5..05f1924 100755 --- a/docker/substitute-env-variables.sh +++ b/docker/substitute-env-variables.sh @@ -5,33 +5,92 @@ # Parameters: # $1: Comma-delimited list of file paths # $2: Comma-delimited list of environment variables -# $3: File path to index.html (optional) +# $3: Absolute path to nginx html directory (optional) +# $4: Should restart nginx (optional) ##################################################################### echo 'Substituting environment variables...' +num_args=0 # The first parameter is a comma-delimited list of paths to files which should be substituted if [[ -z $1 ]]; then echo 'ERROR: No target files given.' exit 1 +else + num_args=1 fi # The second parameter is a comma-delimited list of environment variable names if [[ -z $2 ]]; then echo 'ERROR: No environment variables given.' exit 1 +else + num_args=2 +fi + +# The third parameter is the absolute path to the nginx html directory +if [[ -z $3 ]]; then + echo '' # It's optional. Don't print anything. +else + num_args=3 +fi + +# The fourth parameter, if 'true', is whether we should reload nginx +if [[ -z $4 ]]; then + echo '' # It's optional. Don't print anything. +else + num_args=4 +fi + +# Find & replace BASE_HREF in all files in the nginx html directory +if [[ "$2" == *"BASE_HREF"* ]] && [[ "$2" == *"DEPLOY_URL"* ]]; then + # Add trailing slash to $BASE_HREF if needed + length=${#BASE_HREF} + last_char=${BASE_HREF:length-1:1} + [[ $last_char != "/" ]] && BASE_HREF="$BASE_HREF/"; : + + # Add trailing slash to $DEPLOY_URL if needed + length=${#DEPLOY_URL} + last_char=${DEPLOY_URL:length-1:1} + [[ $last_char != "/" ]] && DEPLOY_URL="$DEPLOY_URL/"; : + + # The third parameter is the absolute path to the nginx html directory + if [[ $num_args -ge 3 ]]; then + # Replace all instances of __REPLACE_ME_WITH_BASE_HREF__ with $BASE_HREF + find "$3" \( -type d -name .git -prune \) -o -type f -print0 | \ + xargs -0 sed -i 's@__REPLACE_ME_WITH_BASE_HREF__@'"$BASE_HREF"'@g' + + echo 'Replacing base href...' + # Wait a few seconds in case find | sed needs more time + sleep 3 + + # Replace all instances of __REPLACE_ME_WITH_DEPLOY_URL__ with $DEPLOY_URL + find "$3" \( -type d -name .git -prune \) -o -type f -print0 | \ + xargs -0 sed -i 's@__REPLACE_ME_WITH_DEPLOY_URL__@'"$DEPLOY_URL"'@g' + + echo 'Replacing deploy url...' + # Wait a few seconds in case find | sed needs more time + sleep 3 + fi fi # Convert "VAR1,VAR2,VAR3,..." to "\$VAR1 \$VAR2 \$VAR3 ..." env_list="\\\$${2//,/ \\\$}" # "\" and "$" are escaped as "\\" and "\$" for file_path in ${1//,/ } do - echo "replacing $env_list in $file_path" + echo "replacing environment variables in $file_path" # Replace strings in the given file(s) in env_list envsubst "$env_list" < "$file_path" > "$file_path".tmp && mv "$file_path".tmp "$file_path" echo '...' + # Wait a second in case envsubst needs more time + sleep 1 + + # If this is the nginx default.conf file, replace double slashes with single slashes + if [[ $file_path == *"/default.conf"* ]]; then + sed -i -e 's@//@/@g' "$file_path" + fi done echo 'Finished substituting environment variables.' @@ -40,17 +99,25 @@ do echo "$env_var = ${!env_var}" done -# The third parameter is the path to the index.html file -# Rewrite base href in index.html. -# Use @ as a sed delimiter because $BASE_HREF will contain a / character -if [[ -z $3 ]]; then - # Execute all other commands with parameters - exit 0 -else - sed -i -e 's@@@' "$3" - - # Execute all other commands with parameters - exec "${@:4}" +# Reload nginx +if [ $num_args -ge 4 ] && [ "$4" == "true" ]; then + # Check to see if nginx command is available + if hash nginx 2> /dev/null; then + # Check to see if nginx is already running + if [ -e /var/run/nginx.pid ]; then + echo "nginx is currently running. Reloading nginx..." + exec nginx -s reload + echo "nginx reloaded." + else + echo "nginx is not yet running. Starting nginx..." + exec nginx -g 'daemon off;' + echo "nginx started." + fi + else + echo "nginx command not found on this system." + fi fi - +# Execute all other commands with parameters +num_args=$((num_args + 1)) +exec "${@:num_args}" diff --git a/nginx.conf b/nginx.conf index 51982f5..7805bc9 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,11 +1,12 @@ server { listen $PORT0; - location / { - root /usr/share/nginx/html; - index index.html index.htm; - try_files $uri $uri/ /index.html =404; - } + port_in_redirect off; - include /etc/nginx/extra-conf.d/*.conf; + location $BASE_HREF/ { + alias /etc/nginx/html/; + index index.html index.htm; + try_files $uri$args $uri $BASE_HREF/index.html; + } } + diff --git a/package-lock.json b/package-lock.json index f6a5122..e6b4544 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3436,6 +3436,14 @@ "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true }, + "@yellowspot/ng-truncate": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@yellowspot/ng-truncate/-/ng-truncate-1.5.1.tgz", + "integrity": "sha512-tAVlVqz1XGAbL3HKg8i/Sy++iilhvoujNkwE34IsVQ+ndiOJEgSmj8OntrsfrkBL2KlOs6L507nUz4MWzh+G0A==", + "requires": { + "tslib": "^1.9.0" + } + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -12291,9 +12299,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sartography-workflow-lib": { - "version": "0.0.180", - "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.180.tgz", - "integrity": "sha512-d/ePxdkeIX/ZW3Sp5NIkZsitxRxS560PWorOd9RaojyJtMks2EgCwuN0Gs18NkT0Qrvk7fJHKYYV89k0/H0djQ==" + "version": "0.0.213", + "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.213.tgz", + "integrity": "sha512-2y4UQk3zYeY0Xu3wqq3UptORxVN/Dp8MPyr7JMNBjM9XCdoDL+nIyhpOA7pS+VfraoEzbm9m4CQamQ9YSGRu6w==" }, "sass": { "version": "1.23.3", diff --git a/package.json b/package.json index 5ac3f7f..e33ae8c 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ "ng": "ng", "start": "ng serve", "build": "ng build", - "build:prod": "ng build --configuration=production", - "build:staging": "ng build --configuration=staging", + "build:prod": "ng build --configuration=production --prod --base-href=__REPLACE_ME_WITH_BASE_HREF__ --deploy-url=__REPLACE_ME_WITH_DEPLOY_URL__", + "build:staging": "ng build --configuration=staging --prod --base-href=__REPLACE_ME_WITH_BASE_HREF__ --deploy-url=__REPLACE_ME_WITH_DEPLOY_URL__", "build:test": "ng build --configuration=test", "test": "ng test", "test:coverage": "ng test --codeCoverage=true --watch=false --browsers=ChromeHeadless", @@ -21,8 +21,8 @@ "e2e-wf:db-setup": "docker exec -it backend pipenv run flask load-example-data", "e2e-wf:pb-setup": "docker exec -it pb pipenv run flask db upgrade", "e2e-wf": "npm run e2e-wf:stop && npm run e2e-wf:clean && npm run e2e-wf:build && npm run e2e-wf:start && npm run e2e-wf:db-upgrade && npm run e2e-wf:db-setup && npm run e2e-wf:pb-setup", - "env": "chmod +x ./docker/substitute-env-variables.sh && ./docker/substitute-env-variables.sh src/index.html PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,PORT0 src/index.html", - "ci": "npm run lint && npm run test:coverage && npm run env && npm run e2e:with-wf && sonar-scanner" + "env": "chmod +x ./docker/substitute-env-variables.sh && ./docker/substitute-env-variables.sh src/index.html PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,PORT0", + "ci": "npm run lint && npm run test:coverage && sonar-scanner" }, "private": true, "dependencies": { @@ -39,6 +39,7 @@ "@angular/router": "^9.0.7", "@ngx-formly/core": "^5.5.15", "@ngx-formly/material": "^5.5.15", + "@yellowspot/ng-truncate": "^1.5.1", "bpmn-js": "^6.4.2", "bpmn-js-properties-panel": "^0.33.2", "camunda-bpmn-moddle": "^4.4.0", @@ -53,7 +54,7 @@ "ngx-file-drop": "^8.0.8", "ngx-markdown": "^9.0.0", "rxjs": "~6.5.4", - "sartography-workflow-lib": "^0.0.180", + "sartography-workflow-lib": "0.0.213", "tslib": "^1.11.1", "uuid": "^7.0.2", "zone.js": "^0.10.3" diff --git a/src/_config.scss b/src/_config.scss index 6293ca1..cd462d8 100644 --- a/src/_config.scss +++ b/src/_config.scss @@ -1,6 +1,6 @@ // GLOBAL SCSS VARIABLES -$body-font-family: '"franklin-gothic-urw", sans-serif'; -$heading-font-family: '"franklin-gothic-urw-cond", sans-serif'; +$body-font-family: 'franklin-gothic-urw', sans-serif; +$heading-font-family: 'franklin-gothic-urw-cond', sans-serif; // COLOR PALETTE @@ -11,6 +11,11 @@ $brand-gray-tint-2: #DADADA; $brand-gray-tint-3: #F1F1EF; $brand-gray-tint-4: scale-color($brand-gray, $lightness: 90%); $body-color: $brand-gray; +$brand-gray-shade-1: scale-color($brand-gray, $lightness: -20%); +$brand-gray-shade-2: scale-color($brand-gray, $lightness: -40%); +$brand-gray-shade-3: scale-color($brand-gray, $lightness: -60%); +$brand-gray-shade-4: scale-color($brand-gray, $lightness: -80%); +$brand-gray-shade-5: scale-color($brand-gray, $lightness: -100%); $body-color-muted: $brand-gray-tint-1; $body-color-light: $brand-gray-tint-4; $brand-gray-muted: $brand-gray-tint-1; @@ -48,20 +53,13 @@ $brand-accent-light: $brand-accent-tint-4; $brand-warning: #DF1E43; $brand-warning-muted: desaturate(scale-color($brand-warning, $lightness: 30%), 20%); $brand-warning-light: scale-color($brand-warning, $lightness: 90%); -$easeDuration: 300ms; -$animationDuration: 500ms; -$tile-height-1x: 226px; -$tile-height-2x: 288px; -$uva-header-height: 40px; -$site-header-height: 64px; -$search-bar-height-sm: 64px; -$search-bar-height-md: 128px; -$search-bar-height-lg: 64px; -$header-height-sm: ($uva-header-height + $site-header-height + $search-bar-height-sm); -$header-height-md: ($uva-header-height + $site-header-height + $search-bar-height-md); -$header-height-lg: ($uva-header-height + $site-header-height + $search-bar-height-lg); // Green $brand-green: #64B343; $brand-green-muted: #8EC774; $brand-green-light: #B5D9A3; + +// Dimensions +$easeDuration: 300ms; +$animationDuration: 500ms; +$header-height: 84px; diff --git a/src/_material.scss b/src/_material.scss index fc6a68a..1a0c036 100644 --- a/src/_material.scss +++ b/src/_material.scss @@ -4,19 +4,19 @@ // Define a custom typography config that overrides the font-family $custom-typography: mat-typography-config( $font-family: $body-font-family, - $display-4: mat-typography-level(2.500rem, 1.0, 700, $heading-font-family), - $display-3: mat-typography-level(2.250rem, 1.0, 700, $heading-font-family), - $display-2: mat-typography-level(2.000rem, 1.0, 700, $heading-font-family), - $display-1: mat-typography-level(1.750rem, 1.0, 700, $heading-font-family), - $headline: mat-typography-level(48px, 1.0, 700, $heading-font-family), - $title: mat-typography-level(1.500rem, 1.0, 700, $body-font-family), - $subheading-2: mat-typography-level(1.375rem, 1.0, 500, $body-font-family), - $subheading-1: mat-typography-level(1.250rem, 1.0, 500, $body-font-family), - $body-2: mat-typography-level(1.000rem, 1.5, 500, $body-font-family), - $body-1: mat-typography-level(1.000rem, 1.5, 500, $body-font-family), - $caption: mat-typography-level(1.000rem, 1.5, 500, $body-font-family), - $button: mat-typography-level(1.000rem, 1.5, 500, $body-font-family), - $input: mat-typography-level(1.000rem, 1.5, 500, $body-font-family) + $display-4: mat-typography-level(3.75rem, 1.0925, 700, $body-font-family), + $display-3: mat-typography-level(2.4917rem, 1.1037, 700, $body-font-family), + $display-2: mat-typography-level(2.2148rem, 1.1287, 700, $body-font-family), + $display-1: mat-typography-level(1.9688rem, 1.1429, 700, $body-font-family), + $headline: mat-typography-level(1.7500rem, 1.1429, 700, $body-font-family), // h1 + $title: mat-typography-level(1.5625rem, 1.1200, 500, $body-font-family), // h2 + $subheading-2: mat-typography-level(1.3750rem, 1.0000, 700, $heading-font-family), // h3 + $subheading-1: mat-typography-level(1.2500rem, 1.1000, 700, $body-font-family), // h4 + $body-2: mat-typography-level(1.1250rem, 1.1111, 500, $body-font-family), // h5 + $body-1: mat-typography-level(1.0000rem, 1.1250, 500, $body-font-family), // p + $caption: mat-typography-level(0.8750rem, 0.7143, 500, $body-font-family), // small + $button: mat-typography-level(1.0000rem, 1.1250, 500, $body-font-family), + $input: mat-typography-level(1.0000rem, 1.1250, 500, $body-font-family) ); $mat-blue: ( diff --git a/src/app/_dialogs/open-file-dialog/open-file-dialog.component.spec.ts b/src/app/_dialogs/open-file-dialog/open-file-dialog.component.spec.ts index 9ccc7fc..610baa1 100644 --- a/src/app/_dialogs/open-file-dialog/open-file-dialog.component.spec.ts +++ b/src/app/_dialogs/open-file-dialog/open-file-dialog.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; @@ -37,6 +38,7 @@ describe('OpenFileDialogComponent', () => { providers: [ ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, { provide: MatDialogRef, useValue: { diff --git a/src/app/_dialogs/workflow-spec-dialog/workflow-spec-dialog.component.spec.ts b/src/app/_dialogs/workflow-spec-dialog/workflow-spec-dialog.component.spec.ts index 4be8eec..278e443 100644 --- a/src/app/_dialogs/workflow-spec-dialog/workflow-spec-dialog.component.spec.ts +++ b/src/app/_dialogs/workflow-spec-dialog/workflow-spec-dialog.component.spec.ts @@ -1,5 +1,6 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef} from '@angular/material/dialog'; import {MatFormFieldModule} from '@angular/material/form-field'; @@ -13,7 +14,7 @@ import {FormlyMaterialModule} from '@ngx-formly/material'; import {ApiService, MockEnvironment, mockWorkflowSpec0, mockWorkflowSpecCategories} from 'sartography-workflow-lib'; import {WorkflowSpecDialogData} from '../../_interfaces/dialog-data'; -import { WorkflowSpecDialogComponent } from './workflow-spec-dialog.component'; +import {WorkflowSpecDialogComponent} from './workflow-spec-dialog.component'; describe('WorkflowSpecDialogComponent', () => { let httpMock: HttpTestingController; @@ -37,10 +38,11 @@ describe('WorkflowSpecDialogComponent', () => { ReactiveFormsModule, RouterTestingModule, ], - declarations: [ WorkflowSpecDialogComponent ], + declarations: [WorkflowSpecDialogComponent], providers: [ ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, { provide: MatDialogRef, useValue: { @@ -59,7 +61,7 @@ describe('WorkflowSpecDialogComponent', () => { {provide: Router, useValue: mockRouter}, ] }) - .compileComponents(); + .compileComponents(); })); beforeEach(() => { diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 03e7839..2f759e1 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -7,8 +7,6 @@ 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'; @Injectable() export class ThisEnvironment implements AppEnvironment { @@ -16,7 +14,7 @@ export class ThisEnvironment implements AppEnvironment { production = environment.production; api = environment.api; irbUrl = environment.irbUrl; - baseHref = environment.baseHref; + title = environment.title; } const routes: Routes = [ @@ -46,15 +44,7 @@ const routes: Routes = [ component: ModelerComponent }, { - path: 'sign-in', - component: SignInComponent - }, - { - path: 'sign-out', - component: SignOutComponent - }, - { - path: 'session/:token', + path: 'session', component: SessionRedirectComponent } ]; @@ -71,7 +61,7 @@ const routes: Routes = [ exports: [RouterModule], providers: [ {provide: 'APP_ENVIRONMENT', useClass: ThisEnvironment}, - {provide: APP_BASE_HREF, useValue: environment.baseHref}, + // {provide: APP_BASE_HREF, useValue: environment.baseHref}, ] }) export class AppRoutingModule { diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 8a70483..e619fbd 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpClient} from '@angular/common/http'; import {HttpClientTestingModule} from '@angular/common/http/testing'; import {Component} from '@angular/core'; @@ -42,6 +43,7 @@ describe('AppComponent', () => { HttpClient, ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, ], }) .compileComponents(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index afa3b86..7521467 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,4 +1,4 @@ -import {APP_BASE_HREF} from '@angular/common'; +import {APP_BASE_HREF, PlatformLocation} from '@angular/common'; import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import {Injectable, NgModule} from '@angular/core'; import {FlexLayoutModule} from '@angular/flex-layout'; @@ -49,8 +49,6 @@ import {ModelerComponent} from './modeler/modeler.component'; import {NavbarComponent} from './navbar/navbar.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'; import {WorkflowSpecCardComponent} from './workflow-spec-card/workflow-spec-card.component'; import {WorkflowSpecListComponent} from './workflow-spec-list/workflow-spec-list.component'; @@ -60,7 +58,22 @@ export class ThisEnvironment implements AppEnvironment { production = environment.production; api = environment.api; irbUrl = environment.irbUrl; - baseHref = environment.baseHref; + title = environment.title; +} + +/** + * This function is used internal to get a string instance of the `` value from `index.html`. + * This is an exported function, instead of a private function or inline lambda, to prevent this error: + * + * `Error encountered resolving symbol values statically.` + * `Function calls are not supported.` + * `Consider replacing the function or lambda with a reference to an exported function.` + * + * @param platformLocation an Angular service used to interact with a browser's URL + * @return a string instance of the `` value from `index.html` + */ +export function getBaseHref(platformLocation: PlatformLocation): string { + return platformLocation.getBaseHrefFromDOM(); } @NgModule({ @@ -78,8 +91,6 @@ export class ThisEnvironment implements AppEnvironment { NavbarComponent, NewFileDialogComponent, OpenFileDialogComponent, - SignInComponent, - SignOutComponent, WorkflowSpecCategoryDialogComponent, WorkflowSpecDialogComponent, WorkflowSpecListComponent, @@ -130,9 +141,9 @@ export class ThisEnvironment implements AppEnvironment { providers: [ {provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline'}}, {provide: 'APP_ENVIRONMENT', useClass: ThisEnvironment}, - {provide: APP_BASE_HREF, useValue: environment.baseHref}, {provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true}, {provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true}, + {provide: APP_BASE_HREF, useFactory: getBaseHref, deps: [PlatformLocation]} ] }) export class AppModule { diff --git a/src/app/diagram/diagram.component.spec.ts b/src/app/diagram/diagram.component.spec.ts index 2937bde..6db23ff 100644 --- a/src/app/diagram/diagram.component.spec.ts +++ b/src/app/diagram/diagram.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {DebugNode} from '@angular/core'; import {async, ComponentFixture, TestBed} from '@angular/core/testing'; @@ -31,6 +32,7 @@ describe('DiagramComponent', () => { providers: [ ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, {provide: Router, useValue: mockRouter}, ] }); diff --git a/src/app/file-list/file-list.component.spec.ts b/src/app/file-list/file-list.component.spec.ts index 902d47a..f67e6c5 100644 --- a/src/app/file-list/file-list.component.spec.ts +++ b/src/app/file-list/file-list.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpHeaders} from '@angular/common/http'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing'; @@ -8,6 +9,7 @@ import {MatSnackBarModule} from '@angular/material/snack-bar'; import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {RouterTestingModule} from '@angular/router/testing'; +import createClone from 'rfdc'; import {of} from 'rxjs'; import { ApiService, @@ -22,7 +24,6 @@ import {DeleteFileDialogComponent} from '../_dialogs/delete-file-dialog/delete-f import {DeleteFileDialogData} from '../_interfaces/dialog-data'; import {GetIconCodePipe} from '../_pipes/get-icon-code.pipe'; import {FileListComponent} from './file-list.component'; -import createClone from 'rfdc'; describe('FileListComponent', () => { @@ -49,6 +50,7 @@ describe('FileListComponent', () => { providers: [ ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, { provide: MatDialogRef, useValue: { diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index f01d428..477a27d 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -1,3 +1,3 @@ diff --git a/src/app/footer/footer.component.spec.ts b/src/app/footer/footer.component.spec.ts index 2ca6c45..b9ad446 100644 --- a/src/app/footer/footer.component.spec.ts +++ b/src/app/footer/footer.component.spec.ts @@ -1,6 +1,7 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FooterComponent } from './footer.component'; +import {APP_BASE_HREF} from '@angular/common'; +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {MockEnvironment} from 'sartography-workflow-lib'; +import {FooterComponent} from './footer.component'; describe('FooterComponent', () => { let component: FooterComponent; @@ -8,9 +9,14 @@ describe('FooterComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ FooterComponent ] + declarations: [FooterComponent], + providers: [ + {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, + ], }) - .compileComponents(); + + .compileComponents(); })); beforeEach(() => { diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts index da17d82..9e532c6 100644 --- a/src/app/footer/footer.component.ts +++ b/src/app/footer/footer.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, Inject, OnInit} from '@angular/core'; +import {AppEnvironment} from 'sartography-workflow-lib'; @Component({ selector: 'app-footer', @@ -7,7 +8,11 @@ import { Component, OnInit } from '@angular/core'; }) export class FooterComponent implements OnInit { - constructor() { } + title: string; + + constructor(@Inject('APP_ENVIRONMENT') private environment: AppEnvironment) { + this.title = environment.title; + } ngOnInit() { } diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index b9bf7b9..0d10643 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -1,2 +1 @@ - - + diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index 2a42f0b..35e50b9 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpClient} from '@angular/common/http'; import {HttpClientTestingModule} from '@angular/common/http/testing'; import {Component} from '@angular/core'; @@ -43,6 +44,7 @@ describe('HomeComponent', () => { HttpClient, ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, {provide: Router, useValue: mockRouter}, ] }) diff --git a/src/app/modeler/modeler.component.spec.ts b/src/app/modeler/modeler.component.spec.ts index 3ea2904..dafe1a9 100644 --- a/src/app/modeler/modeler.component.spec.ts +++ b/src/app/modeler/modeler.component.spec.ts @@ -1,3 +1,4 @@ +import {APP_BASE_HREF} from '@angular/common'; import {HttpErrorResponse, HttpHeaders, HttpResponse} from '@angular/common/http'; import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing'; import {DebugNode} from '@angular/core'; @@ -75,6 +76,7 @@ describe('ModelerComponent', () => { providers: [ ApiService, {provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, + {provide: APP_BASE_HREF, useValue: ''}, { provide: MatDialogRef, useValue: { diff --git a/src/app/navbar/navbar.component.html b/src/app/navbar/navbar.component.html index 763aba1..793295e 100644 --- a/src/app/navbar/navbar.component.html +++ b/src/app/navbar/navbar.component.html @@ -1,9 +1,12 @@ -