diff --git a/Dockerfile b/Dockerfile index 4d675f5e6a84c83977a4773c87014f9b013ae99f..70b8bf7263a68fe846bc69ab285d306153e8f54f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:12 as builder +FROM node:14 as builder ARG BACKEND_URL ENV BACKEND_URL=${BACKEND_URL} diff --git a/README.md b/README.md index c6e738a0957b6dc71ebe988167863aff00f053a6..51cec074433d368be8beb1ad7ab6cb472f09074d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A live version of the Interactive Atlas Viewer is available at [https://interact ### General information -Interactive atlas viewer is built with [Angular (v9.0)](https://angular.io/), [Bootstrap (v4)](http://getbootstrap.com/), and [fontawesome icons](https://fontawesome.com/). Some other notable packages used are [ngrx/store](https://github.com/ngrx/platform) for state management. +Interactive atlas viewer is built with [Angular (v12.0)](https://angular.io/), [Bootstrap (v4)](http://getbootstrap.com/), and [fontawesome icons](https://fontawesome.com/). Some other notable packages used are [ngrx/store](https://github.com/ngrx/platform) for state management. Releases newer than [v0.2.9](https://github.com/HumanBrainProject/interactive-viewer/tree/v0.2.9) also uses a nodejs backend, which uses [passportjs](http://www.passportjs.org/) for user authentication, [express](https://expressjs.com/) as a http framework. @@ -16,7 +16,7 @@ Releases newer than [v0.2.9](https://github.com/HumanBrainProject/interactive-vi #### Prerequisites -- node >= 12 +- latest version of node 12.x.x or node 14.x.x #### Environments diff --git a/docs/releases/v2.5.0.md b/docs/releases/v2.5.0.md index 0f7dfbe92b89bba34755d8e89b1c1c16cc9c8660..2bea69f5eca6f1006eb8f5b768bbda696e033cac 100644 --- a/docs/releases/v2.5.0.md +++ b/docs/releases/v2.5.0.md @@ -7,3 +7,4 @@ ## Under the hood stuff - refactor: remove unneeded code +- upgrade to angular v12 diff --git a/package.json b/package.json index 727a42e219e5fd0d8134afb03c133e93a9543179..658bddf3a53cce05cc9d0ea5ecf19a6264c062ad 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "HBP interactive atlas viewer. Integrating KG query, dataset previews & more. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular", "scripts": { "build-aot": "PRODUCTION=true GIT_HASH=`node -e 'console.log(require(\"./package.json\").version)'` webpack --config ./webpack/webpack.aot.js && node ./third_party/matomo/processMatomo.js", - "dev-server-aot": "BACKEND_URL=${BACKEND_URL:-http://localhost:3000/} PRODUCTION=true GIT_HASH=`node -e 'console.log(require(\"./package.json\").version)'` webpack-dev-server --config ./webpack/webpack.dev-aot.js", + "dev-server-aot": "BACKEND_URL=${BACKEND_URL:-http://localhost:3000/} PRODUCTION=true GIT_HASH=`node -e 'console.log(require(\"./package.json\").version)'` webpack serve --config ./webpack/webpack.dev-aot.js --progress", "test": "karma start spec/karma.conf.js", "e2e": "protractor e2e/protractor.conf", "lint": "eslint src --ext .ts", @@ -15,74 +15,71 @@ "author": "FZJ-INM1-BDA <inm1-bda@fz-juelich.de>", "license": "apache-2.0", "devDependencies": { - "@angular/animations": "^9.0.0", - "@angular/cdk": "^9.0.0", - "@angular/common": "^9.0.0", - "@angular/compiler": "^9.0.0", - "@angular/compiler-cli": "^9.1.4", - "@angular/core": "^9.0.0", - "@angular/elements": "^9.0.0", - "@angular/forms": "^9.0.0", - "@angular/language-service": "^9.0.0", - "@angular/material": "^9.0.0", - "@angular/platform-browser": "^9.0.0", - "@angular/platform-browser-dynamic": "^9.0.0", - "@material/dialog": "^4.0.0", - "@ngtools/webpack": "^9.0.1", + "@angular/animations": "^12.0.0", + "@angular/cdk": "^12.0.0", + "@angular/common": "^12.0.0", + "@angular/compiler": "^12.0.0", + "@angular/compiler-cli": "^12.1.4", + "@angular/core": "^12.0.0", + "@angular/elements": "^12.0.0", + "@angular/forms": "^12.0.0", + "@angular/language-service": "^12.0.0", + "@angular/material": "^12.0.0", + "@angular/platform-browser": "^12.0.0", + "@angular/platform-browser-dynamic": "^12.0.0", + "@angular/router": "^12.0.0", + "@ngtools/webpack": "^12.2.1", "@types/jasmine": "^3.5.0", "@types/webpack-env": "^1.13.6", - "@typescript-eslint/eslint-plugin": "^2.12.0", - "@typescript-eslint/parser": "^2.12.0", + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.2", "angular2-template-loader": "^0.6.2", "browserstack-local": "^1.4.5", "codelyzer": "^5.0.1", "core-js": "^3.0.1", "css-loader": "^3.2.0", - "eslint": "^6.8.0", + "eslint": "^7.32.0", "eslint-plugin-html": "^6.0.0", "file-loader": "^1.1.11", "glob": "^7.1.6", "hammerjs": "^2.0.8", - "html-webpack-plugin": "^3.2.0", + "html-webpack-plugin": "^5.3.2", "jasmine": "^3.1.0", "jasmine-core": "^3.5.0", "jasmine-marbles": "^0.6.0", "jasmine-spec-reporter": "^4.2.1", "json-loader": "^0.5.7", - "karma": "^4.1.0", - "karma-chrome-launcher": "^2.2.0", + "karma": "^6.3.4", + "karma-chrome-launcher": "^3.1.0", "karma-cli": "^2.0.0", - "karma-jasmine": "^2.0.1", - "karma-typescript": "^4.1.1", - "karma-webpack": "^3.0.0", - "lodash.merge": "^4.6.2", + "karma-jasmine": "^4.0.1", + "karma-typescript": "^5.5.1", + "karma-webpack": "^5.0.0", "mini-css-extract-plugin": "^0.8.0", - "node-sass": "^4.14.1", - "protractor": "^6.0.0", + "protractor": "^7.0.0", "raw-loader": "^0.5.1", "reflect-metadata": "^0.1.12", - "rxjs": "6.5.4", - "sass-loader": "^7.2.0", + "rxjs": "^6.6.0", + "sass": "^1.38.0", + "sass-loader": "^12.1.0", "showdown": "^1.9.1", "terser-webpack-plugin": "^3.0.1", "ts-loader": "^4.3.0", "ts-node": "^8.1.0", - "typescript": "~3.7.5", - "uglifyjs-webpack-plugin": "^1.2.5", - "webpack": "^4.41.2", - "webpack-cli": "^3.3.2", + "typescript": "^4.3.5", + "webpack": "^5.50.0", + "webpack-cli": "^4.8.0", "webpack-closure-compiler": "^2.1.6", "webpack-dev-server": "^3.11.2", "webpack-merge": "^4.1.2" }, "dependencies": { - "@angular/router": "^9.1.13", - "@ngrx/effects": "^9.1.1", - "@ngrx/store": "^9.1.1", + "@ngrx/effects": "^12.0.0", + "@ngrx/store": "^12.0.0", "@types/node": "12.12.39", "export-nehuba": "0.0.12", "hbp-connectivity-component": "^0.4.9", "jszip": "^3.6.0", - "zone.js": "^0.10.2" + "zone.js": "^0.11.4" } } diff --git a/spec/karma.conf.js b/spec/karma.conf.js index 76c12d0cbd668862a62d60ff9377427005964bc1..b2559dbe9d5bbcd6c6245cad2b283c70aeeece0a 100644 --- a/spec/karma.conf.js +++ b/spec/karma.conf.js @@ -3,8 +3,17 @@ const merge = require('webpack-merge') const webpackTest = require('../webpack/webpack.test') -const webpackConfig = require('../webpack/webpack.dev') -const fullWebpack = merge(webpackTest, webpackConfig) +const webpackConfig = require('../webpack/webpack.aot-common') +const { AngularWebpackPlugin } = require('@ngtools/webpack') +const fullWebpack = merge(webpackTest, webpackConfig, { + plugins: [ + new AngularWebpackPlugin({ + tsConfigPath: 'tsconfig.spec.json', + // entryModule: 'src/main.module#MainModule', + // directTemplateLoading: true + }), + ] +}) const singleRun = process.env.NODE_ENV === 'test' const browsers = process.env.NODE_ENV === 'test' @@ -22,6 +31,13 @@ module.exports = function(config) { // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], + client: { + jasmine: {}, + clearContext: false + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, // list of files / patterns to load in the browser files: [ @@ -67,6 +83,8 @@ module.exports = function(config) { // available reporters: https://npmjs.org/browse/keyword/karma-reporter reporters: ['progress'], + restartOnFileChange: true, + // web server port port: 9876, diff --git a/spec/test.ts b/spec/test.ts index 478be25bbf91e4b0d442d079f8bc81bd0d868493..79e84c02ff647ce35089fd404ba0593f3afd89c3 100644 --- a/spec/test.ts +++ b/spec/test.ts @@ -10,13 +10,12 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: any; - // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); + platformBrowserDynamicTesting(), + { teardown: { destroyAfterEach: true }}, +) const testContext = require.context('../src', true, /\.spec\.ts$/) testContext.keys().map(testContext) diff --git a/src/atlasComponents/parcellationRegion/region.base.ts b/src/atlasComponents/parcellationRegion/region.base.ts index c69a2f94658760f599f896f16affca4a70ab277c..a16995b9af3a98b69c44f0577e2f6e1226b087df 100644 --- a/src/atlasComponents/parcellationRegion/region.base.ts +++ b/src/atlasComponents/parcellationRegion/region.base.ts @@ -1,4 +1,4 @@ -import { EventEmitter, Input, Output, Pipe, PipeTransform } from "@angular/core"; +import { Directive, EventEmitter, Input, Output, Pipe, PipeTransform } from "@angular/core"; import { select, Store, createSelector } from "@ngrx/store"; import { uiStateOpenSidePanel, uiStateExpandSidePanel, uiActionShowSidePanelConnectivity } from 'src/services/state/uiState.store.helper' import { distinctUntilChanged, switchMap, filter, map, withLatestFrom, tap } from "rxjs/operators"; @@ -9,6 +9,7 @@ import { viewerStateFetchedTemplatesSelector, viewerStateGetSelectedAtlas, viewe import { strToRgb, verifyPositionArg, getRegionHemisphere } from 'common/util' import { getPosFromRegion } from "src/util/siibraApiConstants/fn"; +@Directive() export class RegionBase { public rgbString: string diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts b/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts index 6eed3fb1bcc28e7f59b3133acb4b354a90b5a0e7..85d2e6d005bca99c7d003f148bc6a93fe7e2acb7 100644 --- a/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts +++ b/src/atlasComponents/regionalFeatures/bsFeatures/bsRegionInputBase.ts @@ -3,8 +3,9 @@ import { map, switchMap } from "rxjs/operators"; import { TRegion, IBSSummaryResponse, IBSDetailResponse } from "./type"; import { BsFeatureService, TFeatureCmpInput } from "./service"; import { flattenReducer } from 'common/util' -import { Input } from "@angular/core"; +import { Directive, Input } from "@angular/core"; +@Directive() export class BsRegionInputBase{ protected region$ = new BehaviorSubject<TRegion>(null) diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts index f4e418aa320f7d2e201955b5ab9a56e22ec39e78..b149e359d7dca68da294e98e9138a557bfedf41a 100644 --- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts +++ b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/base.ts @@ -1,6 +1,7 @@ -import { Input } from "@angular/core"; +import { Directive, Input } from "@angular/core"; import { TBSDetail } from "./type"; +@Directive() export class BsFeatureReceptorBase { @Input() bsFeature: TBSDetail diff --git a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts b/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts index 627b097c977eb8fbef6171fb205a0b6f690abd6e..6821e237ff0aae95e6eaa42c99989dec7d5e9b65 100644 --- a/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts +++ b/src/atlasComponents/regionalFeatures/featureContainer/featureContainer.component.spec.ts @@ -42,40 +42,26 @@ const serviceStub = { ]) } -@NgModule({ - declarations: [ - FeatureContainer, - DummyComponent, - ], - entryComponents: [ - DummyComponent - ], - providers: [ - { - provide: RegionalFeaturesService, - useValue: serviceStub - } - ], - exports: [ - FeatureContainer, - DummyComponent, - ] -}) - -class DummyModule{} - describe('> featureContainer.component.ts', () => { describe('> FeatureContainer', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ + beforeEach(async () => { + + await TestBed.configureTestingModule({ imports: [ CommonModule, - DummyModule, ], declarations: [ + FeatureContainer, + DummyComponent, HostCmp, ], + providers: [ + { + provide: RegionalFeaturesService, + useValue: serviceStub + } + ] }).overrideComponent(HostCmp, { set: { template: ` @@ -87,7 +73,7 @@ describe('> featureContainer.component.ts', () => { } }).compileComponents() - })) + }) it('> can be created', () => { const fixture = TestBed.createComponent(HostCmp) diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts b/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts index 6755dfca6a92819dd831118c13ef09b48f66c2c4..21dde06920b0ddf29f384683c5851de9a171445f 100644 --- a/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts +++ b/src/atlasComponents/regionalFeatures/singleFeatures/base/regionFeature.base.ts @@ -1,9 +1,10 @@ -import { EventEmitter, Input, Output, SimpleChanges } from "@angular/core" +import { Directive, EventEmitter, Input, Output, SimpleChanges } from "@angular/core" import { BehaviorSubject, forkJoin, Observable, of } from "rxjs" import { catchError, shareReplay, switchMap, tap } from "rxjs/operators" import { IHasId } from "src/util/interfaces" import { IFeature, RegionalFeaturesService } from "../../regionalFeature.service" +@Directive() export class RegionFeatureBase{ private _feature: IFeature diff --git a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts b/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts index eb9e3c32e9d0ad71e1cd57c5ab1c33157eeae450..11fd197fbd45b569e35f15f5a9ae54ab13f07777 100644 --- a/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts +++ b/src/atlasComponents/regionalFeatures/singleFeatures/iEEGRecordings/iEEGRecordings/iEEGRecordings.component.ts @@ -20,7 +20,7 @@ const selectedColor = [ 255, 0, 0 ] export class IEEGRecordingsCmp extends RegionFeatureBase implements ISingleFeature{ private landmarksLoaded: IHasId[] = [] - private onDestroyCb: Function[] = [] + private onDestroyCb: (() => void)[] = [] private sub: Subscription[] = [] constructor( diff --git a/src/atlasComponents/userAnnotations/annotationMode/annotationMode.component.ts b/src/atlasComponents/userAnnotations/annotationMode/annotationMode.component.ts index 0bacfe6b2d2d0f92d2b292429dcc4682bd05f1f3..38eae7e8134c3e7c87fa16722f1a2e248a929718 100644 --- a/src/atlasComponents/userAnnotations/annotationMode/annotationMode.component.ts +++ b/src/atlasComponents/userAnnotations/annotationMode/annotationMode.component.ts @@ -22,10 +22,10 @@ export class AnnotationMode implements OnDestroy{ name: string iconClass: string } - onClick: Function + onClick: () => void }[] = [] - private onDestroyCb: Function[] = [] + private onDestroyCb: (() => void)[] = [] constructor( private store$: Store<any>, diff --git a/src/atlasComponents/userAnnotations/tools/delete.ts b/src/atlasComponents/userAnnotations/tools/delete.ts index dc817a65012bd3dbe5409fb8656d5b9d5bcb9990..b1658e9cc44f91dc68ed41a5bd1bfe7bd49d0f5c 100644 --- a/src/atlasComponents/userAnnotations/tools/delete.ts +++ b/src/atlasComponents/userAnnotations/tools/delete.ts @@ -1,9 +1,10 @@ -import { OnDestroy } from "@angular/core"; +import { Directive, OnDestroy } from "@angular/core"; import { Observable, Subject, Subscription } from "rxjs"; import { filter, switchMapTo, takeUntil, withLatestFrom } from "rxjs/operators"; import { Point } from "./point"; import { AbsToolClass, IAnnotationEvents, IAnnotationGeometry, IAnnotationTools, TAnnotationEvent, TCallbackFunction, TNgAnnotationPoint, TToolType } from "./type"; +@Directive() export class ToolDelete extends AbsToolClass<Point> implements IAnnotationTools, OnDestroy { public subs: Subscription[] = [] diff --git a/src/atlasComponents/userAnnotations/tools/line.ts b/src/atlasComponents/userAnnotations/tools/line.ts index 1303612f991d1cadc53a1ce73ddf9f043babca52..644258af23408c6edb3b0c03054ad92c400333d4 100644 --- a/src/atlasComponents/userAnnotations/tools/line.ts +++ b/src/atlasComponents/userAnnotations/tools/line.ts @@ -12,7 +12,7 @@ import { TCallbackFunction, } from "./type"; import { Point, TPointJsonSpec } from './point' -import { OnDestroy } from "@angular/core"; +import { Directive, Injectable, OnDestroy } from "@angular/core"; import { Observable, Subject, Subscription } from "rxjs"; import { filter, switchMapTo, takeUntil } from "rxjs/operators"; import { getUuid } from "src/util/fn"; @@ -182,6 +182,7 @@ export class Line extends IAnnotationGeometry{ export const LINE_ICON_CLASS = 'fas fa-slash' +@Directive() export class ToolLine extends AbsToolClass<Line> implements IAnnotationTools, OnDestroy { static PREVIEW_ID='tool_line_preview' public name = 'Line' diff --git a/src/atlasComponents/userAnnotations/tools/point.ts b/src/atlasComponents/userAnnotations/tools/point.ts index 2dcafc2490a82b2dacb3bf5180b7457947de2770..e6fd9fee4f42d8535bd8998b0ffb471e211e0eec 100644 --- a/src/atlasComponents/userAnnotations/tools/point.ts +++ b/src/atlasComponents/userAnnotations/tools/point.ts @@ -1,6 +1,6 @@ import { AbsToolClass, getCoord, IAnnotationEvents, IAnnotationGeometry, IAnnotationTools, INgAnnotationTypes, TAnnotationEvent, TBaseAnnotationGeomtrySpec, TCallbackFunction, TNgAnnotationEv, TSandsPoint, TToolType } from "./type"; -import { merge, Observable, Subject, Subscription } from "rxjs"; -import { OnDestroy } from "@angular/core"; +import { Observable, Subject, Subscription } from "rxjs"; +import { Directive, OnDestroy } from "@angular/core"; import { filter, switchMapTo, takeUntil } from "rxjs/operators"; export type TPointJsonSpec = { @@ -101,6 +101,7 @@ export class Point extends IAnnotationGeometry { export const POINT_ICON_CLASS='fas fa-circle' +@Directive() export class ToolPoint extends AbsToolClass<Point> implements IAnnotationTools, OnDestroy { static PREVIEW_ID='tool_point_preview' public name = 'Point' diff --git a/src/atlasComponents/userAnnotations/tools/poly.ts b/src/atlasComponents/userAnnotations/tools/poly.ts index c33662c2afc022ae8240884c629946587057b662..d226021de999af7b27ae98815f7fb34176f97ff5 100644 --- a/src/atlasComponents/userAnnotations/tools/poly.ts +++ b/src/atlasComponents/userAnnotations/tools/poly.ts @@ -1,6 +1,6 @@ import { IAnnotationTools, IAnnotationGeometry, TAnnotationEvent, IAnnotationEvents, AbsToolClass, INgAnnotationTypes, TNgAnnotationEv, TToolType, TBaseAnnotationGeomtrySpec, TSandsPolyLine, getCoord, TCallbackFunction } from "./type"; import { Point, TPointJsonSpec } from './point' -import { OnDestroy } from "@angular/core"; +import { Directive, OnDestroy } from "@angular/core"; import { merge, Observable, Subject, Subscription } from "rxjs"; import { filter, switchMapTo, takeUntil, withLatestFrom } from "rxjs/operators"; import { getUuid } from "src/util/fn"; @@ -22,7 +22,7 @@ export class Polygon extends IAnnotationGeometry{ } private ptWkMp = new WeakMap<Point, { - onremove: Function + onremove: () => void }>() public removePoint(p: Point) { @@ -223,6 +223,7 @@ export class Polygon extends IAnnotationGeometry{ export const POLY_ICON_CLASS = 'fas fa-draw-polygon' +@Directive() export class ToolPolygon extends AbsToolClass<Polygon> implements IAnnotationTools, OnDestroy { static PREVIEW_ID='tool_poly_preview' diff --git a/src/atlasComponents/userAnnotations/tools/select.ts b/src/atlasComponents/userAnnotations/tools/select.ts index 38a0b11ba39ec9df2ddbb20b875f01cd48575257..fd947eb34e813a956f21349dfd319898ba469fd0 100644 --- a/src/atlasComponents/userAnnotations/tools/select.ts +++ b/src/atlasComponents/userAnnotations/tools/select.ts @@ -1,9 +1,10 @@ -import { OnDestroy } from "@angular/core"; +import { Directive, OnDestroy } from "@angular/core"; import { Observable, Subject, Subscription } from "rxjs"; import { filter } from 'rxjs/operators' import { Point } from "./point"; import { AbsToolClass, IAnnotationEvents, IAnnotationGeometry, IAnnotationTools, TAnnotationEvent, TCallbackFunction, TNgAnnotationPoint, TToolType } from "./type"; +@Directive() export class ToolSelect extends AbsToolClass<Point> implements IAnnotationTools, OnDestroy { public subs: Subscription[] = [] diff --git a/src/atlasComponents/userAnnotations/tools/service.ts b/src/atlasComponents/userAnnotations/tools/service.ts index fde183e33b5d8fd56059d857f4c5dfb600502350..b402976d9817885523a442f28bb9c13299744cfe 100644 --- a/src/atlasComponents/userAnnotations/tools/service.ts +++ b/src/atlasComponents/userAnnotations/tools/service.ts @@ -80,7 +80,7 @@ export class ModularUserAnnotationToolService implements OnDestroy{ private selectedTmpl$ = this.store.pipe( select(viewerStateSelectedTemplatePureSelector), ) - public moduleAnnotationTypes: {instance: {name: string, iconClass: string, toolSelected$: Observable<boolean>}, onClick: Function}[] = [] + public moduleAnnotationTypes: {instance: {name: string, iconClass: string, toolSelected$: Observable<boolean>}, onClick: () => void}[] = [] private managedAnnotationsStream$ = new Subject<{ tool: string annotations: IAnnotationGeometry[] @@ -157,7 +157,7 @@ export class ModularUserAnnotationToolService implements OnDestroy{ editCmp?: ClassInterface<any> }): AbsToolClass<any>{ const { toolCls: Cls, target, editCmp } = arg - const newTool = new Cls(this.annotnEvSubj, arg => this.handleToolCallback(arg)) as T & { ngOnDestroy?: Function } + const newTool = new Cls(this.annotnEvSubj, arg => this.handleToolCallback(arg)) as T & { ngOnDestroy?: () => void } const { name, iconClass, onMouseMoveRenderPreview } = newTool this.moduleAnnotationTypes.push({ diff --git a/src/atlasComponents/userAnnotations/tools/type.ts b/src/atlasComponents/userAnnotations/tools/type.ts index 1716457a166eea87cc6b9943b4c3ebed3538c03a..efb1d9136c74e1f55497efc62b5fda6798b9afbb 100644 --- a/src/atlasComponents/userAnnotations/tools/type.ts +++ b/src/atlasComponents/userAnnotations/tools/type.ts @@ -6,6 +6,8 @@ import { TLineJsonSpec } from "./line" import { TPointJsonSpec } from "./point" import { TPolyJsonSpec } from "./poly" +type TRecord = Record<string, unknown> + /** * base class to be extended by all annotation tools * TODO perhaps split into drawing subclass/utility subclass @@ -158,11 +160,11 @@ export type TToolType = 'selecting' | 'drawing' | 'deletion' export type TCallback = { paintingEnd: { - callArg: {} + callArg: TRecord returns: void } requestManAnnStream: { - callArg: {} + callArg: TRecord returns: Observable<IAnnotationGeometry[]> } message: { @@ -174,7 +176,7 @@ export type TCallback = { returns: void } showList: { - callArg: {} + callArg: TRecord returns: void } } @@ -273,7 +275,7 @@ export abstract class IAnnotationGeometry extends Highlightable { abstract getNgAnnotationIds(): string[] abstract toNgAnnotation(): INgAnnotationTypes[keyof INgAnnotationTypes][] - abstract toJSON(): object + abstract toJSON(): TRecord abstract toString(): string abstract toSands(): ISandsAnnotation[keyof ISandsAnnotation] diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts index 20b08137b3f5b196d360aa858c20d4a367243140..9ee73c58689f765e94e54829a1b9138e43f38f86 100644 --- a/src/atlasViewer/atlasViewer.apiService.service.ts +++ b/src/atlasViewer/atlasViewer.apiService.service.ts @@ -44,7 +44,7 @@ export class AtlasViewerAPIServices implements OnDestroy{ public loadMesh$ = new Subject<ILoadMesh>() - private onDestoryCb: Function[] = [] + private onDestoryCb: (() => void)[] = [] private loadedTemplates$: Observable<any> private selectParcellation$: Observable<any> public interactiveViewer: IInteractiveViewerInterface @@ -64,7 +64,7 @@ export class AtlasViewerAPIServices implements OnDestroy{ } - private dismissDialog: Function + private dismissDialog: () => void public getUserToSelectRegion: IGetUserSelectRegionPr[] = [] public getUserToSelectRegionUI$: Subject<IGetUserSelectRegionPr[]> = new Subject() diff --git a/src/contextMenuModule/service.ts b/src/contextMenuModule/service.ts index be34051f9cfe3f5cc59a71f9707e62289a8bc8d7..a35798d79ecbaa790598842007bc10fc002d44df 100644 --- a/src/contextMenuModule/service.ts +++ b/src/contextMenuModule/service.ts @@ -18,7 +18,7 @@ type TSimple = { type TTmplRef = (TTmpl | TSimple) & { order?: number - onClick?: Function + onClick?: (...arg: any) => void } type CtxMenuInterArg<T> = { diff --git a/src/messagingGlue.ts b/src/messagingGlue.ts index 443b58db56cfe20fcfcbe871232f6a11177977a4..80e459157a717ec90b21f426596e531acbb48843 100644 --- a/src/messagingGlue.ts +++ b/src/messagingGlue.ts @@ -1,4 +1,4 @@ -import { OnDestroy } from "@angular/core"; +import { Injectable, OnDestroy } from "@angular/core"; import { select, Store } from "@ngrx/store"; import { IMessagingActionTmpl, IWindowMessaging } from "./messaging/types"; import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "./services/state/ngViewerState/actions"; @@ -6,6 +6,7 @@ import { viewerStateSelectAtlas } from "./services/state/viewerState/actions"; import { viewerStateFetchedAtlasesSelector } from "./services/state/viewerState/selectors"; import { generalActionError } from "./services/stateStore.helper"; +@Injectable() export class MessagingGlue implements IWindowMessaging, OnDestroy { private onDestroyCb: (() => void)[] = [] diff --git a/src/plugin/atlasViewer.pluginService.service.spec.ts b/src/plugin/atlasViewer.pluginService.service.spec.ts index 2c2c9c83620cd239009daa4f781bb0e159ef0653..41e342b8bf77d8941eb731554972b71217e75b73 100644 --- a/src/plugin/atlasViewer.pluginService.service.spec.ts +++ b/src/plugin/atlasViewer.pluginService.service.spec.ts @@ -11,6 +11,7 @@ import { PureContantService } from "src/util" import { APPEND_SCRIPT_TOKEN, REMOVE_SCRIPT_TOKEN } from "src/util/constants" import { WidgetModule, WidgetServices } from "src/widget" import { PluginServices } from "./atlasViewer.pluginService.service" +import { PluginModule } from "./plugin.module" import { PluginUnit } from "./pluginUnit/pluginUnit.component" const MOCK_PLUGIN_MANIFEST = { @@ -19,20 +20,6 @@ const MOCK_PLUGIN_MANIFEST = { scriptURL: 'http://localhost:10001/script.js' } -@NgModule({ - declarations: [ - PluginUnit, - ], - entryComponents: [ - PluginUnit - ], - exports: [ - PluginUnit - ] -}) - -class PluginUnitModule{} - const spyfn = { appendSrc: jasmine.createSpy('appendSrc') } @@ -52,7 +39,7 @@ describe('> atlasViewer.pluginService.service.ts', () => { AngularMaterialModule, CommonModule, WidgetModule, - PluginUnitModule, + PluginModule, HttpClientTestingModule, ComponentsModule, ], diff --git a/src/routerModule/parseRouteToTmplParcReg.ts b/src/routerModule/parseRouteToTmplParcReg.ts index d626e279fea18182e480a76e39204b633d4f6231..a1ed2a7c47003fbaae169cc49bdd0b7e8be0e3bb 100644 --- a/src/routerModule/parseRouteToTmplParcReg.ts +++ b/src/routerModule/parseRouteToTmplParcReg.ts @@ -18,7 +18,7 @@ export const PARSE_ERROR = { export const encodeId = (id: string) => id && id.replace(/\//g, ':') export const decodeId = (codedId: string) => codedId && codedId.replace(/:/g, '/') -export function parseSearchParamForTemplateParcellationRegion(obj: TUrlPathObj<string[], TUrlAtlas<string[]>>, fullPath: UrlTree, state: any, warnCb: Function) { +export function parseSearchParamForTemplateParcellationRegion(obj: TUrlPathObj<string[], TUrlAtlas<string[]>>, fullPath: UrlTree, state: any, warnCb: (arg: string) => void) { /** * TODO if search param of either template or parcellation is incorrect, wrong things are searched diff --git a/src/routerModule/util.ts b/src/routerModule/util.ts index 224458c860b9ae37073a4ee40a8dd839e7f3ddca..21ccdc6e7bbbb9bab69a399a96ac388d5fbc7439 100644 --- a/src/routerModule/util.ts +++ b/src/routerModule/util.ts @@ -34,7 +34,7 @@ const decodePath = (path: string) => { } } -export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: Function) => { +export const cvtFullRouteToState = (fullPath: UrlTree, state: any, _warnCb?: (arg: string) => void) => { const warnCb = _warnCb || ((...e: any[]) => console.warn(...e)) const pathFragments: UrlSegment[] = fullPath.root.hasChildren() diff --git a/src/screenshot/util.ts b/src/screenshot/util.ts index 5a84dc7f1b76e9a420c3d311d1b7dfdd34e42439..8b8532ddf77a0e8b2a48de2bf082e2caaeb9bbfb 100644 --- a/src/screenshot/util.ts +++ b/src/screenshot/util.ts @@ -10,5 +10,5 @@ interface IScrnShot{ /** * if param is not provided, screenshot entire screen */ -export type TypeHandleScrnShotPromise = (param?: IScrnShot) => Promise<{ revoke: Function, url: string }> +export type TypeHandleScrnShotPromise = (param?: IScrnShot) => Promise<{ revoke: () => void, url: string }> export const HANDLE_SCREENSHOT_PROMISE = new InjectionToken('HANDLE_SCREENSHOT_PROMISE') \ No newline at end of file diff --git a/src/services/dialogService.service.ts b/src/services/dialogService.service.ts index c202eda5884ab18cc47d194d931504e19af11202..ee06d2a91e6a63d5b3e075d6e7cf7a05676108ca 100644 --- a/src/services/dialogService.service.ts +++ b/src/services/dialogService.service.ts @@ -22,7 +22,7 @@ export class DialogService { }) return new Promise((resolve, reject) => this.confirmDialogRef.afterClosed() .subscribe(val => { - if (val) { resolve() } else { reject('User cancelled') } + if (val) { resolve('Success') } else { reject('User cancelled') } }, reject, () => this.confirmDialogRef = null)) diff --git a/src/theme.scss b/src/theme.scss index f311da58eb993b86a235179246c4ab88dcbc79c1..5d8358d9b5f293359edd5bddb5fa63b09daab771 100644 --- a/src/theme.scss +++ b/src/theme.scss @@ -1,17 +1,17 @@ -@import '~@angular/material/theming'; -@import '~@angular/cdk/overlay-prebuilt.css'; +@use 'sass:map'; +@use '~@angular/material' as mat; -@include mat-core(); +@include mat.core(); @mixin custom-cmp($theme) { + $color-config: mat.get-color-config($theme); $foreground: map-get($theme, foreground); $background: map-get($theme, background); - $background-color: map-get($background, background); - $primary: map-get($theme, primary); - $accent: map-get($theme, accent); - $warn: map-get($theme, warn); + $primary: map-get($color-config, primary); + $accent: map-get($color-config, accent); + $warn: map-get($color-config, warn); [iv-custom-comp], .iv-custom-comp @@ -40,62 +40,75 @@ &[bg], &.bg { - background-color: mat-color($background, background); + background-color: mat.get-color-from-palette($background, background); } &[darker-bg], &.darker-bg { - background-color: $background-color; + background-color: mat.get-color-from-palette($background, background); } &[text], &.text { - color: mat-color($foreground, text); + color: mat.get-color-from-palette($foreground, text); } &[primary], &.primary { - color: mat-color($primary); + color: mat.get-color-from-palette($primary, 500); } &[accent], &.accent { - color: mat-color($accent); + color: mat.get-color-from-palette($accent, 500); } &[warn], &.warn { - color: mat-color($warn); + color: mat.get-color-from-palette($warn, 500); } &.hoverable { &:hover { - background-color: mat-color($background, hover); + // background-color: mat-color($background, hover); cursor: pointer; } } } } -$iv-theme-primary: mat-palette($mat-indigo); -$iv-theme-accent: mat-palette($mat-amber); -$iv-theme-warn: mat-palette($mat-red); +$iv-theme-primary: mat.define-palette(mat.$indigo-palette); +$iv-theme-accent: mat.define-palette(mat.$amber-palette); +$iv-theme-warn: mat.define-palette(mat.$red-palette); -$iv-theme: mat-light-theme($iv-theme-primary, $iv-theme-accent, $iv-theme-warn); +$iv-theme: mat.define-light-theme(( + color: ( + primary: $iv-theme-primary, + accent: $iv-theme-accent, + warn: $iv-theme-warn, + ) +)); -@include angular-material-theme($iv-theme); +@include mat.all-component-themes($iv-theme); @include custom-cmp($iv-theme); -$iv-dark-theme-primary: mat-palette($mat-blue); -$iv-dark-theme-accent: mat-palette($mat-amber, A200, A100, A400); -$iv-dark-theme-warn: mat-palette($mat-red); -$iv-dark-theme: mat-dark-theme($iv-dark-theme-primary, $iv-dark-theme-accent, $iv-dark-theme-warn); +$iv-dark-theme-primary: mat.define-palette(mat.$blue-palette); +$iv-dark-theme-accent: mat.define-palette(mat.$amber-palette, A200, A100, A400); +$iv-dark-theme-warn: mat.define-palette(mat.$red-palette); + +$iv-dark-theme: mat.define-dark-theme(( + color: ( + primary: $iv-dark-theme-primary, + accent: $iv-dark-theme-accent, + warn: $iv-dark-theme-warn, + ) +)); /** * attribute has lower priority than class @@ -105,14 +118,14 @@ $iv-dark-theme: mat-dark-theme($iv-dark-theme-primary, $iv-dark-theme-accent, [darktheme=true], .darktheme.darktheme { - @include angular-material-theme($iv-dark-theme); + @include mat.all-component-themes($iv-dark-theme); @include custom-cmp($iv-dark-theme); } [darktheme=false], .lighttheme.lighttheme { - @include angular-material-theme($iv-theme); + @include mat.all-component-themes($iv-theme); @include custom-cmp($iv-theme); } diff --git a/src/ui/help/helpOnePager/helpOnePager.component.spec.ts b/src/ui/help/helpOnePager/helpOnePager.component.spec.ts index d591437defa2372454759049e7fe2e916fbec29f..08f17969c3656fb5d3d73ca8a6adf6270d605eae 100644 --- a/src/ui/help/helpOnePager/helpOnePager.component.spec.ts +++ b/src/ui/help/helpOnePager/helpOnePager.component.spec.ts @@ -1,14 +1,16 @@ import { CommonModule } from '@angular/common' -import { async, TestBed } from '@angular/core/testing' +import { TestBed } from '@angular/core/testing' import { ComponentsModule } from 'src/components' import { AngularMaterialModule } from 'src/sharedModules' -import { PureContantService, UtilModule } from 'src/util' +import { QuickTourModule } from 'src/ui/quickTour' +import { PureContantService } from 'src/util' +import { UtilModule } from 'src/util/util.module' import { HelpOnePager } from './helpOnePager.component' describe('> helpOnePager.component.ts', () => { describe('> HelpOnePager', () => { - beforeEach(async(() => { - TestBed.configureTestingModule({ + beforeEach(async() => { + await TestBed.configureTestingModule({ imports: [ ComponentsModule, CommonModule, @@ -17,6 +19,7 @@ describe('> helpOnePager.component.ts', () => { */ UtilModule, AngularMaterialModule, + QuickTourModule ], declarations: [ HelpOnePager, @@ -28,7 +31,7 @@ describe('> helpOnePager.component.ts', () => { } ] }).compileComponents() - })) + }) it('> should render a table', () => { const fixture = TestBed.createComponent(HelpOnePager) fixture.detectChanges() diff --git a/src/ui/nehubaContainer/2dLandmarks/landmark.base.ts b/src/ui/nehubaContainer/2dLandmarks/landmark.base.ts index 9d424edba5344b152eb561d4f8e3b92a0414925e..953c75ed49d956b42023822fec53daea65adcec7 100644 --- a/src/ui/nehubaContainer/2dLandmarks/landmark.base.ts +++ b/src/ui/nehubaContainer/2dLandmarks/landmark.base.ts @@ -1,5 +1,6 @@ -import { Input } from "@angular/core" +import { Directive, Input } from "@angular/core" +@Directive() export class LandmarkUnitBase{ @Input() public positionX: number = 0 @Input() public positionY: number = 0 diff --git a/src/util/LinkedList.ts b/src/util/LinkedList.ts index 77e8e21e553ee16d74aebd343ee1c1ff6a81b3d9..6d468df6497abfa3ead5aa81fbffa1f1b6dc9b45 100644 --- a/src/util/LinkedList.ts +++ b/src/util/LinkedList.ts @@ -1,4 +1,7 @@ -export interface IDoublyLinkedItem<T extends object> { +// eslint-disable-next-line @typescript-eslint/ban-types +type TNonePrimitive = object + +export interface IDoublyLinkedItem<T extends TNonePrimitive> { next: IDoublyLinkedItem<T> prev: IDoublyLinkedItem<T> thisObj: T @@ -6,7 +9,7 @@ export interface IDoublyLinkedItem<T extends object> { list: DoublyLinkedList<T> } -export class DoublyLinkedList<T extends object>{ +export class DoublyLinkedList<T extends TNonePrimitive>{ public first: IDoublyLinkedItem<T> public last: IDoublyLinkedItem<T> @@ -99,7 +102,7 @@ export class DoublyLinkedList<T extends object>{ } } -export function FindInLinkedList<T extends object>(list: DoublyLinkedList<T>, predicate: (element: IDoublyLinkedItem<T>) => boolean){ +export function FindInLinkedList<T extends TNonePrimitive>(list: DoublyLinkedList<T>, predicate: (element: IDoublyLinkedItem<T>) => boolean){ let compareObj = list.first, returnObj: IDoublyLinkedItem<T> = null diff --git a/src/util/injectionTokens.ts b/src/util/injectionTokens.ts index eed3fbcb10bfe65e71ca23dfab5c3db621778159..f8720f5d6ce4ca2e19c473799afb695bee18be05 100644 --- a/src/util/injectionTokens.ts +++ b/src/util/injectionTokens.ts @@ -8,7 +8,7 @@ export type TClickInterceptorConfig = { export interface ClickInterceptor{ register: (interceptorFunction: (ev: any) => boolean, config?: TClickInterceptorConfig) => void - deregister: (interceptorFunction: Function) => void + deregister: (interceptorFunction: (ev: any) => any) => void } export const CONTEXT_MENU_ITEM_INJECTOR = new InjectionToken('CONTEXT_MENU_ITEM_INJECTOR') diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts index 3dfad4e558d68a7ca22f97c78d6c6985b8dc8157..d6371324add9456c8600470a775a110490afa0e6 100644 --- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts +++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts @@ -134,8 +134,8 @@ export class NehubaViewerUnit implements OnInit, OnDestroy { public ondestroySubscriptions: Subscription[] = [] - private createNehubaPromiseRs: Function - private createNehubaPromise = new Promise(rs => { + private createNehubaPromiseRs: () => void + private createNehubaPromise = new Promise<void>(rs => { this.createNehubaPromiseRs = rs }) diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts index 258c8ccdde186a21fdce5363df728073c65311c1..74176bf7d66e14e882fdba09ec35fc4b5a191db6 100644 --- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts +++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts @@ -55,8 +55,8 @@ describe('> nehubaViewerGlue.component.ts', () => { let mockStore: MockStore let rootLoader: HarnessLoader let fixture: ComponentFixture<NehubaGlueCmp> - beforeEach( async(() => { - TestBed.configureTestingModule({ + beforeEach( async () => { + await TestBed.configureTestingModule({ imports: [ CommonModule, AngularMaterialModule, @@ -116,7 +116,7 @@ describe('> nehubaViewerGlue.component.ts', () => { } ] }).compileComponents() - })) + }) beforeEach(() => { mockStore = TestBed.inject(MockStore) diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts index 665d7a33b321f34d66f362c1a23492b7653351ec..21b11a8d5f56ac41c444856ca99f88d0a4133cd7 100644 --- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts +++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts @@ -84,7 +84,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A public viewerLoaded: boolean = false private onhoverSegments = [] - private onDestroyCb: Function[] = [] + private onDestroyCb: (() => void)[] = [] private viewerUnit: NehubaViewerUnit private multiNgIdsRegionsLabelIndexMap: Map<string, Map<number, any>> diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts index 42c350441b7aba57d1a3d15eece54a238e25b2a7..84a54b7e24da734f57683c6981203d4516dea27a 100644 --- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts +++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts @@ -33,12 +33,6 @@ describe('> nehubaViewerInterface.directive.ts', () => { providers: [ provideMockStore({ initialState: {} }) ] - }).overrideModule(BrowserDynamicTestingModule,{ - set: { - entryComponents: [ - NehubaViewerUnit - ] - } }).overrideComponent(DummyCmp, { set: { template: ` diff --git a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts index c720fb1a073c5432924cc527d8192c5ca376806b..852a10faa56829c7ab8da8b87cbb749a19e04cc4 100644 --- a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts +++ b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts @@ -231,7 +231,7 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, OnChanges, Af const { register, deregister } = clickInterceptor register(handleClick) this.onDestroyCb.push( - () => deregister(register) + () => { deregister(register) } ) } diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts index f0eb2af8c0f4b65ef971973b6b979ab7a36b203c..1426fc874577952974e87f3ecc347ee632004db2 100644 --- a/src/viewerModule/viewerCmp/viewerCmp.component.ts +++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts @@ -212,7 +212,7 @@ export class ViewerCmp implements OnDestroy { public context: TContextArg<TSupportedViewers> private templateSelected: any - private getRegionFromlabelIndexId: Function + private getRegionFromlabelIndexId: (arg: {labelIndexId: string}) => any private genericInfoCF: ComponentFactory<GenericInfoCmp> constructor( diff --git a/tsconfig-aot.json b/tsconfig-aot.json deleted file mode 100644 index 827ddbeb6dbb12d543ea1678d2c99ffa4389cbad..0000000000000000000000000000000000000000 --- a/tsconfig-aot.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "exclude": [ - "**/*.spec.ts", - "./spec/*", - "src/atlasViewerExports/*" - ], - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "moduleResolution": "node", - "module": "esnext", - "target": "es2015", - "sourceMap": false, - "baseUrl": ".", - "paths": { - "third_party/*" : ["third_party/*"], - "src/*" : ["src/*"], - "common/*": ["common/*"] - } - }, - "angularCompilerOptions":{ - "fullTemplateTypeCheck": true, - "strictInjectionParameters": true, - "annotateForClosureCompiler" : true - } -} \ No newline at end of file diff --git a/tsconfig-dev-aot.json b/tsconfig-dev-aot.json deleted file mode 100644 index eb54150de482bdbe847a4f3348affe156f9e8b2e..0000000000000000000000000000000000000000 --- a/tsconfig-dev-aot.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "compilerOptions": { - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "moduleResolution": "node", - "module": "esnext", - "target": "es2015", - "sourceMap": true, - "baseUrl": ".", - "paths": { - "third_party/*" : ["third_party/*"], - "src/*" : ["src/*"], - "common/*": ["common/*"] - } - }, - "angularCompilerOptions":{ - "fullTemplateTypeCheck": true, - "strictInjectionParameters": true, - "annotateForClosureCompiler" : true - } -} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000000000000000000000000000000000000..9eecf098ab9df8a94086e9c511f3800652f701c8 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "exclude": [ + "**/*.spec.ts", + "./spec/*", + "src/atlasViewerExports/*" + ], + "files": [ + "src/main-aot.ts" + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 1833901f2db9f5097d430a3b428314d13b8cb904..15a0003e484369a70d602ca95fa1c95174849205 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,12 +5,17 @@ "moduleResolution": "node", "module": "esnext", "target": "es2015", - "sourceMap": true, + "sourceMap": false, "baseUrl": ".", "paths": { "third_party/*" : ["third_party/*"], "src/*" : ["src/*"], "common/*": ["common/*"] } + }, + "angularCompilerOptions":{ + "fullTemplateTypeCheck": true, + "strictInjectionParameters": true, + "annotateForClosureCompiler" : true } } \ No newline at end of file diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..1397650afa3da693dcb51c426556decae59707d9 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "files": [ + "spec/test.ts" + ], + "include": [ + "src/**/*.spec.ts" + ] +} \ No newline at end of file diff --git a/webpack/webpack.aot-common.js b/webpack/webpack.aot-common.js index 6c98c2f7cec402bdf5868eeaeec3db463ca331c8..3cff3bcc1f16439e218094165d762af1003718a8 100644 --- a/webpack/webpack.aot-common.js +++ b/webpack/webpack.aot-common.js @@ -1,73 +1,10 @@ const webpack = require('webpack') const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') -const ngtools = require('@ngtools/webpack') -const AngularCompilerPlugin = ngtools.AngularCompilerPlugin const merge = require('webpack-merge') const staticAssets = require('./webpack.staticassets') -const compileQuickOnePager = async () => { - - const TITLE = 'Interactive Atlas Viewer Quickstart' - - const showdown = require('showdown') - - const fs = require('fs') - const { promisify } = require('util') - const asyncReadfile = promisify(fs.readFile) - - const mdConverter = new showdown.Converter({ - tables: true - }) - - const pathToMd = path.join(__dirname, '../common/helpOnePager.md') - const mdData = await asyncReadfile(pathToMd, 'utf-8') - return ` -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> - <script src="https://unpkg.com/dompurify@latest/dist/purify.min.js"></script> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>${TITLE}</title> -</head> -<body class="p-4"> - -</body> -<script> -(() => { - const dirty = \`${mdConverter.makeHtml(mdData).replace(/\`/g, '\\`')}\` - const clean = DOMPurify.sanitize(dirty) - document.body.innerHTML = clean -})() -</script> -</html> -` -} -const outputPath = path.resolve(__dirname,'../dist/aot') - -compileQuickOnePager() - .then(html => { - const fs = require('fs') - const { execSync } = require('child_process') - const { promisify } = require('util') - const asyncWrite = promisify(fs.writeFile) - execSync(`mkdir -p ${outputPath}`) - return asyncWrite(path.join(outputPath, 'quickstart.html'), html, 'utf-8') - }) - .catch(e => { - console.warn(e) - }) - const commonAot = { - entry: { - main: './src/main-aot.ts' - }, - output : { - filename : '[name].js', - path : outputPath - }, module: { rules: [ { @@ -80,7 +17,8 @@ const commonAot = { } }, { - test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, + // test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, + test: /\.ts$/, loader: '@ngtools/webpack', exclude : /third_party|plugin_example|spec\.ts|test\.ts/ }, @@ -106,11 +44,6 @@ const commonAot = { new HtmlWebpackPlugin({ template : 'src/index.html' }), - new AngularCompilerPlugin({ - tsConfigPath: 'tsconfig-aot.json', - entryModule: 'src/main.module#MainModule', - directTemplateLoading: true - }), new webpack.DefinePlugin({ // TODO have to figure out how to set this properly // needed to avoid inline eval diff --git a/webpack/webpack.aot.js b/webpack/webpack.aot.js index 0660ec650c1501aea74a41d9e617bb4fc2d9f005..f283f84473616846b11dc1801de3f301b619bb34 100644 --- a/webpack/webpack.aot.js +++ b/webpack/webpack.aot.js @@ -1,6 +1,6 @@ const merge = require('webpack-merge') const aotCommon = require('./webpack.aot-common') - -module.exports = merge(aotCommon, { +const inputOutput = require('./webpack.entry-output') +module.exports = merge(inputOutput, aotCommon, { mode: 'production', }) diff --git a/webpack/webpack.dev-aot.js b/webpack/webpack.dev-aot.js index cca9f12439dd89e528541f7e5cf2edb764df26b1..c04cc954db94b630fa0fa20bf501bbcade50125f 100644 --- a/webpack/webpack.dev-aot.js +++ b/webpack/webpack.dev-aot.js @@ -1,8 +1,9 @@ const merge = require('webpack-merge') const aotCommon = require('./webpack.aot-common') const path = require('path') +const inputOutput = require('./webpack.entry-output') -module.exports = merge(aotCommon, { +module.exports = merge(inputOutput, aotCommon, { mode: 'development', devtool:'source-map', devServer: { diff --git a/webpack/webpack.entry-output.js b/webpack/webpack.entry-output.js new file mode 100644 index 0000000000000000000000000000000000000000..724913798492d58541b34c110f4685623921bb74 --- /dev/null +++ b/webpack/webpack.entry-output.js @@ -0,0 +1,75 @@ +const path = require('path') + +const compileQuickOnePager = async () => { + + const TITLE = 'Interactive Atlas Viewer Quickstart' + + const showdown = require('showdown') + + const fs = require('fs') + const { promisify } = require('util') + const asyncReadfile = promisify(fs.readFile) + + const mdConverter = new showdown.Converter({ + tables: true + }) + + const pathToMd = path.join(__dirname, '../common/helpOnePager.md') + const mdData = await asyncReadfile(pathToMd, 'utf-8') + return ` +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> + <script src="https://unpkg.com/dompurify@latest/dist/purify.min.js"></script> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>${TITLE}</title> +</head> +<body class="p-4"> + +</body> +<script> +(() => { + const dirty = \`${mdConverter.makeHtml(mdData).replace(/\`/g, '\\`')}\` + const clean = DOMPurify.sanitize(dirty) + document.body.innerHTML = clean +})() +</script> +</html> +` +} + +const outputPath = path.resolve(__dirname,'../dist/aot') + +compileQuickOnePager() + .then(html => { + const fs = require('fs') + const { execSync } = require('child_process') + const { promisify } = require('util') + const asyncWrite = promisify(fs.writeFile) + execSync(`mkdir -p ${outputPath}`) + return asyncWrite(path.join(outputPath, 'quickstart.html'), html, 'utf-8') + }) + .catch(e => { + console.warn(e) + }) + +const { AngularWebpackPlugin } = require('@ngtools/webpack') + +module.exports = { + entry: { + main: './src/main-aot.ts' + }, + output : { + filename : '[name].js', + path : outputPath + }, + plugins: [ + new AngularWebpackPlugin({ + tsConfigPath: 'tsconfig.app.json', + // entryModule: 'src/main.module#MainModule', + directTemplateLoading: true + }), + ] +} \ No newline at end of file diff --git a/webpack/webpack.export.aot.js b/webpack/webpack.export.aot.js deleted file mode 100644 index 2612d09449efa54b3a1e4f3bbbd16aceb4744c4b..0000000000000000000000000000000000000000 --- a/webpack/webpack.export.aot.js +++ /dev/null @@ -1,47 +0,0 @@ -const common = require('./webpack.common.js') -const path = require('path') -const ngtools = require('@ngtools/webpack') -const HtmlWebpackPlugin = require('html-webpack-plugin') -const AngularCompilerPlugin = ngtools.AngularCompilerPlugin -const ClosureCompilerPlugin = require('webpack-closure-compiler') - -module.exports = { - - entry : './src/main-aot.ts', - output : { - filename : 'main.js', - path : path.resolve(__dirname,'../dist/export-aot') - }, - module: { - rules: [ - { - test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, - // test : /\.ts$/, - loader: '@ngtools/webpack', - exclude : /third_party/ - }, - { - test : /\.(html|css)$/, - use : { - loader : 'raw-loader', - } - } - ] - }, - plugins : [ - new HtmlWebpackPlugin({ - template : './src/atlasViewerExports/export.html' - }), - new AngularCompilerPlugin({ - tsConfigPath: 'tsconfig-aot.json', - entryModule: 'src/atlasViewerExports/export.module#ExportModule' - }) - ], - resolve : { - extensions : [ - '.ts', - '.js', - '.json' - ] - } -} \ No newline at end of file diff --git a/webpack/webpack.prod.js b/webpack/webpack.prod.js index 325cdd3de8dfd4631952fe887994ab13bd5000f5..63e48c203bc1c9f34c1b540ec6e3060517e67955 100644 --- a/webpack/webpack.prod.js +++ b/webpack/webpack.prod.js @@ -1,6 +1,5 @@ const common = require('./webpack.common.js') const merge = require('webpack-merge') -const Uglify = require('uglifyjs-webpack-plugin') const path = require('path') const ClosureCompilerPlugin = require('webpack-closure-compiler') const ngAssets = require('./webpack.ngassets') diff --git a/webpack/webpack.test.js b/webpack/webpack.test.js index 713c1d28d4bf1a6638fbb0f1c9f61235c8fb0e8d..971e133e612a7a68a769ea79d16a2e9de4058a63 100644 --- a/webpack/webpack.test.js +++ b/webpack/webpack.test.js @@ -1,8 +1,8 @@ module.exports = { module : { rules : [{ - test: /spec\.ts$|test/, - loaders : ['ts-loader'], + test: /spec\.ts$/, + loader : 'ts-loader', exclude : /node_modules|third_party/ }] },