diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..37371cb --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,11 @@ +# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries +# +# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed + +> 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 \ No newline at end of file diff --git a/README.md b/README.md index 96e55e9..7408255 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,39 @@ -# Angular Universal & Anguar-CLI minimal starter +# Monitor Dashboard -> This demo is built following the [Angular-CLI Wiki guide](https://github.com/angular/angular-cli/wiki/stories-universal-rendering) +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.3.10 and has been updated to 11.2.14. -We're utilizing packages from the [Angular Universal @nguniversal](https://github.com/angular/universal) repo, such as [ng-module-map-ngfactory-loader](https://github.com/angular/universal/tree/master/modules/module-map-ngfactory-loader) to enable Lazy Loading. +## Install packages ---- +Run npm install (maybe needs sudo), a script that will delete unused files from library will be run. -## Static or Dynamic -This repo demonstrates the use of 2 different forms of Server Side Rendering. +## Development server -**Static** Also known as "prerendering" -* Happens at build time -* Renders your application and replaces the dist index.html with a version rendered at the route `/`. +Run `npm start` for a dev server. Navigate to `http://localhost:4600/dashboard`. The app will automatically reload if you change any of the source files. -**Dynamic** -* Happens at runtime -* Uses `ngExpressEngine` to render you application on the fly at the requested url. +## Build - CSR ---- +Use the `npm run build-dev` for a development build.
+Use the `npm run build-beta` for a beta build.
+Use the `npm run build-prod` for a production build. -## Installation -* `npm install` or `yarn` +## Build - SSR ---- +Use the `npm run build:ssr-dev` for a development build.
+Use the `npm run build:ssr-beta` for a beta build.
+Use the `npm run build:ssr-prod` for a production build. -## Development (Client-side only rendering) -* run `npm run start` which will start `ng serve` (project served at the standard: localhost:4200) +## Run SSR ---- +`npm run serve:ssr` will run the last server build. -## Production +## Webpack Analyzer -Depending on whether you're publishing dynamic or static prerendering, run the build command, and then serve up your dist folder assets. +In order to analyze bundle size you can run `npm run webpack-bundle-analyzer` -> **NOTE**: To deploy your **Static** site to a static hosting platform you will have to deploy the *`dist/browser`* folder, rather than the usual *`dist`* +## Running unit tests -ie: `npm run build:dynamic` or `npm run build:static`. All of the files that need to be served will be found within the `/dist` folder. - - - ---- - -## Testing Universal (dynamic or static) builds -Locally- - -**Dynamic** : **`npm run start:dynamic`** - -Compiles your application and spins up a Node Express to dynamically serve your Universal application on `http://localhost:4000`. - -**Static** : **`npm run start:static`** - -- Compiles your application and prerenders your applications files, spinning up a demo http-server so you can view it on `http://127.0.0.1:8080` +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). +## Running end-to-end tests +Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). diff --git a/angular.json b/angular.json index 88bf69e..b018be2 100644 --- a/angular.json +++ b/angular.json @@ -1,21 +1,46 @@ { - "$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json", + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { - "ng-universal-demo": { + "monitor-dashboard": { "root": "", "sourceRoot": "src", "projectType": "application", + "prefix": "app", + "schematics": { + "@schematics/angular:class": { + "skipTests": true + }, + "@schematics/angular:component": { + "skipTests": true + }, + "@schematics/angular:directive": { + "skipTests": true + }, + "@schematics/angular:guard": { + "skipTests": true + }, + "@schematics/angular:module": { + "skipTests": true + }, + "@schematics/angular:pipe": { + "skipTests": true + }, + "@schematics/angular:service": { + "skipTests": true + } + }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { - "outputPath": "dist/browser", + "aot": true, + "outputPath": "dist/monitor-dashboard/browser", "index": "src/index.html", "main": "src/main.ts", - "tsConfig": "src/tsconfig.app.json", "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", "assets": [ "src/assets", "src/robots.txt" @@ -36,52 +61,86 @@ "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, - "buildOptimizer": true + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ] }, - "production": { + "beta": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.beta.ts" + } + ], "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "fileReplacements": [ + "budgets": [ { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" }, { - "replace": "src/index.html", - "with": "src/index.prod.html" - }, - { - "replace": "src/robots.txt", - "with": "src/robots.prod.txt" + "type": "anyComponentStyle", + "maximumWarning": "6kb" } ] }, - "beta": { + "production": { + "assets": [ + "src/assets", + { + "input": "src/prod/", + "output": "/", + "glob": "*.txt" + } + ], + "index": { + "input": "src/prod/index.html", + "output": "index.html" + }, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], "optimization": true, "outputHashing": "all", "sourceMap": false, - "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, - "fileReplacements": [ + "budgets": [ { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.beta.ts" + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" } ] } @@ -90,45 +149,33 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "ng-universal-demo:build" + "browserTarget": "monitor-dashboard:build" }, "configurations": { "production": { - "browserTarget": "ng-universal-demo:build:production" - }, - "beta": { - "browserTarget": "ng-universal-demo:build:beta" - }, - "development": { - "browserTarget": "ng-universal-demo:build:development" + "browserTarget": "monitor-dashboard:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { - "browserTarget": "ng-universal-demo:build" + "browserTarget": "monitor-dashboard:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", - "karmaConfig": "./karma.conf.js", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", - "scripts": [ - "src/assets/common-assets/common/jquery.js", - "src/assets/common-assets/common/uikit.min.js", - "src/assets/common-assets/common/uikit-icons.min.js", - "node_modules/jquery/dist/jquery.js" - ], + "karmaConfig": "src/karma.conf.js", "styles": [ "src/styles.css" ], + "scripts": [], "assets": [ - "src/assets", - "src/robots.txt" + "src/assets" ] } }, @@ -147,58 +194,89 @@ "server": { "builder": "@angular-devkit/build-angular:server", "options": { - "outputPath": "dist/server", - "main": "src/main.server.ts", + "outputPath": "dist/monitor-dashboard/server", + "main": "server.ts", "tsConfig": "src/tsconfig.server.json" }, "configurations": { - "production": { + "development": { + "outputHashing": "media", + "sourceMap": false, + "optimization": true + }, + "beta": { + "outputHashing": "media", "fileReplacements": [ { "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - }, - { - "replace": "src/index.html", - "with": "src/index.prod.html" - }, - { - "replace": "src/robots.txt", - "with": "src/robots.prod.txt" + "with": "src/environments/environment.beta.ts" } - ] + ], + "sourceMap": false, + "optimization": true }, - "beta": { + "production": { + "outputHashing": "media", "fileReplacements": [ { "replace": "src/environments/environment.ts", - "with": "src/environments/environment.beta.ts" + "with": "src/environments/environment.prod.ts" } - ] - }, - "development": {} + ], + "sourceMap": false, + "optimization": true + } + } + }, + "serve-ssr": { + "builder": "@nguniversal/builders:ssr-dev-server", + "options": { + "browserTarget": "monitor-dashboard:build", + "serverTarget": "monitor-dashboard:server" + }, + "configurations": { + "production": { + "browserTarget": "monitor-dashboard:build:production", + "serverTarget": "monitor-dashboard:server:production" + } + } + }, + "prerender": { + "builder": "@nguniversal/builders:prerender", + "options": { + "browserTarget": "monitor-dashboard:build:production", + "serverTarget": "monitor-dashboard:server:production", + "routes": [ + "/" + ] + }, + "configurations": { + "production": {} } } } }, - "ng-universal-demo-e2e": { - "root": "e2e", - "sourceRoot": "e2e", + "monitor-dashboard-e2e": { + "root": "e2e/", "projectType": "application", + "prefix": "", "architect": { "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { - "protractorConfig": "./protractor.conf.js", - "devServerTarget": "ng-universal-demo:serve" + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "monitor-dashboard:serve" + }, + "configurations": { + "production": { + "devServerTarget": "monitor-dashboard:serve:production" + } } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { - "tsConfig": [ - "e2e/tsconfig.e2e.json" - ], + "tsConfig": "e2e/tsconfig.e2e.json", "exclude": [ "**/node_modules/**" ] @@ -207,33 +285,5 @@ } } }, - "defaultProject": "ng-universal-demo", - "schematics": { - "@schematics/angular:class": { - "spec": false - }, - "@schematics/angular:component": { - "spec": false, - "inlineStyle": true, - "inlineTemplate": true, - "prefix": "app", - "styleext": "css" - }, - "@schematics/angular:directive": { - "spec": false, - "prefix": "app" - }, - "@schematics/angular:guard": { - "spec": false - }, - "@schematics/angular:module": { - "spec": false - }, - "@schematics/angular:pipe": { - "spec": false - }, - "@schematics/angular:service": { - "spec": false - } - } + "defaultProject": "monitor-dashboard" } diff --git a/clean-library.sh b/clean-library.sh new file mode 100644 index 0000000..716cb96 --- /dev/null +++ b/clean-library.sh @@ -0,0 +1,3 @@ +cd src/app/openaireLibrary +cd ../../../ +echo "Done" diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js new file mode 100644 index 0000000..86776a3 --- /dev/null +++ b/e2e/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './src/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.e2e.json') + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; \ No newline at end of file diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts new file mode 100644 index 0000000..a098055 --- /dev/null +++ b/e2e/src/app.e2e-spec.ts @@ -0,0 +1,23 @@ +import { AppPage } from './app.po'; +import { browser, logging } from 'protractor'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getTitleText()).toEqual('Welcome to monitor-dashboard!'); + }); + + afterEach(async () => { + // Assert that there are no errors emitted from the browser + const logs = await browser.manage().logs().get(logging.Type.BROWSER); + expect(logs).not.toContain(jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry)); + }); +}); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts new file mode 100644 index 0000000..5776aa9 --- /dev/null +++ b/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + navigateTo() { + return browser.get(browser.baseUrl) as Promise; + } + + getTitleText() { + return element(by.css('app-root h1')).getText() as Promise; + } +} diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json new file mode 100644 index 0000000..a6dd622 --- /dev/null +++ b/e2e/tsconfig.e2e.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "jasminewd2", + "node" + ] + } +} \ No newline at end of file diff --git a/package.json b/package.json index b061c11..89ef34f 100644 --- a/package.json +++ b/package.json @@ -1,79 +1,72 @@ { - "name": "openaire-monitor", + "name": "monitor-dashboard", "version": "1.0.0", - "license": "Openaire", - "contributors": [ - "Argiro Kokogiannaki ", - "Konstantina Galouni " - ], "scripts": { "ng": "ng", - "start": " ng serve --port 4600 --disable-host-check --host 0.0.0.0 --base-href /dashboard/", - "start:ssr": "npm run build:ssr && npm run serve:ssr", - "start:prerender": "npm run build:prerender && npm run serve:prerender", - "start:ssr-beta": "npm run build:ssr-beta && npm run serve:ssr", - "start:prerender-beta": "npm run build:prerender-beta && npm run serve:prerender", - "start:ssr-dev": "npm run build:ssr-dev && npm run serve:ssr", - "start:prerender-dev": "npm run build:prerender-dev && npm run serve:prerender", + "start": "ng serve --port 4600 --disable-host-check --host 0.0.0.0", "build": "ng build", - "build:client-and-server-bundles": "ng build --prod --sourceMap --stats-json=true --base-href /dashboard/ && ng run ng-universal-demo:server:production", - "build:client-and-server-bundles-beta": "ng build --configuration=beta --sourceMap --stats-json=true --base-href /dashboard/ && ng run ng-universal-demo:server:beta", - "build:client-and-server-bundles-dev": "ng build --configuration=development --sourceMap --stats-json=true && ng run ng-universal-demo:server:development", - "build:prerender": "npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:prerender", - "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server", - "build:prerender-beta": "npm run build:client-and-server-bundles-beta && npm run webpack:server && npm run generate:prerender", - "build:ssr-beta": "npm run build:client-and-server-bundles-beta && npm run webpack:server", - "build:prerender-dev": "npm run build:client-and-server-bundles-dev && npm run webpack:server && npm run generate:prerender", - "build:ssr-dev": "npm run build:client-and-server-bundles-dev && npm run webpack:server", - "generate:prerender": "cd dist && node prerender", - "webpack:server": "webpack --config webpack.server.config.js --progress --colors", - "serve:prerender": "cd dist/browser && http-server", - "serve:ssr": "node dist/server", - "after-build-clean": "rm -rf src node_modules .idea/ installOpenaireLib.sh deploy dist/browser/assets/common-assets/.svn/ dist/browser/stats.json ; " + "build-dev": "ng build --configuration=development --source-map --base-href /dashboard/", + "build-beta": "ng build --configuration=beta --base-href /dashboard/ --source-map", + "build-prod": "ng build --prod --base-href /dashboard/ --sourceMap ", + "webpack-bundle-analyzer": "ng build --stats-json && webpack-bundle-analyzer dist/monitor-dashboard/browser/stats.json --host 0.0.0.0", + "test": "ng test", + "e2e": "ng e2e", + "dev:ssr": "ng run monitor-dashboard:serve-ssr", + "serve:ssr": "node dist/monitor-dashboard/server/main.js", + "build:ssr-dev": "npm run build-dev && ng run monitor-dashboard:server:development", + "build:ssr-beta": "npm run build-beta && ng run monitor-dashboard:server:beta", + "build:ssr-prod": "npm run build-prod && ng run monitor-dashboard:server:production", + "prerender": "ng run monitor-dashboard:prerender", + "postinstall": "chmod +x clean-library.sh && ./clean-library.sh", + "after-build-clean": "rm -rf dist/monitor-dashboard/browser/assets/common-assets/.svn/ src/app/openaireLibrary/.svn node_modules src/assets/common-assets/.svn/" }, "private": true, "dependencies": { - "@angular/animations": "^7.2.14", - "@angular/cdk": "^7.3.7", - "@angular/common": "7.2.14", - "@angular/compiler": "7.2.14", - "@angular/core": "7.2.14", - "@angular/forms": "7.2.14", - "@angular/http": "7.2.14", - "@angular/material": "^7.3.7", - "@angular/platform-browser": "7.2.14", - "@angular/platform-browser-dynamic": "7.2.14", - "@angular/platform-server": "7.2.14", - "@angular/router": "7.2.14", - "@nguniversal/express-engine": "^6.0.0", - "@nguniversal/module-map-ngfactory-loader": "^6.0.0", - "@types/express": "^4.16.1", + "@angular/animations": "~11.2.14", + "@angular/cdk": "^11.2.13", + "@angular/common": "~11.2.14", + "@angular/compiler": "~11.2.14", + "@angular/core": "~11.2.14", + "@angular/forms": "~11.2.14", + "@angular/localize": "^11.2.14", + "@angular/material": "^11.2.13", + "@angular/platform-browser": "~11.2.14", + "@angular/platform-browser-dynamic": "~11.2.14", + "@angular/platform-server": "~11.2.14", + "@angular/router": "~11.2.14", + "@nguniversal/express-engine": "^11.2.1", "clipboard": "^1.5.16", - "core-js": "^2.4.1", + "core-js": "^2.5.4", + "express": "^4.15.2", "jquery": "^3.4.1", - "ng-recaptcha": "^3.0.5", - "ng2-ckeditor": "1.1.9", - "ngx-json-ld": "0.1.6", - "nouislider": "^14.6.0", - "prom-client": "^11.3.0", + "ng-recaptcha": "^7.0.1", + "ng2-ckeditor": "1.3.1", + "rxjs": "^6.5.1", "ts-md5": "^1.2.0", - "tslib": "^1.9.0", - "zone.js": "^0.8.26" + "tslib": "^2.0.0", + "zone.js": "~0.10.2" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.13.0", - "@angular/cli": "^7.3.9", - "@angular/compiler-cli": "7.2.14", - "@angular/language-service": "7.2.14", - "@types/jquery": "^3.3.29", - "@types/node": "^8.0.30", - "cpy-cli": "^1.0.1", - "http-server": "^0.10.0", - "reflect-metadata": "^0.1.10", - "rxjs": "6.5.1", - "rxjs-compat": "^6.5.1", - "ts-loader": "^4.2.0", - "typescript": "3.2.4", - "webpack-cli": "^3.3.2" + "@angular-devkit/build-angular": "~0.1102.14", + "@angular/cli": "~11.2.14", + "@angular/compiler-cli": "~11.2.14", + "@angular/language-service": "~11.2.14", + "@nguniversal/builders": "^11.2.1", + "@types/express": "^4.17.0", + "@types/compression": "^1.7.0", + "@types/node": "^12.11.1", + "@types/jasmine": "~3.6.0", + "@types/jasminewd2": "~2.0.3", + "codelyzer": "^6.0.0", + "jasmine-core": "~3.8.0", + "jasmine-spec-reporter": "~5.0.0", + "karma": "~6.3.3", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage-istanbul-reporter": "~3.0.2", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "^1.6.0", + "protractor": "~7.0.0", + "ts-node": "~7.0.0", + "typescript": "~4.0.7" } } diff --git a/prerender.ts b/prerender.ts deleted file mode 100644 index c664006..0000000 --- a/prerender.ts +++ /dev/null @@ -1,45 +0,0 @@ -// Load zone.js for the server. -import 'zone.js/dist/zone-node'; -import 'reflect-metadata'; -import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; -import { join } from 'path'; - -import { enableProdMode } from '@angular/core'; -// Faster server renders w/ Prod mode (dev mode never needed) -enableProdMode(); - -// Express Engine -import { ngExpressEngine } from '@nguniversal/express-engine'; -// Import module map for lazy loading -import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; -import { renderModuleFactory } from '@angular/platform-server'; -import { ROUTES } from './static.paths'; - -// * NOTE :: leave this as require() since this file is built Dynamically from webpack -const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main'); - -const BROWSER_FOLDER = join(process.cwd(), 'browser'); - -// Load the index.html file containing referances to your application bundle. -const index = readFileSync(join('browser', 'index.html'), 'utf8'); - -let previousRender = Promise.resolve(); - -// Iterate each route path -ROUTES.forEach(route => { - const fullPath = join(BROWSER_FOLDER, route); - - // Make sure the directory structure is there - if(!existsSync(fullPath)){ - mkdirSync(fullPath); - } - - // Writes rendered HTML to index.html, replacing the file if it already exists. - previousRender = previousRender.then(_ => renderModuleFactory(AppServerModuleNgFactory, { - document: index, - url: route, - extraProviders: [ - provideModuleMap(LAZY_MODULE_MAP) - ] - })).then(html => writeFileSync(join(fullPath, 'index.html'), html)); -}); diff --git a/server.ts b/server.ts index 6e27aea..23a4f34 100644 --- a/server.ts +++ b/server.ts @@ -1,82 +1,77 @@ import 'zone.js/dist/zone-node'; -import 'reflect-metadata'; -import { renderModuleFactory } from '@angular/platform-server'; -import { enableProdMode } from '@angular/core'; +import { ngExpressEngine } from '@nguniversal/express-engine'; import * as express from 'express'; +import * as compression from 'compression'; import { join } from 'path'; -import { readFileSync } from 'fs'; -// Faster server renders w/ Prod mode (dev mode never needed) -enableProdMode(); +import { AppServerModule } from './src/main.server'; +import { APP_BASE_HREF } from '@angular/common'; +import { existsSync } from 'fs'; +import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens"; -// Express server -const app = express(); +// The Express app is exported so that it can be used by serverless Functions. +export function app() { + const server = express(); + server.use(compression()); + const distFolder = join(process.cwd(), 'dist/monitor-dashboard/browser'); + const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index'; -const PORT = 4000; -const DIST_FOLDER = join(process.cwd(), 'dist'); + // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) + server.engine('html', ngExpressEngine({ + bootstrap: AppServerModule, + })); -// Our index.html we'll use as our template -const template = readFileSync(join(DIST_FOLDER, 'browser', 'index.html')).toString(); + server.set('view engine', 'html'); + server.set('views', distFolder); -// * NOTE :: leave this as require() since this file is built Dynamically from webpack -const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main'); + // Example Express Rest API endpoints + // server.get('/api/**', (req, res) => { }); + // Serve static files from /browser + server.get('*.*', express.static(distFolder, { + maxAge: '1y' + })); -// Express Engine -import {ngExpressEngine, RenderOptions} from '@nguniversal/express-engine'; -// Import module map for lazy loading -import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; -import {REQUEST, RESPONSE} from "@nguniversal/express-engine/tokens"; - -// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) -// app.engine('html', ngExpressEngine({ -// bootstrap: AppServerModuleNgFactory, -// providers: [ -// { provide: 'request', useFactory: () => options.req, deps: [] }, -// provideModuleMap(LAZY_MODULE_MAP) -// ] -// })); - -// be able to get request and get domain from there -app.engine('html', (_, options: any, callback) => { - const opts = { - document: template, - url: options.req.url, - extraProviders: [ - provideModuleMap(LAZY_MODULE_MAP), - { - provide: REQUEST, - useValue: options.req - }, - { - provide: RESPONSE, - useValue: options.req.res, - }, - ] - }; - - renderModuleFactory(AppServerModuleNgFactory, opts) - .then(html => callback(null, html) + // All regular routes use the Universal engine + server.get('*', (req, res) => { + res.render(indexHtml, { + req, providers: [ + { + provide: APP_BASE_HREF, + useValue: req.baseUrl + }, + { + provide: REQUEST, useValue: (req) + }, + { + provide: RESPONSE, useValue: (res) + } + ] + } ); -}); -app.set('view engine', 'html'); -app.set('views', join(DIST_FOLDER, 'browser')); + }); + + return server; +} -/* - Example Express Rest API endpoints - - app.get('/api/**', (req, res) => { }); -*/ +function run() { + const port = process.env.PORT || 4000; -// Server static files from /browser -app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), { - maxAge: '1y' -})); + // Start up the Node server + const server = app(); + server.listen(port, () => { + console.log(`Node Express server listening on http://localhost:${port}`); + }); +} -// ALl regular routes use the Universal engine -app.get('*', (req, res) => { - res.render('index', { req }); -}); +// Webpack will replace 'require' with '__webpack_require__' +// '__non_webpack_require__' is a proxy to Node 'require' +// The below code is to ensure that the server is run only when not requiring the bundle. +declare const __non_webpack_require__: NodeRequire; +const mainModule = __non_webpack_require__.main; +const moduleFilename = mainModule && mainModule.filename || ''; +if (moduleFilename === __filename || moduleFilename.includes('iisnode')) { + run(); +} -// Start up the Node server -app.listen(PORT, () => { - console.log(`Node Express server listening on http://localhost:${PORT}`); -}); +export * from './src/main.server'; diff --git a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts index 978455a..31fdce0 100644 --- a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts +++ b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts @@ -5,29 +5,29 @@ import {RouterModule} from "@angular/router"; imports: [RouterModule.forChild([ { path: '', - loadChildren: '../general/general.module#GeneralModule', + loadChildren: () => import('../general/general.module').then(m => m.GeneralModule), data: {hasAdminMenu: true}, pathMatch: 'full' }, { path: 'users', - loadChildren: '../users/users.module#UsersModule', + loadChildren: () => import('../users/users.module').then(m => m.UsersModule), data: {hasAdminMenu: true}, pathMatch: 'full' }, { path: 'indicators', - loadChildren: '../topic/topic.module#TopicModule', + loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule), pathMatch: 'full' }, { path: 'indicators/:topic', - loadChildren: '../topic/topic.module#TopicModule', + loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule), pathMatch: 'full' }, { path: 'admin-tools', - loadChildren: '../admin-tools/admin-tools-routing.module#AdminToolsRoutingModule', + loadChildren: () => import('../admin-tools/admin-tools-routing.module').then(m => m.AdminToolsRoutingModule), data: { hasAdminMenu: true, param: 'stakeholder' diff --git a/src/app/admin-tools/admin-tools-routing.module.ts b/src/app/admin-tools/admin-tools-routing.module.ts index 577f642..9ce473a 100644 --- a/src/app/admin-tools/admin-tools-routing.module.ts +++ b/src/app/admin-tools/admin-tools-routing.module.ts @@ -6,36 +6,32 @@ import {RouterModule} from '@angular/router'; RouterModule.forChild([ { path: 'entities', - loadChildren: '../openaireLibrary/dashboard/entity/entities.module#EntitiesModule', + loadChildren: () => import('../openaireLibrary/dashboard/entity/entities.module').then(m => m.EntitiesModule), + pathMatch: 'full' + }, + { + path: 'classContents', + loadChildren: () => import('../openaireLibrary/dashboard/divhelpcontent/class-help-contents.module').then(m => m.ClassHelpContentsModule), + pathMatch: 'full' + }, + { + path: 'classContents/edit', + loadChildren: () => import('../openaireLibrary/dashboard/divhelpcontent/class-help-content-form.module').then(m => m.ClassHelpContentFormModule), pathMatch: 'full' }, - /* { - path: 'classContents', - loadChildren: '../openaireLibrary/dashboard/divhelpcontent/div-help-contents.module#DivHelpContentsModule' - }, - { - path: 'classContents/new', - loadChildren: '../openaireLibrary/dashboard/divhelpcontent/new-div-help-content.module#NewDivHelpContentModule', - pathMatch: 'full' - }, - { - path: 'classContents/edit', - loadChildren: '../openaireLibrary/dashboard/divhelpcontent/edit-div-help-content.module#EditDivHelpContentModule', - pathMatch: 'full' - },*/ { path: 'helptexts', - loadChildren: '../openaireLibrary/dashboard/helpTexts/page-help-contents.module#PageHelpContentsModule', + loadChildren: () => import('../openaireLibrary/dashboard/helpTexts/page-help-contents.module').then(m => m.PageHelpContentsModule), pathMatch: 'full' }, { path: 'helptexts/edit', - loadChildren: '../openaireLibrary/dashboard/helpTexts/page-help-content-form.module#PageHelpContentFormModule', + loadChildren: () => import('../openaireLibrary/dashboard/helpTexts/page-help-content-form.module').then(m => m.PageHelpContentFormModule), pathMatch: 'full' }, { path: 'pages', - loadChildren: '../openaireLibrary/dashboard/page/pages.module#PagesModule', + loadChildren: () => import('../openaireLibrary/dashboard/page/pages.module').then(m => m.PagesModule), pathMatch: 'full' } ]) diff --git a/src/app/admin-tools/portal-admin-tools-routing.module.ts b/src/app/admin-tools/portal-admin-tools-routing.module.ts index b179ef9..bdd80fb 100644 --- a/src/app/admin-tools/portal-admin-tools-routing.module.ts +++ b/src/app/admin-tools/portal-admin-tools-routing.module.ts @@ -3,9 +3,9 @@ import {RouterModule} from "@angular/router"; @NgModule({ imports: [RouterModule.forChild([ - {path: '', loadChildren: './admin-tools-routing.module#AdminToolsRoutingModule'}, - {path: 'portals', loadChildren: '../openaireLibrary/dashboard/portal/portals.module#PortalsModule'}, - {path: 'classes', loadChildren: '../openaireLibrary/dashboard/divId/divIds.module#DivIdsModule'} + {path: '', loadChildren: () => import('./admin-tools-routing.module').then(m => m.AdminToolsRoutingModule)}, + {path: 'portals', loadChildren: () => import('../openaireLibrary/dashboard/portal/portals.module').then(m => m.PortalsModule)}, + {path: 'classes', loadChildren: () => import('../openaireLibrary/dashboard/divId/divIds.module').then(m => m.DivIdsModule)} ])] }) export class PortalAdminToolsRoutingModule { diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d30365b..bad1f33 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -8,12 +8,12 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard"; const routes: Routes = [ { path: 'reload', - loadChildren: './reload/libReload.module#LibReloadModule', + loadChildren: () => import('./reload/libReload.module').then(m => m.LibReloadModule), data: {hasSidebar: false, hasHeader: false} }, { path: 'user-info', - loadChildren: './login/libUser.module#LibUserModule', + loadChildren: () => import('./login/libUser.module').then(m => m.LibUserModule), data: {hasSidebar: false, isFrontPage: true} }, { @@ -23,31 +23,31 @@ const routes: Routes = [ }, { path: 'admin', - loadChildren: './manageStakeholders/manageStakeholders.module#ManageStakeholdersModule', + loadChildren: () => import('./manageStakeholders/manageStakeholders.module').then(m => m.ManageStakeholdersModule), data: {hasAdminMenu: true}, canActivateChild: [LoginGuard] }, { path: 'admin/admin-tools', - loadChildren: './admin-tools/portal-admin-tools-routing.module#PortalAdminToolsRoutingModule', + loadChildren: () => import('./admin-tools/portal-admin-tools-routing.module').then(m => m.PortalAdminToolsRoutingModule), canActivateChild: [AdminLoginGuard], data: {hasAdminMenu: true} }, { path: 'admin/monitor/admin-tools', - loadChildren: './admin-tools/admin-tools-routing.module#AdminToolsRoutingModule', + loadChildren: () => import('./admin-tools/admin-tools-routing.module').then(m => m.AdminToolsRoutingModule), canActivateChild: [AdminLoginGuard], data: {hasAdminMenu: true, portal: 'monitor'} }, { path: 'admin/:stakeholder', - loadChildren: './admin-stakeholder/admin-stakeholder-routing.module#AdminStakeholderRoutingModule', + loadChildren: () => import('./admin-stakeholder/admin-stakeholder-routing.module').then(m => m.AdminStakeholderRoutingModule), canActivateChild: [AdminDashboardGuard] }, - {path: 'theme', loadChildren: './openaireLibrary/utils/theme/theme.module#ThemeModule'}, + {path: 'theme', loadChildren: () => import('./openaireLibrary/utils/theme/theme.module').then(m => m.ThemeModule)}, { path: '', - loadChildren: './monitor/monitor.module#MonitorModule', + loadChildren: () => import('./monitor/monitor.module').then(m => m.MonitorModule), data: {isFrontPage: true} }, { @@ -61,8 +61,7 @@ const routes: Routes = [ @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules, - onSameUrlNavigation: "reload", - relativeLinkResolution: 'corrected' + onSameUrlNavigation: "reload" })], exports: [RouterModule] }) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c2ea26a..8aea0bf 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,5 @@ import {ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit} from '@angular/core'; -import {ActivatedRoute, NavigationEnd, Params, Router} from '@angular/router'; +import {ActivatedRoute, Data, NavigationEnd, Params, Router} from '@angular/router'; import {EnvProperties} from './openaireLibrary/utils/properties/env-properties'; import {Role, Session, User} from './openaireLibrary/login/utils/helper.class'; import {UserManagementService} from "./openaireLibrary/services/user-management.service"; @@ -16,6 +16,7 @@ import {ConfigurationService} from "./openaireLibrary/utils/configuration/config import {Option} from "./openaireLibrary/sharedComponents/input/input.component"; import {StakeholderUtils} from "./utils/indicator-utils"; import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll"; +import {ConnectHelper} from "./openaireLibrary/connect/connectHelper"; @Component({ @@ -26,6 +27,7 @@ export class AppComponent implements OnInit, OnDestroy { properties: EnvProperties = properties; user: User; params: BehaviorSubject = new BehaviorSubject(null); + data: BehaviorSubject = new BehaviorSubject(null); hasSidebar: boolean = false; hasHeader: boolean = false; hasAdminMenu: boolean = false; @@ -71,9 +73,9 @@ export class AppComponent implements OnInit, OnDestroy { while (r.firstChild) { r = r.firstChild; } - let params = r.snapshot.params; this.paramsResolved = true; - this.params.next(params); + this.params.next(r.snapshot.params); + this.data.next(r.snapshot.data); } })); } @@ -128,7 +130,7 @@ export class AppComponent implements OnInit, OnDestroy { if (stakeholder) { this.stakeholder = stakeholder; LinksResolver.setProperties(this.stakeholder.alias); - this.setProperties(this.stakeholder.type, this.stakeholder.alias); + this.setProperties(this.stakeholder.alias, this.stakeholder.type); if (isSearch) { this.activeTopic = null; } else if (params && params['topic'] && !this.activeTopic) { @@ -142,7 +144,6 @@ export class AppComponent implements OnInit, OnDestroy { } else { this.stakeholder = null; LinksResolver.resetProperties(); - this.resetProperties(); this.navigateToError(); this.buildMenu(); this.loading = false; @@ -166,10 +167,15 @@ export class AppComponent implements OnInit, OnDestroy { this.stakeholder = null; this.buildMenu(); this.loading = false; - this.resetProperties(); } } })); + this.subscriptions.push(this.data.subscribe(data => { + if(data && data.portal) { + this.setProperties(data.portal); + this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity); + } + })); this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.user = user; if (user) { @@ -416,45 +422,17 @@ export class AppComponent implements OnInit, OnDestroy { return this.user && (Session.isPortalAdministrator(this.user) || Session.isCurator(stakeholder.type, this.user) || Session.isManager(stakeholder.type, stakeholder.alias, this.user)); } - private resolvePageInner() { - if (document !== undefined) { - let header = document.getElementById('pager_header_content'); - let inner = document.getElementById('page_content_inner'); - if (header) { - inner.setAttribute('style', '{margin-top:' + header.offsetHeight + '}'); - } else { - inner.setAttribute('style', '{margin-top:' + 0 + '}'); - } - } + public isPublicOrIsMember(visibility: Visibility): boolean { + return !(visibility == "PRIVATE" || (this.isViewPublic && visibility != "PUBLIC")); } - public isPublicOrIsMember(visibility: Visibility): boolean { - if (visibility == "PRIVATE" || (this.isViewPublic && visibility != "PUBLIC")) { - return false; + setProperties(id, type = null){ + this.properties.adminToolsCommunity = id; + if(type) { + this.properties.adminToolsPortalType = type; + } else { + ConnectHelper.setPortalTypeFromPid(id); } - return true; - } - setProperties(type, communityId){ - this.properties.adminToolsCommunity = communityId; - this.properties.adminToolsPortalType = type; - this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity); - } - resetProperties(){ - this.properties.adminToolsCommunity = "monitor"; - this.properties.adminToolsPortalType = "monitor"; this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity); } - - /* createSearchParameters() { - if (!this.stakeholder) { - return {}; - } - if (this.stakeholder.type == "funder") { - return {"relfunder": encodeURIComponent("\"" + this.stakeholder.index_id + "||" + this.stakeholder.index_name + "||" + this.stakeholder.index_shortName + "\"")}; - } else if (this.stakeholder.type == "ri") { - return {"community": encodeURIComponent("\"" + this.stakeholder.index_id + "||" + this.stakeholder.index_name + "\"")}; - } else if (this.stakeholder.type == "organization") { - return {"cf": true}; - } - }*/ } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 16b0562..050bf78 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -37,7 +37,7 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard"; NavigationBarModule, BottomModule, CookieLawModule, - BrowserModule.withServerTransition({appId: 'my-app'}), + BrowserModule.withServerTransition({ appId: 'serverApp' }), AppRoutingModule, BrowserTransferStateModule, SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule diff --git a/src/app/app.server.module.ts b/src/app/app.server.module.ts index 79602ec..795380c 100644 --- a/src/app/app.server.module.ts +++ b/src/app/app.server.module.ts @@ -1,20 +1,14 @@ -import {NgModule} from '@angular/core'; -import {ServerModule} from '@angular/platform-server'; -import {ModuleMapLoaderModule} from '@nguniversal/module-map-ngfactory-loader'; +import { NgModule } from '@angular/core'; +import { ServerModule } from '@angular/platform-server'; -import {AppModule} from './app.module'; -import {AppComponent} from './app.component'; +import { AppModule } from './app.module'; +import { AppComponent } from './app.component'; @NgModule({ imports: [ - // The AppServerModule should import your AppModule followed - // by the ServerModule from @angular/platform-server. AppModule, ServerModule, - ModuleMapLoaderModule, ], - // Since the bootstrapped component is not inherited from your - // imported AppModule, it needs to be repeated here. bootstrap: [AppComponent], }) export class AppServerModule {} diff --git a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts b/src/app/general/edit-stakeholder/edit-stakeholder.component.ts index a4324f6..d857431 100644 --- a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts +++ b/src/app/general/edit-stakeholder/edit-stakeholder.component.ts @@ -26,7 +26,7 @@ declare var UIkit;
-
import('../develop/develop.module').then(m => m.DevelopModule), canDeactivate: [PreviousRouteRecorder], data: { hasSidebar: false, @@ -23,7 +23,7 @@ import {MonitorComponent} from "./monitor.component"; }, { path: ':stakeholder/methodology', - loadChildren: '../methodology/methodology.module#MethodologyModule', + loadChildren: () => import('../methodology/methodology.module').then(m => m.MethodologyModule), canDeactivate: [PreviousRouteRecorder], data: { hasSidebar: false, @@ -32,7 +32,7 @@ import {MonitorComponent} from "./monitor.component"; }, { path: ':stakeholder/search', - loadChildren: '../search/search.module#SearchModule', + loadChildren: () => import('../search/search.module').then(m => m.SearchModule), canDeactivate: [PreviousRouteRecorder] }, { diff --git a/src/app/search/search.module.ts b/src/app/search/search.module.ts index e1ab3b0..bdbebc2 100644 --- a/src/app/search/search.module.ts +++ b/src/app/search/search.module.ts @@ -5,24 +5,24 @@ import {RouterModule} from "@angular/router"; imports: [CommonModule, RouterModule.forChild([ // Search Pages { path: '', redirectTo: 'find/research-outcomes'}, - { path: 'find/research-outcomes', loadChildren: './searchPages/simple/searchResearchResults.module#MonitorSearchResearchResultsModule'}, - { path: 'find/projects', loadChildren: './searchPages/simple/searchProjects.module#MonitorSearchProjectsModule'}, - { path: 'find/dataproviders', loadChildren: './searchPages/simple/searchDataProviders.module#MonitorSearchDataProvidersModule'}, - { path: 'find/organizations', loadChildren: './searchPages/simple/searchOrganizations.module#MonitorSearchOrganizationsModule'}, + { path: 'find/research-outcomes', loadChildren: () => import('./searchPages/simple/searchResearchResults.module').then(m => m.MonitorSearchResearchResultsModule)}, + { path: 'find/projects', loadChildren: () => import('./searchPages/simple/searchProjects.module').then(m => m.MonitorSearchProjectsModule)}, + { path: 'find/dataproviders', loadChildren: () => import('./searchPages/simple/searchDataProviders.module').then(m => m.MonitorSearchDataProvidersModule)}, + { path: 'find/organizations', loadChildren: () => import('./searchPages/simple/searchOrganizations.module').then(m => m.MonitorSearchOrganizationsModule)}, // Advanced Search Pages - { path: 'advanced/research-outcomes', loadChildren: './searchPages/advanced/searchResearchResults.module#MonitorAdvancedSearchResearchResultsModule'}, - { path: 'advanced/projects', loadChildren: './searchPages/advanced/searchProjects.module#MonitorAdvancedSearchProjectsModule'}, - { path: 'advanced/dataproviders', loadChildren: './searchPages/advanced/searchDataProviders.module#MonitorAdvancedSearchDataProvidersModule'}, - { path: 'advanced/organizations', loadChildren: './searchPages/advanced/searchOrganizations.module#MonitorAdvancedSearchOrganizationsModule'}, + { path: 'advanced/research-outcomes', loadChildren: () => import('./searchPages/advanced/searchResearchResults.module').then(m => m.MonitorAdvancedSearchResearchResultsModule)}, + { path: 'advanced/projects', loadChildren: () => import('./searchPages/advanced/searchProjects.module').then(m => m.MonitorAdvancedSearchProjectsModule)}, + { path: 'advanced/dataproviders', loadChildren: () => import('./searchPages/advanced/searchDataProviders.module').then(m => m.MonitorAdvancedSearchDataProvidersModule)}, + { path: 'advanced/organizations', loadChildren: () => import('./searchPages/advanced/searchOrganizations.module').then(m => m.MonitorAdvancedSearchOrganizationsModule)}, // Landing Pages - { path: 'result', loadChildren: './landingPages/result/libResult.module#LibResultModule'}, - { path: 'publication', loadChildren: './landingPages/publication/libPublication.module#LibPublicationModule'}, - { path: 'dataset', loadChildren: './landingPages/dataset/libDataset.module#LibDatasetModule'}, - { path: 'software', loadChildren: './landingPages/software/libSoftware.module#LibSoftwareModule'}, - { path: 'other', loadChildren: './landingPages/orp/libOrp.module#LibOrpModule'}, - { path: 'project', loadChildren: './landingPages/project/libProject.module#LibProjectModule'}, - { path: 'dataprovider', loadChildren: './landingPages/dataProvider/libDataProvider.module#LibDataProviderModule'}, - { path: 'organization', loadChildren: './landingPages/organization/libOrganization.module#LibOrganizationModule'}, + { path: 'result', loadChildren: () => import('./landingPages/result/libResult.module').then(m => m.LibResultModule)}, + { path: 'publication', loadChildren: () => import('./landingPages/publication/libPublication.module').then(m => m.LibPublicationModule)}, + { path: 'dataset', loadChildren: () => import('./landingPages/dataset/libDataset.module').then(m => m.LibDatasetModule)}, + { path: 'software', loadChildren: () => import('./landingPages/software/libSoftware.module').then(m => m.LibSoftwareModule)}, + { path: 'other', loadChildren: () => import('./landingPages/orp/libOrp.module').then(m => m.LibOrpModule)}, + { path: 'project', loadChildren: () => import('./landingPages/project/libProject.module').then(m => m.LibProjectModule)}, + { path: 'dataprovider', loadChildren: () => import('./landingPages/dataProvider/libDataProvider.module').then(m => m.LibDataProviderModule)}, + { path: 'organization', loadChildren: () => import('./landingPages/organization/libOrganization.module').then(m => m.LibOrganizationModule)}, ])] }) export class SearchModule {} diff --git a/src/app/topic/indicators.component.ts b/src/app/topic/indicators.component.ts index e960d7c..f12acee 100644 --- a/src/app/topic/indicators.component.ts +++ b/src/app/topic/indicators.component.ts @@ -83,14 +83,14 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV public numberResults: Map = new Map(); private subscriptions: any[] = []; private urlSubscriptions: any[] = []; - @ViewChild('editChartModal') editChartModal: AlertModal; - @ViewChild('editNumberModal') editNumberModal: AlertModal; - @ViewChild('deleteModal') deleteModal: AlertModal; + @ViewChild('editChartModal', { static: true }) editChartModal: AlertModal; + @ViewChild('editNumberModal', { static: true }) editNumberModal: AlertModal; + @ViewChild('deleteModal', { static: true }) deleteModal: AlertModal; //@ViewChild('deleteAllModal') deleteAllModal: AlertModal; //@ViewChild('deleteAndDisconnectModal') deleteAndDisconnectModal: AlertModal; //@ViewChild('deleteChartSectionModal') deleteChartSectionModal: AlertModal; //@ViewChild('deleteNumberSectionModal') deleteNumberSectionModal: AlertModal; - @ViewChild('deleteSectionModal') deleteSectionModal: AlertModal; + @ViewChild('deleteSectionModal', { static: true }) deleteSectionModal: AlertModal; public sectionTypeToDelete: string; public sectionChildrenActionOnDelete: string; public indicatorChildrenActionOnDelete: string; @@ -99,9 +99,9 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV urlParameterizedMessage = null; showCheckForSchemaEnhancements:boolean = false; private notification: Notification; - @ViewChild('editNumberNotify') editNumberNotify: NotifyFormComponent; - @ViewChild('editChartNotify') editChartNotify: NotifyFormComponent; - @ViewChild('deleteNotify') deleteNotify: NotifyFormComponent; + @ViewChild('editNumberNotify', { static: true }) editNumberNotify: NotifyFormComponent; + @ViewChild('editChartNotify', { static: true }) editChartNotify: NotifyFormComponent; + @ViewChild('deleteNotify', { static: true }) deleteNotify: NotifyFormComponent; constructor(private layoutService: LayoutService, private stakeholderService: StakeholderService, private statisticsService: StatisticsService, diff --git a/src/app/topic/topic.component.ts b/src/app/topic/topic.component.ts index bec616d..f146822 100644 --- a/src/app/topic/topic.component.ts +++ b/src/app/topic/topic.component.ts @@ -59,8 +59,8 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { */ public toggle: boolean = false; - @ViewChild('deleteModal') deleteModal: AlertModal; - @ViewChild('editModal') editModal: AlertModal; + @ViewChild('deleteModal', { static: true }) deleteModal: AlertModal; + @ViewChild('editModal', { static: true }) editModal: AlertModal; public elementChildrenActionOnDelete: string; public filters: FormGroup; public all: Option = { diff --git a/src/app/utils/adminDashboard.guard.ts b/src/app/utils/adminDashboard.guard.ts index 19d993d..c440582 100644 --- a/src/app/utils/adminDashboard.guard.ts +++ b/src/app/utils/adminDashboard.guard.ts @@ -7,14 +7,12 @@ import { RouterStateSnapshot, UrlTree } from '@angular/router'; -import {Observable} from 'rxjs/Observable'; - import {map, take, tap} from "rxjs/operators"; import {UserManagementService} from "../openaireLibrary/services/user-management.service"; import {LoginErrorCodes} from "../openaireLibrary/login/utils/guardHelper.class"; import {Session} from "../openaireLibrary/login/utils/helper.class"; import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; -import {zip} from "rxjs"; +import {Observable, zip} from "rxjs"; @Injectable() @@ -45,7 +43,7 @@ export class AdminDashboardGuard implements CanActivate, CanActivateChild { } } - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { return this.check(state.url, route.params.stakeholder); } diff --git a/src/assets/new.css b/src/assets/new.css index 0cd0fce..ffbd369 100644 --- a/src/assets/new.css +++ b/src/assets/new.css @@ -16,7 +16,7 @@ } .stakeholderPage #page_content { - background-image: url("/assets/monitor-shapes-bg.svg"); + background-image: url("~src/assets/monitor-shapes-bg.svg"); background-size: contain; background-repeat: no-repeat; background-position: bottom; @@ -70,12 +70,12 @@ /*}*/ /*Sidebar Header logo */ #sidebar_main .sidebar_main_header .portal-logo { - background: url("/assets/common-assets/logo-large-monitor.png") no-repeat; + background: url("~src/assets/common-assets/logo-large-monitor.png") no-repeat; background-size: contain; } .sidebar_mini #sidebar_main .sidebar_main_header .portal-logo { - background: url("/assets/common-assets/logo-small-monitor.png") no-repeat; + background: url("~src/assets/common-assets/logo-small-monitor.png") no-repeat; background-size: contain; } diff --git a/src/assets/theme-assets/dashboard-custom.css b/src/assets/theme-assets/dashboard-custom.css index a150484..8292b4f 100644 --- a/src/assets/theme-assets/dashboard-custom.css +++ b/src/assets/theme-assets/dashboard-custom.css @@ -64,14 +64,14 @@ html .dashboard { .dashboard #sidebar_main .sidebar_main_header .portalLogo{ - background: url("/assets/logo-large-monitor.png") no-repeat; + background: url("~src/assets/logo-large-monitor.png") no-repeat; background-size: contain ; margin-left: 35px; margin-top: 5px; } .dashboard .sidebar_mini #sidebar_main .sidebar_main_header .portalLogo{ - background: url("/assets/logo-small-monitor.png") no-repeat !important; + background: url("~src/assets/logo-small-monitor.png") no-repeat !important; background-size: 50px 50px !important; /* background-size: contain !important; margin-left: 5px;*/ diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 4faf8a2..a14ddd6 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -13,7 +13,7 @@ export let properties: EnvProperties = { statisticsFrameAPIURL: "https://www.openaire.eu/stats/", statisticsFrameNewAPIURL: "https://services.openaire.eu/stats-tool/", useNewStatistisTool: true, - monitorStatsFrameUrl:"https://services.openaire.eu/monitor-stats-tool/", + monitorStatsFrameUrl:"https://services.openaire.eu/stats-tool/", useOldStatisticsSchema: false, claimsAPIURL: "https://services.openaire.eu/claims/rest/claimsService/", searchAPIURLLAst: "https://services.openaire.eu/search/v2/api/", diff --git a/src/index.html b/src/index.html index fc63b7d..456b6f1 100644 --- a/src/index.html +++ b/src/index.html @@ -4,24 +4,35 @@ - + - - - - + + + + + + + + + + + + + + + diff --git a/src/karma.conf.js b/src/karma.conf.js new file mode 100644 index 0000000..c008923 --- /dev/null +++ b/src/karma.conf.js @@ -0,0 +1,32 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../coverage/monitor-dashboard'), + reports: ['html', 'lcovonly', 'text-summary'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/src/main.server.ts b/src/main.server.ts index d7c01cd..a085746 100644 --- a/src/main.server.ts +++ b/src/main.server.ts @@ -1 +1,15 @@ +/*************************************************************************************************** + * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates. +*/ +import '@angular/localize/init'; + +import {enableProdMode} from '@angular/core'; + +import {properties} from './environments/environment'; + +if (properties.environment !== "development") { + enableProdMode(); +} + export { AppServerModule } from './app/app.server.module'; +export { renderModule, renderModuleFactory } from '@angular/platform-server'; diff --git a/src/main.ts b/src/main.ts index d8a282e..82a0683 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,5 +9,6 @@ if (properties.environment !== "development") { } document.addEventListener('DOMContentLoaded', () => { - platformBrowserDynamic().bootstrapModule(AppModule); + platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); }); diff --git a/src/polyfills.ts b/src/polyfills.ts index 4e77c07..7c9e495 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -1,3 +1,7 @@ +/*************************************************************************************************** + * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates. + */ +import '@angular/localize/init'; /** * This file includes polyfills needed by Angular and is loaded before the app. * You can add your own extra polyfills to this file. @@ -11,61 +15,53 @@ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. * - * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + * Learn more in https://angular.io/guide/browser-support */ /*************************************************************************************************** * BROWSER POLYFILLS */ -/** IE9, IE10 and IE11 requires all of the following polyfills. **/ -import 'core-js/es6/symbol'; -import 'core-js/es6/object'; -import 'core-js/es6/function'; -import 'core-js/es6/parse-int'; -import 'core-js/es6/parse-float'; -import 'core-js/es6/number'; -import 'core-js/es6/math'; -import 'core-js/es6/string'; -import 'core-js/es6/date'; -import 'core-js/es6/array'; -import 'core-js/es6/regexp'; -import 'core-js/es6/map'; -import 'core-js/es6/weak-map'; -import 'core-js/es6/set'; - /** IE10 and IE11 requires the following for NgClass support on SVG elements */ // import 'classlist.js'; // Run `npm install --save classlist.js`. -/** Evergreen browsers require these. **/ -import 'core-js/es6/reflect'; - - /** - * Required to support Web Animations `@angular/animation`. - * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation - **/ + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + */ // import 'web-animations-js'; // Run `npm install --save web-animations-js`. - +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags.ts'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ /*************************************************************************************************** - * Zone JS is required by Angular itself. + * Zone JS is required by default for Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. - /*************************************************************************************************** * APPLICATION IMPORTS */ - -/** - * Date, currency, decimal and percent pipes. - * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 - */ -// import 'intl'; // Run `npm install --save intl`. -/** - * Need to import at least one locale-data with intl. - */ -// import 'intl/locale-data/jsonp/en'; diff --git a/src/index.prod.html b/src/prod/index.html similarity index 58% rename from src/index.prod.html rename to src/prod/index.html index 500fdce..643184f 100644 --- a/src/index.prod.html +++ b/src/prod/index.html @@ -4,7 +4,7 @@ - + @@ -21,6 +21,21 @@ + + + + + + + + + + + + + + + diff --git a/src/robots.prod.txt b/src/prod/robots.txt similarity index 100% rename from src/robots.prod.txt rename to src/prod/robots.txt diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..1631789 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,20 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json index 16b7847..f3a1b80 100644 --- a/src/tsconfig.app.json +++ b/src/tsconfig.app.json @@ -2,14 +2,13 @@ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", - "baseUrl": "./", - "module": "es2015", - "types": [ - "node" - ] + "types": [] }, - "exclude": [ - "test.ts", - "**/*.spec.ts" + "files": [ + "main.ts", + "polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" ] } diff --git a/src/tsconfig.server.json b/src/tsconfig.server.json index 7e55994..39f85aa 100644 --- a/src/tsconfig.server.json +++ b/src/tsconfig.server.json @@ -1,21 +1,17 @@ { - "extends": "../tsconfig.json", + "extends": "./tsconfig.app.json", "compilerOptions": { - "outDir": "../out-tsc/app", - "baseUrl": "./", - // Set the module format to "commonjs": - "module": "commonjs", + "outDir": "../out-tsc/app-server", + "target": "es2016", "types": [ "node" ] }, - "exclude": [ - "test.ts", - "**/*.spec.ts" + "files": [ + "main.server.ts", + "../server.ts" ], - // Add "angularCompilerOptions" with the AppServerModule you wrote - // set as the "entryModule". "angularCompilerOptions": { - "entryModule": "app/app.server.module#AppServerModule" + "entryModule": "./app/app.server.module#AppServerModule" } } diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json new file mode 100644 index 0000000..de77336 --- /dev/null +++ b/src/tsconfig.spec.json @@ -0,0 +1,18 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", + "polyfills.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/static.paths.ts b/static.paths.ts deleted file mode 100644 index be309ca..0000000 --- a/static.paths.ts +++ /dev/null @@ -1,15 +0,0 @@ -export const ROUTES = [ - '/', - '/lazy', - '/home', - '/search/publication','/search/other','/search/project','/search/dataset','/search/dataprovider','/search/organization', - '/search/find', - '/search/person','/search/publication','/search/project','/search/dataset','/search/dataprovider','/search/organization', - '/search/find/people','/search/find/publications','/search/find/other','/search/find/projects','/search/find/datasets','/search/find/dataproviders','/search/find/organizations', - '/search/advanced/people','/search/advanced/publications','/search/advanced/other','/search/advanced/projects','/search/advanced/datasets','/search/advanced/dataproviders','/search/advanced/organizations', - '/participate/deposit-publications','/participate/deposit-datasets','/participate/deposit-publications-result','/participate/deposit-datasets-result','/participate/deposit-subject-result', - '/search/content-providers','/search/content-providers-table','/search/entity-registries','/search/entity-registries-table','/search/journals','/search/journals-table', - '/project-report','/claims','/myclaims','/participate/claim','/participate/direct-claim','/claims-project-manager', - '/test','/user-info', - '/error', '/*path' -]; diff --git a/tsconfig.json b/tsconfig.json index 8cd9a30..8c693a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,23 @@ { "compileOnSave": false, "compilerOptions": { - "importHelpers": true, + "baseUrl": "./", + "downlevelIteration": true, "outDir": "./dist/out-tsc", "sourceMap": true, "declaration": false, + "module": "es2020", "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "target": "es5", + "importHelpers": true, + "target": "es2015", "typeRoots": [ "node_modules/@types" ], "lib": [ - "es2017", + "es2018", "dom" - ], - "module": "es2015", - "baseUrl": "./" + ] } -} \ No newline at end of file +} diff --git a/webpack.server.config.js b/webpack.server.config.js deleted file mode 100644 index 4d2b44f..0000000 --- a/webpack.server.config.js +++ /dev/null @@ -1,51 +0,0 @@ -// Work around for https://github.com/angular/angular-cli/issues/7200 - -const path = require('path'); -const webpack = require('webpack'); - -module.exports = { - //mode: 'none', - entry: { - // This is our Express server for Dynamic universal - server: './server.ts', - // This is an example of Static prerendering (generative) - prerender: './prerender.ts' - }, - target: 'node', - resolve: { extensions: ['.ts', '.js'] }, - // Make sure we include all node_modules etc - externals: [/(node_modules|main\..*\.js)/,], - optimization: { - minimize: false - }, - output: { - // Puts the output at the root of the dist folder - path: path.join(__dirname, 'dist'), - filename: '[name].js' - }, - module: { - rules: [ - { test: /\.ts$/, loader: 'ts-loader' } - ,{ - // Mark files inside `@angular/core` as using SystemJS style dynamic imports. - // Removing this will cause deprecation warnings to appear. - test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/, - parser: { system: true }, - }, - ] - }, - plugins: [ - new webpack.ContextReplacementPlugin( - // fixes WARNING Critical dependency: the request of a dependency is an expression - /(.+)?angular(\\|\/)core(.+)?/, - path.join(__dirname, 'src'), // location of your src - {} // a map of your routes - ), - new webpack.ContextReplacementPlugin( - // fixes WARNING Critical dependency: the request of a dependency is an expression - /(.+)?express(\\|\/)(.+)?/, - path.join(__dirname, 'src'), - {} - ) - ] -}