From 85ac5ea49301686af5c3fe118cdfb3b971e9b0f8 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 10:48:04 +0300 Subject: [PATCH 01/18] Update typescript to version 4.9.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38e13c9..ef1bf41 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,6 @@ "karma-jasmine-html-reporter": "^1.6.0", "protractor": "~7.0.0", "ts-node": "~7.0.0", - "typescript": "~4.6.4" + "typescript": "~4.9.5" } } -- 2.17.1 From 784d0b0e0ddbbc0190da34d8c21ec3f32f709619 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 11:02:52 +0300 Subject: [PATCH 02/18] Migrate angular core and cli to version 15 and update dependencies to be compatible with the newer version. --- angular.json | 3 ++- package.json | 34 +++++++++++++++++----------------- src/main.server.ts | 2 +- src/test.ts | 6 ------ src/tsconfig.server.json | 1 - tsconfig.json | 5 +++-- 6 files changed, 23 insertions(+), 28 deletions(-) diff --git a/angular.json b/angular.json index 145477d..4d4beee 100644 --- a/angular.json +++ b/angular.json @@ -214,7 +214,8 @@ "development": { "outputHashing": "media", "sourceMap": false, - "optimization": true + "optimization": true, + "vendorChunk": true }, "beta": { "outputHashing": "media", diff --git a/package.json b/package.json index ef1bf41..d3e602b 100644 --- a/package.json +++ b/package.json @@ -21,25 +21,25 @@ }, "private": true, "dependencies": { - "@angular/animations": "^14.2.3", + "@angular/animations": "^15.2.9", "@angular/cdk": "^14.2.2", - "@angular/common": "^14.2.3", - "@angular/compiler": "^14.2.3", - "@angular/core": "^14.2.3", - "@angular/forms": "^14.2.3", - "@angular/localize": "^14.2.3", + "@angular/common": "^15.2.9", + "@angular/compiler": "^15.2.9", + "@angular/core": "^15.2.9", + "@angular/forms": "^15.2.9", + "@angular/localize": "^15.2.9", "@angular/material": "^14.2.2", - "@angular/platform-browser": "^14.2.3", - "@angular/platform-browser-dynamic": "^14.2.3", - "@angular/platform-server": "^14.2.3", - "@angular/router": "^14.2.3", - "@nguniversal/express-engine": "^14.2.0", + "@angular/platform-browser": "^15.2.9", + "@angular/platform-browser-dynamic": "^15.2.9", + "@angular/platform-server": "^15.2.9", + "@angular/router": "^15.2.9", + "@nguniversal/express-engine": "^15.2.1", "axios": "^1.4.0", "clipboard": "^1.5.16", "core-js": "^2.5.4", "express": "^4.15.2", "jquery": "^3.4.1", - "ng-recaptcha": "^10.0.0", + "ng-recaptcha": "^11.0.0", "ng2-ckeditor": "1.3.7", "rxjs": "^6.5.1", "ts-md5": "^1.2.0", @@ -48,11 +48,11 @@ "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "^14.2.3", - "@angular/cli": "^14.2.3", - "@angular/compiler-cli": "^14.2.3", - "@angular/language-service": "^14.2.3", - "@nguniversal/builders": "^14.2.0", + "@angular-devkit/build-angular": "^15.2.9", + "@angular/cli": "^15.2.9", + "@angular/compiler-cli": "^15.2.9", + "@angular/language-service": "^15.2.9", + "@nguniversal/builders": "^15.2.1", "@types/ckeditor": "^4.9.10", "@types/compression": "^1.7.0", "@types/express": "^4.17.0", diff --git a/src/main.server.ts b/src/main.server.ts index ad64c40..62d4e8c 100644 --- a/src/main.server.ts +++ b/src/main.server.ts @@ -12,4 +12,4 @@ if (properties.environment !== "development") { } export { AppServerModule } from './app/app.server.module'; -export { renderModule } from '@angular/platform-server'; + diff --git a/src/test.ts b/src/test.ts index 6b03dbe..ae25f27 100644 --- a/src/test.ts +++ b/src/test.ts @@ -7,8 +7,6 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: any; - // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, @@ -16,7 +14,3 @@ getTestBed().initTestEnvironment( teardown: { destroyAfterEach: false } } ); -// 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.server.json b/src/tsconfig.server.json index 39f85aa..5601502 100644 --- a/src/tsconfig.server.json +++ b/src/tsconfig.server.json @@ -2,7 +2,6 @@ "extends": "./tsconfig.app.json", "compilerOptions": { "outDir": "../out-tsc/app-server", - "target": "es2016", "types": [ "node" ] diff --git a/tsconfig.json b/tsconfig.json index fc8b4c1..668d981 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,13 +10,14 @@ "moduleResolution": "node", "experimentalDecorators": true, "importHelpers": true, - "target": "es2020", + "target": "ES2022", "typeRoots": [ "node_modules/@types" ], "lib": [ "es2018", "dom" - ] + ], + "useDefineForClassFields": false } } -- 2.17.1 From f19ecfdfc55b439b79970ecc00282fc39d798262 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 13:52:18 +0300 Subject: [PATCH 03/18] Update material to angular 15. --- package.json | 6 +++--- src/app/openaireLibrary | 2 +- src/assets/common-assets | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d3e602b..7ccc776 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,13 @@ "private": true, "dependencies": { "@angular/animations": "^15.2.9", - "@angular/cdk": "^14.2.2", + "@angular/cdk": "^15.2.9", "@angular/common": "^15.2.9", "@angular/compiler": "^15.2.9", "@angular/core": "^15.2.9", "@angular/forms": "^15.2.9", "@angular/localize": "^15.2.9", - "@angular/material": "^14.2.2", + "@angular/material": "^15.2.9", "@angular/platform-browser": "^15.2.9", "@angular/platform-browser-dynamic": "^15.2.9", "@angular/platform-server": "^15.2.9", @@ -71,4 +71,4 @@ "ts-node": "~7.0.0", "typescript": "~4.9.5" } -} +} \ No newline at end of file diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index a53c4e9..3b6822c 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit a53c4e90d099d0bf3919df55edceaf7f793427d0 +Subproject commit 3b6822c71f32512533793e6b57f6ff017f4c874e diff --git a/src/assets/common-assets b/src/assets/common-assets index 2fd5784..9cb1f83 160000 --- a/src/assets/common-assets +++ b/src/assets/common-assets @@ -1 +1 @@ -Subproject commit 2fd57843f85125e54adfb95b35776755037ea359 +Subproject commit 9cb1f835a93501d9566ea2a3123d92eecd73f27d -- 2.17.1 From 658e92f1443b185a698c421ca0c37bd240174c9b Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 13:56:34 +0300 Subject: [PATCH 04/18] Update Zone to 0.13.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7ccc776..3425e44 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "ts-md5": "^1.2.0", "tslib": "^2.0.0", "uikit": "3.13.10", - "zone.js": "~0.11.4" + "zone.js": "~0.13.1" }, "devDependencies": { "@angular-devkit/build-angular": "^15.2.9", @@ -71,4 +71,4 @@ "ts-node": "~7.0.0", "typescript": "~4.9.5" } -} \ No newline at end of file +} -- 2.17.1 From 5bd1ab15ef45744f2729c9af7cc10f7690391d81 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 14:31:35 +0300 Subject: [PATCH 05/18] Update angular to version 16 --- angular.json | 12 ++++++---- package.json | 34 +++++++++++++-------------- src/app/app-routing.module.ts | 4 ++-- src/app/app.module.ts | 5 ++-- src/app/openaireLibrary | 2 +- src/app/utils/adminDashboard.guard.ts | 11 ++------- 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/angular.json b/angular.json index 4d4beee..6a72b29 100644 --- a/angular.json +++ b/angular.json @@ -208,14 +208,16 @@ "main": "server.ts", "tsConfig": "src/tsconfig.server.json", "sourceMap": true, - "optimization": false + "optimization": false, + "buildOptimizer": false }, "configurations": { "development": { "outputHashing": "media", "sourceMap": false, "optimization": true, - "vendorChunk": true + "vendorChunk": true, + "buildOptimizer": true }, "beta": { "outputHashing": "media", @@ -226,7 +228,8 @@ } ], "sourceMap": false, - "optimization": true + "optimization": true, + "buildOptimizer": true }, "production": { "outputHashing": "media", @@ -237,7 +240,8 @@ } ], "sourceMap": false, - "optimization": true + "optimization": true, + "buildOptimizer": true } }, "defaultConfiguration": "" diff --git a/package.json b/package.json index 3425e44..f5a38c6 100644 --- a/package.json +++ b/package.json @@ -21,25 +21,25 @@ }, "private": true, "dependencies": { - "@angular/animations": "^15.2.9", + "@angular/animations": "^16.1.7", "@angular/cdk": "^15.2.9", - "@angular/common": "^15.2.9", - "@angular/compiler": "^15.2.9", - "@angular/core": "^15.2.9", - "@angular/forms": "^15.2.9", - "@angular/localize": "^15.2.9", + "@angular/common": "^16.1.7", + "@angular/compiler": "^16.1.7", + "@angular/core": "^16.1.7", + "@angular/forms": "^16.1.7", + "@angular/localize": "^16.1.7", "@angular/material": "^15.2.9", - "@angular/platform-browser": "^15.2.9", - "@angular/platform-browser-dynamic": "^15.2.9", - "@angular/platform-server": "^15.2.9", - "@angular/router": "^15.2.9", - "@nguniversal/express-engine": "^15.2.1", + "@angular/platform-browser": "^16.1.7", + "@angular/platform-browser-dynamic": "^16.1.7", + "@angular/platform-server": "^16.1.7", + "@angular/router": "^16.1.7", + "@nguniversal/express-engine": "^16.1.1", "axios": "^1.4.0", "clipboard": "^1.5.16", "core-js": "^2.5.4", "express": "^4.15.2", "jquery": "^3.4.1", - "ng-recaptcha": "^11.0.0", + "ng-recaptcha": "^12.0.2", "ng2-ckeditor": "1.3.7", "rxjs": "^6.5.1", "ts-md5": "^1.2.0", @@ -48,11 +48,11 @@ "zone.js": "~0.13.1" }, "devDependencies": { - "@angular-devkit/build-angular": "^15.2.9", - "@angular/cli": "^15.2.9", - "@angular/compiler-cli": "^15.2.9", - "@angular/language-service": "^15.2.9", - "@nguniversal/builders": "^15.2.1", + "@angular-devkit/build-angular": "^16.1.6", + "@angular/cli": "^16.1.6", + "@angular/compiler-cli": "^16.1.7", + "@angular/language-service": "^16.1.7", + "@nguniversal/builders": "^16.1.1", "@types/ckeditor": "^4.9.10", "@types/compression": "^1.7.0", "@types/express": "^4.17.0", diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 95798a8..d705d25 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,5 +1,5 @@ -import {NgModule} from '@angular/core'; -import {RouterModule, Routes} from '@angular/router'; +import {inject, NgModule} from '@angular/core'; +import {ActivatedRouteSnapshot, RouterModule, RouterStateSnapshot, Routes} from '@angular/router'; import {OpenaireErrorPageComponent} from './error/errorPage.component'; import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard"; import {AdminDashboardGuard} from "./utils/adminDashboard.guard"; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 7a3c945..322ed52 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,4 +1,4 @@ -import {NgModule} from '@angular/core'; +import {APP_ID, NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {CommonModule} from '@angular/common'; import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http"; @@ -43,13 +43,14 @@ import {CacheIndicatorsModule} from "./cache-indicators/cache-indicators.module" NavigationBarModule, BottomModule, CookieLawModule, - BrowserModule.withServerTransition({appId: 'serverApp'}), + BrowserModule, AppRoutingModule, SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule, IconsModule, CacheIndicatorsModule ], declarations: [AppComponent, OpenaireErrorPageComponent], exports: [AppComponent], providers: [ + {provide: APP_ID, useValue: 'serverApp'}, AdminLoginGuard, AdminDashboardGuard, LoginGuard, { provide: HTTP_INTERCEPTORS, diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 3b6822c..51e3980 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 3b6822c71f32512533793e6b57f6ff017f4c874e +Subproject commit 51e39801796e6c49c97cc721c7b1e797a45a8880 diff --git a/src/app/utils/adminDashboard.guard.ts b/src/app/utils/adminDashboard.guard.ts index cf34e2e..c91dfeb 100644 --- a/src/app/utils/adminDashboard.guard.ts +++ b/src/app/utils/adminDashboard.guard.ts @@ -1,12 +1,5 @@ import {Injectable} from '@angular/core'; -import { - ActivatedRouteSnapshot, - CanActivate, - CanActivateChild, - Router, - RouterStateSnapshot, - UrlTree -} from '@angular/router'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; import {map, take, tap} from "rxjs/operators"; import {UserManagementService} from "../openaireLibrary/services/user-management.service"; import {LoginErrorCodes} from "../openaireLibrary/login/utils/guardHelper.class"; @@ -17,7 +10,7 @@ import {error} from "protractor"; @Injectable() -export class AdminDashboardGuard implements CanActivate, CanActivateChild { +export class AdminDashboardGuard { constructor(private router: Router, private stakeholderService: StakeholderService, -- 2.17.1 From bc955c9d15a7a08dcb31be7d4ca46f56acccafdb Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 1 Aug 2023 14:33:10 +0300 Subject: [PATCH 06/18] Update material to angular 16. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f5a38c6..e61cee9 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,13 @@ "private": true, "dependencies": { "@angular/animations": "^16.1.7", - "@angular/cdk": "^15.2.9", + "@angular/cdk": "^16.1.6", "@angular/common": "^16.1.7", "@angular/compiler": "^16.1.7", "@angular/core": "^16.1.7", "@angular/forms": "^16.1.7", "@angular/localize": "^16.1.7", - "@angular/material": "^15.2.9", + "@angular/material": "^16.1.6", "@angular/platform-browser": "^16.1.7", "@angular/platform-browser-dynamic": "^16.1.7", "@angular/platform-server": "^16.1.7", @@ -71,4 +71,4 @@ "ts-node": "~7.0.0", "typescript": "~4.9.5" } -} +} \ No newline at end of file -- 2.17.1 From d1b30f7925b548c2be2f862d5df85ea0eac09a44 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 4 Aug 2023 15:54:46 +0300 Subject: [PATCH 07/18] Update library --- src/app/app.module.ts | 2 +- src/app/openaireLibrary | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 322ed52..d8d0afd 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -50,7 +50,7 @@ import {CacheIndicatorsModule} from "./cache-indicators/cache-indicators.module" declarations: [AppComponent, OpenaireErrorPageComponent], exports: [AppComponent], providers: [ - {provide: APP_ID, useValue: 'serverApp'}, + {provide: APP_ID, useValue: 'monitor-dashboard'}, AdminLoginGuard, AdminDashboardGuard, LoginGuard, { provide: HTTP_INTERCEPTORS, diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 51e3980..758f2f1 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 51e39801796e6c49c97cc721c7b1e797a45a8880 +Subproject commit 758f2f10ffe6623fb55606ca2e9c29abf89b9b4f -- 2.17.1 From f0cdfccbf438a55fe479d1164917d52446e757f3 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 22 Aug 2023 17:09:41 +0300 Subject: [PATCH 08/18] Update to Uikit 3.16.24 --- package.json | 4 ++-- src/app/openaireLibrary | 2 +- src/app/topic/topic.component.html | 3 ++- src/assets/common-assets | 2 +- src/assets/openaire-theme | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e61cee9..70cb178 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "rxjs": "^6.5.1", "ts-md5": "^1.2.0", "tslib": "^2.0.0", - "uikit": "3.13.10", + "uikit": "3.16.24", "zone.js": "~0.13.1" }, "devDependencies": { @@ -71,4 +71,4 @@ "ts-node": "~7.0.0", "typescript": "~4.9.5" } -} \ No newline at end of file +} diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 758f2f1..d9a8283 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 758f2f10ffe6623fb55606ca2e9c29abf89b9b4f +Subproject commit d9a828363002336b3d333174560796706c7c1bce diff --git a/src/app/topic/topic.component.html b/src/app/topic/topic.component.html index 620ad35..2e5c7ab 100644 --- a/src/app/topic/topic.component.html +++ b/src/app/topic/topic.component.html @@ -9,7 +9,7 @@ +
    diff --git a/src/assets/common-assets b/src/assets/common-assets index 9cb1f83..ae7e623 160000 --- a/src/assets/common-assets +++ b/src/assets/common-assets @@ -1 +1 @@ -Subproject commit 9cb1f835a93501d9566ea2a3123d92eecd73f27d +Subproject commit ae7e623418e7362e80cf9f65db7a004c0857d239 diff --git a/src/assets/openaire-theme b/src/assets/openaire-theme index 5268f27..809a513 160000 --- a/src/assets/openaire-theme +++ b/src/assets/openaire-theme @@ -1 +1 @@ -Subproject commit 5268f277246347aad42349a06eecb915a452841b +Subproject commit 809a51350d0bc63ff870e7312ce9454ae0fd3393 -- 2.17.1 From e705f1a1cf6786cbf4909ce0fad17db72305a1be Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 4 Sep 2023 15:15:43 +0300 Subject: [PATCH 09/18] Convert div - uk-toggle to a - uk-toggle for new Uikit. --- src/app/monitor/monitor.component.html | 6 +++--- src/app/openaireLibrary | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/monitor/monitor.component.html b/src/app/monitor/monitor.component.html index 84ff408..6733d43 100644 --- a/src/app/monitor/monitor.component.html +++ b/src/app/monitor/monitor.component.html @@ -277,14 +277,14 @@ - +
    diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 2102dfb..7650857 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 2102dfb0d70ccbb773ff659342661054155a4c39 +Subproject commit 7650857186bf8ae868bcbe9f13f4b27c7674d8f6 -- 2.17.1 From 05df84db324e9f5d96718dc5a323b554ae4ba0bf Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 12 Sep 2023 18:42:29 +0300 Subject: [PATCH 10/18] Update library and theme --- src/app/openaireLibrary | 2 +- src/assets/openaire-theme | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 7650857..11d0be4 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 7650857186bf8ae868bcbe9f13f4b27c7674d8f6 +Subproject commit 11d0be4ffd6649189f87c91aed1c2d47c5d9b2c8 diff --git a/src/assets/openaire-theme b/src/assets/openaire-theme index 5feca2d..3a4aa92 160000 --- a/src/assets/openaire-theme +++ b/src/assets/openaire-theme @@ -1 +1 @@ -Subproject commit 5feca2d8457324999557feb662b4355d8cf0df4b +Subproject commit 3a4aa92c441467994a45a2c6a4f0c21202945404 -- 2.17.1 From 1686e017b036606485154b9e24bac586f8451e07 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 15 Sep 2023 11:10:57 +0300 Subject: [PATCH 11/18] Update types/node to version 16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 70cb178..e621943 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@types/express": "^4.17.0", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", - "@types/node": "^12.11.1", + "@types/node": "^16.18.50", "codelyzer": "^6.0.0", "jasmine-core": "~3.8.0", "jasmine-spec-reporter": "~5.0.0", -- 2.17.1 From 803186d407bdb598d60cec70bada2e113a598d8a Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 13 Oct 2023 16:29:23 +0300 Subject: [PATCH 12/18] Update libraries --- src/app/openaireLibrary | 2 +- src/assets/openaire-theme | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 11d0be4..dbbd7ec 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 11d0be4ffd6649189f87c91aed1c2d47c5d9b2c8 +Subproject commit dbbd7ec541d96a5062a769dea2255ad9ccb36b13 diff --git a/src/assets/openaire-theme b/src/assets/openaire-theme index 3a4aa92..2dadcf8 160000 --- a/src/assets/openaire-theme +++ b/src/assets/openaire-theme @@ -1 +1 @@ -Subproject commit 3a4aa92c441467994a45a2c6a4f0c21202945404 +Subproject commit 2dadcf85926bc0f11fff22ed94dc197ddd8587c6 -- 2.17.1 From 82fb9cb3293d97fae82c2cf2eb936cbf85a06468 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 16 Oct 2023 20:19:22 +0300 Subject: [PATCH 13/18] Update library before beta deployment --- src/app/openaireLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index dbbd7ec..8d65222 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit dbbd7ec541d96a5062a769dea2255ad9ccb36b13 +Subproject commit 8d6522270c26451c7474630fc71e7fa3e31c5c0e -- 2.17.1 From a3aa80343389222978b90922bdf9c38ea6ab2225 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Thu, 19 Oct 2023 16:33:28 +0300 Subject: [PATCH 14/18] Move topics and cache indicators in library. --- server.ts | 2 +- .../admin-stakeholder-routing.module.ts | 2 +- src/app/app-routing.module.ts | 6 +- src/app/app.component.ts | 2 +- src/app/app.module.ts | 4 +- .../cache-indicators.component.less | 9 - .../cache-indicators.component.ts | 78 - .../cache-indicators.module.ts | 11 - src/app/develop/develop.component.ts | 2 +- .../edit-stakeholder.component.ts | 4 +- .../manageStakeholders.component.ts | 4 +- src/app/monitor/monitor.component.ts | 4 +- src/app/monitor/monitor.module.ts | 2 +- src/app/openaireLibrary | 2 +- src/app/topic/indicators.component.html | 490 ------ src/app/topic/indicators.component.less | 53 - src/app/topic/indicators.component.ts | 1494 ----------------- src/app/topic/topic-routing.module.ts | 19 - src/app/topic/topic.component.html | 380 ----- src/app/topic/topic.component.ts | 795 --------- src/app/topic/topic.module.ts | 49 - src/app/utils/adminDashboard.guard.ts | 44 - src/app/utils/indicator-utils.ts | 1005 ----------- .../services/cache-indicators.service.ts | 26 - src/app/utils/services/statistics.service.ts | 25 - .../utils/services/stats-profiles.service.ts | 20 - src/cache-indicators.ts | 262 --- 27 files changed, 17 insertions(+), 4777 deletions(-) delete mode 100644 src/app/cache-indicators/cache-indicators.component.less delete mode 100644 src/app/cache-indicators/cache-indicators.component.ts delete mode 100644 src/app/cache-indicators/cache-indicators.module.ts delete mode 100644 src/app/topic/indicators.component.html delete mode 100644 src/app/topic/indicators.component.less delete mode 100644 src/app/topic/indicators.component.ts delete mode 100644 src/app/topic/topic-routing.module.ts delete mode 100644 src/app/topic/topic.component.html delete mode 100644 src/app/topic/topic.component.ts delete mode 100644 src/app/topic/topic.module.ts delete mode 100644 src/app/utils/adminDashboard.guard.ts delete mode 100644 src/app/utils/indicator-utils.ts delete mode 100644 src/app/utils/services/cache-indicators.service.ts delete mode 100644 src/app/utils/services/statistics.service.ts delete mode 100644 src/app/utils/services/stats-profiles.service.ts delete mode 100644 src/cache-indicators.ts diff --git a/server.ts b/server.ts index f4ec9c1..cbf797e 100644 --- a/server.ts +++ b/server.ts @@ -12,7 +12,7 @@ import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens"; import {properties} from "./src/environments/environment"; import axios, {AxiosHeaders} from "axios"; import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder"; -import {CacheIndicators} from "./src/cache-indicators"; +import {CacheIndicators} from "./src/app/openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators"; import {Session, User} from "./src/app/openaireLibrary/login/utils/helper.class"; var bodyParser = require('body-parser'); diff --git a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts index fb8a2a8..57a5a62 100644 --- a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts +++ b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts @@ -21,7 +21,7 @@ import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; }, { matcher: HelperFunctions.routingMatcher(['indicators', 'indicators/:topic']), - loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule), + loadChildren: () => import('../openaireLibrary/monitor-admin/topic/topic.module').then(m => m.TopicModule), data: {hasInternalSidebar: true}, pathMatch: 'full' }, diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d705d25..dcf6a82 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,9 +1,9 @@ -import {inject, NgModule} from '@angular/core'; -import {ActivatedRouteSnapshot, RouterModule, RouterStateSnapshot, Routes} from '@angular/router'; +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; import {OpenaireErrorPageComponent} from './error/errorPage.component'; import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard"; -import {AdminDashboardGuard} from "./utils/adminDashboard.guard"; import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard"; +import {AdminDashboardGuard} from "./openaireLibrary/monitor-admin/utils/adminDashboard.guard"; const routes: Routes = [ { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9a56bbf..1568ebe 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -18,7 +18,7 @@ import {LinksResolver} from "./search/links-resolver"; import {Header} from "./openaireLibrary/sharedComponents/navigationBar.component"; import {properties} from "../environments/environment"; import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service"; -import {StakeholderUtils} from "./utils/indicator-utils"; +import {StakeholderUtils} from "./openaireLibrary/monitor-admin/utils/indicator-utils"; import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll"; import {ConnectHelper} from "./openaireLibrary/connect/connectHelper"; import {ResourcesService} from "./openaireLibrary/monitor/services/resources.service"; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d8d0afd..d1594e6 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,7 +21,6 @@ import {HttpInterceptorService} from "./openaireLibrary/http-interceptor.service import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service"; import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service"; import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard"; -import {AdminDashboardGuard} from "./utils/adminDashboard.guard"; import { NotificationsSidebarModule } from "./openaireLibrary/notifications/notifications-sidebar/notifications-sidebar.module"; @@ -29,7 +28,8 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard"; import {IconsModule} from "./openaireLibrary/utils/icons/icons.module"; import {IconsService} from "./openaireLibrary/utils/icons/icons.service"; import {incognito} from "./openaireLibrary/utils/icons/icons"; -import {CacheIndicatorsModule} from "./cache-indicators/cache-indicators.module"; +import {AdminDashboardGuard} from "./openaireLibrary/monitor-admin/utils/adminDashboard.guard"; +import {CacheIndicatorsModule} from "./openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.module"; @NgModule({ diff --git a/src/app/cache-indicators/cache-indicators.component.less b/src/app/cache-indicators/cache-indicators.component.less deleted file mode 100644 index 08d5c2a..0000000 --- a/src/app/cache-indicators/cache-indicators.component.less +++ /dev/null @@ -1,9 +0,0 @@ -@import (reference) "~src/assets/openaire-theme/less/_import-variables.less"; - -.cache-progress { - position: fixed; - bottom: 0; - right: 0; - transform: translate(-50%, -50%); - z-index: @global-z-index; -} diff --git a/src/app/cache-indicators/cache-indicators.component.ts b/src/app/cache-indicators/cache-indicators.component.ts deleted file mode 100644 index 9a485ba..0000000 --- a/src/app/cache-indicators/cache-indicators.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {Component, Inject, Input, OnChanges, OnDestroy, OnInit, PLATFORM_ID, SimpleChanges} from "@angular/core"; -import {Report} from "../../cache-indicators"; -import {CacheIndicatorsService} from "../utils/services/cache-indicators.service"; -import {interval, Subject, Subscription} from "rxjs"; -import {map, switchMap, takeUntil} from "rxjs/operators"; - -@Component({ - selector: 'cache-indicators', - template: ` -
    -
    -
    - -
    -
    - `, - styleUrls: ['cache-indicators.component.less'] -}) -export class CacheIndicatorsComponent implements OnInit, OnChanges, OnDestroy { - report: Report; - subscriptions: Subscription[] = []; - interval: number = 10000; - readonly destroy$ = new Subject(); - @Input() alias: string; - - constructor(private cacheIndicatorsService: CacheIndicatorsService, - @Inject(PLATFORM_ID) private platformId) { - } - - ngOnInit() { - this.getReport(); - } - - ngOnChanges(changes: SimpleChanges) { - if(changes.alias) { - this.getReport(); - } - } - - getReport() { - this.clear(); - this.subscriptions.push(this.cacheIndicatorsService.getReport(this.alias).subscribe(report => { - this.getReportInterval(report); - })); - } - - getReportInterval(report: Report) { - if(this.isBrowser && (this.report || !report?.completed)) { - this.report = report; - this.subscriptions.push(interval(this.interval).pipe( - map(() => this.cacheIndicatorsService.getReport(this.alias)), - switchMap(report => report), - takeUntil(this.destroy$)).subscribe(report => { - console.log(this.alias); - this.report = report; - if(this.report.completed) { - this.destroy$.next(); - } - })); - } - } - - clear() { - this.subscriptions.forEach(subscription => { - subscription.unsubscribe(); - }) - this.report = null; - } - - - get isBrowser() { - return this.platformId === 'browser'; - } - - ngOnDestroy() { - this.clear(); - } -} diff --git a/src/app/cache-indicators/cache-indicators.module.ts b/src/app/cache-indicators/cache-indicators.module.ts deleted file mode 100644 index aa9cd99..0000000 --- a/src/app/cache-indicators/cache-indicators.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {NgModule} from "@angular/core"; -import {CommonModule} from "@angular/common"; -import {CacheIndicatorsComponent} from "./cache-indicators.component"; -import {IconsModule} from "../openaireLibrary/utils/icons/icons.module"; - -@NgModule({ - imports: [CommonModule, IconsModule], - declarations: [CacheIndicatorsComponent], - exports: [CacheIndicatorsComponent] -}) -export class CacheIndicatorsModule {} diff --git a/src/app/develop/develop.component.ts b/src/app/develop/develop.component.ts index 6a7b6e5..0847e04 100644 --- a/src/app/develop/develop.component.ts +++ b/src/app/develop/develop.component.ts @@ -6,7 +6,7 @@ import {Meta, Title} from "@angular/platform-browser"; import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service"; import {properties} from "../../environments/environment"; import {Router} from "@angular/router"; -import {StakeholderUtils} from "../utils/indicator-utils"; +import {StakeholderUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils"; import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields"; import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"; import {PiwikService} from "../openaireLibrary/utils/piwik/piwik.service"; diff --git a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts b/src/app/general/edit-stakeholder/edit-stakeholder.component.ts index 93c418b..b66b680 100644 --- a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts +++ b/src/app/general/edit-stakeholder/edit-stakeholder.component.ts @@ -1,7 +1,7 @@ import {Component, Input, OnDestroy, ViewChild} from "@angular/core"; import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder"; import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; -import {StakeholderUtils} from "../../utils/indicator-utils"; +import {StakeholderUtils} from "../../openaireLibrary/monitor-admin/utils/indicator-utils"; import {Option} from "../../openaireLibrary/sharedComponents/input/input.component"; import {Subscription} from "rxjs"; import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties"; @@ -15,7 +15,7 @@ import {NotifyFormComponent} from "../../openaireLibrary/notifications/notify-fo import {NotificationUtils} from "../../openaireLibrary/notifications/notification-utils"; import {Notification} from "../../openaireLibrary/notifications/notifications"; import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler"; -import {StatsProfilesService} from "../../utils/services/stats-profiles.service"; +import {StatsProfilesService} from "../../openaireLibrary/monitor-admin/utils/services/stats-profiles.service"; @Component({ selector: 'edit-stakeholder', diff --git a/src/app/manageStakeholders/manageStakeholders.component.ts b/src/app/manageStakeholders/manageStakeholders.component.ts index 90cccdc..57cd300 100644 --- a/src/app/manageStakeholders/manageStakeholders.component.ts +++ b/src/app/manageStakeholders/manageStakeholders.component.ts @@ -3,7 +3,7 @@ import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholde import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"; import {Stakeholder, StakeholderEntities, Visibility} from "../openaireLibrary/monitor/entities/stakeholder"; import {Subscriber, zip} from "rxjs"; -import {StakeholderUtils} from "../utils/indicator-utils"; +import {StakeholderUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils"; import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms"; import {AlertModal} from "../openaireLibrary/utils/modal/alert"; import {Option} from "../openaireLibrary/sharedComponents/input/input.component"; @@ -13,7 +13,7 @@ import {Session} from "../openaireLibrary/login/utils/helper.class"; import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component"; import {properties} from "../../environments/environment"; import {ActivatedRoute} from "@angular/router"; -import {CacheIndicatorsService} from "../utils/services/cache-indicators.service"; +import {CacheIndicatorsService} from "../openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.service"; import {NotificationHandler} from "../openaireLibrary/utils/notification-handler"; type Tab = 'all' | 'templates'| 'profiles'; diff --git a/src/app/monitor/monitor.component.ts b/src/app/monitor/monitor.component.ts index abe9f53..0f8b30f 100644 --- a/src/app/monitor/monitor.component.ts +++ b/src/app/monitor/monitor.component.ts @@ -21,8 +21,8 @@ import { Topic, Visibility } from "../openaireLibrary/monitor/entities/stakeholder"; -import {StatisticsService} from "../utils/services/statistics.service"; -import {IndicatorUtils} from "../utils/indicator-utils"; +import {StatisticsService} from "../openaireLibrary/monitor-admin/utils/services/statistics.service"; +import {IndicatorUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils"; import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; import {UntypedFormBuilder, UntypedFormControl} from "@angular/forms"; import {Subscriber, Subscription} from "rxjs"; diff --git a/src/app/monitor/monitor.module.ts b/src/app/monitor/monitor.module.ts index 2525165..25f385e 100644 --- a/src/app/monitor/monitor.module.ts +++ b/src/app/monitor/monitor.module.ts @@ -12,7 +12,7 @@ import {Schema2jsonldModule} from "../openaireLibrary/sharedComponents/schema2js import {SEOServiceModule} from "../openaireLibrary/sharedComponents/SEO/SEOService.module"; import {MonitorRoutingModule} from "./monitor-routing.module"; import {MonitorComponent} from "./monitor.component"; -import {StatisticsService} from "../utils/services/statistics.service"; +import {StatisticsService} from "../openaireLibrary/monitor-admin/utils/services/statistics.service"; import {SideBarModule} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sideBar.module"; import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module"; import {UserMiniModule} from "../openaireLibrary/login/userMiniModule.module"; diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index dbbd7ec..de3fbe8 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit dbbd7ec541d96a5062a769dea2255ad9ccb36b13 +Subproject commit de3fbe8d69ebab14da17913704db3f6a0e35983a diff --git a/src/app/topic/indicators.component.html b/src/app/topic/indicators.component.html deleted file mode 100644 index ecdc0cd..0000000 --- a/src/app/topic/indicators.component.html +++ /dev/null @@ -1,490 +0,0 @@ -
    -
    -
    Number Indicators
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - -
    - -
    -
    -
    {{indicator.name}}
    -
    - - -- -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    Chart Indicators
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - -
    - -
    -
    -
    -
    - {{indicator.name}} -
    - -
    - -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - Create a custom indicator -
    -
    - Use our advance tool to create a custom Indicator that suit the needs of your funding - KPI's. -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    {{urlParameterizedMessage}}
    -
    -
    - -
    -
    -
    -
    - There are schema enhancements that can be applied in this query.Apply - now -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - JSON Path -
    -
    -
    - This JSON path is not valid or the result has not been calculated yet. - Please press calculate on box below to see the result. -
    -
    -
    -
    -
    - - - - - - -
    -
    - -
    -
    -
    -
    -
    - - - - - -- - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    {{urlParameterizedMessage}}
    -
    -
    - -
    -
    -
    -
    - There are schema enhancements that can be applied in this query. Apply - now -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    - -
    - You are about to delete - "{{indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title?indicator.indicatorPaths[0].parameters.title:'')}}" indicator permanently. -
    - Indicators of all profiles based on this default indicator, will be deleted as well. -
    - - - - Are you sure you want to proceed? -
    -
    -
    - - -
    -
    - -
    - You are about to delete this section and its indicators permanently. -
    - Sections of all profiles based on this default section and their contents, will be deleted as well. -
    - - - - Are you sure you want to proceed? -
    -
    - - -
    -
    - -
    -
    -
    diff --git a/src/app/topic/indicators.component.less b/src/app/topic/indicators.component.less deleted file mode 100644 index 627ab18..0000000 --- a/src/app/topic/indicators.component.less +++ /dev/null @@ -1,53 +0,0 @@ -@import (reference) "~src/assets/openaire-theme/less/_import-variables"; - -.number-preview { - border: @global-border-width solid @global-border; - background: transparent; - border-radius: @global-border-radius; - min-width: 100px; - min-height: 70px; -} - -.refresh-indicator { - background-color: @global-overlay-background; - border-radius: @global-border-radius; - position: absolute; - color: @global-inverse-color; - z-index: 1; -} - -.section { - padding: 60px 45px; - border-radius: @global-border-radius; - border: @global-border-width solid @global-border; - position: relative; - background: @global-inverse-color; - border-left: 5px @global-primary-background solid; - - .tools { - position: absolute; - top: 0; - left: 50%; - transform: translate(-50%, -100%); - max-width: 50px; - padding: 5px 10px; - background-image: @global-primary-gradient; - color: @global-inverse-color; - -webkit-clip-path: polygon(20% 5%, 80% 5%, 100% 100%, 0% 100%); - clip-path: polygon(20% 5%, 80% 5%, 100% 100%, 0% 100%); - display: none; - } - - &:hover { - .tools { - display: block; - - a { - color: currentColor; - &:hover { - text-decoration: none; - } - } - } - } -} diff --git a/src/app/topic/indicators.component.ts b/src/app/topic/indicators.component.ts deleted file mode 100644 index 8a0435d..0000000 --- a/src/app/topic/indicators.component.ts +++ /dev/null @@ -1,1494 +0,0 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, - HostListener, - Input, - OnChanges, - OnDestroy, - OnInit, - SimpleChanges, - ViewChild -} from "@angular/core"; -import { - Format, - Indicator, - IndicatorPath, - IndicatorSize, - IndicatorType, - Section, - Stakeholder, - Visibility -} from "../openaireLibrary/monitor/entities/stakeholder"; -import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils"; -import { - AbstractControl, - UntypedFormArray, - UntypedFormBuilder, - UntypedFormControl, - UntypedFormGroup, - Validators -} from "@angular/forms"; -import {AlertModal} from "../openaireLibrary/utils/modal/alert"; -import {StatisticsService} from "../utils/services/statistics.service"; -import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; -import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser"; -import {Reorder, StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; -import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"; -import {Observable, Subscriber} from "rxjs"; -import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; -import {Router} from "@angular/router"; -import {Role, Session, User} from "../openaireLibrary/login/utils/helper.class"; -import {StringUtils} from "../openaireLibrary/utils/string-utils.class"; -import {Notification} from "../openaireLibrary/notifications/notifications"; -import {NotificationUtils} from "../openaireLibrary/notifications/notification-utils"; -import {NotifyFormComponent} from "../openaireLibrary/notifications/notify-form/notify-form.component"; -import {NotificationService} from "../openaireLibrary/notifications/notification.service"; -import {properties} from "../../environments/environment"; -import {NotificationHandler} from "../openaireLibrary/utils/notification-handler"; - -declare var UIkit; - -@Component({ - selector: 'indicators', - templateUrl: './indicators.component.html', - styleUrls: ['indicators.component.less'] -}) -export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit { - filesToUpload: Array; - errorMessage = ""; - public properties: EnvProperties = properties; - @Input() - public topicIndex: number = 0; - @Input() - public categoryIndex: number = 0; - @Input() - public subcategoryIndex: number = 0; - @Input() - public stakeholder: Stakeholder = null; - @Input() - public changed: Observable; - @Input() - public user: User = null; - public preview: string; - public indicatorUtils: IndicatorUtils = new IndicatorUtils(); - public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); - public numberIndicatorFb: UntypedFormGroup; - public chartIndicatorFb: UntypedFormGroup; - public chartSections: UntypedFormArray; - public numberSections: UntypedFormArray; - /** - * Editable indicator - */ - public section: Section; - public indicator: Indicator; - public index: number = -1; - public editing: boolean = false; - public dragging: boolean = false; - /** Caches */ - public safeUrls: Map = new Map([]); - public numberResponses: Map = new Map(); - public numberResults: Map = new Map(); - /** Import / Export Indicators */ - importLoading: boolean = false; - @ViewChild('editChartModal', {static: true}) editChartModal: AlertModal; - @ViewChild('editNumberModal', {static: true}) editNumberModal: AlertModal; - @ViewChild('deleteModal', {static: true}) deleteModal: AlertModal; - @ViewChild('deleteSectionModal', {static: true}) deleteSectionModal: AlertModal; - public sectionTypeToDelete: string; - public sectionChildrenActionOnDelete: string; - public indicatorChildrenActionOnDelete: string; - urlParameterizedMessage = null; - showCheckForSchemaEnhancements: boolean = false; - private notification: Notification; - @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; - @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; - @ViewChild('deleteNotify', {static: true}) deleteNotify: NotifyFormComponent; - - public isFullscreen: boolean = false; - - @HostListener('fullscreenchange', ['$event']) - @HostListener('webkitfullscreenchange', ['$event']) - @HostListener('mozfullscreenchange', ['$event']) - @HostListener('MSFullscreenChange', ['$event']) - screenChange(event) { - this.isFullscreen = !this.isFullscreen; - } - - /** - * Subscriptions - **/ - private subscriptions: any[] = []; - private urlSubscriptions: any[] = []; - private numberSubscription: any[] = []; - - constructor(private layoutService: LayoutService, - private stakeholderService: StakeholderService, - private statisticsService: StatisticsService, - private notificationService: NotificationService, - private fb: UntypedFormBuilder, - private router: Router, - private cdr: ChangeDetectorRef, - private sanitizer: DomSanitizer) { - this.filesToUpload = []; - } - - ngOnInit(): void { - if (this.stakeholder) { - this.setCharts(); - this.setNumbers(); - } - this.changed.subscribe(() => { - this.setCharts(); - this.setNumbers(); - this.initReorder(); - }) - } - - ngOnDestroy(): void { - this.subscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } else if (value instanceof Function) { - value(); - } - }); - this.urlSubscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - this.numberSubscription.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - } - - ngAfterViewInit(): void { - this.initReorder(); - } - - ngOnChanges(changes: SimpleChanges): void { - if (this.canEdit) { - if (changes.topicIndex || changes.categoryIndex || changes.subcategoryIndex) { - this.initReorder(); - this.setCharts(); - this.setNumbers(); - } - } - } - - initReorder() { - this.subscriptions.forEach(value => { - if (value instanceof Function) { - value(); - } - }); - if (document !== undefined) { - let callback = (list, type: IndicatorType, action: 'moved' | 'added' | 'removed'): void => { - let items: HTMLCollection = list.current.children; - let reordered = []; - for (let i = 0; i < items.length; i++) { - if (items.item(i).id) { - reordered.push(items.item(i).id); - } - } - let reorder: Reorder = { - action: action, - target: list.detail[1].id, - ids: reordered - } - this.reorderIndicators(list.current.id.toString().split('-')[1], type, reorder); - }; - this.numbers.forEach((section) => { - this.subscriptions.push(UIkit.util.on(document, 'start', '#number-' + section._id, (): void => { - this.dragging = true; - })); - this.subscriptions.push(UIkit.util.on(document, 'stop', '#number-' + section._id, (): void => { - this.dragging = false; - })); - this.subscriptions.push(UIkit.util.on(document, 'moved', '#number-' + section._id, (list): void => { - callback(list, "number", 'moved'); - })); - this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => { - callback(list, "number", 'added'); - })); - this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => { - callback(list, "number", 'removed'); - })); - }); - this.charts.forEach((section) => { - this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'moved'); - })); - this.subscriptions.push(UIkit.util.on(document, 'added', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'added'); - })); - this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'removed'); - })); - }); - } - } - - hide(element: any) { - UIkit.dropdown(element).hide(); - } - - setCharts() { - this.chartSections = this.fb.array([]); - this.charts.forEach(section => { - this.chartSections.push(this.fb.group({ - _id: this.fb.control(section._id), - title: this.fb.control(section.title), - creationDate: this.fb.control(section.creationDate), - stakeholderAlias: this.fb.control(section.stakeholderAlias), - defaultId: this.fb.control(section.defaultId), - type: this.fb.control(section.type), - indicators: this.fb.control(section.indicators) - })); - section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - let url = this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath); - if (!this.safeUrls.get('url')) { - indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); - this.safeUrls.set(url, indicatorPath.safeResourceUrl); - } - }); - }) - }); - } - - setNumbers() { - this.numberSections = this.fb.array([]); - this.numberResults.clear(); - let urls: Map = new Map(); - this.numbers.forEach((section, i) => { - this.numberSections.push(this.fb.group({ - _id: this.fb.control(section._id), - title: this.fb.control(section.title), - creationDate: this.fb.control(section.creationDate), - stakeholderAlias: this.fb.control(section.stakeholderAlias), - defaultId: this.fb.control(section.defaultId), - type: this.fb.control(section.type), - indicators: this.fb.control(section.indicators) - })); - section.indicators.forEach((number, j) => { - let url = this.indicatorUtils.getFullUrl(this.stakeholder, number.indicatorPaths[0]); - const pair = JSON.stringify([number.indicatorPaths[0].source, url]); - const indexes = urls.get(pair) ? urls.get(pair) : []; - indexes.push([i, j]); - urls.set(pair, indexes); - }); - }); - this.numberSubscription.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - urls.forEach((indexes, pair) => { - let parsed = JSON.parse(pair); - let response = this.numberResponses.get(pair); - if (response) { - this.calculateResults(response, indexes); - } else { - this.numberSubscription.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(parsed[0]), parsed[1]).subscribe(response => { - this.calculateResults(response, indexes); - this.numberResponses.set(pair, response); - })); - } - }); - } - - private calculateResults(response: any, indexes: [number, number][]) { - indexes.forEach(([i, j]) => { - let result = JSON.parse(JSON.stringify(response)); - this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { - if (result) { - result = result[jsonPath]; - } - }); - if (typeof result === 'string' || typeof result === 'number') { - result = Number(result); - if (result === Number.NaN) { - result = 0; - } - } else { - result = 0; - } - this.numberResults.set(i + '-' + j, result); - }); - } - - get charts(): Section[] { - if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { - return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts; - } else { - return []; - } - } - - get numbers(): Section[] { - if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { - return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers; - } else { - return []; - } - } - - set numbers(sections: Section[]) { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers = sections; - } - - get open(): boolean { - return this.layoutService.open; - } - - get canEdit() { - return this.stakeholder && - this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]; - } - - public get numberIndicatorPaths(): UntypedFormArray { - return this.numberIndicatorFb.get('indicatorPaths') as UntypedFormArray; - } - - public get chartIndicatorPaths(): UntypedFormArray { - return this.chartIndicatorFb.get('indicatorPaths') as UntypedFormArray; - } - - public getNumberClassBySize(size: IndicatorSize) { - if (size === 'small') { - return 'uk-width-medium@m uk-width-1-1'; - } else if (size === 'medium') { - return 'uk-width-1-4@l uk-width-1-2@m uk-width-1-1'; - } else { - return 'uk-width-1-2@l uk-width-1-1@m uk-width-1-1'; - } - } - - public getChartClassBySize(size: IndicatorSize) { - if (size === 'small') { - return 'uk-width-1-3@xl uk-width-1-2@m uk-width-1-1'; - } else if (size === 'medium') { - return 'uk-width-1-2@l uk-width-1-1'; - } else { - return 'uk-width-1-1'; - } - } - - public addJsonPath(index: number) { - if (index == 0 && this.getJsonPath(index).getRawValue()[index].indexOf(",") != -1) { - //if in the first path there are more than one paths comma separated, split them and autogenerate the forms - let paths = this.getJsonPath(index).getRawValue()[index].split(","); - for (let i = 0; i < paths.length; i++) { - if (i != 0) { - this.getJsonPath(index).push(this.fb.control('', Validators.required)); - } - } - this.getJsonPath(index).setValue(paths) - } else { - this.getJsonPath(index).push(this.fb.control('', Validators.required)); - } - } - - public removeJsonPath(i: number, j: number) { - if (this.getJsonPath(i).enabled) { - this.getJsonPath(i).removeAt(j); - } - } - - public validateJsonPath(index: number, dirty: boolean = false) { - let indicatorPath: UntypedFormGroup = this.numberIndicatorPaths.at(index); - if (this.indicator.defaultId === null) { - this.getJsonPath(index).disable(); - } - indicatorPath.get('result').setErrors({validating: true}); - this.subscriptions.push(this.statisticsService.getNumbers(null, indicatorPath.get('url').value).subscribe(response => { - let result = JSON.parse(JSON.stringify(response)); - this.getJsonPath(index).controls.forEach(jsonPath => { - if (result) { - result = result[jsonPath.value]; - } - }); - setTimeout(() => { - if (this.indicator.defaultId === null) { - this.getJsonPath(index).enable(); - if (dirty) { - this.getJsonPath(index).markAsDirty(); - } - } - indicatorPath.get('result').setErrors(null); - if (typeof result === 'string' || typeof result === 'number') { - result = Number(result); - if (result !== Number.NaN) { - indicatorPath.get('result').setValue(result); - } else { - indicatorPath.get('result').setValue(0); - } - } else { - indicatorPath.get('result').setValue(0); - } - }, 500); - }, error => { - setTimeout(() => { - if (this.indicator.defaultId === null) { - this.getJsonPath(index).enable(); - if (dirty) { - this.getJsonPath(index).markAsDirty(); - } - } - indicatorPath.get('result').setErrors(null); - indicatorPath.get('result').setValue(0); - }, 500); - })); - } - - public getJsonPath(index: number): UntypedFormArray { - return this.numberIndicatorPaths.at(index).get('jsonPath') as UntypedFormArray; - } - - public getCurrentJsonPath(index: number): string[] { - return this.section.indicators[this.index].indicatorPaths[index].jsonPath; - } - - public getParameters(index: number): UntypedFormArray { - return this.chartIndicatorPaths.at(index).get('parameters') as UntypedFormArray; - } - - public getParameter(index: number, key: string): UntypedFormControl { - return this.getParameters(index).controls.filter(control => control.value.key === key)[0] as UntypedFormControl; - } - - private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) { - return this.sanitizer.bypassSecurityTrustResourceUrl( - this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); - } - - private getUrlByStakeHolder(indicatorPath: IndicatorPath) { - return this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)); - } - - public addNumberIndicatorPath(url: string = '', parameters: UntypedFormArray = new UntypedFormArray([]), source: string = 'stats-tool', jsonPath: UntypedFormArray = new UntypedFormArray([]), format: Format = "NUMBER") { - if (jsonPath.length === 0) { - jsonPath.push(this.fb.control('', Validators.required)); - } - this.numberIndicatorPaths.push(this.fb.group({ - url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]), - jsonPath: jsonPath, - result: this.fb.control(0, Validators.required), - source: this.fb.control(source, Validators.required), - format: this.fb.control(format, Validators.required) - } - )); - let index = this.numberIndicatorPaths.length - 1; - if (this.numberIndicatorPaths.at(index).get('url').valid) { - this.validateJsonPath(index); - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); - } - if (this.indicator.defaultId === null) { - this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { - this.numberIndicatorPaths.at(index).get('result').setValue(null); - if (this.numberIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." - } else { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder." - } - } else { - this.urlParameterizedMessage = null; - } - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index] = indicatorPath; - } else { - this.indicator.indicatorPaths.push(indicatorPath); - } - if (indicatorPath.source) { - this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source); - } - if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) { - let paths = indicatorPath.jsonPath; - for (let i = 0; i < paths.length; i++) { - if (i == this.getJsonPath(index).length) { - this.getJsonPath(index).push(this.fb.control('', Validators.required)); - } - } - this.getJsonPath(index).setValue(paths) - } - } else { - this.urlParameterizedMessage = null; - } - }) - ); - - this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].jsonPath = value; - } - this.numberIndicatorPaths.at(index).get('result').setValue(null); - }) - ); - this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].source = value; - } - }) - ); - } else { - this.numberIndicatorPaths.at(index).get('url').disable(); - this.numberIndicatorPaths.at(index).get('jsonPath').disable(); - this.numberIndicatorPaths.at(index).get('source').disable(); - } - } - - public addChartIndicatorPath(value: string = '', parameters: UntypedFormArray = new UntypedFormArray([]), disableUrl: boolean = false, type: string = null) { - this.chartIndicatorPaths.push(this.fb.group({ - url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]), - parameters: parameters, - type: this.fb.control(type) - } - )); - let index = this.chartIndicatorPaths.length - 1; - if (disableUrl) { - this.chartIndicatorPaths.at(index).get('url').disable(); - } else { - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); - this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { - if (this.chartIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." - } else { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Please make sure chart data is for the current stakeholder." - } - } else { - this.urlParameterizedMessage = null; - } - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); - (this.chartIndicatorPaths.at(index) as UntypedFormGroup).get('type').setValue(indicatorPath.type); - let parameters = this.getParametersAsFormArray(indicatorPath); - (this.chartIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', parameters); - if (!this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index] = indicatorPath; - this.indicator.indicatorPaths[index].safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); - } else { - indicatorPath.safeResourceUrl = this.indicator.indicatorPaths[index].safeResourceUrl; - this.indicator.indicatorPaths[index] = indicatorPath; - } - } else { - this.urlParameterizedMessage = null; - } - })); - } - } - - private isStakeholderParametersValid(indicatorPath: IndicatorPath) { - return !((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_name") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") == -1) - || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") == -1 && indicatorPath.url.indexOf("index_name") == -1 && (indicatorPath.url).indexOf("index_shortName") == -1)); - - } - - private getJsonPathAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { - let jsonPath = this.fb.array([]); - if (indicatorPath.jsonPath) { - indicatorPath.jsonPath.forEach(path => { - jsonPath.push(this.fb.control(path, Validators.required)); - }); - } - return jsonPath; - } - - private getParametersAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { - let parameters = this.fb.array([]); - if (indicatorPath.parameters) { - Object.keys(indicatorPath.parameters).forEach(key => { - if (this.indicatorUtils.ignoredParameters.indexOf(key) === -1) { - if (this.indicatorUtils.parametersValidators.has(key)) { - parameters.push(this.fb.group({ - key: this.fb.control(key), - value: this.fb.control(indicatorPath.parameters[key], this.indicatorUtils.parametersValidators.get(key)) - })); - } else { - parameters.push(this.fb.group({ - key: this.fb.control(key), - value: this.fb.control(indicatorPath.parameters[key]) - })); - } - } - }); - } - return parameters; - } - - public editNumberIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; - this.section = section; - this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; - if (this.index !== -1) { - this.indicator = HelperFunctions.copy(this.section.indicators[this.index]); - this.numberIndicatorFb = this.fb.group({ - _id: this.fb.control(this.indicator._id), - name: this.fb.control(this.indicator.name, Validators.required), - description: this.fb.control(this.indicator.description), - creationDate: this.fb.control(this.indicator.creationDate), - additionalDescription: this.fb.control(this.indicator.additionalDescription), - visibility: this.fb.control(this.indicator.visibility), - indicatorPaths: this.fb.array([], Validators.required), - type: this.fb.control(this.indicator.type), - width: this.fb.control(this.indicator.width), - height: this.fb.control(this.indicator.height), - defaultId: this.fb.control(this.indicator.defaultId) - }); - this.indicator.indicatorPaths.forEach(indicatorPath => { - this.addNumberIndicatorPath(this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath), indicatorPath.format); - }); - } else { - this.indicator = new Indicator('', '', '', 'number', 'small', 'small', "PUBLIC", []); - this.numberIndicatorFb = this.fb.group({ - _id: this.fb.control(this.indicator._id), - name: this.fb.control(this.indicator.name, Validators.required), - description: this.fb.control(this.indicator.description), - additionalDescription: this.fb.control(this.indicator.additionalDescription), - visibility: this.fb.control(this.indicator.visibility), - indicatorPaths: this.fb.array([], Validators.required), - type: this.fb.control(this.indicator.type), - width: this.fb.control(this.indicator.width), - height: this.fb.control(this.indicator.height), - defaultId: this.fb.control(this.indicator.defaultId) - }); - this.addNumberIndicatorPath(); - } - if (this.indicator.defaultId) { - setTimeout(() => { - this.numberIndicatorFb.get('description').disable(); - }, 0); - } - this.editNumberModal.cancelButtonText = 'Cancel'; - this.editNumberModal.okButtonLeft = false; - this.editNumberModal.alertMessage = false; - if (this.index === -1) { - this.editNumberModal.alertTitle = 'Create a new number indicator'; - this.editNumberModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } else { - this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; - this.editNumberModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } - this.editNumberModal.stayOpen = true; - this.editNumberModal.open(); - } - - public editChartIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; - this.urlSubscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - this.section = section; - this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; - if (this.index !== -1) { - this.indicator = HelperFunctions.copy(this.section.indicators[this.index]); - this.chartIndicatorFb = this.fb.group({ - _id: this.fb.control(this.indicator._id), - name: this.fb.control(this.indicator.name), - creationDate: this.fb.control(this.indicator.creationDate), - description: this.fb.control(this.indicator.description), - additionalDescription: this.fb.control(this.indicator.additionalDescription), - visibility: this.fb.control(this.indicator.visibility), - indicatorPaths: this.fb.array([]), - width: this.fb.control(this.indicator.width), - height: this.fb.control(this.indicator.height), - defaultId: this.fb.control(this.indicator.defaultId) - }); - this.indicator.indicatorPaths.forEach(indicatorPath => { - this.addChartIndicatorPath(this.getUrlByStakeHolder(indicatorPath), - this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); - indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); - }); - } else { - this.indicator = new Indicator('', '', '', 'chart', 'medium', 'medium', "PUBLIC", []); - this.chartIndicatorFb = this.fb.group({ - _id: this.fb.control(this.indicator._id), - name: this.fb.control(this.indicator.name), - description: this.fb.control(this.indicator.description), - additionalDescription: this.fb.control(this.indicator.additionalDescription), - visibility: this.fb.control(this.indicator.visibility), - indicatorPaths: this.fb.array([]), - width: this.fb.control(this.indicator.width, Validators.required), - height: this.fb.control(this.indicator.height, Validators.required), - defaultId: this.fb.control(this.indicator.defaultId) - }); - this.addChartIndicatorPath(); - } - if (this.indicator.defaultId) { - setTimeout(() => { - this.chartIndicatorFb.get('description').disable(); - }, 0); - } - this.editChartModal.cancelButtonText = 'Cancel'; - this.editChartModal.okButtonLeft = false; - this.editChartModal.alertMessage = false; - if (this.index === -1) { - this.editChartModal.alertTitle = 'Create a new chart indicator'; - this.editChartModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editChartNotify.reset(this.notification.message); - } else { - this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; - this.editChartModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - ; - this.editChartNotify.reset(this.notification.message); - } - this.editChartModal.stayOpen = true; - this.editChartModal.open(); - } - - saveIndicator() { - this.editing = true; - if (this.indicator.type === 'chart') { - this.chartIndicatorFb.get('description').enable(); - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, true); - this.section = this.charts.find(section => section._id === this.section._id); - } else { - this.numberIndicatorFb.get('description').enable(); - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, false); - this.section = this.numbers.find(section => section._id === this.section._id); - } - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, - this.section._id - ]; - this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.indicator, path).subscribe(indicator => { - if (this.index !== -1) { - this.section.indicators[this.index] = indicator; - } else { - this.section.indicators.push(indicator); - } - this.notification.entity = indicator._id; - this.notification.stakeholder = this.stakeholder.alias; - this.notification.stakeholderType = this.stakeholder.type; - this.notification.groups = [Role.curator(this.stakeholder.type)]; - if (this.stakeholder.defaultId) { - this.notification.groups.push(Role.manager(this.stakeholder.type, this.stakeholder.alias)); - if (this.indicator.type === "chart") { - this.setCharts(); - this.chartIndicatorFb = null; - this.editChartNotify.sendNotification(this.notification); - } else { - this.setNumbers(); - this.numberIndicatorFb = null; - this.editNumberNotify.sendNotification(this.notification); - } - } else { - this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL, null, this.stakeholder._id).subscribe(stakeholders => { - stakeholders.forEach(value => { - this.notification.groups.push(Role.manager(value.type, value.alias)) - }); - if (this.indicator.type === "chart") { - this.setCharts(); - this.chartIndicatorFb = null; - this.editChartNotify.sendNotification(this.notification); - } else { - this.setNumbers(); - this.numberIndicatorFb = null; - this.editNumberNotify.sendNotification(this.notification); - } - }); - } - UIkit.notification('Indicator has been successfully saved', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - if (this.indicator.type === "chart") { - this.editChartModal.cancel(); - } else { - this.editNumberModal.cancel(); - } - }, error => { - this.chartIndicatorFb = null; - UIkit.notification(error.error.message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - if (this.indicator.type === "chart") { - this.editChartModal.cancel(); - } else { - this.editNumberModal.cancel(); - } - })); - } - - saveIndicators(sections) { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id - ]; - this.subscriptions.push(this.stakeholderService.saveBulkElements(this.properties.monitorServiceAPIURL, sections, path).subscribe(stakeholder => { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts = stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts; - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers = stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers; - this.setCharts(); - this.setNumbers(); - this.initReorder(); - this.notification = NotificationUtils.importIndicators(this.user.fullname, this.stakeholder.alias); - this.notification.entity = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id; - this.notification.name = this.user.firstname; - this.notification.surname = this.user.lastname; - this.notification.stakeholder = this.stakeholder.alias; - this.notification.stakeholderType = this.stakeholder.type; - this.notification.groups = [Role.curator(this.stakeholder.type)]; - if (this.stakeholder.defaultId) { - this.notification.groups.push(Role.manager(this.stakeholder.type, this.stakeholder.alias)); - this.notificationService.sendNotification(this.notification).subscribe(notification => { - UIkit.notification('A notification has been sent successfully', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - }, error => { - UIkit.notification('An error has occurred. Please try again later', { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - }); - } else { - this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL, null, this.stakeholder._id).subscribe(stakeholders => { - stakeholders.forEach(value => { - this.notification.groups.push(Role.manager(value.type, value.alias)) - }); - this.notificationService.sendNotification(this.notification).subscribe(notification => { - NotificationHandler.rise('A notification has been sent successfully'); - }, error => { - NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - }); - }); - } - this.editing = false; - this.importLoading = false; - NotificationHandler.rise('Indicators have been imported successfully!'); - }, error => { - this.chartIndicatorFb = null; - NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - this.editing = false; - this.importLoading = false; - })); - - - } - - reorderIndicators(sectionId: string, type: IndicatorType, reorder: Reorder) { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, - sectionId - ]; - this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, reorder, type).subscribe(indicators => { - if (type === 'chart') { - this.charts.find(section => section._id === sectionId).indicators = indicators; - this.setCharts(); - } else { - this.numbers.find(section => section._id === sectionId).indicators = indicators; - this.setNumbers(); - } - this.editing = false; - })); - } - - hasDifference(index: number): boolean { - let hasDifference = false; - this.chartIndicatorPaths.at(index).value.parameters.forEach((parameter) => { - if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { - hasDifference = true; - return; - } - }); - return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !== - this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString(); - } - - public get isAdministrator(): boolean { - return Session.isPortalAdministrator(this.user); - } - - public get isCurator(): boolean { - return this.isAdministrator || Session.isCurator(this.stakeholder.type, this.user); - } - - refreshIndicator() { - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, 'chart', true); - this.indicator.indicatorPaths.forEach(indicatorPath => { - indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); - }); - } - - deleteIndicatorOpen(section: Section, indicatorId: string, type: string, childrenAction: string = null) { - this.indicatorChildrenActionOnDelete = null; - if (childrenAction == "delete") { - this.indicatorChildrenActionOnDelete = childrenAction; - } else if (childrenAction == "disconnect") { - this.indicatorChildrenActionOnDelete = childrenAction; - } - - this.section = section; - if (type === 'chart') { - this.index = this.charts.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId); - } else { - this.index = this.numbers.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId); - } - this.indicator = section.indicators.find(value => value._id == indicatorId); - this.deleteModal.alertTitle = 'Delete indicator'; - this.deleteModal.cancelButtonText = 'No'; - this.deleteModal.okButtonText = 'Yes'; - this.notification = NotificationUtils.deleteIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.deleteNotify.reset(this.notification.message); - this.deleteModal.stayOpen = true; - this.deleteModal.open(); - } - - deleteIndicator() { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, - this.section._id, - this.indicator._id - ]; - this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.indicatorChildrenActionOnDelete).subscribe(() => { - if (this.indicator.type === 'chart') { - this.charts.find(section => section._id === this.section._id).indicators.splice(this.index, 1); - this.setCharts(); - } else { - this.numbers.find(section => section._id === this.section._id).indicators.splice(this.index, 1); - this.setNumbers(); - } - UIkit.notification('Indicator has been successfully deleted', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.notification.entity = this.indicator._id; - this.notification.stakeholder = this.stakeholder.alias; - this.notification.stakeholderType = this.stakeholder.type; - this.notification.groups = [Role.curator(this.stakeholder.type)]; - if (this.stakeholder.defaultId) { - this.notification.groups.push(Role.manager(this.stakeholder.type, this.stakeholder.alias)); - this.deleteNotify.sendNotification(this.notification); - } else { - this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL, null, this.stakeholder._id).subscribe(stakeholders => { - stakeholders.forEach(value => { - this.notification.groups.push(Role.manager(value.type, value.alias)) - }); - this.deleteNotify.sendNotification(this.notification); - }); - } - this.editing = false; - this.deleteModal.cancel(); - }, error => { - UIkit.notification(error.error.message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.deleteModal.cancel(); - })); - } - - changeIndicatorStatus(sectionId: string, indicator: Indicator, visibility: Visibility) { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, - sectionId, - indicator._id - ]; - this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(returnedElement => { - indicator.visibility = returnedElement.visibility; - UIkit.notification('Indicator has been successfully changed to ' + indicator.visibility.toLowerCase(), { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - }, error => { - UIkit.notification('An error has been occurred. Try again later', { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - })); - } - - saveSection(focused: boolean, sectionControl: AbstractControl, index: number, type: IndicatorType = "chart") { - if (!focused && sectionControl.dirty) { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id - ]; - this.subscriptions.push(this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, sectionControl.value, path, index).subscribe(section => { - if (type === 'chart') { - this.charts[index] = section; - this.setCharts(); - } else { - this.numbers[index] = section; - this.setNumbers(); - } - this.initReorder(); - UIkit.notification('Section has been successfully saved', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - }, error => { - UIkit.notification(error.error.message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - })); - } - } - - createSection(index = -1, type: IndicatorType = 'chart') { - this.editing = true; - this.section = new Section(type, null, null, this.stakeholder.alias); - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id - ]; - this.subscriptions.push(this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, this.section, path, index).subscribe(section => { - if (type === 'chart') { - if (index !== -1) { - this.charts.splice(index, 0, section); - } else { - this.charts.push(section); - } - this.setCharts(); - } else { - if (index !== -1) { - this.numbers.splice(index, 0, section); - } else { - this.numbers.push(section); - } - this.setNumbers(); - } - this.initReorder(); - UIkit.notification('Section has been successfully created', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - }, error => { - UIkit.notification(error.error.message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - })); - } - - // deleteNumberSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteNumberSectionModal.alertTitle = 'Delete Section'; - // this.deleteNumberSectionModal.cancelButtonText = 'No'; - // this.deleteNumberSectionModal.okButtonText = 'Yes'; - // this.deleteNumberSectionModal.open(); - // } - // - // deleteChartSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteChartSectionModal.alertTitle = 'Delete Section'; - // this.deleteChartSectionModal.cancelButtonText = 'No'; - // this.deleteChartSectionModal.okButtonText = 'Yes'; - // this.deleteChartSectionModal.open(); - // } - - deleteSectionOpen(section: Section, index: number, type: IndicatorType, childrenAction: string = null) { - if (!this.editing && !section.defaultId) { - this.sectionTypeToDelete = type; - this.sectionChildrenActionOnDelete = null; - if (childrenAction == "delete") { - this.sectionChildrenActionOnDelete = childrenAction; - } else if (childrenAction == "disconnect") { - this.sectionChildrenActionOnDelete = childrenAction; - } - - this.section = section; - this.index = index; - this.deleteSectionModal.alertTitle = 'Delete Section'; - this.deleteSectionModal.cancelButtonText = 'No'; - this.deleteSectionModal.okButtonText = 'Yes'; - this.deleteSectionModal.stayOpen = true; - this.deleteSectionModal.open(); - } - } - - deleteSection() { - this.editing = true; - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, - this.section._id - ]; - this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.sectionChildrenActionOnDelete).subscribe(() => { - if (this.sectionTypeToDelete === "chart") { - this.charts.splice(this.index, 1); - this.setCharts(); - } else { - this.numbers.splice(this.index, 1); - this.setNumbers(); - } - this.initReorder(); - UIkit.notification('Section has been successfully deleted', { - status: 'success', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.deleteSectionModal.cancel(); - }, error => { - UIkit.notification(error.error.message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.deleteSectionModal.cancel(); - })); - } - - private checkForSchemaEnhancements(url: string) { - this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url); - } - - migrateFromOldImportJsonFile(charts) { - // first section contains numbers - // second contains charts - let hasNumbers = false; - for (let chart of charts) { - if (chart['type'] == 'number') { - hasNumbers = true; - break; - } - } - let chartsSection = (hasNumbers ? 1 : 0); // no numbers: first sections contains charts - for (let chart of charts) { - if (chart['sectionIndex'] == null) { - chart['sectionIndex'] = chart['type'] == 'chart' ? chartsSection : 0; - } - } - return charts; - } - - importIndicatorsAndSave(charts: any[]) { - let sectionsToSave: Section[] = []; - let countIndicators = 0; - // name description additionalDescription, height, width, visibility - let noValidParams = 0; - let duplicates = 0; - charts = this.migrateFromOldImportJsonFile(charts); - for (let chart of charts) { - if (!sectionsToSave[chart['sectionIndex']]) { - let sectionToSave = new Section(chart['sectionType'] ? chart['sectionType'] : chart['type'], chart['sectionTitle']); - sectionToSave.indicators = []; - sectionsToSave[chart['sectionIndex']] = sectionToSave; - } - let exists = false; - let indicatorPath; - // validate indicators' schema from file - let invalid_file_message; - if (!chart.type) { - invalid_file_message = "No indicator type is specified. Type should be chart or number."; - } else if (chart.type != "chart" && chart.type != "number") { - invalid_file_message = "Invalid indicator type. Type should be chart or number."; - } else if (chart.type == "number" && !chart.jsonPath) { - invalid_file_message = "No jsonPath is specified for number indicator." - } else if (!chart.url) { - invalid_file_message = "No indicator url is specified."; - } - - if (invalid_file_message) { - UIkit.notification(invalid_file_message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - break; - } - - if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } - } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, this.stakeholder, - chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } - } - if (!this.isStakeholderParametersValid(indicatorPath)) { - noValidParams++; - } - if (!exists) { - let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, "RESTRICTED", [indicatorPath]); - sectionsToSave[chart['sectionIndex']].indicators.push(i); - countIndicators++; - } - - } - - if (duplicates > 0) { - UIkit.notification(duplicates + " urls already exist and will not be imported!", { - status: 'warning', - timeout: 6000, - pos: 'bottom-right' - }); - } - if (noValidParams > 0) { - let noValidMessage = "Some indicators couldn't be generated properly. Please make sure chart data is for the current stakeholder."; - if (this.stakeholder.defaultId == null) { - noValidMessage = "Some indicators couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."; - } - UIkit.notification(noValidMessage, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - } else if (sectionsToSave.length > 0 && countIndicators > 0) { - this.saveIndicators(sectionsToSave.filter(section => !!section)); - } - if (sectionsToSave.length == 0 || countIndicators == 0) { - UIkit.notification(" No urls imported!", { - status: 'warning', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - } - } - - public exportIndicators(subcategoryIndex) { - this.editing = true; - let indicators = []; - let index: number = 0; - let indexIndicator: number = 0; - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].numbers.forEach(section => { - section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, "jsonPath": indicatorPath.jsonPath, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); - }); - index++; - }); - - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].charts.forEach(section => { - section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.getUrlByStakeHolder(indicatorPath), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); - }); - index++; - - }); - - let topic = this.stakeholder ? this.stakeholder.topics[this.topicIndex] : null; - let category = topic ? topic.categories[this.categoryIndex] : null; - let subCategory = category ? category.subCategories[this.subcategoryIndex] : null; - - var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(indicators)], {type: 'application/json'})); - var a = window.document.createElement('a'); - window.document.body.appendChild(a); - a.setAttribute('style', 'display: none'); - a.href = jsonFileUrl; - a.download = this.stakeholder.alias + "_" + topic.alias + "_" + category.alias + "_" + subCategory.alias + ".json"; - a.click(); - window.URL.revokeObjectURL(jsonFileUrl); - a.remove(); // remove the element - - this.editing = false; - } - - fileChangeEvent(fileInput: any, index) { - this.index = index; - this.editing = true; - this.importLoading = true; - this.filesToUpload = >fileInput.target.files; - this.upload(); - } - - upload() { - if (this.filesToUpload.length == 0) { - console.error("There is no selected file to upload."); - UIkit.notification("There is no selected file to upload.", { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - return; - } else { - if (this.filesToUpload[0].name.indexOf(".json") == -1 || (this.filesToUpload[0].type != "application/json")) { - console.error("No valid file type. The required type is JSON"); - UIkit.notification("No valid file type. The required type is JSON", { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - return; - } - } - - this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], this.filesToUpload).then(async (result: string) => { - - let json_result = JSON.parse(result); - - // validate file - if (!json_result || json_result.length == 0) { - UIkit.notification("Importing file is empty", { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - } else { - this.importIndicatorsAndSave(json_result); - } - }, (error) => { - console.error("Error importing files", error); - UIkit.notification("Error importing files", { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - }); - } - - makeFileRequest(url: string, params: Array, files: Array) { - return new Promise((resolve, reject) => { - const formData: any = new FormData(); - const xhr = new XMLHttpRequest(); - for (let i = 0; i < files.length; i++) { - formData.append("uploads[]", files[i], files[i].name); - } - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status == 200) { - resolve(xhr.response); - } else { - reject(xhr.response); - } - } - }; - xhr.open("POST", url, true); - xhr.send(formData); - }); - } - - copyToClipboard(value) { - const tempBox = document.createElement('textarea'); - tempBox.style.position = 'fixed'; - tempBox.style.left = '0'; - tempBox.style.top = '0'; - tempBox.style.opacity = '0'; - tempBox.value = value; - document.body.appendChild(tempBox); - tempBox.focus(); - tempBox.select(); - tempBox.setSelectionRange(0, 99999); - document.execCommand('copy'); - document.body.removeChild(tempBox); - NotificationHandler.rise('Copied to clipboard'); - } -} diff --git a/src/app/topic/topic-routing.module.ts b/src/app/topic/topic-routing.module.ts deleted file mode 100644 index d862297..0000000 --- a/src/app/topic/topic-routing.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {NgModule} from '@angular/core'; -import {RouterModule} from '@angular/router'; -import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard'; -import {TopicComponent} from "./topic.component"; -import {CanExitGuard} from "../openaireLibrary/utils/can-exit.guard"; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - component: TopicComponent, - canDeactivate: [PreviousRouteRecorder, CanExitGuard] - } - ]) - ] -}) -export class TopicRoutingModule { -} diff --git a/src/app/topic/topic.component.html b/src/app/topic/topic.component.html deleted file mode 100644 index 2e5c7ab..0000000 --- a/src/app/topic/topic.component.html +++ /dev/null @@ -1,380 +0,0 @@ - - - -
    -
    - -
    - You are about to delete "{{element.name}}" {{type}} permanently. -
    - {{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well. -
    - Are you sure you want to proceed? -
    -
    - -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    - You have the option to change the visibility status of your {{type}}, with or without applying the changed status to - its contents. -
    -
    - -
    -
    - -
    -
    -

    Note:

    -
    - The status of the {{type}} prevails the status of its contents. - For example, if a {{type}}'s status is private, while it has - a category, subcategory or an indicator - a subcategory or an indicator - an indicator - that is public, the private status of the {{type}} dominates. -
    -
    -
    diff --git a/src/app/topic/topic.component.ts b/src/app/topic/topic.component.ts deleted file mode 100644 index 68d2320..0000000 --- a/src/app/topic/topic.component.ts +++ /dev/null @@ -1,795 +0,0 @@ -import { - AfterViewInit, - ChangeDetectorRef, - Component, Inject, - OnDestroy, - OnInit, PLATFORM_ID, - QueryList, - ViewChild, - ViewChildren -} from '@angular/core'; -import {ActivatedRoute, Router} from '@angular/router'; -import {Title} from '@angular/platform-browser'; -import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties'; -import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../openaireLibrary/monitor/entities/stakeholder"; -import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; -import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; -import {AlertModal} from "../openaireLibrary/utils/modal/alert"; -import {BehaviorSubject, Subject, Subscriber, Subscription} from "rxjs"; -import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; -import {StakeholderUtils} from "../utils/indicator-utils"; -import {StringUtils} from "../openaireLibrary/utils/string-utils.class"; -import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard"; -import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; -import {Option} from "../openaireLibrary/sharedComponents/input/input.component"; -import {properties} from "../../environments/environment"; -import {Session, User} from "../openaireLibrary/login/utils/helper.class"; -import {UserManagementService} from "../openaireLibrary/services/user-management.service"; -import {TransitionGroupComponent} from "../openaireLibrary/utils/transition-group/transition-group.component"; -import {NotificationHandler} from "../openaireLibrary/utils/notification-handler"; - -declare var UIkit; - -@Component({ - selector: 'topic', - templateUrl: './topic.component.html', -}) -export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeactivateComponent { - private topicSubscriptions: any[] = []; - private subscriptions: any[] = []; - public properties: EnvProperties = properties; - public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); - public loading: boolean = false; - public stakeholder: Stakeholder; - public user: User; - /** - * Stakeholder change event - * */ - public change: Subject = new Subject(); - /** - * Current topic - **/ - public topicIndexSubject: BehaviorSubject = new BehaviorSubject(0); - public topicIndex: number = 0; - /** - * Current category - */ - public categoryIndexSubject: BehaviorSubject = new BehaviorSubject(0); - public categoryIndex: number = 0; - /** - * Current Subcategory - */ - public subCategoryIndexSubject: BehaviorSubject = new BehaviorSubject(0); - public subCategoryIndex: number = 0; - /** - * Current element and index of topic, category or subcategory to be deleted. - */ - public form: UntypedFormGroup; - public element: Topic | Category | SubCategory; - public type: 'topic' | 'category' | 'subcategory' = "topic"; - public index: number = -1; - public visibility: Visibility; - - @ViewChild('deleteModal', {static: true}) deleteModal: AlertModal; - @ViewChild('editModal', {static: true}) editModal: AlertModal; - @ViewChild('visibilityModal', {static: true}) visibilityModal: AlertModal; - @ViewChildren(TransitionGroupComponent) transitions: QueryList; - - public elementChildrenActionOnDelete: string; - public filters: UntypedFormGroup; - public all: Option = { - value: 'all', - label: 'All' - }; - - constructor( - private route: ActivatedRoute, - private router: Router, - private title: Title, - private fb: UntypedFormBuilder, - private stakeholderService: StakeholderService, - private userManagementService: UserManagementService, - private layoutService: LayoutService, - private cdr: ChangeDetectorRef, - @Inject(PLATFORM_ID) private platformId) { - } - - public ngOnInit() { - let subscription: Subscription; - this.subscriptions.push(this.topicIndexSubject.asObservable().subscribe(index => { - this.topicChanged(() => { - this.topicIndex = index; - }); - })); - this.subscriptions.push(this.categoryIndexSubject.asObservable().subscribe(index => { - this.categoryChanged(() => { - this.categoryIndex = index; - }); - })); - this.subscriptions.push(this.subCategoryIndexSubject.asObservable().subscribe(index => { - this.subCategoryChanged(() => { - this.subCategoryIndex = index; - }); - })); - this.subscriptions.push(this.route.params.subscribe(params => { - if (subscription) { - subscription.unsubscribe(); - } - subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { - if (stakeholder) { - this.stakeholder = stakeholder; - if (params['topic']) { - this.chooseTopic(this.stakeholder.topics.findIndex(topic => topic.alias === params['topic'])); - } else { - this.chooseTopic(0); - } - this.chooseCategory(0); - this.filters = this.fb.group({ - chartType: this.fb.control('all'), - status: this.fb.control('all'), - keyword: this.fb.control('') - }); - if (this.topicIndex === -1) { - this.navigateToError(); - } else { - this.title.setTitle(stakeholder.name + " | Indicators"); - } - } - }); - this.topicSubscriptions.push(subscription); - })); - this.topicSubscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { - this.user = user; - })) - } - - ngAfterViewInit() { - if(this.topics) { - let activeIndex = UIkit.nav(this.topics.element.nativeElement).items.findIndex(item => item.classList.contains('uk-open')); - if(activeIndex !== this.topicIndex) { - setTimeout(() => { - UIkit.nav(this.topics.element.nativeElement).toggle(this.topicIndex, true); - }); - } - } - } - - get isBrowser() { - return this.platformId === 'browser'; - } - - public ngOnDestroy() { - this.topicSubscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - this.subscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - } - - canExit(): boolean { - this.topicSubscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } - }); - this.stakeholderService.setStakeholder(this.stakeholder); - return true; - } - - private findById(id: string) { - return this.transitions?this.transitions.find(item => item.id === id):null; - } - - get topics(): TransitionGroupComponent { - return this.findById('topics'); - } - - get categories(): TransitionGroupComponent { - return this.findById('categories-' + this.topicIndex); - } - - get subCategories(): TransitionGroupComponent { - return this.findById('subCategories'); - } - - hide(element: any) { - UIkit.dropdown(element).hide(); - } - - stakeholderChanged() { - this.change.next(); - } - - public saveElement() { - if (this.type === "topic") { - this.saveTopic(); - } else if (this.type === "category") { - this.saveCategory(); - } else { - this.saveSubCategory(); - } - } - - public deleteElement() { - if (this.type === "topic") { - this.deleteTopic(); - } else if (this.type === "category") { - this.deleteCategory(); - } else { - this.deleteSubcategory(); - } - } - - public changeElementStatus(propagate: boolean = false) { - if (this.type === "topic") { - this.changeTopicStatus(propagate); - } else if (this.type === "category") { - this.changeCategoryStatus(propagate); - } else { - this.changeSubcategoryStatus(propagate); - } - } - - public chooseTopic(topicIndex: number) { - this.topicIndexSubject.next(topicIndex); - } - - topicChanged(callback: Function, save: boolean = false) { - if(this.topics && save) { - this.topics.disable(); - } - if(this.categories) { - this.categories.disable(); - } - if(this.subCategories) { - this.subCategories.disable(); - } - if(callback) { - callback(); - } - this.cdr.detectChanges(); - if(this.topics && save) { - this.topics.init(); - this.topics.enable(); - } - if(this.categories) { - this.categories.init(); - this.categories.enable(); - } - if(this.subCategories) { - this.subCategories.init(); - this.subCategories.enable(); - } - } - - private buildTopic(topic: Topic) { - let topics = this.stakeholder.topics.filter(element => element._id !== topic._id); - this.form = this.fb.group({ - _id: this.fb.control(topic._id), - name: this.fb.control(topic.name, Validators.required), - description: this.fb.control(topic.description), - creationDate: this.fb.control(topic.creationDate), - alias: this.fb.control(topic.alias, [ - Validators.required, - this.stakeholderUtils.aliasValidator(topics) - ] - ), - visibility: this.fb.control(topic.visibility), - defaultId: this.fb.control(topic.defaultId), - categories: this.fb.control(topic.categories), - icon: this.fb.control(topic.icon) - }); - this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { - let i = 1; - value = this.stakeholderUtils.generateAlias(value); - this.form.controls['alias'].setValue(value); - while (this.form.get('alias').invalid) { - this.form.controls['alias'].setValue(value + i); - i++; - } - })); - } - - public editTopicOpen(index = -1) { - this.index = index; - this.type = 'topic'; - if (index === -1) { - this.buildTopic(new Topic(null, null, null, "PUBLIC")); - } else { - this.buildTopic(this.stakeholder.topics[index]); - } - this.editOpen(); - } - - public saveTopic() { - if (!this.form.invalid) { - let path = [this.stakeholder._id]; - let callback = (topic: Topic): void => { - this.topicChanged(() => { - if (this.index === -1) { - this.stakeholder.topics.push(topic); - } else { - this.stakeholder.topics[this.index] = HelperFunctions.copy(topic); - } - }, true); - }; - if (this.index === -1) { - this.save('Topic has been successfully created', path, this.form.value, callback); - } else { - this.save('Topic has been successfully saved', path, this.form.value, callback); - } - } - } - - public changeTopicStatus(propagate: boolean = false) { - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.index]._id - ]; - let callback = (topic: Topic): void => { - this.topicChanged(() => { - this.stakeholder.topics[this.index] = HelperFunctions.copy(topic); - }, true); - } - this.changeStatus(this.stakeholder.topics[this.index], path, this.visibility, callback, propagate); - this.visibilityModal.cancel(); - } - - public deleteTopicOpen(index = this.topicIndex, childrenAction: string = null) { - this.type = 'topic'; - this.index = index; - this.element = this.stakeholder.topics[this.index]; - this.deleteOpen(childrenAction); - } - - public deleteTopic() { - let path: string[] = [ - this.stakeholder._id, - this.stakeholder.topics[this.index]._id - ]; - let callback = (): void => { - this.topicChanged(() => { - this.stakeholder.topics.splice(this.index, 1); - if(this.topicIndex === this.index) { - this.chooseTopic(Math.max(0, this.index - 1)); - } - }, true); - }; - this.delete('Topic has been successfully be deleted', path, callback, (this.topicIndex === this.index)); - } - - public moveTopic(index: number, newIndex: number = index - 1) { - this.topics.init(); - let path = [this.stakeholder._id]; - let ids = this.stakeholder.topics.map(topic => topic._id); - HelperFunctions.swap(ids, index, newIndex); - this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { - HelperFunctions.swap(this.stakeholder.topics, index, newIndex); - if(this.topicIndex === index) { - this.chooseTopic(newIndex); - } else if(this.topicIndex === newIndex) { - this.chooseTopic(index); - } - }, error => { - NotificationHandler.rise(error.error.message) - }); - } - - public chooseCategory(index: number) { - this.categoryIndexSubject.next(index); - this.chooseSubcategory(0); - } - - categoryChanged(callback: Function, save: boolean = false) { - if(this.categories && save) { - this.categories.disable(); - } - if(this.subCategories) { - this.subCategories.disable(); - } - if(callback) { - callback(); - } - this.cdr.detectChanges(); - if(this.categories && save) { - this.categories.init(); - this.categories.enable(); - } - if(this.subCategories) { - this.subCategories.init(); - this.subCategories.enable(); - } - } - - private buildCategory(category: Category) { - let categories = this.stakeholder.topics[this.topicIndex].categories.filter(element => element._id !== category._id); - this.form = this.fb.group({ - _id: this.fb.control(category._id), - name: this.fb.control(category.name, Validators.required), - description: this.fb.control(category.description), - creationDate: this.fb.control(category.creationDate), - alias: this.fb.control(category.alias, [ - Validators.required, - this.stakeholderUtils.aliasValidator(categories) - ] - ), - visibility: this.fb.control(category.visibility), - defaultId: this.fb.control(category.defaultId), - subCategories: this.fb.control(category.subCategories) - }); - this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { - let i = 1; - value = this.stakeholderUtils.generateAlias(value); - this.form.controls['alias'].setValue(value); - while (this.form.get('alias').invalid) { - this.form.controls['alias'].setValue(value + i); - i++; - } - })); - } - - public editCategoryOpen(index: number = -1) { - this.index = index; - this.type = 'category'; - if (index === -1) { - this.buildCategory(new Category(null, null, null, "PUBLIC")); - } else { - this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]); - } - this.editOpen(); - } - - public saveCategory() { - if (!this.form.invalid) { - let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id]; - let callback = (category: Category): void => { - this.categoryChanged(() => { - if (this.index === -1) { - this.stakeholder.topics[this.topicIndex].categories.push(category); - this.categories.init(); - } else { - this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category); - } - }, true); - }; - if (this.index === -1) { - this.save('Category has been successfully created', path, this.form.value, callback); - } else { - this.save('Category has been successfully saved', path, this.form.value, callback); - } - } - } - - public changeCategoryStatus(propagate: boolean = false) { - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.index]._id - ]; - let callback = (category: Category): void => { - this.categoryChanged(() => { - this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category); - }, true); - } - this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.index], path, this.visibility, callback, propagate); - this.visibilityModal.cancel(); - } - - public deleteCategoryOpen(index: number, childrenAction: string = null) { - this.type = 'category'; - this.index = index; - this.element = this.stakeholder.topics[this.topicIndex].categories[this.index]; - this.deleteOpen(childrenAction); - } - - public deleteCategory() { - let path: string[] = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.index]._id - ]; - let callback = (): void => { - this.categoryChanged(() => { - this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1); - if(this.categoryIndex === this.index) { - this.chooseCategory(Math.max(0, this.index - 1)); - } - }, true); - }; - this.delete('Category has been successfully be deleted', path, callback); - } - - public moveCategory(index: number, newIndex: number = index - 1) { - this.categories.init(); - let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id]; - let ids = this.stakeholder.topics[this.topicIndex].categories.map(category => category._id); - HelperFunctions.swap(ids, index, newIndex); - this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { - HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories, index, newIndex); - if(this.categoryIndex === index) { - this.chooseCategory(newIndex); - } else if(this.categoryIndex === newIndex) { - this.chooseCategory(index); - } - }, error => { - NotificationHandler.rise(error.error.message) - }); - } - - chooseSubcategory(subcategoryIndex: number) { - this.subCategoryIndexSubject.next(subcategoryIndex); - } - - subCategoryChanged(callback: Function, save: boolean = false) { - if(this.subCategories && save) { - this.subCategories.disable(); - } - if(callback) { - callback(); - } - this.cdr.detectChanges(); - if(this.subCategories && save) { - this.subCategories.init(); - this.subCategories.enable(); - } - } - - private buildSubcategory(subCategory: SubCategory) { - let subCategories = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.filter(element => element._id !== subCategory._id); - this.form = this.fb.group({ - _id: this.fb.control(subCategory._id), - name: this.fb.control(subCategory.name, Validators.required), - description: this.fb.control(subCategory.description), - creationDate: this.fb.control(subCategory.creationDate), - alias: this.fb.control(subCategory.alias, [ - Validators.required, - this.stakeholderUtils.aliasValidator(subCategories) - ] - ), - visibility: this.fb.control(subCategory.visibility), - defaultId: this.fb.control(subCategory.defaultId), - charts: this.fb.control(subCategory.charts), - numbers: this.fb.control(subCategory.numbers) - }); - this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { - let i = 1; - value = this.stakeholderUtils.generateAlias(value); - this.form.controls['alias'].setValue(value); - while (this.form.get('alias').invalid) { - this.form.controls['alias'].setValue(value + i); - i++; - } - })); - } - - public editSubCategoryOpen(index: number = -1) { - this.index = index; - this.type = 'subcategory'; - if (index === -1) { - this.buildSubcategory(new SubCategory(null, null, null, "PUBLIC")); - } else { - this.buildSubcategory(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[index]); - } - this.editOpen(); - } - - public saveSubCategory() { - if (!this.form.invalid) { - let path: string[] = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id - ]; - let callback = (subCategory: SubCategory): void => { - this.subCategoryChanged(() => { - if (this.index === -1) { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.push(subCategory); - } else { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index] = HelperFunctions.copy(subCategory); - } - }, true); - }; - if (this.index === -1) { - this.save('Subcategory has been successfully created', path, this.form.value, callback); - } else { - this.save('Subcategory has been successfully saved', path, this.form.value, callback); - } - } - } - - public changeSubcategoryStatus(propagate: boolean = false) { - let path = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id - ]; - let callback = (subcategory: SubCategory): void => { - this.subCategoryChanged(() => { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index] = HelperFunctions.copy(subcategory); - }, true); - } - this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index], path, this.visibility, callback, propagate); - this.visibilityModal.cancel(); - } - - - public deleteSubcategoryOpen(index, childrenAction: string = null) { - this.type = 'subcategory'; - this.index = index; - this.element = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]; - this.deleteOpen(childrenAction); - } - - public deleteSubcategory() { - let path: string[] = [ - this.stakeholder._id, - this.stakeholder.topics[this.topicIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id - ]; - let callback = (): void => { - this.subCategoryChanged(() => { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1); - if(this.subCategoryIndex === this.index) { - this.chooseSubcategory(Math.max(0, this.index - 1)); - } - }, true); - }; - this.delete('Subcategory has been successfully be deleted', path, callback); - } - - public moveSubCategory(index: number, newIndex: number = index - 1) { - this.subCategories.init(); - let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id]; - let ids = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.map(subCategory => subCategory._id); - HelperFunctions.swap(ids, index, newIndex); - this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { - HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories, index, newIndex); - if(this.subCategoryIndex === index) { - this.chooseSubcategory(newIndex); - } else if(this.subCategoryIndex === newIndex) { - this.chooseSubcategory(index); - } - }, error => { - NotificationHandler.rise(error.error.message) - }); - } - - private navigateToError() { - this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}}); - } - - get isCurator(): boolean { - return Session.isPortalAdministrator(this.user) || Session.isCurator(this.stakeholder.type, this.user); - } - - private editOpen() { - this.editModal.cancelButtonText = 'Cancel'; - this.editModal.okButtonLeft = false; - this.editModal.alertMessage = false; - if (this.index === -1) { - this.editModal.alertTitle = 'Create a new ' + this.type; - this.editModal.okButtonText = 'Create'; - } else { - this.editModal.alertTitle = 'Edit ' + this.type + '\'s information '; - this.editModal.okButtonText = 'Save'; - } - this.editModal.stayOpen = true; - this.editModal.open(); - } - - private deleteOpen(childrenAction: string = null) { - this.elementChildrenActionOnDelete = null; - if (childrenAction == "delete") { - this.elementChildrenActionOnDelete = childrenAction; - } else if (childrenAction == "disconnect") { - this.elementChildrenActionOnDelete = childrenAction; - } - - this.deleteModal.alertTitle = 'Delete ' + this.type; - this.deleteModal.cancelButtonText = 'No'; - this.deleteModal.okButtonText = 'Yes'; - // this.deleteModal.cancelButton = false; - // this.deleteModal.okButton = false; - this.deleteModal.stayOpen = true; - this.deleteModal.open(); - } - - private save(message: string, path: string[], saveElement: any, callback: Function, redirect = false) { - this.loading = true; - this.topicSubscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => { - callback(saveElement); - this.stakeholderChanged(); - this.loading = false; - this.editModal.cancel(); - NotificationHandler.rise(message); - if (redirect) { - this.router.navigate(['../' + saveElement.alias], { - relativeTo: this.route - }); - } - }, error => { - this.loading = false; - this.editModal.cancel(); - NotificationHandler.rise(error.error.message, 'danger'); - })); - } - - private delete(message: string, path: string[], callback: Function, redirect = false) { - this.loading = true; - this.topicSubscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => { - callback(); - this.stakeholderChanged(); - this.loading = false; - this.deleteModal.cancel(); - NotificationHandler.rise(message); - if (redirect) { - this.back(); - } - }, error => { - this.loading = false; - this.deleteModal.cancel(); - NotificationHandler.rise(error.error.message, 'danger'); - })); - } - - private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility, callback: Function = null, propagate: boolean = false) { - this.topicSubscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility, propagate).subscribe(returnedElement => { - if(propagate) { - callback(returnedElement); - NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been successfully changed to ' + returnedElement.visibility.toLowerCase()); - } else { - element.visibility = returnedElement.visibility; - NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been successfully changed to ' + element.visibility.toLowerCase()); - } - }, error => { - NotificationHandler.rise(error.error.message, 'danger'); - })); - } - - back() { - this.router.navigate(['../'], { - relativeTo: this.route - }); - } - - public getPluralTypeName(): string { - if (this.type == "topic") { - return "Topics"; - } else if (this.type == "category") { - return "Categories"; - } else if (this.type == "subcategory") { - return "Subcategories"; - } else { - return this.type; - } - } - - public get isSmallScreen() { - return this.layoutService.isSmallScreen; - } - - public get open() { - return this.layoutService.open; - } - - public toggleOpen(event: MouseEvent) { - event.preventDefault(); - this.layoutService.setOpen(!this.open); - } - - public openVisibilityModal(index: number, visibility: Visibility, type: any) { - this.index = index; - this.visibility = visibility; - this.type = type; - this.visibilityModal.alertTitle = 'Visibility Status'; - this.visibilityModal.alertFooter = false; - this.visibilityModal.open(); - } -} diff --git a/src/app/topic/topic.module.ts b/src/app/topic/topic.module.ts deleted file mode 100644 index 9f046ef..0000000 --- a/src/app/topic/topic.module.ts +++ /dev/null @@ -1,49 +0,0 @@ -import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; - -import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard'; - -import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service'; -import {TopicComponent} from "./topic.component"; -import {TopicRoutingModule} from "./topic-routing.module"; -import {RouterModule} from "@angular/router"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; -import {IndicatorsComponent} from "./indicators.component"; -import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module"; -import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module"; -import {ClickModule} from "../openaireLibrary/utils/click/click.module"; -import {IconsService} from "../openaireLibrary/utils/icons/icons.service"; -import {earth, incognito, restricted} from "../openaireLibrary/utils/icons/icons"; -import {IconsModule} from "../openaireLibrary/utils/icons/icons.module"; -import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module"; -import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module"; -import {NotifyFormModule} from "../openaireLibrary/notifications/notify-form/notify-form.module"; -import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module"; -import {TransitionGroupModule} from "../openaireLibrary/utils/transition-group/transition-group.module"; -import {NumberRoundModule} from "../openaireLibrary/utils/pipes/number-round.module"; -import {SideBarModule} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sideBar.module"; -import { - SidebarMobileToggleModule -} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module"; - -@NgModule({ - imports: [ - CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule, - ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule - ], - declarations: [ - TopicComponent, IndicatorsComponent - ], - providers: [ - PreviousRouteRecorder, - PiwikService - ], - exports: [ - TopicComponent - ] -}) -export class TopicModule { - constructor(private iconsService: IconsService) { - this.iconsService.registerIcons([earth, incognito, restricted]); - } -} diff --git a/src/app/utils/adminDashboard.guard.ts b/src/app/utils/adminDashboard.guard.ts deleted file mode 100644 index c91dfeb..0000000 --- a/src/app/utils/adminDashboard.guard.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {Injectable} from '@angular/core'; -import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; -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 {Observable, zip} from "rxjs"; -import {error} from "protractor"; - - -@Injectable() -export class AdminDashboardGuard { - - constructor(private router: Router, - private stakeholderService: StakeholderService, - private userManagementService: UserManagementService) { - } - - check(path: string, alias: string): Observable | boolean { - let errorCode = LoginErrorCodes.NOT_LOGIN; - return zip( - this.userManagementService.getUserInfo(), this.stakeholderService.getStakeholder(alias) - ).pipe(take(1),map(res => { - if(res[0]) { - errorCode = LoginErrorCodes.NOT_ADMIN; - } - return res[0] && res[1] && (Session.isPortalAdministrator(res[0]) || - Session.isCurator(res[1].type, res[0]) || Session.isManager(res[1].type, res[1].alias, res[0])) - }),tap(authorized => { - if(!authorized){ - this.router.navigate(['/user-info'], {queryParams: {'errorCode': errorCode, 'redirectUrl':path}}); - } - })); - } - - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { - return this.check(state.url, route.params.stakeholder); - } - - canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { - return this.check(state.url, childRoute.params.stakeholder); - } -} diff --git a/src/app/utils/indicator-utils.ts b/src/app/utils/indicator-utils.ts deleted file mode 100644 index b186f4b..0000000 --- a/src/app/utils/indicator-utils.ts +++ /dev/null @@ -1,1005 +0,0 @@ -import { - ChartHelper, - FilterType, - Indicator, - IndicatorFilterUtils, - IndicatorPath, - IndicatorPathType, - IndicatorType, - SourceType, - Stakeholder, - StakeholderEntities, - SubCategory, - Topic, - Visibility -} from "../openaireLibrary/monitor/entities/stakeholder"; -import {AbstractControl, ValidatorFn, Validators} from "@angular/forms"; -import {Option} from "../openaireLibrary/sharedComponents/input/input.component"; -import {Session} from "../openaireLibrary/login/utils/helper.class"; -import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; -import {properties} from "../../environments/environment"; - -export class StakeholderUtils { - - statuses: Option[] = [ - {value: 'PUBLIC', label: 'Public'}, - {value: 'RESTRICTED', label: 'Restricted'}, - {value: 'PRIVATE', label: 'Private'} - ]; - - types: Option[] = [ - {value: 'funder', label: StakeholderEntities.FUNDER}, - {value: 'ri', label: StakeholderEntities.RI}, - {value: 'project', label: StakeholderEntities.PROJECT}, - {value: 'organization', label: StakeholderEntities.ORGANIZATION} - ]; - - visibility: Option[] = [ - {icon: 'earth', value: "PUBLIC", label: 'Public'}, - {icon: 'restricted', value: "RESTRICTED", label: 'Restricted'}, - {icon: 'incognito', value: "PRIVATE", label: 'Private'}, - ]; - - locales: Option[] = [ - {value: "en", label: 'English'}, - {value: "eu", label: 'Europe'} - ]; - - visibilityIcon: Map = new Map([ - ["PUBLIC", 'earth'], - ["PRIVATE", 'incognito'], - ["RESTRICTED", 'restricted'] - ]); - - getTypesByUserRoles(user, id: string = null): Option[] { - let types = []; - for (let type of this.types) { - if (Session.isCurator(type.value, user) || Session.isPortalAdministrator(user) || (id && Session.isManager(type.value, id, user))) { - types.push(type); - } - } - return types; - } - - public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[], isDefault: boolean = false): Stakeholder { - funder.topics = HelperFunctions.copy(defaultTopics); - for (let topic of funder.topics) { - topic.defaultId = !isDefault ? topic._id : null; - topic._id = null; - for (let category of topic.categories) { - category.defaultId = !isDefault ? category._id : null; - category._id = null; - let subTokeep: SubCategory[] = []; - for (let subCategory of category.subCategories) { - subCategory.defaultId = !isDefault ? subCategory._id : null; - subCategory._id = null; - subTokeep.push(subCategory); - for (let section of subCategory.charts) { - let chartsTokeep: Indicator[] = []; - section.defaultId = !isDefault ? section._id : null; - section.stakeholderAlias = funder.alias; - section._id = null; - for (let indicator of section.indicators) { - indicator.defaultId = !isDefault ? indicator._id : null; - indicator._id = null; - chartsTokeep.push(indicator); - for (let indicatorPath of indicator.indicatorPaths) { - if (indicatorPath.parameters) { - Object.keys(indicatorPath.parameters).forEach(key => { - if (key == "index_name") { - indicatorPath.parameters[key] = funder.index_name; - } else if (key == "index_id") { - indicatorPath.parameters[key] = funder.index_id; - } else if (key == "index_shortName") { - indicatorPath.parameters[key] = funder.index_shortName.toLowerCase(); - } - }); - } - } - } - section.indicators = chartsTokeep; - } - for (let section of subCategory.numbers) { - section.defaultId = !isDefault ? section._id : null; - section.stakeholderAlias = funder.alias; - section._id = null; - for (let indicator of section.indicators) { - indicator.defaultId = !isDefault ? indicator._id : null; - indicator._id = null; - } - } - - } - category.subCategories = subTokeep; - } - } - return funder; - } - - aliasValidatorString(elements: string[]): ValidatorFn { - return (control: AbstractControl): { [key: string]: string } | null => { - if (control.value && elements.find(element => - element === control.value - )) { - return {'error': 'Alias already in use'}; - } - return null; - } - } - - aliasValidator(elements: any[]): ValidatorFn { - return (control: AbstractControl): { [key: string]: string } | null => { - if (control.value && elements.find(element => - element.alias === control.value - )) { - return {'error': 'Alias already in use'}; - } - return null; - } - } - - generateAlias(name: string): string { - let alias = name.toLowerCase(); - while (alias.includes('/') || alias.includes(' ')) { - alias = alias.replace(' / ', '-'); - alias = alias.replace('/', '-'); - alias = alias.replace(' ', '-'); - } - return alias; - } -} - -export class IndicatorUtils { - - allChartTypes: Option[] = [ - {value: 'pie', label: 'Pie'}, - {value: 'table', label: 'Table'}, - {value: 'line', label: 'Line'}, - {value: 'column', label: 'Column'}, - {value: 'bar', label: 'Bar'}, - {value: 'other', label: 'Other'} - ]; - basicChartTypes: IndicatorPathType[] = ["pie", "line", "column", "bar"]; - defaultChartType: IndicatorPathType = "other"; - indicatorSizes: Option[] = [ - {value: 'small', label: 'Small (Enabled only for large screens)'}, - {value: 'medium', label: 'Medium'}, - {value: 'large', label: 'Large'} - ]; - - allSourceTypes: Option[] = [ - {value: 'search', label: 'Search'}, - {value: 'statistics', label: 'Statistics'}, - {value: 'stats-tool', label: 'Statistics tool'} - ]; - - formats: Option[] = [ - {value: "NUMBER", label: "Number"}, - {value: "PERCENTAGE", label: "Percentage"} - ]; - - sourceTypes: Option[] = [ - {value: 'stats-tool', label: 'Statistics tool'} - ]; - - isActive: Option[] = [ - {icon: 'brightness_1', iconClass: '', value: true, label: 'Active'}, - {icon: 'brightness_1', value: false, label: 'Inactive'}, - ]; - - parametersValidators: Map = new Map([ - ['start_year', [Validators.required, Validators.pattern('^\\d+$')]], - ['end_year', [Validators.required, Validators.pattern('^\\d+$')]] - ]); - ignoredParameters = ['index_name', 'index_id', 'index_shortName']; - statsProfileParameter = 'profile'; - - numberSources: Map = new Map(); - chartSources: Map = new Map(); - - constructor() { - this.numberSources.set('statistics', [properties.statisticsAPIURL]); - this.numberSources.set('search', [properties.searchAPIURLLAst]); - this.numberSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); - this.chartSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); - this.chartSources.set('old', [properties.statisticsFrameAPIURL]); - this.chartSources.set('image', [""]); - } - - getSourceType(source:string): SourceType{ - let sourceType: SourceType = 'search'; - this.numberSources.forEach((values, key) => { - if(key == source) { - sourceType = key; - } - }); - return sourceType; - } - - getChartUrl(source: SourceType, url: string): string { - return this.chartSources.get(source)[0] + url; - } - - getNumberUrl(source: SourceType, url: string): string { - return this.numberSources.get(this.getSourceType(source))[0] + url; - } - - getNumberSource(url: string): SourceType { - let source: SourceType = 'search'; - this.numberSources.forEach((values, key) => { - values.forEach((value) => { - if (value !== '' && url.indexOf(value) !== -1) { - source = key; - } - }); - }); - return source; - } - - getChartSource(url: string): SourceType { - let source: SourceType = 'image'; - this.chartSources.forEach((values, key) => { - values.forEach((value) => { - if (value !== '' && url.indexOf(value) !== -1) { - source = key; - } - }); - }); - return source; - } - - getChartTypes(initialType) { - let types: Option[] = []; - if (this.basicChartTypes.indexOf(initialType) != -1) { - (this.allChartTypes).forEach(option => { - if (this.basicChartTypes.indexOf(option.value) != -1) { - types.push(option); - } - }); - return types; - } else if (initialType == "table") { - (this.allChartTypes).forEach(option => { - if (initialType == option.value) { - types.push(option); - } - }); - return types; - } else { - return this.allChartTypes; - } - } - - public getFullUrl(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string { - let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; - if (stakeholder.statsProfile) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile) - } - if (indicatorPath.parameters) { - Object.keys(indicatorPath.parameters).forEach(key => { - let replacedValue = indicatorPath.parameters[key]; - if (startYear && key == "start_year" && indicatorPath.filters["start_year"]) { - replacedValue = (replacedValue < startYear) ? startYear : replacedValue; - } - if (endYear && key == "end_year" && indicatorPath.filters["end_year"]) { - replacedValue = (replacedValue > endYear) ? endYear : replacedValue; - } - if (key == "index_id") { - replacedValue = stakeholder.index_id; - } - if (key == "index_name") { - replacedValue = stakeholder.index_name; - } - if (key == "index_shortName") { - replacedValue = stakeholder.index_shortName.toLowerCase(); - } - - replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) - }); - } - if (indicatorPath.chartObject) { - if (fundingL0 && indicatorPath.filters["fundingL0"]) { - let newJsonObject = JSON.parse(replacedUrl); - for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { - if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { - queries["query"]["filters"] = []; - } - //TODO check how it works if the query already has a filter - queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["fundingL0"].replace(ChartHelper.prefix + "fundingL0" + ChartHelper.suffix, fundingL0))); - } - replacedUrl = JSON.stringify(newJsonObject); - } - if (startYear && indicatorPath.filters["start_year"]) { - let newJsonObject = JSON.parse(replacedUrl); - - for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { - if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { - queries["query"]["filters"] = []; - } - //TODO check how it works if the query already has a filter - queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["start_year"].replace(ChartHelper.prefix + "start_year" + ChartHelper.suffix, startYear))); - } - replacedUrl = JSON.stringify(newJsonObject); - } - if (endYear && indicatorPath.filters["end_year"]) { - let newJsonObject = JSON.parse(replacedUrl); - for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { - if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { - queries["query"]["filters"] = []; - } - //TODO check how it works if the query already has a filter - queries["query"]["filters"].push(JSON.parse(indicatorPath.filters["end_year"].replace(ChartHelper.prefix + "end_year" + ChartHelper.suffix, endYear))); - } - replacedUrl = JSON.stringify(newJsonObject); - } - - } - //For numbers (e.g. from stats-api , search service, etc) - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id)); - } - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name)); - } - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName)); - } - return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); - } - - public getFullUrlWithFilters(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded: boolean = false): string { - indicatorPath.filtersApplied = 0; - let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; - if (stakeholder.statsProfile) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile); - } - if (indicatorPath.parameters) { - Object.keys(indicatorPath.parameters).forEach(key => { - let replacedValue = indicatorPath.parameters[key]; - if (startYear && key == "start_year") { - replacedValue = (replacedValue < startYear) ? startYear : replacedValue; - //if there is a parameter that is filtered and the value of the parameter changes, count the filter as applied - indicatorPath.filtersApplied++; - } - if (endYear && key == "end_year") { - replacedValue = (replacedValue > endYear) ? endYear : replacedValue; - //if there is a parameter that is filtered and the value of the parameter changes, count the filter as applied - indicatorPath.filtersApplied++; - } - if (key == "index_id") { - replacedValue = stakeholder.index_id; - } - if (key == "index_name") { - replacedValue = stakeholder.index_name; - } - if (key == "index_shortName") { - replacedValue = stakeholder.index_shortName.toLowerCase(); - } - - replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) - }); - } - if (fundingL0) { - if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { - let filterResults = this.addFilter(replacedUrl, 'fundingL0', fundingL0); - replacedUrl = filterResults.url; - indicatorPath.filtersApplied += filterResults.filtersApplied; - } - } - if (startYear) { - if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { - let filterResults = this.addFilter(replacedUrl, 'start_year', startYear); - replacedUrl = filterResults.url; - indicatorPath.filtersApplied += filterResults.filtersApplied; - } - } - if (endYear) { - if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { - let filterResults = this.addFilter(replacedUrl, 'end_year', endYear); - replacedUrl = filterResults.url; - indicatorPath.filtersApplied += filterResults.filtersApplied; - } - } - if (coFunded) { - if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { - let filterResults = this.addFilter(replacedUrl, 'co-funded', endYear); - replacedUrl = filterResults.url; - indicatorPath.filtersApplied += filterResults.filtersApplied; - } - } - - //For numbers - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id)); - } - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name)); - } - if (replacedUrl.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) != -1) { - replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName)); - } - //Check apply enhancements return this.applySchemaEnhancements( ..); - return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); - - } - - private addFilter(replacedUrl, filterType: FilterType, filterValue) { - let newJsonObject = JSON.parse(replacedUrl); - let filterApplied: boolean = false; - let queryIndex = 0; - for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { - /*Chart with Named Queries*/ - if (queries["query"]["name"] && !queries["query"]["select"]) { - - if (queries["query"]["name"].indexOf("monitor.") == -1 || !queries["query"]["parameters"]) { - continue; - } - if (filterType == 'fundingL0') { - let paramFields = queries["query"]["name"].split(".").slice(3); - let filterPosition = queries["query"]["name"].split(".").indexOf(filterType == "fundingL0" ? 'fl0' : filterType); - if (filterPosition != -1) { - //already filtered - //TODO double check if we need to override if the fl0 is already filtered - filterPosition -= 3; - /* //update the value - if(paramFields.length == queries["query"]["parameters"].length ){ - //ok - queries["query"]["parameters"][filterPosition] = filterValue; - }else if((paramFields.length + 2) == queries["query"]["parameters"].length || (paramFields.length*2 + 4) == queries["query"]["parameters"].length){ - queries["query"]["parameters"][filterPosition + 2]=filterValue; - filterApplied = true; - } - if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){ - queries["query"]["parameters"][(2* filterPosition) + 5]=filterValue; - }*/ - //if applied with the same value mark as filtered - if (paramFields.length == queries["query"]["parameters"].length && queries["query"]["parameters"][filterPosition] == filterValue) { - filterApplied = true; - } else if ((paramFields.length + 2) == queries["query"]["parameters"].length || (paramFields.length * 2 + 4) == queries["query"]["parameters"].length && queries["query"]["parameters"][filterPosition + 2] == filterValue) { - filterApplied = true; - } - } else { - // if((paramFields.length*2) == queries["query"]["parameters"].length){ - // queries["query"]["parameters"].splice(paramFields.length, 0, filterValue); - // } - if ((paramFields.length * 2 + 4) == queries["query"]["parameters"].length) { - queries["query"]["parameters"].splice(paramFields.length + 1, 0, filterValue); - } - queries["query"]["name"] = queries["query"]["name"] + ".fl0"; - queries["query"]["parameters"].push(filterValue); - filterApplied = true; - } - } else { - let paramFields = queries["query"]["name"].split(".").slice(3); - if ((paramFields.length + 2) == queries["query"]["parameters"].length || (paramFields.length * 2 + 4) == queries["query"]["parameters"].length) { - filterApplied = true; - if (filterType == "start_year") { - queries["query"]["parameters"][0] = parseInt(filterValue); - } else if (filterType == "end_year") { - queries["query"]["parameters"][1] = parseInt(filterValue); - } - } - if ((paramFields.length * 2 + 4) == queries["query"]["parameters"].length) { - filterApplied = true; - if (filterType == "start_year") { - queries["query"]["parameters"][paramFields.length + 2] = parseInt(filterValue); - } else if (filterType == "end_year") { - queries["query"]["parameters"][paramFields.length + 3] = parseInt(filterValue); - } - } - } - // it is a name query - continue; - } - if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { - queries["query"]["filters"] = []; - } - /*Chart with proper json object*/ - //apply the filter in any select fields - for (let select of queries["query"]["select"]) { - let filterString = IndicatorFilterUtils.getFilter(select["field"], filterType); - if (filterString) { - let filter = JSON.parse(filterString); - //check if filter already exists - let filterposition = IndicatorFilterUtils.filterIndexOf(filter, queries["query"]["filters"]); - if (filterposition) { - if (queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] != filter['groupFilters'][0]["values"][0].replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue)) { - //change filter value - // queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filter['groupFilters'][0]["values"][0].replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue); - //add user filter value - // queries["query"]["filters"].push(JSON.parse(filterString.replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue))); - // update colors - //if noit a pie, map and chart has more than one query - // - if (!newJsonObject.hasOwnProperty("mapDescription") && queries["type"] != "pie" && this.isComparingChart(newJsonObject, filter)) { - let activeColors = ["#7CB5EC", "#434348", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a"]; - let inActiveColors = ["#E4EFFB", "#D8D8D9", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a"]; - if (!newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"]) { - newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"] = activeColors; - } - newJsonObject[this.getDescriptionObjectName(newJsonObject)]["colors"][queryIndex] = inActiveColors[queryIndex]; - filterApplied = true; - } else if (filterType == "start_year" || filterType == "end_year") { - //if has date filter already - if (filterType == "start_year" && parseInt(filterValue) > parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) { - queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue; - } else if (filterType == "end_year" && parseInt(filterValue) < parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) { - queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue; - } - filterApplied = true; - } - } else { - filterApplied = true; - } - } else { - queries["query"]["filters"].push(JSON.parse(filterString.replace(ChartHelper.prefix + filterType + ChartHelper.suffix, filterValue))); - filterApplied = true; - } - } - } - queryIndex++; - } - return {"url": JSON.stringify(newJsonObject), "filtersApplied": (filterApplied) ? 1 : 0}; - } - - isComparingChart(newJsonObject, filter,) { - let queriesCount = this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)].length : newJsonObject[this.getDescriptionObjectName(newJsonObject)].length; - let values = []; - if (queriesCount < 2) { - return false; - } - for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { - let filterposition = IndicatorFilterUtils.filterIndexOf(filter, queries["query"]["filters"]); - if (filterposition) { - if (values.indexOf(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]) == -1) { - values.push(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]); - } - } - } - return values.length > 1; - } - - generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type: IndicatorType, addParameters: boolean = true): Indicator { - let indicator: Indicator = new Indicator(form.name, form.description, form.additionalDescription, type, - form.width, form.height, form.visibility, indicatorPaths, form.defaultId); - indicator._id = form._id; - form.indicatorPaths.forEach((indicatorPath, index) => { - indicator.indicatorPaths[index].type = indicatorPath.type; - indicator.indicatorPaths[index].format = indicatorPath.format; - if (addParameters) { - indicatorPath.parameters.forEach(parameter => { - indicator.indicatorPaths[index].parameters[parameter.key] = parameter.value; - if (parameter.key === 'type') { - indicator.indicatorPaths[index].type = parameter.value; - } - }); - } - }); - return indicator; - } - - generateIndicatorByNumberUrl(source: SourceType, url: string, stakeholder: Stakeholder, jsonPath = [], sourceServices: string[] = []): IndicatorPath { - let indicatorPath = new IndicatorPath(null, source, url, null, jsonPath); - if (source === 'stats-tool') { - indicatorPath.url = url.split("json=")[0] + "json="; - indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1]; - indicatorPath.chartObject = decodeURIComponent(url.indexOf("json=") != -1 ? url.split("json=")[1] : ""); - let chart = JSON.parse(indicatorPath.chartObject); - this.parameterizeDefaultQuery(chart, indicatorPath, stakeholder); - this.extractStakeHolders(chart, indicatorPath, stakeholder); - indicatorPath.chartObject = JSON.stringify(chart); - if (!jsonPath || jsonPath.length == 0 || (jsonPath.length == 1 && jsonPath[0] == "")) { - indicatorPath.jsonPath = ["data", "0", "0", "0"]; - } - // this.addResultFilters(chart, indicatorPath); - } else { - for (let service of sourceServices) { - if (url.indexOf(service) != -1) { - url = url.split(service)[1]; - } - } - try { - if (url.indexOf(encodeURIComponent(stakeholder.index_id)) !== -1) { - url = url.split(encodeURIComponent(stakeholder.index_id)).join(ChartHelper.prefix + "index_id" + ChartHelper.suffix); - } - if (url.indexOf(encodeURIComponent(stakeholder.index_name)) !== -1) { - url = url.split(encodeURIComponent(stakeholder.index_name)).join(ChartHelper.prefix + "index_name" + ChartHelper.suffix); - } - if (url.indexOf(encodeURIComponent(stakeholder.index_shortName)) !== -1) { - url = url.split(encodeURIComponent(stakeholder.index_shortName)).join(ChartHelper.prefix + "index_shortName" + ChartHelper.suffix); - } - indicatorPath.url = url; - } catch (e) { - console.error(e); - } - } - return indicatorPath; - } - - generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder: Stakeholder): IndicatorPath { - let indicatorPath = new IndicatorPath(type, source, null, null, []); - try { - if (source === 'stats-tool') { - indicatorPath.url = url.split("json=")[0] + "json="; - indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1]; - indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]); - let chart = JSON.parse(indicatorPath.chartObject); - if (indicatorPath.url == "chart?json=") { - - if (chart["library"] && (chart["library"] == "HighCharts" || chart["library"] == "eCharts" || chart["library"] == "HighMaps")) { - indicatorPath.type = this.extractType(chart, indicatorPath); - } else { - indicatorPath.type = this.defaultChartType; - } - - this.extractTitle(chart, indicatorPath); - this.extractSubTitle(chart, indicatorPath); - this.extractXTitle(chart, indicatorPath); - this.extractYTitle(chart, indicatorPath); - } else if (indicatorPath.url == "table?json=") { - indicatorPath.type = "table"; - } - if (indicatorPath.url == "chart?json=" || indicatorPath.url == "table?json=") { - // common for tables and other chart types - this.extractDataTitle(chart, indicatorPath); - this.parameterizeDefaultQuery(chart, indicatorPath, stakeholder); - this.extractStakeHolders(chart, indicatorPath, stakeholder); - this.extractStartYear(chart, indicatorPath); - this.extractEndYear(chart, indicatorPath); - indicatorPath.chartObject = JSON.stringify(chart); - } - } else if (source === 'old') { - indicatorPath.url = url.split("data=")[0].split("/stats/")[1] + "data="; - indicatorPath.chartObject = decodeURIComponent(url.split("data=")[1].split("&")[0]); - indicatorPath.type = type; - let chart = JSON.parse(indicatorPath.chartObject); - this.extractOldToolTitle(chart, indicatorPath); - this.extractOldToolXTitle(chart, indicatorPath); - this.extractOldToolYTitle(chart, indicatorPath); - indicatorPath.chartObject = JSON.stringify(chart); - } else { - indicatorPath.url = url; - indicatorPath.type = type; - } - } catch (e) { - console.error(e); - indicatorPath.url = url; - indicatorPath.type = type; - } - if (indicatorPath.type == null) { - indicatorPath.type = this.defaultChartType; - } - return indicatorPath; - } - - private getQueryObjectName(obj) { - if ((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queriesInfo")) { - return "queriesInfo"; - } else if ((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queries")) { - return "queries"; - } - } - - private getDescriptionObjectName(obj) { - if (obj.hasOwnProperty("mapDescription")) { - return "mapDescription"; - } else if (obj.hasOwnProperty("chartDescription")) { - return "chartDescription"; - } else if (obj.hasOwnProperty("tableDescription")) { - return "tableDescription"; - } else if (obj.hasOwnProperty("series")) { - return "series"; - } - } - - private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType { - let type = (obj[this.getDescriptionObjectName(obj)] && obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"]) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"] : ""; - if (this.basicChartTypes.indexOf(type) == -1) { - type = this.defaultChartType; - } else { - obj[this.getDescriptionObjectName(obj)]["queries"][0]["type"] = ChartHelper.prefix + "type" + ChartHelper.suffix; - indicatorPath.parameters['type'] = type; - } - return type; - } - - private extractStakeHolders(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { - this.extractFunder(obj, indicatorPath, stakeholder); - this.extractRI(obj, indicatorPath, stakeholder); - this.extractOrganization(obj, indicatorPath, stakeholder); - } - - private extractFunder(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { - if (stakeholder.type != "funder") { - return; - } - for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { - if (query["query"]["profile"]) { - query["query"]["profile"] = ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix; - } - if (!query["query"]["filters"]) { - return; - } - for (let filter of query["query"]["filters"]) { - for (let gfilter of filter["groupFilters"]) { - //ignore field No Of Funders - if (gfilter["field"].indexOf(" funder") != -1 && gfilter["field"].indexOf(" funders") == -1) {//new statistcs schema - gfilter["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; - indicatorPath.parameters["index_name"] = stakeholder.index_name; - } else if (gfilter["field"].indexOf(".funder") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; - indicatorPath.parameters["index_name"] = stakeholder.index_name; - } else if (gfilter["field"].indexOf(".funder.id") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; - indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName; - } - } - } - } - } - - private extractRI(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { - if (stakeholder.type != "ri") { - return; - } - for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { - if (query["query"]["profile"]) { - query["query"]["profile"] = ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix; - } - if (!query["query"]["filters"]) { - return; - } - for (let filter of query["query"]["filters"]) { - for (let gfilter of filter["groupFilters"]) { - if (gfilter["field"].indexOf(".context.name") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; - indicatorPath.parameters["index_name"] = stakeholder.index_name; - } else if (gfilter["field"].indexOf(".context.id") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; - indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName; - } - } - } - } - } - - private extractOrganization(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { - // works for publication.project.organization.name - // and publication.organization.name - if (stakeholder.type != "organization") { - return; - } - for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { - if (query["query"]["profile"]) { - query["query"]["profile"] = ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix; - } - if (!query["query"]["filters"]) { - return; - } - for (let filter of query["query"]["filters"]) { - for (let gfilter of filter["groupFilters"]) { - if (gfilter["field"].indexOf(".organization.name") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; - indicatorPath.parameters["index_name"] = stakeholder.index_name; - } else if (gfilter["field"].indexOf(".organization.id") != -1) { - gfilter["values"][0] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; - indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName; - } - } - } - } - } - - private extractStartYear(obj, indicatorPath: IndicatorPath) { - let start_year; - for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { - if (!query["query"]["filters"]) { - return; - } - for (let filter of query["query"]["filters"]) { - for (let gfilter of filter["groupFilters"]) { - if ((gfilter["field"].indexOf(".year") != -1 || gfilter["field"].indexOf(".start year") != -1) && gfilter["type"].indexOf(">") != -1) { - start_year = gfilter["values"][0]; - gfilter["values"][0] = ChartHelper.prefix + "start_year" + ChartHelper.suffix; - indicatorPath.parameters["start_year"] = start_year; - } - } - } - } - } - - private extractEndYear(obj, indicatorPath: IndicatorPath) { - let end_year; - for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { - if (!query["query"]["filters"]) { - return; - } - for (let filter of query["query"]["filters"]) { - for (let gfilter of filter["groupFilters"]) { - if ((gfilter["field"].indexOf(".year") != -1 || gfilter["field"].indexOf(".start year") != -1) && gfilter["type"].indexOf("<") != -1) { - end_year = gfilter["values"][0]; - gfilter["values"][0] = ChartHelper.prefix + "end_year" + ChartHelper.suffix; - indicatorPath.parameters["end_year"] = end_year; - } - } - } - } - } - - private parameterizeDefaultQuery(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { - let name = ""; - for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { - //monitor.{{stakeholderType}}.{{queryname}} - //parameters: stakeholderId*, type - if (query["query"]["name"]) { - name = query["query"]["name"]; - let parameters = (query["query"]["parameters"]) ? query["query"]["parameters"] : []; - if (name.split('.')[0] == "rcd" && parameters.length > 0 && stakeholder.type == "ri") { - //rcd.{{queryname}} - parameters[0] = ChartHelper.prefix + "index_id" + ChartHelper.suffix; - indicatorPath.parameters["index_id"] = stakeholder.index_id; - } else if (name.split('.')[0] == "monitor" && parameters.length == 0 && stakeholder.type == "funder") { - // old saved queries without params - //monitor.{{funder_shortName}}.{{type}}.{{queryname}} - let stakeholderSN = name.split('.')[1]; - query["query"]["name"] = name.split('.' + stakeholderSN + ".")[0] + "." + ChartHelper.prefix + "index_shortName" + ChartHelper.suffix + "." + name.split('.' + stakeholderSN + ".")[1]; - indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName.toLowerCase(); - } else if (name.split('.')[0] == "monitor" && parameters.length > 0 && name.split('.')[1] == stakeholder.type) { - // new parameterized queries - //monitor.{{type}}.{{queryname}}.{{param1 - id }}.{{param2 result-type}}.{{fl0}} --> params [start year, end year, id, result type, fl0] - - let index = (name.split('.').slice(3).length + 2 == parameters.length) ? [2] : ((name.split('.').slice(3).length * 2 + 4 == parameters.length) ? [2, name.split('.').slice(3).length + 4] : [0]); - for (let i of index) { - if (name.split('.').length > 3 && name.split('.')[3] == "id") { - parameters[i] = ChartHelper.prefix + "index_id" + ChartHelper.suffix; - indicatorPath.parameters["index_id"] = stakeholder.index_id; - } else if (name.split('.').length > 3 && name.split('.')[3] == "shortname") { - parameters[i] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; - indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName.toLowerCase(); - } else if (name.split('.').length > 3 && name.split('.')[3] == "name") { - parameters[i] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; - indicatorPath.parameters["index_name"] = stakeholder.index_name; - } - } - } - } - } - } - - private extractDataTitle(obj, indicatorPath: IndicatorPath) { - let index = 0; - if (!obj[this.getDescriptionObjectName(obj)] || !obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { - return; - } - for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { - if (query["name"]) { - let name = query["name"]; - query["name"] = ChartHelper.prefix + "data_title_" + index + ChartHelper.suffix; - indicatorPath.parameters["data_title_" + index] = name; - } - index++; - } - } - - private extractTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj[this.getDescriptionObjectName(obj)]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["title"]["text"]; - obj[this.getDescriptionObjectName(obj)]["title"]["text"] = ChartHelper.prefix + "title" + ChartHelper.suffix; - } else if (obj[this.getDescriptionObjectName(obj)]["options"] && obj[this.getDescriptionObjectName(obj)]["options"]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["options"]["title"]; - obj[this.getDescriptionObjectName(obj)]["options"]["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix; - } - indicatorPath.parameters["title"] = title ? title : ""; - } - - private extractSubTitle(obj, indicatorPath: IndicatorPath) { - let subtitle = ""; - if (obj[this.getDescriptionObjectName(obj)]["subtitle"]) { - subtitle = obj[this.getDescriptionObjectName(obj)]["subtitle"]["text"]; - obj[this.getDescriptionObjectName(obj)]["subtitle"]["text"] = ChartHelper.prefix + "subtitle" + ChartHelper.suffix; - indicatorPath.parameters["subtitle"] = subtitle ? subtitle : ""; - } else if (obj[this.getDescriptionObjectName(obj)]["title"] && obj[this.getDescriptionObjectName(obj)]["title"] && obj[this.getDescriptionObjectName(obj)]["title"]["subtext"]) { - subtitle = obj[this.getDescriptionObjectName(obj)]["title"]["subtext"]; - obj[this.getDescriptionObjectName(obj)]["title"]["subtext"] = ChartHelper.prefix + "subtitle" + ChartHelper.suffix; - indicatorPath.parameters["subtitle"] = subtitle ? subtitle : ""; - } - } - - private extractXTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]["text"]; - obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]["text"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix; - } else if (obj[this.getDescriptionObjectName(obj)]["options"] && obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"] && obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"]; - obj[this.getDescriptionObjectName(obj)]["options"]["hAxis"]["title"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix; - } else if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"]) { - title = obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"]; - obj[this.getDescriptionObjectName(obj)]["xAxis"]["name"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix; - } - indicatorPath.parameters["xAxisTitle"] = title ? title : ""; - } - - private extractYTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]["text"]; - obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]["text"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix; - } else if (obj[this.getDescriptionObjectName(obj)]["options"] && obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"] && obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"]) { - title = obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"]; - obj[this.getDescriptionObjectName(obj)]["options"]["vAxis"]["title"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix; - } else if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"]) { - title = obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"]; - obj[this.getDescriptionObjectName(obj)]["yAxis"]["name"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix; - } - indicatorPath.parameters["yAxisTitle"] = title ? title : ""; - } - - private extractOldToolTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj["title"]) { - title = obj["title"]; - obj["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix; - indicatorPath.parameters["title"] = title; - - } - } - - private extractOldToolXTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj["xaxistitle"]) { - title = obj["xaxistitle"]; - obj["xaxistitle"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix; - indicatorPath.parameters["xAxisTitle"] = title; - } - } - - private extractOldToolYTitle(obj, indicatorPath: IndicatorPath) { - let title = ""; - if (obj["fieldsheaders"]) { - title = Array.isArray(obj["fieldsheaders"]) ? obj["fieldsheaders"][0] : obj["fieldsheaders"]; - if (Array.isArray(obj["fieldsheaders"])) { - obj["fieldsheaders"][0] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix; - } else { - obj["fieldsheaders"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix; - } - indicatorPath.parameters["yAxisTitle"] = title; - } - } - - public checkForSchemaEnhancements(url: string): boolean { - return url != this.applySchemaEnhancements(url); - } - - public applySchemaEnhancements(url: string): string { - let resultEnhancements = [ - [".project.acronym", ".project acronym"], - [".project.title", ".project title"], - [".project.funder", ".project funder"], - [".project.funding level 0", ".project funding level 0"], - [".datasource.name", ".HostedBy datasource"], - [".datasource.type", ".HostedBy datasource type"] - ]; - let changes = ""; - for (let field of resultEnhancements) { - for (let type of ["publication", "software", "dataset", "other", "result"]) { - if (url.indexOf(encodeURIComponent(type + field[0])) != -1) { - changes += "Changed " + type + field[0] + " to " + type + field[1] + "\n"; - url = url.split(encodeURIComponent(type + field[0])).join(encodeURIComponent(type + field[1])); - } - } - } - - if (url.split('json=').length > 1) { - let obj = JSON.parse(decodeURIComponent(url.split('json=')[1])); - for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { - if (!query["query"]["profile"] || query["query"]["profile"] == 'OpenAIRE All-inclusive' || query["query"]["profile"] == 'OpenAIRE original') { - changes += (query["query"]["profile"] ? ("Changed profile \"" + query["query"]["profile"] + "\" to ") : "Added profile ") + " \"monitor\""; - query["query"]["profile"] = 'monitor'; - } - } - url = url.split('json=')[0] + "json=" + encodeURIComponent(JSON.stringify(obj)); - } - return url; - } -} diff --git a/src/app/utils/services/cache-indicators.service.ts b/src/app/utils/services/cache-indicators.service.ts deleted file mode 100644 index 64320cb..0000000 --- a/src/app/utils/services/cache-indicators.service.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {Injectable} from "@angular/core"; -import {HttpClient} from "@angular/common/http"; -import {properties} from "../../../environments/environment"; -import {BehaviorSubject, Observable} from "rxjs"; -import {CustomOptions} from "../../openaireLibrary/services/servicesUtils/customOptions.class"; -import {map, tap} from "rxjs/operators"; -import {Report} from "../../../cache-indicators"; - -@Injectable({ - providedIn: 'root' -}) -export class CacheIndicatorsService { - - constructor(private http: HttpClient) { - } - - createReport(alias: string) { - return this.http.post(properties.domain + properties.baseLink + '/cache/' + alias, {}, CustomOptions.registryOptions()) - .pipe(map(res => res.report)); - } - - getReport(alias: string) { - return this.http.get(properties.domain + properties.baseLink + '/cache/' + alias, CustomOptions.registryOptions()) - .pipe(map(res => res.report)); - } -} diff --git a/src/app/utils/services/statistics.service.ts b/src/app/utils/services/statistics.service.ts deleted file mode 100644 index 49defe2..0000000 --- a/src/app/utils/services/statistics.service.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {Injectable} from '@angular/core'; -import {HttpClient} from "@angular/common/http"; -import {Observable} from "rxjs"; -import {SourceType} from "../../openaireLibrary/monitor/entities/stakeholder"; -import {properties} from "../../../environments/environment"; -import {IndicatorUtils} from "../indicator-utils"; - - -@Injectable({ - providedIn: 'root' -}) -export class StatisticsService { - - indicatorsUtils = new IndicatorUtils(); - - constructor(private http: HttpClient) {} - - getNumbers(source: SourceType, url: string): Observable { - if (source !== null) { - return this.http.get(this.indicatorsUtils.getNumberUrl(source, url)); - } else { - return this.http.get(url); - } - } -} diff --git a/src/app/utils/services/stats-profiles.service.ts b/src/app/utils/services/stats-profiles.service.ts deleted file mode 100644 index 0698ea6..0000000 --- a/src/app/utils/services/stats-profiles.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {Injectable} from "@angular/core"; -import {HttpClient} from "@angular/common/http"; -import {properties} from "../../../environments/environment"; -import {Observable} from "rxjs"; -import {CustomOptions} from "../../openaireLibrary/services/servicesUtils/customOptions.class"; -import {map} from "rxjs/operators"; - -@Injectable({ - providedIn: 'root' -}) -export class StatsProfilesService { - - constructor(private http: HttpClient) { - } - - getStatsProfiles(): Observable { - return this.http.get(properties.monitorStatsFrameUrl + 'schema/profiles') - .pipe(map(profiles => profiles.map(profile => profile.name))); - } -} diff --git a/src/cache-indicators.ts b/src/cache-indicators.ts deleted file mode 100644 index 8817488..0000000 --- a/src/cache-indicators.ts +++ /dev/null @@ -1,262 +0,0 @@ -import {IndicatorType, Stakeholder} from "./app/openaireLibrary/monitor/entities/stakeholder"; -import axios from "axios"; -import {IndicatorUtils} from "./app/utils/indicator-utils"; -import {Composer} from "./app/openaireLibrary/utils/email/composer"; -import {properties} from "./environments/environment"; -import {error} from "protractor"; - - -export interface CacheItem { - reportId: string, - type: IndicatorType, - url: string -} - -export class Report { - creator: string; - name: string; - success: number; - errors: { - url: string, - status: number - }[]; - total: number; - completed: boolean; - percentage: number - - constructor(total: number, name: string, creator: string) { - this.creator = creator; - this.name = name; - this.success = 0; - this.errors = []; - this.total = total; - this.completed = false; - } - - setPercentage() { - this.percentage = Math.floor((this.success + this.errors.length) / this.total * 100); - } -} - -export class CacheIndicators { - - private static BATCH_SIZE = 10; - - private reports: Map = new Map(); - private queue: CacheItem[] = []; - private process: Promise; - private isFinished: boolean = true; - - stakeholderToCacheItems(stakeholder: Stakeholder) { - let cacheItems: CacheItem[] = []; - let indicatorUtils = new IndicatorUtils(); - stakeholder.topics.forEach(topic => { - topic.categories.forEach(category => { - category.subCategories.forEach(subCategory => { - subCategory.numbers.forEach(section => { - section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - let url = indicatorUtils.getNumberUrl(indicatorPath.source, indicatorUtils.getFullUrl(stakeholder, indicatorPath)); - cacheItems.push({ - reportId: stakeholder._id, - type: 'number', - url: url - }); - }); - }); - }); - subCategory.charts.forEach(section => { - section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - let url = indicatorUtils.getChartUrl(indicatorPath.source, indicatorUtils.getFullUrl(stakeholder, indicatorPath)); - cacheItems.push({ - reportId: stakeholder._id, - type: 'chart', - url: url - }); - }); - }); - }); - }); - }); - }); - return cacheItems; - } - - public exists(id: string) { - return this.reports.has(id); - } - - public completed(id: string) { - return !this.exists(id) || this.reports.get(id).completed; - } - - public createReport(id: string, cacheItems: CacheItem[], name: string, creator: string) { - let report = new Report(cacheItems.length, name, creator); - this.reports.set(id, report); - this.addItemsToQueue(cacheItems); - return report; - } - - public getReport(id: string) { - return this.reports.get(id); - } - - private async processQueue() { - this.isFinished = false; - while (this.queue.length > 0) { - let batch = this.queue.splice(0, CacheIndicators.BATCH_SIZE); - await this.processBatch(batch); - } - } - - private async processBatch(batch: CacheItem[]) { - let promises: Promise[] = []; - let ids = new Set(); - batch.forEach(item => { - let promise; - ids.add(item.reportId); - if (item.type === 'chart') { - let [url, json] = item.url.split('?json='); - json = decodeURIComponent(json); - json = statsToolParser(JSON.parse(json)); - promise = axios.post(url, json); - } else { - promise = axios.get(item.url); - } - promises.push(promise.then(response => { - let report = this.reports.get(item.reportId); - if (report) { - report.success++; - report.setPercentage(); - } - return response; - }).catch(error => { - let report = this.reports.get(item.reportId); - if (report) { - report.errors.push({url: item.url, status: error.response.status}); - report.setPercentage(); - } - return error.response; - })); - }); - await Promise.all(promises); - ids.forEach(id => { - let report = this.reports.get(id); - if (report?.percentage === 100) { - report.completed = true; - this.sendEmail(report); - } - }); - } - - private addItemsToQueue(cacheItems: CacheItem[]) { - cacheItems.forEach(item => { - this.queue.push(item); - }); - if (this.isFinished) { - this.processQueue().then(() => { - this.isFinished = true; - }); - } - } - - sendEmail(report: Report) { - let email = Composer.composeEmailToReportCachingProcess(report); - axios.post(properties.adminToolsAPIURL + "sendMail/", email).catch(error => { - console.error(error); - }); - } -} - -export function statsToolParser(dataJSONobj: any): any { - let RequestInfoObj = Object.assign({}); - switch (dataJSONobj.library) { - case "GoogleCharts": - //Pass the Chart library to ChartDataFormatter - RequestInfoObj.library = dataJSONobj.library; - RequestInfoObj.orderBy = dataJSONobj.orderBy; - - //Create ChartInfo Object Array - RequestInfoObj.chartsInfo = []; - //Create ChartInfo and pass the Chart data queries to ChartDataFormatter - //along with the requested Chart type - RequestInfoObj.chartsInfo = dataJSONobj.chartDescription.queriesInfo; - break; - case "eCharts": - //Pass the Chart library to ChartDataFormatter - RequestInfoObj.library = dataJSONobj.library; - RequestInfoObj.orderBy = dataJSONobj.orderBy; - - //Create ChartInfo Object Array - RequestInfoObj.chartsInfo = []; - - //Create ChartInfo and pass the Chart data queries to ChartDataFormatter - //along with the requested Chart type - for (let index = 0; index < dataJSONobj.chartDescription.queries.length; index++) { - let element = dataJSONobj.chartDescription.queries[index]; - var ChartInfoObj = Object.assign({}); - - if (element.type === undefined) - ChartInfoObj.type = dataJSONobj.chartDescription.series[index].type; - else - ChartInfoObj.type = element.type; - - if (element.name === undefined) - ChartInfoObj.name = null; - else - ChartInfoObj.name = element.name; - - ChartInfoObj.query = element.query; - RequestInfoObj.chartsInfo.push(ChartInfoObj); - } - break; - case "HighCharts": - RequestInfoObj.library = dataJSONobj.library; - RequestInfoObj.orderBy = dataJSONobj.orderBy; - //Pass the Chart type to ChartDataFormatter - var defaultType = dataJSONobj.chartDescription.chart.type; - //Create ChartInfo Object Array - RequestInfoObj.chartsInfo = []; - //Create ChartInfo and pass the Chart data queries to ChartDataFormatter - //along with the requested Chart type - dataJSONobj.chartDescription.queries.forEach(element => { - var ChartInfoObj = Object.assign({}); - - if (element.type === undefined) - ChartInfoObj.type = defaultType; - else - ChartInfoObj.type = element.type; - - if (element.name === undefined) - ChartInfoObj.name = null; - else - ChartInfoObj.name = element.name; - - ChartInfoObj.query = element.query; - RequestInfoObj.chartsInfo.push(ChartInfoObj); - }); - break; - case "HighMaps": - RequestInfoObj.library = dataJSONobj.library; - //Create ChartInfo Object Array - RequestInfoObj.chartsInfo = []; - - //Create ChartInfo and pass the Chart data queries to ChartDataFormatter - dataJSONobj.mapDescription.queries.forEach(element => { - var ChartInfoObj = Object.assign({}); - - if (element.name === undefined) - ChartInfoObj.name = null; - else - ChartInfoObj.name = element.name; - - ChartInfoObj.query = element.query; - RequestInfoObj.chartsInfo.push(ChartInfoObj); - }); - break; - default: - console.log("Unsupported Library: " + dataJSONobj.library); - } - return RequestInfoObj; -} -- 2.17.1 From b50411c396143bca46f2269234ed796b5faf35cd Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 20 Oct 2023 19:07:56 +0300 Subject: [PATCH 15/18] [monitor-admin-library | DONE | CHANGED]: Move general in library --- .../admin-stakeholder-routing.module.ts | 2 +- .../edit-stakeholder.component.less | 10 - .../edit-stakeholder.component.ts | 443 ------------------ .../edit-stakeholder.module.ts | 14 - src/app/general/general-routing.module.ts | 19 - src/app/general/general.component.html | 29 -- src/app/general/general.component.ts | 75 --- src/app/general/general.module.ts | 40 -- .../manageStakeholders.component.ts | 2 +- .../manageStakeholders.module.ts | 2 +- src/app/openaireLibrary | 2 +- 11 files changed, 4 insertions(+), 634 deletions(-) delete mode 100644 src/app/general/edit-stakeholder/edit-stakeholder.component.less delete mode 100644 src/app/general/edit-stakeholder/edit-stakeholder.component.ts delete mode 100644 src/app/general/edit-stakeholder/edit-stakeholder.module.ts delete mode 100644 src/app/general/general-routing.module.ts delete mode 100644 src/app/general/general.component.html delete mode 100644 src/app/general/general.component.ts delete mode 100644 src/app/general/general.module.ts diff --git a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts index 57a5a62..656baa3 100644 --- a/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts +++ b/src/app/admin-stakeholder/admin-stakeholder-routing.module.ts @@ -6,7 +6,7 @@ import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; imports: [RouterModule.forChild([ { path: '', - loadChildren: () => import('../general/general.module').then(m => m.GeneralModule), + loadChildren: () => import('../openaireLibrary/monitor-admin/general/general.module').then(m => m.GeneralModule), pathMatch: 'full' }, { diff --git a/src/app/general/edit-stakeholder/edit-stakeholder.component.less b/src/app/general/edit-stakeholder/edit-stakeholder.component.less deleted file mode 100644 index e5f71cd..0000000 --- a/src/app/general/edit-stakeholder/edit-stakeholder.component.less +++ /dev/null @@ -1,10 +0,0 @@ -.uk-border-circle { - width: 100px; - height: 100px; - position: relative; - - & > img { - max-width: 64px; - max-height: 64px; - } -} diff --git a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts b/src/app/general/edit-stakeholder/edit-stakeholder.component.ts deleted file mode 100644 index b66b680..0000000 --- a/src/app/general/edit-stakeholder/edit-stakeholder.component.ts +++ /dev/null @@ -1,443 +0,0 @@ -import {Component, Input, OnDestroy, ViewChild} from "@angular/core"; -import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder"; -import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; -import {StakeholderUtils} from "../../openaireLibrary/monitor-admin/utils/indicator-utils"; -import {Option} from "../../openaireLibrary/sharedComponents/input/input.component"; -import {Subscription} from "rxjs"; -import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties"; -import {properties} from "../../../environments/environment"; -import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service"; -import {UtilitiesService} from "../../openaireLibrary/services/utilities.service"; -import {Role, Session, User} from "../../openaireLibrary/login/utils/helper.class"; -import {UserManagementService} from "../../openaireLibrary/services/user-management.service"; -import {StringUtils} from "../../openaireLibrary/utils/string-utils.class"; -import {NotifyFormComponent} from "../../openaireLibrary/notifications/notify-form/notify-form.component"; -import {NotificationUtils} from "../../openaireLibrary/notifications/notification-utils"; -import {Notification} from "../../openaireLibrary/notifications/notifications"; -import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler"; -import {StatsProfilesService} from "../../openaireLibrary/monitor-admin/utils/services/stats-profiles.service"; - -@Component({ - selector: 'edit-stakeholder', - template: ` -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    - OR -
    -
    -
    -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    {{uploadError}}
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - `, - styleUrls: ['edit-stakeholder.component.less'] -}) -export class EditStakeholderComponent implements OnDestroy { - @Input() - public disableAlias: boolean = false; - public stakeholderFb: UntypedFormGroup; - public secure: boolean = false; - public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); - public defaultStakeholdersOptions: Option[]; - public defaultStakeholders: Stakeholder[]; - public alias: string[]; - public stakeholder: Stakeholder; - public isDefault: boolean; - public isNew: boolean; - public loading: boolean = false; - public types: Option[]; - public statsProfiles: string[]; - public properties: EnvProperties = properties; - private subscriptions: any[] = []; - /** - * Photo upload - * */ - public file: File; - public photo: string | ArrayBuffer; - public uploadError: string; - public deleteCurrentPhoto: boolean = false; - private maxsize: number = 200 * 1024; - user: User; - @ViewChild('notify', {static: true}) notify: NotifyFormComponent; - private notification: Notification; - - constructor(private fb: UntypedFormBuilder, - private stakeholderService: StakeholderService, - private statsProfileService: StatsProfilesService, - private utilsService: UtilitiesService, private userManagementService: UserManagementService,) { - } - - ngOnDestroy() { - this.reset(); - } - - public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean) { - this.reset(); - this.deleteCurrentPhoto = false; - this.stakeholder = stakeholder; - this.alias = alias; - this.defaultStakeholders = defaultStakeholders; - this.isDefault = isDefault; - this.isNew = isNew; - this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { - this.user = user; - if (this.isCurator) { - this.subscriptions.push(this.statsProfileService.getStatsProfiles().subscribe(statsProfiles => { - this.statsProfiles = statsProfiles; - }, error => { - this.statsProfiles = []; - })); - } else { - this.statsProfiles = []; - } - this.types = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias); - this.stakeholderFb = this.fb.group({ - _id: this.fb.control(this.stakeholder._id), - defaultId: this.fb.control(this.stakeholder.defaultId), - name: this.fb.control(this.stakeholder.name, Validators.required), - description: this.fb.control(this.stakeholder.description), - index_name: this.fb.control(this.stakeholder.index_name, Validators.required), - index_id: this.fb.control(this.stakeholder.index_id, Validators.required), - index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required), - statsProfile: this.fb.control(this.stakeholder.statsProfile, Validators.required), - locale: this.fb.control(this.stakeholder.locale, Validators.required), - projectUpdateDate: this.fb.control(this.stakeholder.projectUpdateDate), - creationDate: this.fb.control(this.stakeholder.creationDate), - alias: this.fb.control(this.stakeholder.alias, - [ - Validators.required, - this.stakeholderUtils.aliasValidatorString( - this.alias.filter(alias => alias !== this.stakeholder.alias) - )] - ), - isDefault: this.fb.control((this.isDefault)), - visibility: this.fb.control(this.stakeholder.visibility, Validators.required), - type: this.fb.control(this.stakeholder.type, Validators.required), - topics: this.fb.control(this.stakeholder.topics), - isUpload: this.fb.control(this.stakeholder.isUpload), - logoUrl: this.fb.control(this.stakeholder.logoUrl), - }); - if (this.stakeholder.isUpload) { - this.stakeholderFb.get('logoUrl').clearValidators(); - this.stakeholderFb.get('logoUrl').updateValueAndValidity(); - } else { - this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]); - this.stakeholderFb.get('logoUrl').updateValueAndValidity(); - } - this.subscriptions.push(this.stakeholderFb.get('isUpload').valueChanges.subscribe(value => { - if (value == true) { - this.stakeholderFb.get('logoUrl').clearValidators(); - this.stakeholderFb.updateValueAndValidity(); - } else { - this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]); - this.stakeholderFb.updateValueAndValidity(); - } - })); - this.secure = (!this.stakeholderFb.get('logoUrl').value || this.stakeholderFb.get('logoUrl').value.includes('https://')); - this.subscriptions.push(this.stakeholderFb.get('logoUrl').valueChanges.subscribe(value => { - this.secure = (!value || value.includes('https://')); - })); - this.initPhoto(); - this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => { - this.onTypeChange(value, defaultStakeholders); - })); - this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required)); - if (!this.isNew) { - this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.notify.reset(this.notification.message); - if (this.isAdmin) { - if (this.disableAlias) { - setTimeout(() => { - this.stakeholderFb.get('alias').disable(); - }, 0); - } - } else { - if (!this.isCurator) { - setTimeout(() => { - this.stakeholderFb.get('statsProfile').disable(); - }, 0); - } - setTimeout(() => { - this.stakeholderFb.get('alias').disable(); - this.stakeholderFb.get('index_id').disable(); - this.stakeholderFb.get('index_name').disable(); - this.stakeholderFb.get('index_shortName').disable(); - }, 0); - } - setTimeout(() => { - this.stakeholderFb.get('type').disable(); - }, 0); - } else { - this.notification = NotificationUtils.createStakeholder(this.user.firstname + ' ' + this.user.lastname); - this.notify.reset(this.notification.message); - setTimeout(() => { - this.stakeholderFb.get('type').enable(); - }, 0); - } - })); - } - - public get isAdmin() { - return Session.isPortalAdministrator(this.user); - } - - public get isCurator() { - return this.stakeholder && (this.isAdmin || Session.isCurator(this.stakeholder.type, this.user)); - } - - public get disabled(): boolean { - return (this.stakeholderFb && this.stakeholderFb.invalid) || - (this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) || - (this.uploadError && this.uploadError.length > 0); - } - - public get dirty(): boolean { - return this.stakeholderFb && this.stakeholderFb.dirty; - } - - public get canChooseTemplate(): boolean { - return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions; - } - - reset() { - this.uploadError = null; - this.stakeholderFb = null; - this.subscriptions.forEach(subscription => { - if (subscription instanceof Subscription) { - subscription.unsubscribe(); - } - }); - } - - onTypeChange(value, defaultStakeholders: Stakeholder[]) { - this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required)); - this.defaultStakeholdersOptions = [{ - label: 'New blank profile', - value: '-1' - }]; - defaultStakeholders.filter(stakeholder => stakeholder.type === value).forEach(stakeholder => { - this.defaultStakeholdersOptions.push({ - label: 'Use ' + stakeholder.name + ' profile', - value: stakeholder._id - }) - }); - } - - public save(callback: Function, errorCallback: Function = null) { - this.loading = true; - if (this.file) { - this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/" + encodeURIComponent(this.stakeholderFb.getRawValue().type) + "/" + encodeURIComponent(this.stakeholderFb.getRawValue().alias), this.file).subscribe(res => { - this.deletePhoto(); - this.stakeholderFb.get('logoUrl').setValue(res.filename); - this.removePhoto(); - this.saveStakeholder(callback, errorCallback); - }, error => { - this.uploadError = "An error has been occurred during upload your image. Try again later"; - this.saveStakeholder(callback, errorCallback); - })); - } else if (this.deleteCurrentPhoto) { - this.deletePhoto(); - this.saveStakeholder(callback, errorCallback); - } else { - this.saveStakeholder(callback, errorCallback); - } - } - - public saveStakeholder(callback: Function, errorCallback: Function = null) { - if (this.isNew) { - let defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId); - this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(), - (defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault)); - this.removePhoto(); - if(this.stakeholderFb.getRawValue().isDefault) { - this.stakeholderFb.get('defaultId').setValue(null); - } - this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, - this.stakeholderFb.getRawValue()).subscribe(stakeholder => { - this.notification.entity = stakeholder._id; - this.notification.stakeholder = stakeholder.alias; - this.notification.stakeholderType = stakeholder.type; - this.notification.groups = [Role.curator(stakeholder.type)]; - this.notify.sendNotification(this.notification); - NotificationHandler.rise(stakeholder.name + ' has been successfully created'); - callback(stakeholder); - this.loading = false; - }, error => { - NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - if (errorCallback) { - errorCallback(error) - } - this.loading = false; - })); - } else { - this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue()).subscribe(stakeholder => { - this.notification.entity = stakeholder._id; - this.notification.stakeholder = stakeholder.alias; - this.notification.stakeholderType = stakeholder.type; - this.notification.groups = [Role.curator(stakeholder.type), Role.manager(stakeholder.type, stakeholder.alias)]; - this.notify.sendNotification(this.notification); - NotificationHandler.rise(stakeholder.name + ' has been successfully saved'); - callback(stakeholder); - this.loading = false; - }, error => { - NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - if (errorCallback) { - errorCallback(error) - } - this.loading = false; - })); - } - } - - fileChangeEvent(event) { - if (event.target.files && event.target.files[0]) { - this.file = event.target.files[0]; - if (this.file.type !== 'image/png' && this.file.type !== 'image/jpeg') { - this.uploadError = 'You must choose a file with type: image/png or image/jpeg!'; - this.stakeholderFb.get('isUpload').setValue(false); - this.stakeholderFb.get('isUpload').markAsDirty(); - this.removePhoto(); - } else if (this.file.size > this.maxsize) { - this.uploadError = 'File exceeds size\'s limit! Maximum resolution is 256x256 pixels.'; - this.stakeholderFb.get('isUpload').setValue(false); - this.stakeholderFb.get('isUpload').markAsDirty(); - this.removePhoto(); - } else { - this.uploadError = null; - const reader = new FileReader(); - reader.readAsDataURL(this.file); - reader.onload = () => { - this.photo = reader.result; - this.stakeholderFb.get('isUpload').setValue(true); - this.stakeholderFb.get('isUpload').markAsDirty(); - }; - } - } - } - - initPhoto() { - if (this.stakeholderFb.getRawValue().isUpload) { - this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value; - } - } - - removePhoto() { - if (this.file) { - if (typeof document != 'undefined') { - (document.getElementById("photo")).value = ""; - } - this.initPhoto(); - this.file = null; - } - } - - remove() { - this.stakeholderFb.get('isUpload').setValue(false); - this.stakeholderFb.get('isUpload').markAsDirty(); - this.removePhoto(); - this.stakeholderFb.get('logoUrl').setValue(null); - if (this.stakeholder.isUpload) { - this.deleteCurrentPhoto = true; - } - } - - public deletePhoto() { - if (this.stakeholder.logoUrl && this.stakeholder.isUpload) { - this.subscriptions.push(this.utilsService.deletePhoto(this.properties.utilsService + '/delete/' + - encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholder.alias) + "/" + this.stakeholder.logoUrl).subscribe()); - } - } -} diff --git a/src/app/general/edit-stakeholder/edit-stakeholder.module.ts b/src/app/general/edit-stakeholder/edit-stakeholder.module.ts deleted file mode 100644 index 6f08416..0000000 --- a/src/app/general/edit-stakeholder/edit-stakeholder.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {NgModule} from "@angular/core"; -import {EditStakeholderComponent} from "./edit-stakeholder.component"; -import {CommonModule} from "@angular/common"; -import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module"; -import {ReactiveFormsModule} from "@angular/forms"; -import {IconsModule} from "../../openaireLibrary/utils/icons/icons.module"; -import {NotifyFormModule} from "../../openaireLibrary/notifications/notify-form/notify-form.module"; - -@NgModule({ - imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule], - declarations: [EditStakeholderComponent], - exports: [EditStakeholderComponent] -}) -export class EditStakeholderModule {} diff --git a/src/app/general/general-routing.module.ts b/src/app/general/general-routing.module.ts deleted file mode 100644 index 0dec748..0000000 --- a/src/app/general/general-routing.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {NgModule} from '@angular/core'; -import {RouterModule} from '@angular/router'; -import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard'; -import {GeneralComponent} from "./general.component"; - -@NgModule({ - imports: [ - RouterModule.forChild([ - { - path: '', - component: GeneralComponent, - canDeactivate: [PreviousRouteRecorder], - data: {hasSidebar: true} - } - ]) - ] -}) -export class GeneralRoutingModule { -} diff --git a/src/app/general/general.component.html b/src/app/general/general.component.html deleted file mode 100644 index b6617a5..0000000 --- a/src/app/general/general.component.html +++ /dev/null @@ -1,29 +0,0 @@ -
    -
    - -
    -
    - - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    diff --git a/src/app/general/general.component.ts b/src/app/general/general.component.ts deleted file mode 100644 index 03045f0..0000000 --- a/src/app/general/general.component.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from "@angular/core"; -import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; -import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"; -import {Stakeholder} from "../openaireLibrary/monitor/entities/stakeholder"; -import { Subscription, zip} from "rxjs"; -import {EditStakeholderComponent} from "./edit-stakeholder/edit-stakeholder.component"; -import {properties} from "../../environments/environment"; -import {Title} from "@angular/platform-browser"; - -@Component({ - selector: 'general', - templateUrl: "./general.component.html" -}) -export class GeneralComponent implements OnInit, OnDestroy { - - public stakeholder: Stakeholder; - public alias: string[]; - public properties: EnvProperties = properties; - public defaultStakeholders: Stakeholder[]; - public loading: boolean = false; - private subscriptions: any[] = []; - @ViewChild('editStakeholderComponent') editStakeholderComponent: EditStakeholderComponent; - - constructor(private stakeholderService: StakeholderService, - private cdr: ChangeDetectorRef, - private title: Title) { - } - - ngOnInit() { - this.loading = true; - this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { - this.stakeholder = stakeholder; - this.cdr.detectChanges(); - if(this.stakeholder) { - this.title.setTitle(this.stakeholder.name + " | General"); - let data = zip( - this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL), - this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL) - ); - this.subscriptions.push(data.subscribe(res => { - this.defaultStakeholders = res[0]; - this.alias = res[1]; - this.reset(); - this.loading = false; - })); - } - })); - } - - public reset() { - this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, this.stakeholder.defaultId == null, false) - } - - - public save() { - this.loading = true; - this.editStakeholderComponent.save((stakeholder) => { - this.stakeholder = stakeholder; - this.stakeholderService.setStakeholder(this.stakeholder); - this.reset(); - this.loading = false; - }, (error) => { - console.error(error); - this.loading = false; - }); - } - - ngOnDestroy() { - this.subscriptions.forEach(subscription => { - if(subscription instanceof Subscription) { - subscription.unsubscribe(); - } - }); - } -} diff --git a/src/app/general/general.module.ts b/src/app/general/general.module.ts deleted file mode 100644 index 054c309..0000000 --- a/src/app/general/general.module.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {NgModule} from "@angular/core"; -import {GeneralComponent} from "./general.component"; -import {GeneralRoutingModule} from "./general-routing.module"; -import {PreviousRouteRecorder} from "../openaireLibrary/utils/piwik/previousRouteRecorder.guard"; -import {CommonModule} from "@angular/common"; -import {RouterModule} from "@angular/router"; -import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module"; -import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module"; -import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module"; -import {ReactiveFormsModule} from "@angular/forms"; -import {EditStakeholderModule} from "./edit-stakeholder/edit-stakeholder.module"; -import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module"; -import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module"; -import { - SidebarMobileToggleModule -} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module"; - -@NgModule({ - declarations: [GeneralComponent], - imports: [ - GeneralRoutingModule, - CommonModule, - RouterModule, - InputModule, - LoadingModule, - AlertModalModule, - ReactiveFormsModule, - EditStakeholderModule, - PageContentModule, - LogoUrlPipeModule, - SidebarMobileToggleModule - ], - providers: [ - PreviousRouteRecorder, - ], - exports: [GeneralComponent] -}) -export class GeneralModule { - -} diff --git a/src/app/manageStakeholders/manageStakeholders.component.ts b/src/app/manageStakeholders/manageStakeholders.component.ts index 57cd300..094e045 100644 --- a/src/app/manageStakeholders/manageStakeholders.component.ts +++ b/src/app/manageStakeholders/manageStakeholders.component.ts @@ -10,7 +10,7 @@ import {Option} from "../openaireLibrary/sharedComponents/input/input.component" import {Title} from "@angular/platform-browser"; import {UserManagementService} from "../openaireLibrary/services/user-management.service"; import {Session} from "../openaireLibrary/login/utils/helper.class"; -import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component"; +import {EditStakeholderComponent} from "../openaireLibrary/monitor-admin/general/edit-stakeholder/edit-stakeholder.component"; import {properties} from "../../environments/environment"; import {ActivatedRoute} from "@angular/router"; import {CacheIndicatorsService} from "../openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.service"; diff --git a/src/app/manageStakeholders/manageStakeholders.module.ts b/src/app/manageStakeholders/manageStakeholders.module.ts index 612c671..230c644 100644 --- a/src/app/manageStakeholders/manageStakeholders.module.ts +++ b/src/app/manageStakeholders/manageStakeholders.module.ts @@ -8,7 +8,6 @@ import {InputModule} from "../openaireLibrary/sharedComponents/input/input.modul import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module"; import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module"; import {ReactiveFormsModule} from "@angular/forms"; -import {EditStakeholderModule} from "../general/edit-stakeholder/edit-stakeholder.module"; import {IconsModule} from "../openaireLibrary/utils/icons/icons.module"; import {IconsService} from "../openaireLibrary/utils/icons/icons.service"; import {earth, incognito, restricted} from "../openaireLibrary/utils/icons/icons"; @@ -19,6 +18,7 @@ import { SidebarMobileToggleModule } from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module"; import {SliderTabsModule} from "../openaireLibrary/sharedComponents/tabs/slider-tabs.module"; +import {EditStakeholderModule} from "../openaireLibrary/monitor-admin/general/edit-stakeholder/edit-stakeholder.module"; @NgModule({ declarations: [ManageStakeholdersComponent], diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index de3fbe8..1710819 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit de3fbe8d69ebab14da17913704db3f6a0e35983a +Subproject commit 1710819fb9d35bedeaca4d85db664b8f79be2e76 -- 2.17.1 From a7f1dd809fb7dfd92e5ae3ed8c4d96f3ed2f695f Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 24 Oct 2023 11:57:53 +0300 Subject: [PATCH 16/18] Update library after merge with monitor-admin-library --- src/app/openaireLibrary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 1710819..8647136 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 1710819fb9d35bedeaca4d85db664b8f79be2e76 +Subproject commit 864713680315a5c9bf0cf4323b428547e04db957 -- 2.17.1 From 0be362e6467b11e3e9a3681954f4d481a2db5d9e Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Wed, 25 Oct 2023 15:16:39 +0300 Subject: [PATCH 17/18] [angular-16 | DONE | CHANGED]: Make dashboard-sidebar sticky instead of fixed. --- src/app/app.component.html | 18 +++++++++--------- src/app/openaireLibrary | 2 +- src/assets/common-assets | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index 3d850d9..78a4651 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,23 +2,23 @@
    -